Search Microcontrollers

Monday, June 23, 2014

Arduino Robot - LiPo batteries update

I said (here) I did not know much about LiPo battery output and their maximum discharge rate.
I made a few assumptions and simply said that my 1200mAh 25C should have been more than fine (for this project) since if it could power an RC car/helicopter, then it should have been more than enough for my  two small DC motors and few other digital electronics.

Still, it was a good opportunity to understand some  more and I researched the meaning of that "25C", here the results :

When you have a battery pack that is declared at xxx mAh you actually know the maximum charge that can be stored in it, but that does not tell you how fast you can (safely, possibly) discharge it or in other words, how many Amperes of current you can draw from it.
1200mAh means that if you draw 1200mA continuously, a completely charged battery will be depleted in 1 hour (assuming you can pull all the charge, which is quite unlikely due to voltage drop that goes with it, plus it is advisable to pull only 80% max of the battery charge to prolong its life).
That does not leave any clue on how you can use that charge, is it going to be at 10mA at a time, at 10A or else?

That's  where the "C" rating comes into place for LiPo batteries.
From what I found the C coefficient has to be multiplied by the total charge of your battery (1200mAh in my case) and that gives the maximum (peak) Amps you can draw.
Now, a bit of math tells us that a 1200mAh @25C can output a whopping 30Amps peak.. at least in theory.
Honestly I don't really think that figure is anywhere near a realistic one, 30A is a scary amount of current even at the moderate voltage we are dealing with (average 7.4V, up to 8.something).
We are talking about 220Watts of energy (7.4 * 30)!
Granted at 30A you would drain the fully charged battery in only 2.4 minutes (1.200/30.000*60)... but I still believe that 30A * 7.4V for two continuous minutes are still a serious business.
I initially thought I had it all wrong, but searching on the web it seems these are the correct figures (!!!).
One of the sources here.

However, when I look at those small wires coming out of it, I see something that seems to have pretty good quality, but still I hardly see them carrying 30Amps without transforming suddenly in a smelly ball of smoke.
I would not feel really safe exceeding 5A, which again is about 10x more than I need.

In conclusion : The max current seems more than adequate for my purpose, all hail to the magic of LiPo batteries... yes but...
Right, is this all so cool, no flipside?
Well, it is until you happen to short circuit your battery, in that case I fear the best thing that can happen is a bit of smoke, fire if it was not your lucky  day and a nice "kaboom" if your horoscope that day was not favorable (in that case you probably deserve it, at least for believing in horoscopes!).
With big power comes big responsibility, play it safe! 

Monday, June 16, 2014

Arduino Robot - "Zeroing" Stepper motors

Hello, this is yet another post related to the series dedicated to the Arduino Rover project.
These posts, although eventually enjoyable by any kind of maker, are targeted to young and non particularly expert geeks.
Not long ago I was toying around with hall effect sensors, the reason I was is related to today's posts.

The rover will have three ultrasound sensors (yup, 3!!! they are cheap :) ) in the front side.
Two of them will point slightly on the side (one per each side, symmetrically) and the central one normally will point straight ahead.
This one will be mounted on a stepper motor which will allow the rover to scan the area in front of it (and eventually map it, sending back sonar data via the NRF24L01+ radio).
To avoid ultrasonic interference the three modules will be triggered separately (the two side ones will be on the same trigger, sensors have a 15 degree angle sensitivity, they will be pointing in directions that are way more than that angle apart).

Stepper motors, particularly the one I chose (a cheap 28bjy-48, with gearbox reduction), can have a very fine resolution, so they can provide a very precise scanning, way more than the 15deg sensitivity angle of the ultrasound sensor... gotta do something about that, probably via software.

Despite the fact they can rotate an extremely precise amount of degrees, unfortunately they cannot remember their position, it is normally up to the software to keep track of it.
But what happens if you reset the MCU running such piece of software while the motor is in a given position X?
It happens that whatever variable you were using -if not stored in some flash memory or similar solution- it will be re-initialized at boot time after the reset.

Sure, saving this variable in a non volatile storage might help... but still might fall short of other issues, such as a motor "missing" a few steps.
Actually you instruct the motor to move X steps, but you have no feedback if it actually moved that precise number of steps.
It normally does, unless it gets stuck against something.

