Electron Pi

My notebook on Raspberry Pi and Arduino projects

Tag Archives: Arduino

Feedback – an Arduino, a servo and a photocell

Ages back I was looking at feedback loops with transistors. This time, I’m going out beyond the circuit board, and using a servo and a photocell. I thought – what’s the simplest possible feedback loop system that could be interesting? We need one sensor and one actuator. For a sensor – people seem to go for photocells (i.e. photoresistors) as a good first sensor to play with. And for an actuator – servo motors are easy to play with, if you’ve got an Arduino. So why don’t we put a photocell on a servo motor?

Of course, anything to do with this hobby involves a lot of fuss over side issues. For me, the fuss involved getting tooled up to cut a small bit of plywood to attach to the servo motor to act as a long arm. However, once all that was in place, the rest of it was fairly easy to set up. The best way to show things – video:

This started from the Knob example, which lets you control a servo motor using a potentiometer. Basically – it takes an ADC reading, scales it from 0-1023 to 0-180, and tells the servo to go to the result. High numbers represent bright light. The simplest change is to replace the “bottom half” of the potentiometer setup with a photoresistor, to give a simple voltage divider like so:

Voltage divider_schem

Then, run the thing. At first I tried to get it to do things by casting shadows on the photoresistor. However, I ended up finding out that shining a light on or near it worked better. Fortunately I my USB power bank has a built-in bright white LED which makes a handy torch.

So there are two sorts of feedback that can happen here. Imagine a situation where light is shining on the photocell at an angle. One way, the servo can turn the photoresistor towards the light, the other way, the servo can turn the photoresistor away from the light. The side on which the light is shining is important. On one side – as the light gets brighter, it makes the servo turn towards the light, making the light get further brighter and so on – positive feedback. On the other side, as the light gets brighter, it makes the servo turn away from the light, making the light get dimmer, making the servo turn back towards the light, and so on. One of two things can happen. Either the system reaches some sort of equilibrium, or it overshoots and oscillates. As servos can be a bit slow, we sometimes get oscillation.

As can be seen in the video, this sort-of allows for a form of light tracking – except that in some places, the system will try to keep the photocell relatively dim by pointing it at an angle to the light, and at others it will try to point it directly towards the light. After a while the system can’t find a way to be pointing towards the light, so it swings away.

So how to make a proper light tracker? Well, we could add an extra photocell, but instead, why not just change the software? Instead of letting the light level set the position of the servo, let the rate of change of light level control the rate of change of servo position. Take a reading, let the servo move in a direction, take another reading. If the reading is higher, then this looks good – keep going in that direction. Otherwise, change direction.

It took a little fiddling to get things to work properly – the main thing seemed to be that the servo needed a little time to settle into a new position between readings. However, when I’d figured that out, it seemed to be working quite nicely.

Anyway, the Arduino code is here.

So that’s about the simplest feedback system with mechanical parts I could think of. The next step? More sensors, more actuators.

DAC Shieldlet

I made a – for want of a better word – a shieldlet.

IMG_2237 IMG_2241

This is the DAC from the previous post. First – it wasn’t meant to go over the top of the Arduino like that, but rather to stick out to the side. However, I made a mistake when thinking about which way round things went. Second – the output pin in the centre of the board is a bit unconventional – I put a blob of solder on the board, and stuck a header pin on top – I think I had to re-warm the solder once or twice, I definitely melted the plastic a little. Ideally I’d want a socket rather than a pin, but I didn’t have any sockets handy. Third – it’s a real pain trying to tell brown from red on those resistors! Fortunately they gave the 20k resistors thick bands, and the 10k resistors thin ones. Last – it works! I soldered it up and it works! It actually gives the voltages I wanted it to! Now I have two DACs!

I’m doing Science and I’m still alive

So I have a DAC (see earlier), and the Arduino has an ADC, which means I can have a real go at understanding my components. Simple example – an LED. This is a 5mm green LED got from who-knows-where, that I had in my box of components. An LED needs a resistor – how about 220Ω. I got out my multimeter and it said 218Ω – such are the tolerances of resistors. Anyway, a schematic:

DACADC

And we have a very simple bit of code, in Github here, that sweeps the DAC up and down the voltage range, sees what the ADC has to say, then prints two numbers to the serial port. This gets picked up via the serial monitor, and cut-and-pasted into Excel. Yes, Excel, the graphing tool that people who use real graphing tools like to sneer at, but when I was doing my chemistry PhD – and indeed undergraduate degree – it was essential. Anyway, the readings get converted to voltages – ADC by dividing by 1024 and multiplying by 5, DAC by dividing by 4096 and multiplying by 5. The ADC voltage is thus the voltage across the LED, the voltage across the resistor is the DAC voltage minus the ADC voltage. Knowing the resistance of the resistor, and the voltage across it, I = V/R, so we can work out the current going through the resistor – which is going to be the same as the current going through the LED. R = V/I, so we can work out the resistance across the LED. P = IV, so we can work out the power consumption of the LED. So, have some graphs:

