Search Microcontrollers

Showing posts with label Robot. Show all posts
Showing posts with label Robot. Show all posts

Sunday, August 17, 2014

Arduino Robot - Putting it together

The time of putting (almost) all together finally came.
My young student Marco came over to my place with his family for a week, I showed them around a bit and sure enough we spared quite some time to assemble the robot.

We did not complete the task, as it was never the plan, but we reached a point where Marco can take over and finish almost autonomously (with my remote support) as a "deeper" learning experience.

(In the picture Marco installing the stepper motor 
that moves the scanning ultrasound sensor)

At this point the rover can move a specific amount of centimeters in each direction (using feedback from the encoders), we tested the ultrasound sensors and plenty of functionality is already included in the software (3 different turn types are  implemented : on the spot, sharp, shallow, plus motor speed balancing is implemented, coordinate management etc..).
Separately the NRF24L01+ radio system is connected to another arduino pro and an I2C based communication protocol is drafted (and tested) to communicate with the arduino driving the motors+sensors and with other I2C devices.
Also a UART protocol is used to communicate between the PC and the "base" radio station, the PC software is in Java.

Over time I will help Marco discovering the different parts he likes and activate them.

Meanwhile I would like to share with you a few lessons learnt from this exercise :

1) Cables!
Okay, we decided to pack a lot of features in this project, so we had to support them with software... but that was not the hard part.
All the devices must be somehow connected with data and power lines and this quickly generates a mess with the cables.
I wanted this specific project done in a way that things could easily be attached and detached, so I had to use a lot of improvised connectors and "flying"  cables.
As a general rule, maybe for a more "permanent" project, you may want to secure down your cables to the chassis as much as possible.


We used a female connector to provide 5V+ground connections to the devices connected on the bottom of the rover : 3 Ultrasound Sensors, Stepper Motor, Hall effect sensor, 2 Encoders.
Only for these power connections 14 wires are floating around!
We use velcro to keep them from getting in the way of wheels etc.
We took the +5V rail out of the motor driver as it contains a 5V LDO regulator (motors are powered @6V, the logic on the H-Bridge driver runs at 5V, hence the internal regulator).

2) Encoders
Encoders are simple right? what could possibly go wrong with them?
Well... turns out you should consider a few things when using them.
I got ourselves a few optocouplers, I carefully checked they were "slotted" (those that are U shaped, emitter on one side, photo-transistor on the other side) and the spacing of the U was ok with the thickness of my encoder wheels.
At least I got that part right :)
Then I started to test those couplers and with my surprise they did not work as expected.
There are several issues, the main one being that when light hits the phototransistor, it's  base is activated, but the internal resistance does not go down to zero.
Big deal you may think, something you might also expect, no?
Sure, makes sense, but the issue is that that forms a voltage divider with the pull down resistor you have to add and as a result of that the "high"  level is way lower than 5V.
In my case it was around 2V, while the low level was sitting roughly at 1.3-1.7V.

Direct result of this is that you are not likely going to feed this output directly to an Arduino digital input and in fact I have seen in the web people using an analog input instead and configuring via software the analog threshold to properly detect the logic level.
While that can be a solution, it prevents the usage of interrupts (which are available on digital inputs).
For this reason, some small circuits are sold, containing the coupler, a comparator, the needed resistors and even two fancy tiny leds (pwr-on and logic level).
These circuits make things way easier : simply provide +5V, GND and read a 5V clean logic signal back.

(encoder board with comparator, installed on top of the encoder wheel) 

You might avoid them if you are using an MCU that has embedded comparators, else I strongly suggest you buy these little boards as they save you a lot of trouble.

A final issue with photocouplers is that they are sensitive to ambient light.
That turned out to be a no-problem once installed on the rover as in that position they receive a limited amount of external light, however it polluted my tests when I was trying them on the bench.
No big deal, but something you should account for,

Also I found not particularly smart that the boards I received had male connectors soldered on the same side of the coupler, that forced me to cut slots in the rover chassis and hook the device from behind it.
And yes, I checked if it was worth de-soldering them and re-soldering them on the opposite side, unfortunately the copper layer on the printed board is so thin that if you get anywhere near with a solder iron, you better know very well what you are doing.