So a good solution is to detect a zero position and reset your position variable on that at each boot or even from time to time during normal operation.

Then the question becomes :how to?
As we said, a stepper motor provides no feedback, so we need to ADD something that does.
A typical solution is to use a magnetic or optical device, basically something static that can detect a moving part without touching it.

I went for the magnetic solution, using a hall effect sensor and  neodymium magnets.


The one in the picture is just a test setup, as you can see the small hall effect sensor is taped down while the final solution will hopefully be a bit more stable.
The stepper motor is physically on the opposite side, below the wooden surface, and  a 2mm thick piece of plastic is connected to its shaft, coming this side of the chassis.



I am using some tiny round neodymium magnets (got 200 of those, also really cheap on ebay), they are 3mm in diameter and 1 mm thick, so I was able to embed 2 of them in the 2mm thick plastic.
I simply drilled a 2.8mm hole with my dremel, they are slightly forced in, no need for glue or anything else, they just stay there nicely.

I connected motor and sensor to the arduino, using a mega for this test,  a Uno or pro mini would do the same, I just had this one available at the moment and did not want to disconnect the others I am using for other purposes.

Then using the Stepper Library demo code (configured to run with the mega pins)
I managed to have the motor turn clockwise for a few steps and counter-clockwise for the same number of steps, continuously.
The LED is turned on if the digital pin connected to the sensor is LOW (sensor is active LOW).



The key thing is that I move the motor 1 step at a time and at each step I poll the sensor (you could theoretically use interrupts for this, but I will need two interrupts for the speed encoders and arduino does not have any spare int available :( ).

Now that we saw it works, we need to consider that, even if those magnets are really small -and you might find smaller ones, but they become more difficult to handle- they still cover an area that is represented by a finite number of steps.
Arguably this area might change a bit depending on the distance (the radius) at which you place them from the shaft.

The idea is to consider as ZERO the position of the stepper motor that corresponds to the center of the magnet being over the center of the sensor.
We then need to calculate, when the magnet hits the sensor, how many steps it needs to clear it again.

My simple code is here :

#include <Stepper.h>
int input_pin = 52;
int sensor_vcc =50;
int led_pin = 13;
int cnt=0;
int dir =-1;
int lastSensor = LOW;


// initialize the stepper library 
// I am using a MEGA!!
Stepper myStepper(stepsPerRevolution, 30,26,28,24);  

void setup()
{
 Serial.begin(9600);
 pinMode(led_pin,OUTPUT);
 pinMode(input_pin,INPUT_PULLUP);
 pinMode(sensor_vcc,OUTPUT);
 digitalWrite(sensor_vcc,HIGH); 
 digitalWrite(led_pin,LOW); 
 myStepper.setSpeed(40);
}

void loop()
{
   if (digitalRead(input_pin)==LOW)
   {
      //detecting magnet
      if (lastSensor==LOW)
      {
        cnt=0;
        lastSensor=HIGH;
      }
      cnt++;
   } else 
    if (lastSensor==HIGH) 
    {
      Serial.println(cnt);
      lastSensor= LOW;
    }
   myStepper.step(dir);   
}

Turns out that the readings are quite consistent and it usually takes 36 steps with that sensor, placed in that position, with those magnets etc... you need to run your own measurements if you try to replicate this experiment.



You probably noticed that the numbers tend to increase after few passes, that happened because the tape started to warp a bit when heated by the lamp and the sensor raised a bit getting closer to the magnet.
As I pressed it down again it temporarily went back to 37, this will not happen when the sensor is securely placed on the rover.
As a general rule, when you zero your motor at boot or anytime you may need it, you should also check again this number of steps and get half the value as the zero position.

Wednesday, June 11, 2014

Arduino Robot - PSU

The Rover is supposed to have plenty of devices on it, it will have a couple of arduino's (maybe 3), several sensors, two dc motors, a stepper motor, a radio...

That calls for some energy!
The easy solution would be to use the 4xAA battery holder provided with the kit, but there are a few reasons this could be a bit less than optimal :

1) If we plan to use rechargeable batteries, the output would be 4x1.2V = 4.8V which is probably enough to run the 5V arduinos, but a bit weak for the dc motors (they give you full power at 6V).