LEDgraphs

And here we go. Going up the voltage range, the LED is essentially an open circuit until the applied voltage reaches the magic 1.8V threshold. I’ve plotted the “resistance” across it on a logarithmic scale, but really can we trust that? We’re trying to work out a resistance by subtracting two voltages which are very similar to each other, so any errors in the voltage measurement are going to have strong effects – hence the spiky bits on the green curve. Above the threshold voltage, it seems that current, power, and voltage across the resistor are all in linear proportion to the “excess” voltage. The curve that isn’t so nice is the voltage drop across the LED – above 1.8V, it goes to 2.05V, and the curve is… more curvy, not a nice straight line. On the datasheets for LEDs, they do quote voltage ranges, the voltages I’m measuring seem a little low (perhaps the 5V from the Arduino is approximate…) but maybe components vary a bit.

The one thing there isn’t a nice recording of is brightness. Glancing back and forth between the serial console and the LED, it seems that the first glimmers appear at DAC settings around 1550 or so, corresponding to the 1.8V threshold on our graphs. However, I wouldn’t call it “reasonably bright” until the DAC setting hit around 2100 – that’s about 2.5V, corresponding to 1.9V across the LED. Even past that, the brightness seems to increase a little.

Working out how LED brightness varies with voltage is not easy though – if you want a nice easy-to-control light level, use PWM! It must be possible to get some nice standardised light meter – ah look, eBay will do digital light meters for about 10 pounds, or there are some cheaper light sensors, or I can try to work out how the resistance of a photoresistor varies with light levels. Anyway… I read somewhere, probably wikipedia, that you can use an LED and a photoresistor to make a voltage-controlled resistor. Once you’ve got one of those, there’s all sorts of fun to be had with voltage-controlled amplifiers, oscillators, filters etc. Stay tuned!

Frustrations

There’s been a bit of a hiatus; partly I’ve become a bit busier than I had been. Also, there have been a few frustrations. I’ve had one of those 16×2 LCD displays, which doesn’t work. I’ve had one case of a pi stopping working for reasons unknown – seems to be permanently fried, might have something to do with battery power. Currently – I’ve got a pi robot, I’ve got a new motor controller, and I can’t make one of the wheels go forward. Not from the pi anyway. If I take the lead that gives the go-forward signal and plug it into the power rail on my breadboard, it works… but not from an IO pin on the pi. The other three leads work no problem, I’ve tried different IO pins, no luck. The next step, I suppose, is seeing if the IO pins which aren’t doing anything will light an LED. Or maybe the IO pin isn’t quite beefy enough somehow, and if I use it to control a transistor then that might do something. It’s a bit of a downer.

One thing I keep coming back to is the difference between the Arduino and the pi; the Arduino seems to have fewer frustrations attached to it.

Which has all reminded me to watch Jeri Ellsworth’s YouTube video on the Secret to Learning Electronics – Fail and Fail often. I should get back to some of that.

 

Timings

I got a digital-to-analog converter (DAC) from Adafruit. There’s a tutorial here. I quote: “Some nice extras with this chip: for chips that have 3.4Mbps Fast Mode I2C (Arduino’s don’t) you can update the Vout at ~200 KHz.” I looked at they’re test program, which generates a triangle wave of all 4096 output values – so 8192 outputs – and a cycle takes 1235 milliseconds. That works out at about 150 microseconds per output – about 6.6kHz. Which is about the speed of the on-board ADC. Disadvantages: the DAC takes up two analogue pins, for one DAC channel. What if I wanted another channel or two?

Cheap DAC options – one is to use a PWM pin, and a passive RC filter. Connect the PWM pin to a 10k resistor, the other end of the resistor to a 10μF capacitor and to output (A0 on the Arduino for a test circuit), connect the other end of the capacitor to ground. Disadvantage; there’s still very definitely some PWM signal there. How about a 100μF capacitor. Better, but there’s still a detectable trace of PWM signal, and now we’re waiting around 10 seconds for the thing to settle. Faster settling? How about an extra PWM pin, connected via a 100R resistor rather than 10k, and only put it in output mode for a short burst. The idea is to use “input” mode not for input but for high impedance – to make the pin active only briefly, and inert the rest of the time (this all leads into tri-state logic which I had no idea about before getting going with the Arduino and the pi).  This cuts down on settling time. However, a 100x difference in resistors means the system still takes a while to settle, as when the 100R line is connected, the system can overshoot. Using the ADC to tell when the system has reached its target voltage… you still get overshoots. Plus you need to use an ADC line. There’s a little irony in using ADC to do DAC, seeing as your ADC has a DAC inside.