3) Arduino interrupts
Normal arduino boards (uno, pro etc) allow you to use two hardware interrupts on digital pins 2 and 3.
That seemed good enough for me as we only had two encoders.
I am not sure yet about this and I am planning to run some specific tests, but I had the impression that servicing the two interrupts with two different dedicated ISR and having them possibly triggering at the same time might result in missed interrupts.
At this point I cannot claim that arduino misses interrupts and since I did not check how the ATMega MCU itself manages interrupts I am not aware if this is actually possible... however I noticed some strange behavior, particularly when debugging via serial port at the same time (it might be due to timing).
This is one of the times when I wish I had a NVIC available like in the Stellaris/Tiva series.

4) Cheap motors
There are available in kits and on ebay cheap DC motors, they run at 6V, do not require a lot of current, contain a reduction gear and they are normally provided with wheel and encoder wheel.
To be honest, they are really cool, but their connections are extremely fragile.
It is ok when they are locked in place and you are not shuffling them around, but if occasionally the connection wires you soldered to them get tight... this may easily rip apart the connections.
That happened to us and we had to dismount one of the motors and solder a new wire almost directly on the brush.
Unless you practice Zen frequently, I strongly suggest you try to avoid that.

(Installing the tail wheel)

Overall it was a real fun experience, as it always is when playing with Arduino.
It is amazing how easy is to explain technology to an enthusiastic and smart 10 year old using Arduino, I really believe it is a perfect platform for this task.
I personally prefer to have a bit more control over the hardware, but that comes with some more complexity, which definitely adds to the fun once you can grasp the basics, until then : Arduino all the way :)

Aside from the main robot activity I was able to help Marco learn how to solder, about serial protocols (I2C, SPI...), how to use a drill press, how to use a multimeter and read an oscilloscope.

There is a new geek in town! :)


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) :)



Thursday, May 22, 2014

Arduino Robot - Ultrasound Sensor

Ultrasound sensors are one of the first things you want to implement in a robotic rover.
They are quite cheap, easy to use and can provide a lot of fun as they can sense obstacles in front of the robot.

You are probably familiar with Sonars (SOund Navigation And Ranging) as they are equipped on ships to sense objects below the water surface.
The principle is quite easy : an ultrasonic wave is generated by an emitter, it travels through a medium (water in the case of sonars, air in our case), eventually bounces against an obstacle and is reflected back where a receiver detects it.

Sound is quite fast, but way slower than light and slow enough to allow us to measure the time it takes to travel to the obstacle and back.
As we know the speed of sound in air (about 340 m/s, can vary a bit depending on temperature, air pressure etc) and a microcontroller is fast enough to measure the time between the emission of the sound and the detection of its reflected wave, we can measure the distance with acceptable accuracy.

The equation we use is s = v x t where s is the distance we are trying to calculate, v is the speed of sound (340 m/s) and t is the time we measure with the microcontroller.

One of the most commonly used sensors is the HC-SR04 which has an incredibly easy to use interface.
It is a 5V device (perfect for Arduino) that uses a trigger pin to fire out an ultrasonic pulse and sends back the echo on an echo pin.

In fact the sensor makes it a bit easier for us to calculate the time since the echo pin goes high once the sound is emitted (which happens roughly 0.5ms after we activate the trigger) and back low once the reflected wave is detected.


In the picture you can see I hooked the sensor to an Arduino Uno, and my oscilloscope to the trigger (channel one, red) and echo (channel 2, yellow) signals.
The target was placed at about 12 cm from the sensor, so the sound must travel about 24 cm (it goes to the target and is reflected back, so it travels the distance twice).

Using the cursors on my scope, I checked the time the echo pin was high and found it was 0.742 ms (sorry, was unable to focus better on the screen).


Using the formula we have 2 * s = 340 * (0.742/1000)  => s =  170 * (0.000742) = 0.126 m = 12.6 cm which is reasonably accurate (I calculated 12 cm from the edge of the emitter, but I guess the sound is emitted a bit back of that).

