|1930 - meetup|
Interfacing simple electronics with computer WITHOUT ARDUINO
From time to time i want to interface few simple ad-hoc circuits with my computer and i do not want to use arduino for such trivial tasks. Arduino is much more than USB connected I/O port and i see no reason for using it for tasks which can be done using $2 soundcards…
These are few of tasks that can be solved using soundcard and common audio equipment:
Note there are few more related projects like audioport for example.
After being inspired by Biofeedback, Brain hacking project, i've decided that i want to log my motions during sleep for later analysis. I've had PIR motion detector which has quite simple analogue interface. You power it up using 12V and connect what you need to internal NC switch (relay that conducts electricity when no motion is detected and stop conducting for a monment when motion is detected). I wanted my sleep-motion log to contain real time clock. That would mean that i need to make arduino keep RTC and store lots of data, which is very inconvenient. Another solution is to connect arduino to Linux box and use it just to signal PIR sensor state while computer will be doing all the logging. This is much more convenient but wait! Do i really need arduino? I can connect PIR sensor using old keyboard or even my soundcard!
Well so i want to interface device which is acting as NC switch with my soundcard… If i connect it directly to microphone input of my soundcard i will probably get nothing more than clicks that will be quite hard to analyze and i will probably not be able to safely tell wheter switch is switched on or off. I had to take everything to another level. I can take some beeping sound generated by some kind of simple 555 oscillator, switch it using my switch and then record it. Sounds like a plan. But then i realized it again… OMG i still have the computer, i can use it to generate sounds for me.
So all i need to do is launch some program that will generate sine wave for me (eg.: alsa-utils: speaker-test -t sine) and then i will just route the sound trough PIR sensor and using soundcard again back to computer. Computer will record sound at very low quality using arecord (from alsa-utils again) and then i will be able to analyze state of PIR sensor in time using any audio-editing software which can plot it on the screen. So i've written simple sleepmonitor script to automatically generate sinewave while recording to low-quality wav file with date in it's name.
__________ | ___ _______ __________| / \/ \/ | 3.5mm Stereo Jack | || || | | || || | (Mono version has right and \___/\_______/\__________| ground merged in single pole) | ^ ^ ^ |___________ * LEFT | | * RIGHT | * GROUND ___________ | | | PIR | LEFT =---------+ | | Soundcard INPUT GROUND =--+ | | | | | | | | +-----|-o/ NC | | +-----|-/ Switch | Soundcard OUTPUT GROUND =--+ | | | LEFT =---------+ | | | 12V Power | | + - | |__|__|_____| | | To supply
But that was not enough for me. I wanted to detect the presence of sound and generate structured log that can be analyzed afterwards. Some time ago i've been writing software called “beatdetect” which should be triggering some software events based on sound input, but it doesn't performed very well as it had no clue of time or frequency domain. It just triggered event anytime when some audio sample had value bigger than treshold. It was missing few sounds and having lots of false possitives. But i've learned some stuff since those times and i know that if you need to react to the audio signal, you have to react to measurings done in frequency domain - simply measuring intensity of signal is not enough. So i decided to write better software.
You probbably know that you can use (Discrete) (Fast) Fourrier Transform to detect frequencies in audio signal, but i've read some article some time ago and i've found that Goertzel Algorithm will suit my needs much better. While FFT will give you full range of frequencies contained in sampled audio, Goertzel will only give you magnitude of frequencies you wanted to know, but it will do the job quite faster using less complex code. That's exactly what i needed. I just need to detect the single frequeny generated by alsa's speaker-test (which is 440Hz by default). I've googled a bit and found nice implementation of Goertzel in C. So i've decided to write some nice scriptable program around it and so i've done. You can find it here: https://github.com/Harvie/Programs/tree/master/c/goertzel
Once i've created scriptable goertzel binary there were lot's of thinks that we can do with it while using just little bash, eg.:
Now the BASH script takes report from the goertzel analysis and translates it to nice log, which is the thing i was looking for:
0.00 1343981413 2012-08-03 10:10:13 0 (Nothing 115 After 1 secs) 27.75 1343981441 2012-08-03 10:10:41 1 (MOTION! 1 After 28 secs) 31.75 1343981445 2012-08-03 10:10:45 0 (Nothing 33 After 4 secs) 48.00 1343981461 2012-08-03 10:11:01 1 (MOTION! 2 After 16 secs) 58.25 1343981471 2012-08-03 10:11:11 0 (Nothing 74 After 10 secs) 58.75 1343981472 2012-08-03 10:11:12 1 (MOTION! 0 After 1 secs) 61.25 1343981474 2012-08-03 10:11:14 0 (Nothing 83 After 2 secs) 65.75 1343981479 2012-08-03 10:11:19 1 (MOTION! 1 After 5 secs) 79.50 1343981493 2012-08-03 10:11:33 0 (Nothing 85 After 14 secs)
And i've been even able to graph my motions using gnuplot to make it simpler to analyze: I think that some kind of periodicity of sleep cycle can be clearly seen in graph. Next step is to make software that will set my alarm to wake me up in some comfortable phase (the phase with lots of movements is when you can wake up full of energy)
Once i have signals from PIR in bash you can use it to controll anything you want… For me it seemed to be fun to control lcd backlight using (xset dpms force on/off command):
Goertzel.c is also capable of omitting irrelevant lines from report, so BASH overhead is minimized because data are passed to BASH only when something interesting changes. Program can be configured to let us know only when magnitude of some frequency in signal crosses treshold value. This lowers latency of whole architecture by doing most of processing directly in C code, so BASH script will get notified only when switch changes it's state.
We also do not need to debounce switches connected to soundcard as bounces does not have big effect in frequency domain.
Another good thing about this approach is that we can connect lots of switches to single soundcard input. All we need is make them switch different frequencies that do not interferre with each other. Which means that we can connect 2-4 switches using single stereo soundcard (it can generate two different frequencies - one in each channel and both of them can be routed to two inputs if properly separated). If we build some external source of signal we can connect much more switches using more frequencies.
BTW you can also find Goertzel for Arduino which can enable you to controll your robots using soundcard, android phone, FM tuner & transmitter or even mp3 player if you don't mind loss of interactivity. Anyway this can be achieved by simple analogue passive envelope demodulator.
It is possible to controll servos using soundcard or any similar device capable of audio output. Servo motors have 3 wires: ground, power and PWM signal. While ground is common, power can be obtained from battery or DC adapter and PWM signal can be generated by uC or such kind of device like soundcard or MP3 player.