Go Down

Topic: calculating velocity using hall effect (Read 1 time) previous topic - next topic

tasha

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 change
const int  hallSensor = 14;    // the pin sensor is connected to


// Variables will change:
int sensorCounter = 0;       // counter for the number of senses
int disCounter = 0;
int sensorState = 1;         // current state of the button
int lastSensorState = 1;     // previous state of the button
unsigned 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

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

tasha

I'm using pullup resistors in my circuit... Should I still do it in my program?

RuggedCircuits

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

tasha

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

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.

tasha

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

tasha

I meant high as it responds to the magnet and increments the counter... sorry

TomServo

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 change
const int  hallSensor = 14;    // the pin sensor is connected to


// Variables will change:
int sensorCounter = 0;       // counter for the number of senses
int disCounter = 0;
int sensorState = 1;         // current state of the button
int lastSensorState = 1;     // previous state of the button
unsigned 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