Arduino has a nice function to detect the duration of a pulse (so you don' t need to actively poll the pin, it does it for you), it is called pulseIn() and returns the duration of the pulse in microseconds.

Let's see the test sketch.

#define triggerPin 8
#define echoPin 9

void setup() {
  Serial.begin (9600);
  pinMode(triggerPin, OUTPUT);
  pinMode(echoPin, INPUT);
 }

float distance() // distance in mm
{
  long pulse = 0;
  digitalWrite(triggerPin, LOW);  
// force a low/high transition 
  delayMicroseconds(5); 
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(10); 
  digitalWrite(triggerPin, LOW);
  pulse = pulseIn(echoPin, HIGH);
  return pulse * 0.17; 
}

void loop() {
  Serial.print(distance());
  Serial.println(" mm");
  delay(1000);
}  

From where the 0.17 constant is coming?

The pulse is measured in microseconds, but the speed of sound is measured in meters per seconds (340) => we need to divide by 1.000.0000.
However we want to measure in millimeters, not meters, so we need to multiply by 1.000.
We also know we have to divide by two since the sound travels the distance twice (to the obstacle and back).

340 / 1000000 * 1000 /2 = 0.17

With this simple formula we can easily calculate the distance of obstacles in front of our robot.

Each sensor, according to the datasheet, covers a 15 degree angle and for our rover we will probably want to detect obstacles on a 90 degree angle on the front side.
Probably we will achieve this with 3 sensors, one of which (the center one) will also be mounted on a stepping motor to allow the rover to scan the area around.
In normal operation the center sensor will be still and facing forward, the other two sensors will face 45 degrees (or maybe 30 which should be more than enough to avoid interference) on the left and right.
It is in theory possible that small obstacles can land between two sensors, but as the rovers moves towards them, it is unlikely they will never be detected.
We then might start the scanning upon detection of a near obstacle, to assess in detail the scene in front.

To ensure there will be no interference between the center sensor and the two side ones, we will activate them separately, plus the Arduino is not capable of measuring multiple pulses at the same time anyways.

The Idea of having a moving sensor is to allow scanning of the area to " map"  the space in front of the robot.
Obviously we will need to mount this scanning sensor a bit higher than the others, else it might be in the shadow of the other sensors.
A possible solution would be to mount the two side sensors BELOW the chassis and the scanning one on top.



As you can see in the picture, the sensor and the stepping motor would fit below the chassis without reducing the clearance since they do not pass the level of the wheel motor.

Some versions of the rover have two layer in the chassis, not the one I bought, but if needed I might add another layer protecting the circuitry mounted in the bottom part.

Tuesday, May 20, 2014

Arduino Robot - Electric Motors

In the previous post we assumed we were able to activate the two electric DC motors, in this post we will make sure this assumption is backed by facts and real knowledge.

The motors we are using are small & cheap motors that can operate with a voltage of 3-6V.
They do not require a lot of current (as they are not really strong), however such current cannot be provided by an Arduino digital output.
Moreover motors can generate some nasty spikes in current and it is not advisable to connect them anyways to a direct MCU output.

A specific driver circuit is normally used, it is called H - Bridge and it is basically constituted by 4 transistors.
This circuit allows, via two logic level pins, to drive the motor by selecting the polarity of the two outputs and therefore making it spin clockwise or counter-clockwise.

While we could build such circuit, a good option is to buy a pre-built integrated circuit.
The one I selected is a small board based on the L298N chip which can drive two DC motors with up to 2A each (way more than we need).

L298N

So, for each DC motor there are 3 logic pins available :
Enable
Dir1
Dir2

The Enable pin is used to activate a specific motor, eventually it can be shorted with a jumper directly on the board to always activate it.
Alternatively you can use it to feed a pwm signal to control the motor speed.
I believe sending a PWM on Dir1 and Dir2 instead also works, so, provided we use pins that support that functionality (3, 5, 6, 9, 10, and 11 on most arduinos, the Mega is a bit different) we can use two single logic connections per each motor.

This is my test setup


The red board in the picture is the H-Bridge, you can see it is connected to a PSU (5V for this experiment, we will use 6V on the Rover) and separately to the 4 logic pins on the arduino (not visible in the picture, you can just see the wires going to the driver board).

I was not able to find a lot of info about the motors, but the table below provides pretty much what we need.


The maximum current @6v is 150mA and since our driver can provide up to 2000mA we should be more than ok.

An H-Bridge uses Dir1 to make the motor turn on one direction and Dir2 to make it turn the opposite direction, so we will need to activate them alternatively.
We will use analogWrite() to sned them a PWM wave to control the speed.

As we need two motors (left and right) we use 4 pins (6,9,10,11)

int left1        =10;
int left2        =11;
int right1       =6;
int right2       =9;    

We also add two variables to memorize if the motor is turning in one direction or the other, we will need this once we use the encoders to calculate the speed, in fact those encoders can tell us the speed, but not the direction, so we will use these variables to get that missing information.

int leftDir  =1;
int rightDir =1;

Then we set up two functions to control the left and right motor, the speed should be between -255 and 255

void leftMotor(int speed)
{
   if (speed>=0)
   {
     analogWrite(left1,0);
     analogWrite(left2,speed);
     leftDir = 1;
   } else
   {
     analogWrite(right1,-speed);
     analogWrite(right2,0);
     leftDir = -1;
   }
}


void rightMotor(int speed)
{
   if (speed>=0)
   {
     analogWrite(right1,0);
     analogWrite(right2,speed);
     rightDir = 1;
   } else
   {
     analogWrite(right1,-speed);
     analogWrite(right2,0);
     rightDir = -1;
   }
}

A simple setup to configure the pins

void setup() {
  pinMode(left1, OUTPUT); 
  pinMode(left2, OUTPUT);
  pinMode(right1, OUTPUT);  
  pinMode(right2, OUTPUT); 
  digitalWrite(left1,LOW);
  digitalWrite(left2,LOW);
  digitalWrite(right1,LOW);
  digitalWrite(right2,LOW);
 }

and a loop function to test if everything works fine, this one will make a motor (the right one) spin clockwise for 3 seconds, stop for half a second, then spin counter-clockwise, stop half second etc.

void loop() {
  rightMotor(255);
  delay(3000);
  rightMotor(0);
  delay(500);
  rightMotor(-255);
  delay(3000);
  rightMotor(0);
  delay(500);
}

Indeed the code can be optimized a bit, but I think in this form it should be quite understandable.
To test the various speeds I think it is best to have the motor mounted on the rover, so that we can apply some load instead of letting it spin freely.

Tip : if you are using stronger motors, make sure the wires you use to connect them to the driver and to connect the driver to the power supply can handle the needed current.

On the rover we will have a 7.4V Lipo battery, which will be connected to a small 3A buck converter to bring the voltage down to the needed 6V.
A buck converter is a device that uses a combination of  inductor / capacitor to reduce a given voltage to a desired level, using a high frequency PWM.
It might seem an overkill for this purpose, but now they can be found pretty cheap and provide a good efficiency which helps in maximizing the battery charge usage.


Arduino Robot - Moving around and steering

It is true the Rover we are planning will have to do many things, but the most basic thing it has to do is to stroll around, to put it simpler : move.

It is a Two Wheel Drive rover, meaning it will have a small electric motor on each of its two traction wheels and it will have a third traction-less wheel on the back, just to balance it out.

It will be able to steer like tanks do, by changing the speed of each motor accordingly.
The simple way to look at this is by considering some basic combination of speeds :
1) The two wheels are turning in the same direction (forward) and with the same speed -> the  rover will drive on a straight line, moving forward
2) The wheels are turning with opposite directions, but the same speed -> the rover will turn on itself, around the middle point between the two wheels

