Search Microcontrollers

Showing posts with label Hall Effect. Show all posts
Showing posts with label Hall Effect. Show all posts

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.

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