2) The battery holder consumes a bit of space and the pack will weight a bit

3) As the provided voltage is already quite low, when batteries discharge this will drop further to a level that is not sufficient to power the devices, limiting our ability to fully use the energy stored in the batteries.

I thought a better solution would have been a LiPO battery, a two cells one gives an average 7.4V which is high enough for the motors, the arduinos etc, leaving enough room for voltage drop.


You can easily find batteries like this one on ebay, I am no expert with these, but some common sense reasoning helps in making sure the one you select is ok for your project :
1) The only energy hungry parts in the rover are the two DC motors, they need 6V and can sink a limited amount of current. I found some data, but not really sure about it since no part number was mentioned, some sources say the max current could be 250mA per motor, most of the sources say it is way less... I assumed 250mA to be conservative
2) Most RC models have non geared and power hungry dc motors, so , whatever battery that works for them will do just fine with the motors we have. To be on the safe side I purchased a 25C (high discharge rate)
3) 1200mAH is not much, but comparable to the charge of NiCd rechargeable AA batteries, with the benefit that the higher voltage will allow us to better use the charge.

So, I went for a 1200mAH, 25C 2 cells (7.4V) LiPo battery, and got a balanced charger for it.

Probably I could feed the Motors directly from the battery, but again to play it safe and have a predictable result I decided to step down the voltage to about 6V for them.

We know there are different options to step down DC voltages, at least 3 come to my mind :
1) Use a linear voltage regulator (probably the most common)
2) Use a buck converter
3) Use the drop voltage of  (a series of) diodes

Linear voltage regulators are pretty handy, easy to use, they provide a clean output, but they are normally not efficient.
Here we are dealing with motors, no need for a clean power supply, but conversion efficiency might be important, so buck converters become a good option.
Diode drop voltage is not suitable because of efficiency, and does not regulate the output, it simply reduces the input voltage of a  given amount of volts (usually 0.6V per diode).

 So, I got myself a nice buck converter, they can be sourced really cheap now so they are becoming a good alternative for DC regulation , at least when you want to exceed 1 Amp.


Less than 2$ shipped, 3Amp maximum (leaves room for eventual future upgrades) and a wide range input/ output with a max 92% conversion efficiency (advertised).
Not too bad.

The problem with linear regulators is that the difference between the input and the output voltage is obtained mostly by dissipating energy as heat, therefore their conversion efficiency is pretty low.
If you have a power hungry device then efficiency becomes relevant, in fact if I have to supply only 100mA,5V and I have a 50% efficiency, I am wasting 5*0.1 W =0.5Watts of energy.
Now, if we had the same efficiency with a  3000mA output, then the wasted energy would have been 5*3 = 15W !! which also requires proper heat dissipation.

That said, we still need to power the arduinos and the other connected devices... here we definitely need a clean power source, and the power consumption is going to be pretty low, so linear regulators are a good option.

I selected to use the arduino pro mini because it is really small, cheap and provides the same features as the Uno board... well, almost.


The first thing to consider is that these boards are available at different voltages (3.3V and 5V) and different frequencies (8MHz and 16MHz).
I went for a 5V 16MHz one.
Second thing to know is that they do not include and FTDI interface like the Uno, so if you want to program them you need one external (I have a few always floating around on my desk, normally :) ).

The other important thing is that they do include a voltage regulator (the tiny chip on the middle-left part of the picture), so that you can feed them a non regulated input (5V to 16V)....
BUT the Uno contains a secondary regulator providing 3.3V supply for sensors and whatever you need to power at 3.3V, the pro mini does not have such secondary regulator.

We need 3.3V for the radio, the compass and other sensors... so that will be provided by our PSU board via another linear voltage regulator.
To be fair, here the internal voltage drop of the diodes would have been a decent solution : the input could have been the 5V regulated VCC from the Arduino pro, the current needed is few milliAmps, so 3 diodes in series would provide a 1.8V drop -> 5-1.8 = 3.2V,. good enough for our 3.3V supply.

