Search Microcontrollers

Tuesday, May 27, 2014

Arduino Robot - Hall Effect sensors

Hall effect sensors are tiny devices that can rapidly sense the presence of a magnetic field.

This effect was discovered by Edwin Hall back in 1879 and it is based upon the interaction of magnetic fields with electric ones.

Edwin Hall (from Wikipedia)

Technically, what a hall effect detector does is to operate as a switch activated by a magnetic field in the proximity.
In other words, it is a reliable way to activate a switch between two moving parts, without having them to physically touch.
This turns in handy when you need to detect the rotation speed of an object (i.e. a HDD drive disk) and you don't want to have the moving part and the static one touching (which would lead to friction and eventually wear off the contact after some time).

When a magnetic field interacts with an electric field (and it is not parallel to it), electrons are subject to a force (Lorentz Force) that makes them alter their path.


In step 1 an electric field exists in the conductor, electrons move from left to right.
A non parallel (try to visualize it in 3D, ideally perpendicular to the XY plane) a magnetic field generates a Lorentz Force on the electrons.
In step 2 the Lorentz Force pushes the electrons against the upper border of the conductor generating a polarization - / + on the two edges of the conductor.
In step 3 the polarization difference is measured as a voltage perpendicularly to the conductor.

Some commercial devices are available to be used directly as digital switches.
I used some A3144E, which can be easily sourced online at relatively low cost (paid less than 2$ for a set of 10, shipped).


To use them is quite simple, just connect the center pin to GND, the left one (looking at the device you should see the writings on it to make sure you are facing the correct side) to VCC (4.5V up to 28V, it contains a regulator) and the right pin to your digital input.
The output voltage is = Vcc, so be careful if you are planning to use a 3.3V MCU.

A very basic Arduino sketch to test it :

int input_pin = 7;
int led_pin = 13;

void setup()
{
 pinMode(led_pin,OUTPUT);
 pinMode(input_pin,INPUT_PULLUP);
 digitalWrite(led_pin,LOW); 
}

void loop()
{
   digitalWrite(led_pin,!digitalRead(input_pin));
}

Notice I enable a pullup resistor on the input, just in case to avoid floating signals.
Another thing you should mind is that this sensor is activated by a magnetic field of a specific polarity, the opposite polarity is activated by the opposite side of the same sensor, make sure you place you magnet correctly.

The reason why I am testing these sensors is to identify a ZERO point for a stepping motor.
Let me explain better : I will mount a ultrasound sensor on top of a stepping motor, this will enable a fine scanning of the area.
However unfortunately stepping motors do not record or detect their position, so if the sensor is all the way to the left, in the middle or half way to the right, only the software, counting the steps, can tell.
Unfortunately if you reset your MCU the sensor will remain in whatever position it was before the reset and the step count will start from zero.

So, when booting the MCU I could move the stepping motor until a tiny magnet reaches a hall effect sensor.
Depending on the size of the magnet we can calculate how many steps we will need to clear it, thus we can calculate the mid point giving us a reliable zero reading.
I will probably use two sensors, static and a rotating neodymium magnet (will rotate together with the ultrasound sensor), meaning I will need to travel 180 degrees maximum before hitting one of the two sensors and being able to calculate the exact position.
Hopefully I will be able to show details of the construction once I present the ultrasound scanner, provided I will finally implement it that way :)


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.