sábado, 27 de abril de 2013

Using adafruit motor shield for DC motor & Servos


In this post I am writting about my experience with Adafruit motor shield. This shield comes unsoldered, so first step is to solder it, for what there is a detailed explanation at ladyada web. In the same web there are code examples to use it for steppers and dc motors, and it is quite simple to use so I am not repeating it here.

I was interested in experimenting with L293D chip, compared to L298 that I have already used for the same motors (the dc motors of pirate4wd hobby car). The final purpose is to have an rc car controlled by arduino gsm bluevia shield. The results of this tests will make me decide to use L293D or L298. I can tell you right now the result: I am using adafruit motor shield (L293D) instead of arduino motor shield (L298). This is just beacuse it works better for this dc motors and with the battery I use, of course it cannot be deduced that one is better than the other in every situation.



Things that can be learned in this project:

- L293D motor driver and batteries
- Shift Register (74HCT595, the chip in the middle of the shield)
- Servo Motors: fascinating Servo library and tips about how to supply power to them.


L293D & batteries

Quadruple half H Brigge, same as double full bridge of L298. L298D has output clamp diodes incorporated (not in L298), and ouput current 600mA (1.2A peak) per channel, compared to the 2A per channel of L298, that are the most important differences. 

Remembering the current consumed by the dc motors of pirate4wd car, and taking into account that motors are paired, I will need maximum 260mA per motor (520mA total as they are parallel connected) for 3V operation, and aproximately double of that for 6V operation. I couldn't find the saturation voltages for L298D in order to calculate the voltage that will rest for dc motor from motor supply, but multimeter reads about 2V between motor + and -, both for 9V battery and 4xAA battery (6V), so it should be similar to L298, between 3V and 6V.


I tried two powering options:

- 9V battery, this batteries are not known for offering great current drain. In datasheet you can see that they are designed for moderate and medium drain devices (not for toys for example). The reason of this is that this batteries are composed of several small cells in series, small cells with few mAh capacity  (200mAh) , and draining for example 500mA will make voltage drop rapidly.

- 4xAA battreries, 6V total,  less voltage for motor, but greater current response, dc motors run better. The capacity of each AA is between 1500mAh and 3000mAh, that will respond better to a "high" current drain of 500mA. 




Anyway, it was a good opportunity to read and learn about batteries, I recommend this post from letsmakerobots, and reading a couple of battery datasheets, one interesting point is that battery capacity (mAh) depends a lot on the drained current in the case of alkalines, and not so much for lithium ones. For a 9V alkaline battery, with a 500mA load, battery capacity is about 400mAh, and with a 25mA load it changes to 600mAh. Another point is that not all batteries offer high currents so happily, each one is designed for a type of load, and that is something to take into account when choosing one for your motor.



74HCT595 Shift Register

Actually I made it work without knowing this chip internals, just that it was used to get 8 digital outputs from 4, so the only purpose of it is to save 4 arduino digital outputs to use 2 of them with servos, and even leave a couple of arduino digital pins free (2 and 13). Each L293D uses 4 input pins plus 2 enable controls, a total of 6, which means 12 digital outputs for 4 motors, the total of available digital pins on arduino (0-13, but 0 and 1 are serial rx and tx).

Trying to understand the board completely I searched and found this excellent deep explanation at the ladyada faqs page for this shield, it is a very interesting document for beginners such as I. Although explains it based on an old AFMotor library code that used atmega ports to manage 74HCT595 inputs, the new version of this library uses arduino pins directly and digitalWrite on them instead of dealing with atmega ports B and D registers (DDRB, PORTB).



Servo motors & Servo Library

If you don't know how a servo works, you can read this simple introduction, or search the internet, there is a lot of info out there about it. Knowing that, servo library usage is simple and well documented, what seemed fascinating to me is the complexity of its internal management of timers to generate PWM.

The basic principle is to use atmega timers to trigger interrupts every 20ms and generate the needed pulse width at digital outputs, not so complicated, but Servo library says that can manage up to 12 servos, and atmega328p just have 3 timers, and timer0 is used for timing functions that are still available when using Servo library. Depending on the platform, the library uses a predefined set of timers, and in the case of atmega328p, it uses just Timer1 (16bits), and the cost is that we can't use PWM (analogWrite) on digital pins 9 and 10. This is because these are the arduino pins that corresponds to Output Compare Match OC1A and OC1B of Timer 1.

