11 years, 5 months ago.

Hall sensor measurement - help/advice needed

Hello, i'm trying to measure the RPM and speed of a wheel attached to a dc motor. I have this hall sensor: https://www.sparkfun.com/datasheets/Components/General/Hall-US1881EUA.pdf and a magnet placed on the wheel.

I have this following code sector where i'm trying to calculate those two parameters, but i only get a speed of 0.06xxx meters / second, which is far too low. I even timed it on a 1 meter space and i got 2.2 seconds, so somewhere around 0.5 meters / second is more likely to be correct.

So this is the code, i tried to adapt it from here: http://mbed.org/users/powerstrokediesel97/code/Test1/

#include "mbed.h"
 
Serial pc(USBTX, USBRX); 
Timer t;
InterruptIn risingEdge(p5);
 
DigitalOut myled(LED1);
DigitalOut myled2(LED2);
 
long int count;
 
void pulses() {
/*
    if(myled2 == 1) {
        myled2 = 0;
    } else {
        myled2 = 1;
    }
*/
    count++;
}
 
int main() {
 
    risingEdge.rise(&pulses);
    while(1) {    
        t.reset();
        t.start();
        count = 0;
        while(t.read_ms() < 1000) {
            ;
        }       
        t.stop();
        long int temp = count;
        pc.printf("Count: %d", temp);
        double circumference = 0.06 * 3.1416; // 6 cm wheel diameter * PI
        double rev = (double)temp;
        double rpm = rev*60.0;
        double speed = circumference * rev;       
      pc.printf(" %0.2f ", rpm);
      pc.printf(" %f m/s", speed);
      pc.putc(0xA);
        pc.putc(0xD);
    }
}

Any help is welcome, as well as any other approaches. Thanks!

nvm

posted by Erik - 29 May 2013

3 Answers

11 years, 5 months ago.

Better define 'count' as volatile, otherwise the compiler might get a bit too happy optimizing it away. And your while(t.read... stuff does exactly the same as wait_ms(1000). The wait uses the same method, so it isn't like it does many for loops with nop instructions, it just checks the timer to see how much time has passed.

Is the number of counts you measure correct?

Yes the number of counts is correct, i've set count as volatile long int count; So that while loop just makes sure that the timer runs for 1 second and then it stops, thus allowing me to get the rotations / second and then multiply by 60 and get RPM ? Thank you for your answer. Have a nice day!

posted by Razvan Coban 30 May 2013
11 years, 5 months ago.

What circuitry are you using. The hall sensor is open drain and needs a pull-up resistor. You may also want to add some small capacitor to remove noise. Is the magnet close/strong enough so that you get a decent signal.

I have a 10Kohm placed between 5V and VOUT on the hall sensor. Yes i see on the oscilloscope the signal in the moment that the magnet passes by with both poles. I double checked by turning on LEd1 when the north pole passses (.rise) and LED2 when the south passes and de-latches the sensor (.fall). Should i use 2 magnets placed simetrically one against the other ? Thank you for you answer, have a nice day !

posted by Razvan Coban 30 May 2013
11 years, 5 months ago.

new code that returns 1.5 - 2 m/s - getting close to normal

#include "mbed.h"
 
Serial pc(USBTX, USBRX); 
Timer t;
InterruptIn risingEdge(p5);
 
DigitalOut myled(LED1);
DigitalOut myled2(LED2);
 
volatile long int count;
 
void pulses() {
    if(myled2 == 1) {
        myled2 = 0;
    } else {
        myled2 = 1;
    }
    count++;
}
 
int main() {
    risingEdge.rise(&pulses); 
    while(1) {
        t.reset();
        t.start();
        count = 0;
        while(t.read_ms() < 1001) {
            ;
        }     
        t.stop();
        long int temp = count;
        pc.printf("Count: %d", temp);
        double circumference = 0.06 * 3.1416; // 6 cm wheel diameter * pi 
        double rev = (double)temp;
        double rpm = rev*60;
        double speed = circumference * rev;  
        pc.printf(" %0.2f RPM", rpm);
        pc.printf(" speed: %f m/s", speed);
        pc.putc(0xA);
        pc.putc(0xD);
    }
}