Go Down

### Topic: calculating velocity using hall effect (Read 2351 times)previous topic - next topic

#### natasha

##### Oct 12, 2010, 11:37 pm
I using Hall effect sensor http://parts.digikey.com/1/parts/948176-sensor-hall-effect-mini-pnl-mnt-55100-3h-02-a.html and trying to calculate velocity in intervals of 5 seconds. However, the velocity is displaying zero. It should be a simple fix, but not sure what I'm doing wrong.

Code: [Select]
`//const will not changeconst int  hallSensor = 14;    // the pin sensor is connected to// Variables will change:int sensorCounter = 0;       // counter for the number of sensesint disCounter = 0;int sensorState = 1;         // current state of the buttonint lastSensorState = 1;     // previous state of the buttonunsigned int rpm;unsigned long timeOld;unsigned long changeTime;unsigned long dTime = 0;int distance = 0;int changeDistance = 0;int prevDistance = 0;long velocity = 0;void setup() {  // initialize the sensor pin as a input:  pinMode(sensorCounter, INPUT);  // initialize serial communication:  Serial.begin(9600);}void loop() {  // read the sensor state  sensorState = digitalRead(hallSensor);  dTime=millis();  // compare the sensorState to its previous state  if (sensorState != lastSensorState) {    // if the state has changed, increment the counter    if (sensorState == LOW) {      // if the current state is LOW then the sensor      // wend from off to on:      sensorCounter++;      disCounter++;      timeOld = millis();      Serial.println("on");      Serial.print("number of button pushes:  ");      Serial.println(sensorCounter, DEC);    }    else {      // if the current state is HIGH then the button      // wend from on to off:      Serial.println("off");    }        lastSensorState = sensorState;  }    changeTime = millis()-timeOld;     if (changeTime > 5000) {      velocity = 0;      dTime = millis();      Serial.println("Did this work boo ya!!!?");}     else if (millis() - dTime == 5000) {       velocity = (21/22)*disCounter;       disCounter = 0;       Serial.println("Did this work?");       dTime = millis(); }             /* if (changeTime > 5000) {      velocity = 0;      dTime = millis(); }      else if (millis() - dTime == 5000) {        velocity = (disCounter*7560)/11;        disCounter = 0;        dTime = millis(); }   */                  distance = 7 * sensorCounter;    // 7 feet is one revolution of a 26" tire                  Serial.print("Velocity: ");      Serial.print(velocity);      Serial.println(" MPH");   }`

#### RuggedCircuits

#1
##### Oct 13, 2010, 12:20 am
In your setup() function, you are applying the pinMode() function to sensorCounter but I think you want to apply it to hallSensor.

Also, the sensor you have selected needs a pullup resistor so you should enable it:

Code: [Select]
`pinMode(hallSensor, INPUT);digitalWrite(hallSensor, HIGH);`

--
The Gadget Shield: accelerometer, RGB LED, IR transmit/receive, light sensor, potentiometers, pushbuttons

#### natasha

#2
##### Oct 13, 2010, 12:53 am
I'm using pullup resistors in my circuit... Should I still do it in my program?

#### RuggedCircuits

#3
##### Oct 13, 2010, 12:55 am
No, shouldn't be necessary to enable pullups in your program if you have them externally. How big a resistor? Connected to what voltage?

Are you sure you have connected to pin 14? Which Arduino are you using?

--
The Quick Shield: breakout all 28 pins to quick-connect terminals

#### natasha

#4
##### Oct 13, 2010, 12:57 am
When a magnet is applied to the sensor it reads as high, we would like to know the speed. And can't figure it out right : (

#### RuggedCircuits

#5
##### Oct 13, 2010, 01:09 am
Does it read low when you take the magnet away? Because I think it's backwards...it should read LOW when you apply a magnet to the sensor.

--
Need a custom shield? Let us design and build one for you.

#### natasha

#6
##### Oct 13, 2010, 01:12 am
Wait... I will have to check on the resistors.. I got things mixed up, working on too many modules at once

I don't have the resistors, I don't have the board with me right now so I couldn't remember. But like I mentioned the sensor responding and we get a high we just have a problem interpreting that into speed in 5s intervals

#### natasha

#7
##### Oct 13, 2010, 01:18 am
I meant high as it responds to the magnet and increments the counter... sorry

#### TomServo

#8
##### Oct 15, 2010, 06:10 am
Your else if() statement is incorrect.  It appears that it would only operate if it took exactly 5000ms between the dTime setting on line 32 and the else if() on line 59.  I'm not sure why you have both dTime and changeTime and timeOld - what is the purpose of each?
You should only need one.  Set it initially to zero, and when it goes greater than or equal to 5000 more than the current time, calculate the velocity and reset it to the current time.
Something like this:

Code: [Select]
`//const will not changeconst int  hallSensor = 14;    // the pin sensor is connected to// Variables will change:int sensorCounter = 0;       // counter for the number of sensesint disCounter = 0;int sensorState = 1;         // current state of the buttonint lastSensorState = 1;     // previous state of the buttonunsigned int rpm;unsigned long timeOld;int distance = 0;int changeDistance = 0;int prevDistance = 0;long velocity = 0;void setup() {  // initialize the sensor pin as a input:  pinMode(sensorCounter, INPUT);  // initialize serial communication:  Serial.begin(9600);}void loop() {  // read the sensor state  sensorState = digitalRead(hallSensor);  // compare the sensorState to its previous state  if (sensorState != lastSensorState) {    // if the state has changed, increment the counter    if (sensorState == LOW) {      // if the current state is LOW then the sensor      // wend from off to on:      sensorCounter++;      disCounter++;      Serial.println("on");      Serial.print("number of button pushes:  ");      Serial.println(sensorCounter, DEC);    }    else {      // if the current state is HIGH then the button      // wend from on to off:      Serial.println("off");    }    lastSensorState = sensorState;  }    if (millis() - timeOld >= 5000) {      velocity = (21/22)*disCounter;        distance = 7 * sensorCounter;        timeOld = millis();      Serial.println("Did this work boo ya!!!?");        disCounter = 0;        Serial.print("Velocity: ");        Serial.print(velocity);        Serial.print(" MPH");    }} `

You could improve your accuracy greatly by calculating velocity based on the actual time taken for those pulses.  So if you got 10 pulses in 4.3 seconds, calculate it actually as 10 in 4.3s and not 10 in 5s.  It'd be a little difficult to do with your current structure, though.  You'd need a while loop... maybe something like this:
Code: [Select]
`void loop() {  // read the sensor state  while(digitalRead(hallSensor) == 0){}    //wait for the sensor to read HIGH  while(digitalRead(hallSensor) == 1){}    //wait for the sensor to read LOW  startTime = millis();                    //record the time when the sensor went LOW  while(millis() - startTime < 5000){      //loop for 5 seconds    while(digitalRead(hallSensor == 0){}   //wait for the sensor to read HIGH    while(digitalRead(hallSensor == 1){}   //wait for the sensor to go LOW again    sensorCounter++;                       //increment the counter    endTime = millis();                    //set the current time as the endTime - this will get updated every pulse  }  rpm = (60000 * sensorCounter)/(endTime - startTime);     //once 5s goes by, you can calculate RPM based on the number of sensor counts and the time elapsed between the first count and last.                                                           //60000ms in a minute.  velocity = rpm * .025;                                   //velocity in mph.  sensorCounter = 0;                                       //Reset the sensor counter.  No need to reset the startTime or endTime.}`

Go Up