The way the library maps ticks to real time is using these functions located at Arduino.h:

#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define microsecondsToClockCycles(a) ((a)*clockCyclesPerMicrosecond()) 

that takes into account the real cpu clock configured for the micro. 

One thing I didn't understand completely is why 12 servos, servo signals can last from 1 to 2ms, suppose the worst case: all 12 servos are set to 2ms, that sums 24ms, and servo protocol expects a signal every 20ms (50Hz). Investigating the code and servo protocol you can see that, in that case the next interrupt will began just after last servo is served, so the frame rate will decrease that cycle to 41.6Hz, a drop of 16%, decreasing the frame rate means that servos will reduce holding power, speed and precission. Servo library uses REFRESH_INTERVAL constant (set to 20ms) to ensure the maximum frame rate, but doesn't control the minimum, just controls the number of servos per timer, what yields to 41,6Hz in the worst case, I suppose that is the maximum deviation assumed, and why the maximum number of servos is set to 12.

One important point for using servos is how to power them. In the adafruit board, servo power comes from arduino 5V (no easy way of powering from motor power inputs), and this is not adequate for my microservos. Every time I move servos arduino resets itself, I suppose beacause of a lack of power that makes brown-out detector to auto reset. In arduino UNO (atmega328p) the Extended Fuse default is set to 0x05, which sets the BODLEVEL to 2.7V, so I suppose servo drains so much current that triggers arduino Brown-Out Detector. Here is a detailed explanation of why servos should be powered from a different source that arduino.

This happens with arduino powered from USB 2.0 (500mA max load), but if I powered arduino from a wall adapter there is no problem as it drains more than 500mA (1000mA exactly, at 12V).

At the end, as I needed to power the servo in the rc car,  I used one battery for arduino and another one for dc motors and servos (4xAA) connected through the ground pin to the arduino GND. I think it is a bit forced, 6V is too low for dc motors, but microservo voltage range is [4.8-6]V (datasheet), the other option was to use 3 batteries...

There is a curious conflict using Servo and SoftwareSerial libraries together that drove me mad some days. I used SoftwareSerial to access the xbee shield. The first times, once I connected the remote control and it began to send i/o samples to the xbee in the car, the servos began to move erraticaly, I though it was some kind of problem involving batteries, evil spirits and xbee draining too much at transmission time. At the end I discovered it was a software problem, beacuse the SoftwareSerial library disable interrupts when transmitting (cli();), and that interferes with the Servo library way of generating "pwm" signal, you can see here a video showing the same problem in another project. I avoided to solve the software problem and directly used Serial communication for xbee shield, but it could be a challenging project to make both libraries to live together in peace.

By the way, the servo will be used to move a platform that holds a camera that will be controlled wirelessly through the gsm shield, but that will be another day.

My code for the arduino at the car.

domingo, 21 de abril de 2013

Arduino Motor Shield R3


I purchased an arduino motor shield to use it with the pirate4wd car chasis, but at the end I was able to design my own board (previous post) including atmega328p and L298 circuit. So just for justifying the money spent I wanted to try it, and here I show what came out of that test.



Firstsable I was a bit dissapointed with the board, with 6 output connectors I thought I could control lots of things, perhaps both dc motors and servos, but:

- outputs TWI IN and TWI OUT were unusable, as I had an Arduino UNO R2, and this board is designed  for Arduino UNO R3, which has a couple of extra connectors on each side. Two of them are SDA and SCL, used for TWI connectors. Apart from that, you can use it with Arduino UNO R2 without problems.

- outputs OUT 5 and OUT 6 (Orange ones), connected to two arduino digital pins, are powered with 5V from arduino, and I expected them to be powered from motor shield Vin, to separate motor power from arduino and avoiding unstabilities on Arduino. If don't know why you can read this excellent web. Anyway 5V from Arduino could be enough for small hobby servos..