Another option is an R-2R ladder. I’ve got some extra resistors on order to make one of these. The problem with these is that they eat digital pins – one pin per bit. Maybe we could use a shift register.

A third option – what about using my nice DAC to charge a capacitor? The trick would be to take the DAC’s output and re-use it elsewhere, whilst “storing” the voltage. I can see a transistor here, also the use of an op-amp as a voltage buffer. Stay tuned…

The electret microphone: doing it properly

So, I’ve been progressively trying to understand the electret microphone and associated components. My latest circuit:

opamp_schem2

So, R1 is part of the pre-amp circuit for the microphone – apparently the microphone contains a FET too. Experimentation still shows that 10k is ideal – I tried a couple of resistors around 5k, but not wonderful. C1 is a 100nF ceramic capacitor. This was the bit I omitted at first, due to not really understanding things. R2 and R3 look a lot like a voltage divider, with the centre point being at 2.5V. Thought: a voltage divider relies on V=IR, if both resistors have the same resistance and current then the voltages across them will be the same. If there’s current flowing in or out of the capacitor, then there could be some extra (or reduced) current flowing through one of the resistors – at any rate, the current through those resistors won’t be the same. So current going back-and-forth through the capacitor (it lets AC through, but it can’t keep letting current through in one direction) will be converted into an up-and-down voltage at the centre point. I tried using lower resistance resistors, and the strength of the signal varies depending on the resitances chosen. R4 and R5 again look a lot like a voltage divider – providing a 2.5V reference voltage for the op-amp. Then there’s the all-important feedback resistor at R6. Without it – i.e. nothing connects to the output except my Arduino, the output will be either 5V or 0.5V – with it, there is a feedback loop that adjusts the reference voltage, allowing the gain of the op-amp to be damped.

Interestingly, the average voltage I get out isn’t in the middle of the voltage range. My op-amp seems to clip the signal somewhere below the maximum voltage, but goes all the way to 0V nicely. I suspect this might interact with the feedback loop in an interesting manner.

Still, we’ve eliminated that potentiometer, which was always a stop-gap. Also, there’s a capacitor which is ripe for replacement – the capacitor forms part of a high-pass filter, what about making the filter tighter? I went down by powers of ten, all the way down to 100pF. There, the response was very diminished, although it could pick up even me making a low hum. One thing that did come though quite well was sources of noise like finger snapping, me making “sh” noises, scratching the breadboard etc. Another advantage of eliminating the potentiometer is that my breadboard is looking a little less crowded, so there should be room for filters, peak detection, etc. In fact, it looks like the sort of thing I ought to be able to solder up on a bit of stripboard or perfboard, and thus have my very own electret microphone breakout board.

Next step – op amp

So I had a very simple circuit to get a few millivolts out of an electret microphone. But what about more? One recommendation is an op-amp. Afrotechmods (all of his YouTube videos are well worth looking at) has a nice tutorial, however there’s one little issue. I have a 5v +ve power rail, and a 0V ground, and I want the output to be between those two values. The op-amp I have handy is an LM358N but as far as I can tell, for the simple purposes of getting things working, it should only make a difference in terms of pin-outs. I don’t think I mind some DC coming from the microphone (I could be embarrassing myself horribly here, hey, I’m a beginner), so maybe we don’t need a high-pass filter. The difficulty is in getting the op-amp to amplify a difference between the “quiet” voltage from the op-amp, and the actual signal from the op-amp. The solution? The usual circuits have a feedback loop, where the -ve reference pin is connected to ground via a resistor. Suppose we connected it to some other voltage. You can get a voltage of your choice using a the middle pin of a potentiometer that goes from 5v to ground, so let’s try that. There’s a little work involved in twiddling the potentiometer to get a reading that’s in the middle of the scale, but once we’ve done that, it’s all nicely set up. There’s probably a mathematical formula which tells you what the resistances should be, but it’s easy enough to twiddle a dial.

 ompamp_bb opamp_schem

I’m not sure if I’ve drawn the polarity right. Oh well. You can adjust the gain by making the 100k resistor larger or smaller

The output can be plotted as before. This is me making a long ooooooooo noise, trying to be quiet enough that the FFT peaks don’t hit the ceiling:

wave

Getting going with an electret microphone and an Arduino

Reading about electret microphones, it all seemed very complicated. However, the wikipedia page makes it very simple. I’m using a PPCOM-08635 – it’s a SparkFun part, supplied via Proto-Pic. Anyway, if you take the schematic on the wikipedia page, and simplify it even further. All we need is one resistor.

electret_bb

Two observations – first, it helps if you wire it up the right way around. If you wire it up the wrong way around, you still get a signal, just not as good. Don’t trust the red and black in my diagram! Second – the value of the resistor matters. I put a 10k resistor in first, tried 1k and 100k and found 10k was the best. 10k puts the quiet output in the middle of the display, and seems to give nice peaks. I think the microphone has a built-in resistance – impedance? I don’t yet understand impedance.