3) One wheel is turning, the other one is still -> The rover will rotate and the center of rotation will be the still wheel.


We can generalize the concept and find the center of rotation for any combination of wheel rotation velocity.
It is easier to do that using vector match which is quite intuitive, I am saying this because the target audience of this article includes very young makers that eventually did not study it yet... don't  get scared :)

If we represent the velocity as an arrow starting from the center of the wheel and pointing to the direction in which the rover is moving, we can use some basic geometry to figure stuff out.


As you can see in the example above the right wheel is rotating roughly twice as fast as the left one, this is why the V2 arrow is about twice as long as the V1 one.
This means that in the same amount of time the right wheel will travel twice as the distance traveled by the left one.
Now, if we connect the base of the arrows and extend the line, then we connect the top of the arrows and we also extend that line, we discover they eventually touch themselves in a point.
That point (the red triangle) is the center of rotation, in fact if V1 = V2 those lines will never touch which means that the center of rotation does not exist... and that is  because there is no rotation at all.
If V1 = V2 the rover would drive in a straight line.

The same concept works for about any combination of velocities.


In this second example V1 and V2 have different direction and modulus (modulus just means how "long" a vector is), can we compute the position of the center of rotation?
Indeed we can, as previously said, basic geometry comes in help.


We want to find X, it is the distance between the left wheel and the center of rotation, you can easily see that we can then relate it to any point we consider the center of the rover, like the middle point between the two wheels.

The green and red triangles are similar, so we can state that :

X : V1 = (D + X) : V2

Note that we use (D + X) or (D - X) depending on which way the X arrow is pointing.
Resolving : 

X = V1/V2 * (D + X)
X = V1/V2 * D + V1/V2 * X
X (1-V1/V2)) = V1/V2 * D


  V1/V2 * D
X =   ------------------    
 1-V1/V2

Now say we want to relate everything to the middle point of the axis connecting the two wheels :

  V1/V2 * D
X =       ----------------    + D/2

 1-V1/V2