That's the bad part, the rest went quite as expected. First thing was to cut Vin connect jumper that connects shield power and arduino power (just cut the small connection with a cutter or little screwdriver)

I could use the same code as with my homemade board, just changing inputs and pwm pins adequated to the motor shield pins and considering that IN2 is IN1 inverted if brake jumper is connected (and IN4 is IN3 inverted).



One interesting thing I found useful was the treatment of sense signals, with and opamp to set up the range [0-3.3V] (been 3.3V max current: 2A), and impedance to arduino ADC inputs.


I had some measurements to test the current drawn by the motors in several conditions

Car hold on air. There are two motors connected in parallel, so supposing half of the current for each, at the beginning it sources 450mA and after that it reduce to 300mA average




Car fixed, no movement (Stall current). Much more that on air as expected, motor 600mA per motor at the very first and 500mA after first spike. But 1200mA total, not reaching the 2A limit of L298 but justifying using one channel for two motors, other option coould be a couple of L293, one for each two motors as it has 600mA per channel, and a peak current of 1200mA (it can be interesting to test forcing one L293 for the two motors)




Car free running on floor. First spike simillar to stall current: 600mA per motor, but after that it decays to 250mA per motor. That first spike is on of the reasons why motor power should be separated from microcontroller supply.



Finally a photo of the car using the motor shield.




martes, 16 de abril de 2013

Arduino rc car using L298 and Xbee S1


I will share here my first experience making something that moves. Is a simple rc car made with dfrobot pirate4wd chasis platform, a homemade arduino using atmega328p, LM298 as motor driver and a couple of xbee s1 to remotely control it.






I learned interesting things with this project, useful things that can be (will be) used in another projects that involves controlling motors remotely, that things are:

- xbee i/o line passing as a very simple way of communicating sensor data.
- motor drivers, considerations on power, types of motors, get introduced to it at least


The remote control


It is composed of a parallax joystick, a Xbee Explorer Regulated and a Xbee S1, all powered thorugh a 3.7V Lipo. The Xbee Explorer Regulated has a Micrel 5205 regulator, very low dropout (150mV at 45mA, that is the transmit current of Xbee S1), so 3.7V supply is ok.

 I got inspired at this web, Digi Xbee modules have an interesting thing that is I/O line passing, which consists in sending wirelesly analog and digital signals connected to certain pins, it is well explained at Digi site both for analog and digital. Internal ADC is 10 bits, enough for passing parallax joystick values.

 

It is easier in S1 modules, as you have external VREF for ADC, in S2 VREF is internally referenced to 1.2V, so you will have to accomodate analog signal to that range. I did it with Xbee S1, connecting VCC to VREF (pin 14, named RES in Xbee Explorer Regulated), and to the joysctick VCC, it is easier and need less components.