In a previous post I had an Arduino sketch and Processing script; this turns out to be very nice for displaying the output. One thing is that my 2kHz sampling frequency is a little low. If I whistle, then I get a nice peak in the Fourier transform. If I start low, the peak is at the left of the graph – low frequency. If I make higher and higher whistles, the peak gets further to the right, until it hits the edge, and “bounces back”. Also, at whistles higher than the bounce-back point, with a high whistle, the waves look longer than with a lower whistle. Now it happens that I have a musical instrument – a mandolin – handy, so I can generate a 440Hz A (or thereabouts, I haven’t tuned the thing in years). That sound is generating a peak quite close to the right of the display, but a little lower than the bounce-back point.

Other obsevation – I have a cheap motor. If I power the motor off a completely separate circuit, then if I let the motor get too near to the microphone, there is *lots* of noise, the average reading gets lower, it’s all crazy. I suppose the magnetic fields generated with the motor are interfering with the microphone. It might make the project of listening to a motor (to listen out for the squeal of a stalled motor, for example) trickier.

For a simple circuit to get going with, it works remarkably well. I’ll want to do further amplification, which will mean complications, and it would be useful to rewrite the software, to sample at a higher frequency and send data to the computer in batches, also there’s some analog signal processing I could think about doing – a VU meter, perhaps with some high-, low- or even band-pass filters. Some on-Arduino processing, with the built-in FFT library, maybe.

Edited To Add: This is, I suppose, Part 1 in a series of 4. The remaining parts are here (where I add in an op-amp), here (where I add a capacitor between the electret and the op-amp), and here (where I do volume sensing with the output).

For reference

Time to do 1000 operations, in a for loop, in microseconds:

digitalWrite – 4300 (approx 240kHz)
digitalRead – 4172 (approx 240kHz)
analogRead – 112104 (approx 9kHz)

That’s 27 times as slow for analogRead. Considering you’re getting 10-bit ADC, that’s a bit less than 3 operations per bit. Considering that ADC works by making voltages by DAC and then using a comparator to see if those voltages are too low or high, that isn’t bad. However, I wonder if there’s some trick with a 1-bit ADC to make use of that 240kHz…

More plotting, with Arduino and Processing

I’m impressed with the Arduino. As a bit of kit that lets you say “I hear you can use LEDs as sensors” and then get to a running system very quickly, it’s very nice. Doing anything directly with a pi is more faff.

It seems that the Arudino software is part of a family; Fritzing is the electronics drawing package, and Processing is what started the family off. Processing seems to be Java made handy. Getting started with it reminded me of old-school 8-bit basic; everything to draw shapes on the screen is a part of the language, rather than being off in some obtuse library somewhere, it’s got a handy event loop, it’s all nice. On the other hand, under the hood, it’s Java, which means that there’s a great big pile of Java libraries that you can use. Obviously we can’t have enough graph-plotting libraries, so let’s write yet another. And that big pile of Java – let’s pull in a Fourier transform. Everyone likes periodic phenomena. It turns out that the Arduino examples page includes a simple graph-plotting solution, using Arduino and Processing – however, we can make improvements.

Arduino side – first, let’s crank up the baud rate on the serial to 115200 – that’s what the documentation recommends. Second – timing. Let’s keep accurate time; take a note of the time in microseconds, and each time round the loop, add an increment to that time. That gives us a time to delay until. One nice thing about the Arduino compared with the pi is that it is real time. With the pi, you can hope to do some things reasonably quickly, but you can’t be sure of getting a reading each millisecond – not with accurate timing, at any rate. With the Arduino, we seem to be able to have a sample-and-send loop which runs at 2kHz. This is not wonderful; a classic A note is 440Hz (quite close to the standard Arduino PWM frequency), so you’re unlikely to get a good look at the waveform. Motors – I saw one advertised at 12300 rpm – that’s 205Hz. The slowness here seems to be the serial port; I did a little testing and if I recall right, it was possible to do 9 analogRead operations per milliseconds, so if we were happy with recording some data then sending as a chunk, we could get 9kHz. Not wonderful, but an improvement.

Processing – you can add a .jar file to your build path with Add File. Most of the graph plotting is pretty trivial; the only slightly tricky thing is driving the Fourier transform. To do: detect peaks, and say what frequency the peaks correspond to. In fact, there’s probably quite a lot that could be done here. One nice thing about the Processing code is the way the event loop deals with input from Serial, and drawing the screen, as separate things. Worrying about the update schedule for the display is one thing that is taken out of your hands.

There’s code at: https://github.com/ptc24/electron-pi/tree/master/ardugraph – both Arduino and Processing.