Go Down

Topic: Measuring Speed of Bicycle (Read 303 times) previous topic - next topic

ningaman151

Jul 09, 2019, 06:23 pm Last Edit: Jul 09, 2019, 06:31 pm by ningaman151
Hello I am trying to measure the speed of a bicycle with an Arduino bicycle computer. I tried using an interrupt service routine that measures the speed based on the time of the last interrupt. However, that is not ideal for many reasons. For example slow speeds have a slower refresh time than faster speeds.

What I'm doing now is having an interrupt service routine that increments a count variable that is then used in a different function to measure the speed depending on the value of count. count is decremented using another function that is called at a certain interval.

What I'm not sure about is how to measure the speed based on count, and when (how often) to decrement count.

Here is the relevant code, count is a static member variable of the class BicycleComputer:

Interrupt service routine:
Code: [Select]

static void BicycleComputer::trigger_hallsensor()
{
  count++;
  my_spd_dst.dst += tire_circ_km;
}


Speed measurement:
Code: [Select]

void BicycleComputer::measure_speed()
{
  unsigned long now = millis();
 
  unsigned long delta_time = now - prev_lcd_time;
 
  if(delta_time >= BC_MEASURE_INTERVAL)
  {
    prev_lcd_time = now;
   
    my_spd_dst.spd = double(tire_circ) / double(delta_time) * 3.6 * double(count);
    }
  }
}



Decrement count:
Code: [Select]

bool BicycleComputer::reset_count()
{
  if(count > 0 and wait(prev_time, BC_RESET_COUNT_INTERVAL)) // Wait function waits until the specified interval is reached
  {
    count = --;
  }
}


What I'm currently thinking is having the measure speed part of the code reset count, so therefore count is incremented until the speed is measured, where then all the counts are expended and the counting up starts over again. What do you think?

Delta_G

That's what I'd do.  When you go to check the speed get the length of time since the last time you checked speed, get the number of counts, and start count over.  Then you can use the number of counts to get the distance and the distance and time to get speed. 

Remember to protect count when you read it if it is larger than a byte.  Turn interrupts off, get a copy of the value and reset to zero, then turn interrupts back on.  You don't want it to increment in the middle of that process. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

jpom

I'm using a Hall Effect sensor to measure the speed of my car.

I dropped the interrupt approach as it was too involved. I simply monitor the pin and measure the time elapsed between two consecutive highs. From that I calculate the speed.

The speed reading is consistently accurate.

Paul__B

Common "newbie" mistake, using interrupts for things when it is clearly inappropriate.  :smiley-roll:

Second "newbie" mistake, snippets.

ningaman151

Common "newbie" mistake, using interrupts for things when it is clearly inappropriate.  :smiley-roll:
How would I register the hall sensor/reed switch without using interrupts?

wildbill

Don't use any delays in your code and just poll the sensor. The state change detention example may be useful.

Idahowalker

#6
Sep 20, 2019, 04:02 pm Last Edit: Sep 20, 2019, 04:09 pm by Idahowalker
The rim of the wheel of the bike has a size, imagine that. Now holding onto the wheel rim size thought. In your bicycle specs you will have a wheel size; such as 26 IN x 1.4 IN: 26 inches or 700C x 28 MM: 700c. The first number represents the size of the wheel and if the wheel rotates one time the bike moves forward that wheel size distance. If a sensor is attached to the wheel and there is a pickup that can count the number of times the sensor is triggered one can determine the distance traveled. With 2 sensors the granularity increases and with 4 sensors the granularity increases even more.

Since I tend to use ESP32's I'd use the ESP32 PCNT API, which works in the background.

Quote
The PCNT (Pulse Counter) module is designed to count the number of rising and/or falling edges of an input signal. Each pulse counter unit has a 16-bit signed counter register and two channels that can be configured to either increment or decrement the counter. Each channel has a signal input that accepts signal edges to be detected, as well as a control input that can be used to enable or disable the signal input. The inputs have optional filters that can be used to discard unwanted glitches in the signal.
https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/pcnt.html

jremington


Go Up