If you want to do it with Xbee S2 you will need a voltage divider, and if not familiar with it, this reading will be useful, as you will have to consider Xbee ADC input impedance (1Mohm for series 2) and voltage source output impedance (for my joystick, with a 4K7, beeing in the middle will be 2k3 using Thevenin theorem, in the order of Kohms anyway. Resistor values should be bigger than voltage source output impedance and smaller than adc input impedance, something in the order of 100kohm will be good.

So, connecting joystick outputs to analog inputs of Xbee, select from joystick to digital input, configuring it as indicated in the link above, you will have the values at the receiver, in series 1 (802.15.4) you can get the values atthe receiver both through the UART (setting IU=1), and/or as PWM outputs. Depending on your purposes, you can use directly the PWM, but remember, is not "real" analog, you must use a RC filter to get the analog DC, also explained at digi.


In my case I recieved the API packet (line passing needs API mode), and get the values in my arduino/atmega328p code to process them and make the pirate4wd move according to joystick.


The car

The chasis used is the pirate4wd from dfrobot, mine came without manual, but it can be found online, although it is not really necessary, just to know the dc motor characteristics:



Seen the stall current perhaps a L298 is oversized, as it can source up to 2A per channel, but I just wanted to test this chip, I will have another try witrh L293 soon.
The controller is constructed at a pinhole board with atmega328p at 16Mhz, xbee socket for receiver mounted on Xbee Regulated board, 7805 5V regulator for atmega and L298 with its army of diodes (1N0007).



First thing is to solder motor cables, as L298 only has outputs for two motors, one solution is to connect each side motors to the same cable, but with polarity inverted, as they are oriented in opposite directions. Solder interruptor from batteries holder and then to a power output to the control board.



After mechanical part is solved, you have to deal with L298 control with atmega, you can find lot of tutorials online. If you don't already know, it is a good opportunity to learn about H brigde motor controllers. Knowing that, you just have to control motor direction with IN pins, and motor power level with ENABLE pins, using a PWM atmega output. I leave here my code.


Some tips that could be useful for other people trying to do something similar:

- socket for L298, as pins are separated 0.05 inch, you cannot connect it directly to a 0.1 inch hole board, it can be solved bending 45º the legs of a pin strip, solder that to the board and inserting L298 on it.
- separate power to motors and to microcontroller, I tried firstable powering 7805 5V output to atmega328p and regulator input to Vs pin of L298 (and output diodes supply) and I could see the current breakdown when driving the motor through a "power on" led connected an atmega digital ouput. After powering motors with a separate 9V supply, there is no influence from motors to microcontroller. Excellent explanation and video here.
- consider 9V min battery for motors. The AA batteries holder that comes with pirate4wd is 7.5V, and this is not too much for these dc motors. They will work, but not at 100% of their capacity. They run 100rpm at 3V and 200rpm at 6V, but. even with 7.5V you will have about 2.5V final voltage applied to motors. There is a important characteristic at L298 datasheet, it is the Source and Sink saturation voltage, that sums between 3.2V and 4.9V, so that leaves just (7.5 - 4.9) = 2.6V in the worst case for the motors.




- consider to program some "throttle smooth start control" in your atmega software, if you drive motor from 0 to 100 in 1 second then probably L298 will saturate (sure if you use less than 9V motor supply), you can see an example of gradual acceleration in my code defining a maximum acceleration per second "MAX_ACELERATION".



domingo, 14 de abril de 2013

Playing with sound: wtv020sd & LM386


I must say I thought managing sound electronically was simpler than it actually is. Interferences, amplifier distortion, impedance matching, it is not easy to get acceptable quality without knowledge about amplification and speakers, so I didn't get it as good as I expected at the beginning, but learned some things that I am going to share, so you could reach some point better than mine.

The central part of the project was the wtv020sd module from sparkfun.



It is quite easy to manage with this library. You just have to consider this tips:

- Chip works at 3.3V, although some people is using it directly with arduino/atmega digital lines at 5V without problems.. The board from sparkfun comes with a 5V to 3.3V regulator, so there is no problem with the supply, but I prefer to shift digital lines level from atmega using a diode and a resistor, as recommended in tip #10 of this great document from Microchip ( I used a 3k3 resistor as recommended in the forum by ac2013)
- Micro SD standard also works at 3.3V, and it seems that this is the most delicate part, and depending on the SD card the module will work or will not at 5V.
- Take into account the manufacturer recommendations about audio format (ad4, samples here)
- Don't take into account the manufacturer recommendation about SD size limit 1GB, I am using it with a 2GB SD card, formated with FAT (not FAT32).
- The library works good, but you should add a delay in playVoice function, as it reads the busy pin to detect the song's end. 50ms before reading busy pin is enough


The module has two kind of outputs, one PWM to directly connect a speaker , and one 16 bit DAC to connect to an amplifier. The speaker output works perfect, and quite loud, with a 8 ohm speaker. But if you want it  louder you can use an amplifier stage, you have the circuit for LM386 in the manufacturer datasheet:


This is how I built it:


And here is where I reach my limits. I couldn't get a clear sound after the amplifier stage. Even keeping input lines as short as possible, and using all recommended capacitors, with exact values and including 10nF at pin 7 not shown in schematic but useful as I have checked by myself in other audio project, it is used to get 50dB of PSRR = Power Supply Rejection Ratio and it really improves results.



Amplification works quite fine using low values of 10K input potentiometer that regulates volume, but when I increase volume distortion appears. I must say that using LM386 N1  (325mW output power) it works fine even with high volume, but using LM386 N4 (1000mW output power) distortion appears with low volume.

I found this graph in the datasheet,



it relates distortion with output power, for 6V and 8ohm load at 1Khz, and that is exactly what I get, and that are my conditions on load and supply, I get distortion just when the output power is about a 10/20% of maximum (200mW) . So perhaps, if I increase supply and also increase load impedance, I could get same power with less distortion. Let's calculate:

Suppose P1 = V1*I1 = V1*V1/R1, is the power I have now, with 6V supply and 8ohm load

If  I double  voltage (12V) and quadruplicate load (32ohm) :V2= 2V1, and R2=4R1, then P2 = 4V1*V1/4R1= P1, and I2 = 0.5I1, I get the same output power but half output current, so probably less distortion (move the curve in the graph to the right), and that matches with the datasheet that says that 1W power can be obtained with 16V, and 32ohm load..But I don't know if all this reasoning is acceptable, I will apreciate comments, for example output voltage is not linear with input supply, that quits precision to my calculation but not quits all the reason.



Using 9V to supply LM386 I got better results in fact, I could move the potentiometer on the input pin almost to 30% or 40% without distortion. I also measured the input voltage from wtv020sd, that was 1,72V mean, quite high, amplified by a gain of 20 would be more than 30V, which is much more than the supply (= distortion). The maximum gain without distortion would be 9/1.7= 5, that's input pot to 25%.


Electret, Xbee 868 pro and Cosm graphs


The pupose of this project is to take noise measurements from a electret microphone, read them with atmega328p ADC and send through xbee 868 pro to a computer where a dongle with another xbee 868 receives the values and send to cosm for showing a graph.

I will detail here the tips dealing with xbee and cosm, you can read about taking the electret output in a previous post.

I used xbee 868 pro just because is what I have in hand. Atmega328p is powered at 5V, from a 7805 regulator, so I used a xbee regulated explorer board from sparkfun to connect the xbee. It has a micrel 5205 voltage regulator to suply 3.3V to xbee, and a tricky diode at DIN pin to convert signal lines from 5V to 3.3V.


This diode is worth some comments, as it gave me some headache, and made me learn some things about pull up resistors, and how they are used for example for I2C bus. I recommend this reading about it:

Atmega328p output pins are [4.2 - 5]V (5V supply), so, [3.2 - 4V] (diode 1V forward) after DIN diode at Xbee DIN input. And Xbee inputs are [0.8VCC - VCC], that is [2.64-3.3] (3.3V supply). That is supposed to match, but reality is that it is mandatory to have xbee internal pull up at DIN pin activated for this to work. DIN pull up is not activated by default at 868 pro module, you need to activate it with the PR AT command. Don't know what is the exact reason of this not working without it.

Another tip about using Xbee with atmega328p is about the xbee-arduino library. I had some confusion with API mode, You can configure API mode with AT commands (or X-CTU software), setting AP parameter to 1 (API mode) or 2 (API mode with escaped characters). And after that, everything you send through xbee serial uart will be encapsulated in an API message, so you won't need to create a API message using xbee-arduino library, or you will end up with a complete API message encapsulated inside another xbee api message, but probably you will not be a fool such as I... Rest of the Xbee configuration, destination address broadcast, same net id on both xbee modules, 38400 baud rate (for some reason I had problems using 9600).

This is a photo of the board that take electret values, amplifies them with LM386 N1 and send wirelessly though xbee:



In the recepction part I have a small pc, with a xbee usb dongle. It has a c# program that manually parse xbee API message and send the value to Cosm. Here you have the atmega and c# solution. I use SoftwareSerial to connect to Xbee beacuse "standard" tx and rx pins of atmega are used to program the micro and debugging through serial monitor. The important part about sending values to Cosm is this:


byte[] postArray = Encoding.ASCII.GetBytes(value.ToString());
WebClient wc = new WebClient();
wc.Headers.Add("X-PachubeApiKey", apiKey);
byte[] response = wc.UploadData("http://www.pachube.com/api/" + feedId + ".csv", "PUT", postArray);



And here you can see the graph obtained at Cosm:







Noise meter with electret microphone and atmega328p


In the beginning I though to make a more or less accurate noise vu meter, giving me actual noise dBSPL, but after playing around for some time with electret microphone, and reading about sound pressure level decibels (dBSPL) and microphone datasheet, I think what at the end came up is just a graph where only relative values are meaningful.

Sound and microphones are not so simple as I expected. Key parameters of microphone datasheet are:

Sensitivity, -46dBV for electret, calculated as 20*log(sensitivity in mV/Pa / 1000mV/Pa), which gives: 5.01 mV/Pa. So, from the mV output of electret I can calculate the sound presure level in Pascals, taking into account that 94dBSPL = 1Pa as a reference. If recommend these readings to clarify concepts:


SNR, 58dB for electret, which means that I cannot measure less than 94-58= 36dBSPL, as noise will generate a similar output in electret as equivalent 36dBSPL sound, its well explained here.

Frequency response, +-3dB linear, 0 dB at 1Khz

Maximum SPL that microphone can measure, 110dB for electret

So, whith these values in mind, taking into account that it is a 1euro microphone, and that the amplifier stage with LM386N1 has a voltage gain of 20, theoretically I could calculate dBSPL.

The amplifier stage is done with LM386-N1, as recommmended in this web.

About LM386 some important tips from my point of view:

- when used in a breadboard noise was much bigger than in the soldered board, I suppose for the wires acting like antennas.
- the capacitor of 10nF at pin 7 (bypass), made important updrade for me, and it is not commonly mentioned in the webs I read
- also made important improvement the 100nF and 100uF from supply to ground, near to the vcc pin of the chip
- using the capacitor between 1 and 8 generated much noise, so I quit it and stay with a gain of 20

Amplifier output is connected to atmega 10bit ADC, and as LM386 bias the input signal to half of the supply voltage, we should have more or less 512 reading ADC in atmega in a perfect silence. I have made this table to see which values should be expected in an ideal situation:


The electret voltage is calculated as output from LM386 divided by gain of 20, Pascals are obtained using the electret sensitivity 5.01 mV/Pa.and dBSPL is calculated using the reference 94dBSPL = 1 Pascal.

Don't know very well how to interpret this, as looking to dbSPL references, I can see for example the expected value for a very calm room is 30dB. I get 61dBSPL for perfect silence, so I interpret, SNR value means that aat 94dBSPL of test sound, electret generate a noise of 94 - 58 = 36dBSPL, so supossing this is true for all the dynamic range of the microphone, and supossing this noise is added to real audio, if I substract this 36dB to the dBSPL column I would obtain a value similar to reference tables: 26dBSPL for calm room, and 96 for max output, beacuse 900 is the maximum ADC value I can get in my tests.

After all this tests and calculations, only thing I really trust is that I can get relative values, not abdsolute ones, at least accurately. So taking the value obtained at silence as 30dB and shifting the dBSPL column values 30dB down is enough for my project.

This is a photo os the final board, it has some more things than electret, LM386 and Atmega328p, as electret sound measurement was just part of the project, the final objetive is to reproduce a sound depending on noise measurements and time, using ds1307 rtc and wtc020sd-16p audio module from Sparkfun. I will write about the wtc020sd-16p module in another post, it' a great and cheap way to reproduce acceptable quality sound at low cost in your projects.



The atmega is configured to work at 16Mhz, because it was intended in the beginning to do some audio processing, any kind of echo or something like that, but I realized later that I had not enough space in atmega to store audio samples. Taking as a reference 64kbps audio pcm, as if it was voice (This comes from human voice been 4Khz max, sample at 8Khz by the Nyquist Theorem,  which means 8000 samples per second, and 8bits per sample= 64kbps). I will need 64/8 = 8KBytes per second, even with a small sketch it will rest  around 15 o 20 KB free memory inside Atmega Flash, for maximum 1 second of sound, not enough for my purposes. So I could have used atmega internal RC oscillator at 8Mhz and saved the crystal and a couple of capacitors. In another post I will write about how to configure atmega at 8Mhz.

Excel file for calculations.