I just preferred to integrate this in the PSU board, but realized I ran out of 3.3V regulators (actually I do have some SMD ones, but they would be a pain to be soldered to the proto board) so I went for a variable regulator, the famous LM317 (you should always have a few around).



Turns out it was not a good idea, let me explain why.
The LM317 is fairly easy to use, quite versatile, has a poor efficiency (but since we need few mA it would do) and can provide up to 1.5A output if mounted on a heat sink.
Way more than we need, right?
Nope, sometimes it is better to get "just what you need".
Turns out that I always disregarded one of the characteristics of this extremely useful device : it does not work if the load is less than 10mA.
Once I configured the circuit placing proper R1 and R2 (V = 1.25(1+(R2/R1))) I had no load and I was measuring the voltage, discovering it was ranging from 2.3V to 4.8V, oscillating in an unpredictable way.

Now, the radio will sink up to 14mA when transmitting, this would give us enough load, but when not transmitting the sum of all the 3.3V devices connected will be less than 10mA.

I temporarily patched the circuit adding a 330Ohm resistor in parallel to the load, that works but it is a sub-optimal solution as I am now constantly wasting 10mA of energy on the 3.3V rail!
It will have to do until the 3.3V regulators I ordered (got some 100mA ones) arrive.



On the proto board I soldered all the different parts, added an LED for every rail (battery, motor, 3.3v), some pins to connect directly the 3.3V devices etc.

The board itself is mounted with spacers and is protected with a rubber-ish sheet that also provides enough pressure to hold the battery in place.
The battery slides below the board.


(Note, it is all mounted on top of some wooden temporary chassis which I am using to study the optimal position of the various parts before drilling -or better let my young student drill- holes in the final one).

Another feature I wanted to add is the ability to monitor the voltages of the 3 rails, in order to detect when the battery is discharging or if one of the regulators is malfunctioning/ not properly configured.

To achieve that the Arduino's ADC is going to help, however some precautions must be taken.

The maximum voltages on the 3 rails are : 8.5V (maximum voltage of the battery), 8.5V (itf the buck converts 1:1) and 4.5V (if the 3.3V regulator is off).

The 5V arduino can accept maximum 5V on its ADC, exceeding this limit might actually burn it (and no, we don't want that, right?).

So, it is rather safe to feed the 3.3V rail to the ADC, but not the other ones, we will add a voltage divider (a couple of  resistors, you can google it up if you don't  know how it works), dividing by two.
The analogRead function provides a value between 0 and 1023 since the ADC has a 10 bit resolution and, if you do not use an external reference voltage, 1023 corresponds to the Arduino's VCC (roughly 5v).

Let's  say we read adcX on the pin connected to the 3.3V rail.
We know there is no voltage divider on that one, so 1023 would mean 5V ->

adcX : V = 1023 : 5

-> V = adcX * 5 / 1023   being V the calculated voltage.

For the other two rails, we know we have /2 a voltage divider, so 1023 would mean 10V instead of 5.

-> V = adcX * 10 / 1023

I did fetch the values (I have a second arduino connected to my pc via FTDI serial, it acts as a "serial to radio" bridge with a protocol I implemented for it. The radio connects to the arduino pro on the rover which itnerprets the commands and answers) and noticed they were a bit off.

My multimeter was giving me 3.38V on the 3.3V, while Arduino was returning 3.13V.

This is to be expected and it can be corrected easily.
What happens here is that the Vcc  provided by the regulator on the arduino is not exactly 5V, so the reference for the ADC conversion is not 5V either!

Do we need to know the exact Vcc then?
No, not necessarily, we can just compute the error between the value reported by the multimeter and the one calculated by arduino.



The ratio between those two values gives us a correction factor that can be applied to all calculations (in my case it was 1.093).
Normally you would want to check that ratio with a set of different measurements and eventually consider that as the linear regulator becomes warmer it might drift a bit altering again the ratio.
There are technical solutions for this, such as adding an external reference, but that exceeds the purpose of this experiment.

Overall, now the rover has a decent power management which includes feedback control, it has an almost reliable radio communication system... 
We are almost ready for Mars... or, well, maybe the backyard (for now) :)