Let's assume D = 10 cm,  V1 = -50 rpm ,  V2 = 100 rpm.

X = -50/100 * 10 / (1 +50/100) + 10/2 = -5 / 1.5 + 5 = 2.66 cm  

The coordinate system we are using has the center in the middle point of the axis connecting the wheels and positive X facing left.

Knowing the center of rotation is key to be able to plot maneuvers, i.e. if we need to drive around an obstacle, but it is also important to calculate the position of the robot at any time.

In fact we might try to drive the two motors with a predictable velocity, eventually equal, but for various reasons one might turn a bit faster than the other forcing our rover into a undesired shallow turn and by consequence missing the predicted trajectory.
That's  not really a huge issue provided we can timely apply corrective actions, and this becomes possible if we also measure the real velocity of the wheels.

A typical way to measure the rotation speed of something is to attach an encoder, a small and simple device that sends an impulse every known number of degrees of rotation.
This is typically achieved using a small plastic wheel with a number of holes in it


The U shaped thingy visible in the bottom right is an opto-coupler, on one side of the U there is an LED and on the other side a photo-transistor.
When light generated by the LED hits the transistor, current is allowed to flow through it and that can be detected as a logic 1 on the pins of a MCU.
If the plastic wheel is placed in the U, when it turns it will generate a 0 level each time there is no hole between the LED and the transistor and a 1 each time a hole is between the two.

Finally, if we know how many holes (N) are in the wheel , we can easily compute how many degrees there are between each hole.

deg = 360 / N

And if we count how many times a 0-1 pulse happens on the selected pin of the MCU , we can also compute how many revolution the traction wheel performed:

rev = pulses * 360 / N


The schematics to connect the encoder to the Arduino are pretty simple :
the green triangle represents the LED, the red / white crossed circle represents the transistor.
There is a specific reason why we selected pin 2 on the Arduino, but we will dig into that detail later.

At this point we ASSUME we can activate the two electric motors and we know how we can use a "feedback loop" to measure how much they really moved.
Next step will be to see the details on how to activate the motors.

Monday, May 19, 2014

Arduino Robot

I played a bit with Arduino some time ago and I think it is a great idea to get started with MCUs.
I believe it can support you even when you try to do more complicated stuff, but I stopped playing with it for a while since I preferred to get into a more " hardcore " scenario with MCUs.

That said, a couple of years ago, I gifted an Arduino Uno to a young kid (he is the 11yo son of my cousin) who got totally hooked on this thing.

So, to help him advance, now, I proposed to do a sort of Arduino Bootcamp this summer and to build some kind of robot rover together, in about 1 week.

For this reason I am preparing some material and thought that maybe I could document here my experiments so they could be useful to others.
It will be basic stuff, but still enjoyable I guess, to be fair I am not yet sure what the end result will be as I will try to adapt to things he can understand.

The inspiration is the Curiosity Rover that is strolling on Mars... I believe (I am pretty sure actually :) ) we will do something a bit simpler than that, but the idea is to have a rover that can be autonomous (avoiding obstacles, computing directions, speeds etc) and that can receive high level orders via a digital radio connected to a PC on which we will run probably a java client (that I will write).



I guess we will have another arduino as a bridge for the digital radio to the pc.

The rover is based on a 2WD chassis that can be easily found on ebay.


 Rotary encoders will allow us to measure the speed of the robot and calculate its position by integration.
We are planning to use a digital compass to identify the heading, ultrasound modules (most likely 3 of them) to detect obstacles and to scan the area (one of them is going to be mounted on a stepping motor).

I also have some IR emitter/detectors that eventually can be used to implement a "follow the path" functionality, not sure we will be able to stick that one in in time, but maybe we will just add the hardware and later on we will enable the functionality via software.

I am assuming we will use 3 arduinos for the rover itself as we need a lot of i/o (maybe a mega would be enough tho) and this is an option for me to illustrate some serial protocol concepts (we will use uart/spi and I2C, I am leaning towards I2C to allow the communications between the 3 mcus).

If all this sounds interesting to you, then stay tuned, I will document my experiments and tests while I get ready to explain those concepts and ideas to my young colleague!
Plus, hopefully, I will document the construction and tests of the robot which should happen this summer (in a week).

If you have ideas or suggestions, send them in before this summer!

Meanwhile I will probably put on hold my other experiments (I already have a second part on NRF24L01 ready, but not publishing yet until I finish the full series) and focus on this Arduino project.
I simply don' t have enough time for both, sorry.