Speed sensor calculation using Python

Yazidapple
Posts: 24
Joined: Wed Mar 23, 2016 3:06 pm

Speed sensor calculation using Python

There are 2 methods for calculating speed using Python.

The first method is using "pre-defined interval".
The second method is using "calculated interval".

Before we dive straight into the code let me show you the setup of this project. What we need are RaspberryPi, hall effect sensor or reed switch and small magnet. You can use either one of the sensor and the code would be pretty much the same.
The hall effect sensor that I'm using is of Unipolar type. Depending on how you setup the magnet on the spinning mechanism, it will decide which type of hall sensor is suitable for you. Unipolar sensor can only get triggered on one side of the sensor. Bipolar sensor has the ability to detect magnet in both directions.

Reed sensor is a much simpler device to use for this project . I will show you how to use both sensors.
As this project is just a prototype for the wheel of our motorcycle/car, I'm using a cpu fan as a replacement for the real wheel.
The magnet is mounted on the flat surface of the fan.

Hall effect sensor has 3 pins or legs. There are VCC, Ground and Output.
Connect the VCC to 3.3V . (correction! I wrote 5V earlier)
Ground as usual.
And output to any GPIO that you wish. If everything is connected, you are good to go.

CALCULATED INTERVAL METHOD

(CODE)

Code: Select all

``````#!/usr/bin/python3
import RPi.GPIO as GPIO
from time import sleep
import time, math

dist_meas = 0.00
km_per_hour = 0
rpm = 0
elapse = 0
sensor = 12
pulse = 0
start_timer = time.time()

def init_GPIO():					# initialize GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(sensor,GPIO.IN,GPIO.PUD_UP)

def calculate_elapse(channel):				# callback function
global pulse, start_timer, elapse
pulse+=1								# increase pulse by 1 whenever interrupt occurred
elapse = time.time() - start_timer		# elapse for every 1 complete rotation made!
start_timer = time.time()				# let current time equals to start_timer

def calculate_speed(r_cm):
global pulse,elapse,rpm,dist_km,dist_meas,km_per_sec,km_per_hour
if elapse !=0:							# to avoid DivisionByZero error
rpm = 1/elapse * 60
circ_cm = (2*math.pi)*r_cm			# calculate wheel circumference in CM
dist_km = circ_cm/100000 			# convert cm to km
km_per_sec = dist_km / elapse		# calculate KM/sec
km_per_hour = km_per_sec * 3600		# calculate KM/h
dist_meas = (dist_km*pulse)*1000	# measure distance traverse in meter
return km_per_hour

def init_interrupt():
GPIO.add_event_detect(sensor, GPIO.FALLING, callback = calculate_elapse, bouncetime = 20)

if __name__ == '__main__':
init_GPIO()
init_interrupt()
while True:
calculate_speed(20)	# call this function with wheel radius as parameter
print('rpm:{0:.0f}-RPM kmh:{1:.0f}-KMH dist_meas:{2:.2f}m pulse:{3}'.format(rpm,km_per_hour,dist_meas,pulse))
sleep(0.1)
``````
Using calculated interval method is better and more precise than pre-defined interval.
Here, we make use of the time.time() module in Python to precisely measure time duration of each interrupt interval.
We are using add_event_detect() to take advantage of the GPIO pin interrupt event handler.
Here we use one callback function called "calculate_elapse(channel)". This function will get called anytime interrupt event happens.

TRY to grab this concept in order to understand this code.

We are using ONE magnet mounted on one of the fan blade and ONE hall effect sensor
mounted on a static surface on our fan chassis.

Therefore, we could come up with an assumption that 1 complete rotation will be made whenever 1 interrupt event occurs.

From that assumption, we could determine the time duration of 1 complete rotation in our callback function.

So, lets take a look at the callback function in the code. It is named "calculate_elapse(channel)". In that function, we have
3 main global variables. Global variables are made so that their values can be used outside that local function which
in our case, our local variable is the callback function named "calculate_elapse(channel)". The globals are:

- pulse
- start_timer
- elapse

1) pulse : a counter variable used to count the number of interrupts. it can also be used to calculate total distance travelled
by the wheel.
2) start_timer : a time variable that stores the initial timestamp before an interrupt occurs and stores the current timestamp
after the interrupt has occurred!
3) elapse : time duration of 1 complete rotation by subtracting the timestamp during interrupt instance with start_timer which holds
the initial timestamp before that interrupt occurred.

After we have calculated the elapse, we immediately set our new start_timer with the current timestamp so that it can be used to
calculate our next elapse value if new interrupt occurs.

Now that we have our global elapse value, we can move on to next function which is "calculate_speed(r_cm)". this function will be called
in our main loop. This function takes in one parameter which is the radius of wheel in centimeter (you could use meter if you wish).
As the global elapse value is now accessible in this function, we can calculate the speed of the wheel using simple mathematical
formula.

First, we have to make sure that our elapse value is not Zero to avoid DivisionByZero error.

Round Per Minute (rpm) can be calculated using : rpm = 1/elapse * 60
where 1 is referring to 1 complete rotation and 60 is referring to 60 seconds.

circ_cm (wheel circumference) can be calculated using : 2 x pi x radius

dist_km (distance moved in km) can be calculated using : dist_km = circ_cm/100000

km_per_sec (speed in KM/s) calculated using: km_per_sec = dist_km / elapse

km_per_hour (speed in KM/h) calculated using: km_per_hour = km_per_sec * 3600

That's all for the CALCULATED INTERVAL METHOD! You can try it with your Raspberry Pi and get the result printed on the terminal. Good luck!
Last edited by Yazidapple on Tue Jun 14, 2016 9:32 am, edited 1 time in total.

Massi
Posts: 1690
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: Speed sensor calculation using Python

Yazidapple wrote: Hall effect sensor has 3 pins or legs. There are VCC, Ground and Output.
Connect the VCC to 5V .
Ground as usual.
And output to any GPIO that you wish. If everything is connected, you are good to go.
This is ok only if the hall has a OC output. If it's a RC output you can damage your pi powering it with 5V
Here, we make use of the time.time() module in Python to precisely measure time duration of each interrupt interval.
probably if you want to "precisely measure time duration of each interrupt interval" you should use pigpio.
Pigpio timestamps interrupts when they occurr, in your code you use the (not so) precise python time.time() when the callback is executed.

Yazidapple
Posts: 24
Joined: Wed Mar 23, 2016 3:06 pm

Re: Speed sensor calculation using Python

Massi wrote:
Yazidapple wrote: Hall effect sensor has 3 pins or legs. There are VCC, Ground and Output.
Connect the VCC to 5V .
Ground as usual.
And output to any GPIO that you wish. If everything is connected, you are good to go.
This is ok only if the hall has a OC output. If it's a RC output you can damage your pi powering it with 5V
Here, we make use of the time.time() module in Python to precisely measure time duration of each interrupt interval.
probably if you want to "precisely measure time duration of each interrupt interval" you should use pigpio.
Pigpio timestamps interrupts when they occurr, in your code you use the (not so) precise python time.time() when the callback is executed.
thanks for the feedback bro. i'll try to improve this code and the setup! still learning anyway

joan
Posts: 13755
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Speed sensor calculation using Python

http://abyz.co.uk/rpi/pigpio/examples.h ... ead_RPM_py shows a method using pigpio.

You might be interested in viewtopic.php?f=37&t=90243

Yazidapple
Posts: 24
Joined: Wed Mar 23, 2016 3:06 pm

Re: Speed sensor calculation using Python

joan wrote:http://abyz.co.uk/rpi/pigpio/examples.h ... ead_RPM_py shows a method using pigpio.

You might be interested in viewtopic.php?f=37&t=90243
Thanks so much! Thats really what I was looking for before I started working with this project.

am3u
Posts: 1
Joined: Tue Jul 26, 2016 6:22 pm

Re: Speed sensor calculation using Python

but how much accurate is it

Yazidapple
Posts: 24
Joined: Wed Mar 23, 2016 3:06 pm

Re: Speed sensor calculation using Python

am3u wrote:but how much accurate is it
the accuracy is quite acceptable for small and simple project where you just wanna create a simple speedometer to calculate the speed of your bike / motobike. as mentioned our friend above, pigpio method is the most accurate implementation.

Onkarb68
Posts: 2
Joined: Mon Jan 23, 2017 1:23 pm

Re: Speed sensor calculation using Python

Can anyone please tell which RPM sensor has got best accuracy for Raspberry pi3 model B?

ilman
Posts: 22
Joined: Wed Mar 08, 2017 5:08 am

Re: Speed sensor calculation using Python

i've tried the code and i get a normal result overall. but reading can't back to 0 if rotation get stopped. how did it happen?

Yazidapple
Posts: 24
Joined: Wed Mar 23, 2016 3:06 pm

Re: Speed sensor calculation using Python

ilman wrote:i've tried the code and i get a normal result overall. but reading can't back to 0 if rotation get stopped. how did it happen?

actually its just because there's simply no logic for it in the code
i just found a speed sensor (rotary disc) for Arduino on this website.
https://brainy-bits.com/blogs/tutorials ... th-arduino

i think you can use that code as reference to modify the Python code.

Code: Select all

``````#include <OneWire.h>
unsigned int counter=0;

void docount()  // counts from the speed sensor
{
counter++;  // increase +1 the counter value
}

void timerIsr()
{
Timer1.detachInterrupt();  //stop the timer
Serial.print("Motor Speed: ");
int rotation = (counter / 20);  // divide by number of holes in Disc
Serial.print(rotation,DEC);
Serial.println(" Rotation per seconds");
counter=0;  //  reset counter to zero
Timer1.attachInterrupt( timerIsr );  //enable the timer
}

void setup()
{
Serial.begin(9600);

Timer1.initialize(1000000); // set timer for 1sec
attachInterrupt(0, docount, RISING);  // increase counter when speed sensor pin goes High
Timer1.attachInterrupt( timerIsr ); // enable the timer
}

void loop()
{
// just leave it empty if you have nothing else to do in your program
}

``````

Yazidapple
Posts: 24
Joined: Wed Mar 23, 2016 3:06 pm

Re: Speed sensor calculation using Python

Onkarb68 wrote:Can anyone please tell which RPM sensor has got best accuracy for Raspberry pi3 model B?
are you asking for devices that could be used as speed sensor for Raspberry Pi?
any hall effect sensor or even a simple reed switch would suffice.

gurudattakr123
Posts: 2
Joined: Wed Mar 15, 2017 4:07 pm

Re: Speed sensor calculation using Python

How can we change this code so that rpm and kmph must come back to 0 when wheel is not rotating?

Yazidapple
Posts: 24
Joined: Wed Mar 23, 2016 3:06 pm

Re: Speed sensor calculation using Python

gurudattakr123 wrote:How can we change this code so that rpm and kmph must come back to 0 when wheel is not rotating?

will work on that. as for now you could try to search for other alternatives. i would recommend you to use Arduino for speedometer project instead of Pi.

Massi
Posts: 1690
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: Speed sensor calculation using Python

gurudattakr123 wrote:How can we change this code so that rpm and kmph must come back to 0 when wheel is not rotating?
well probably the program works based on callback, so if no signal is received, no calculation is done.
You can try playing with pigpio's watchdogs
http://abyz.co.uk/rpi/pigpio/python.html#set_watchdog
you should setup, in the callback, a watchdog on the GPIO so that if no callback is called within the timeout, the watchdog will call it and you'll return 0
Obviously in every callback you should cancel the previous watchdog and setup the new one.

RaMaSen
Posts: 3
Joined: Sun Jun 11, 2017 7:55 pm

Re: Speed sensor calculation using Python

Hi,

The calculation methods I can comprehend,
however........ I want to use a ble sensor instead of an GPIO sensor for my project (I have a Major dislike towards Cords when it can be done Wireless).
I get data from my ble sensor but can't use it nor calculate the RPM from it.
The point for me is:
I have my sensor mounted Under my bike pedal, it sends data to my Rpi3 on my bikes handlebar.
My Rpi3 has a Blinkt! hat on it and I want it to respond to my pedling stance.
example:
20-45 Rpm on my pedal/crank -->> Blinkt! goes Red flashing
46-60 Rpm on my pedal/crank -->> Blinkt! goes Green flashing.
60-90 Rpm on my pedal/crank -->> Blinkt! goes Blue flashing

I wish to use it for a Constant stance in biking.

can you please help me out with this?
I Really don't know where y missing link is.

thnx in advance.
Life is not just "good' when you open your eyes, it's Really GOOD when you realize you have another day to LIVE!

Yazidapple
Posts: 24
Joined: Wed Mar 23, 2016 3:06 pm

Re: Speed sensor calculation using Python

RaMaSen wrote:
Wed Sep 27, 2017 9:26 pm
Hi,

The calculation methods I can comprehend,
however........ I want to use a ble sensor instead of an GPIO sensor for my project (I have a Major dislike towards Cords when it can be done Wireless).
I get data from my ble sensor but can't use it nor calculate the RPM from it.
The point for me is:
I have my sensor mounted Under my bike pedal, it sends data to my Rpi3 on my bikes handlebar.
My Rpi3 has a Blinkt! hat on it and I want it to respond to my pedling stance.
example:
20-45 Rpm on my pedal/crank -->> Blinkt! goes Red flashing
46-60 Rpm on my pedal/crank -->> Blinkt! goes Green flashing.
60-90 Rpm on my pedal/crank -->> Blinkt! goes Blue flashing

I wish to use it for a Constant stance in biking.

can you please help me out with this?
I Really don't know where y missing link is.

thnx in advance.
what kind of BLE sensor are you using? is your Pi receiving any data from it? mind to elaborate further?

mohamedchihime
Posts: 1
Joined: Sun Apr 08, 2018 4:38 pm

Re: Speed sensor calculation using Python

hi
can anyone help me if the pulse sensor give wave instead of measuring or there any device work in sending wave for nerve instead of vibration

c17hawke
Posts: 1
Joined: Tue May 22, 2018 9:56 am

Thanks for this post

This post helped me to interface my raspberry pi 3 with LM393 Chip 1CH Optocoupler Motor Speed Measuring Counter Sensor Module.

RaMaSen
Posts: 3
Joined: Sun Jun 11, 2017 7:55 pm

Re: Speed sensor calculation using Python

Yazidapple wrote:
Fri Feb 23, 2018 6:40 pm
RaMaSen wrote:
Wed Sep 27, 2017 9:26 pm
Hi,

The calculation methods I can comprehend,
however........ I want to use a ble sensor instead of an GPIO sensor for my project (I have a Major dislike towards Cords when it can be done Wireless).
I get data from my ble sensor but can't use it nor calculate the RPM from it.
The point for me is:
I have my sensor mounted Under my bike pedal, it sends data to my Rpi3 on my bikes handlebar.
My Rpi3 has a Blinkt! hat on it and I want it to respond to my pedling stance.
example:
20-45 Rpm on my pedal/crank -->> Blinkt! goes Red flashing
46-60 Rpm on my pedal/crank -->> Blinkt! goes Green flashing.
60-90 Rpm on my pedal/crank -->> Blinkt! goes Blue flashing

I wish to use it for a Constant stance in biking.

can you please help me out with this?
I Really don't know where y missing link is.

thnx in advance.
what kind of BLE sensor are you using? is your Pi receiving any data from it? mind to elaborate further?
Sure!
I intend to use a wahoo cadence sensor or a metawear RG developmentboard.
Both are still reluctant to hand over data
Life is not just "good' when you open your eyes, it's Really GOOD when you realize you have another day to LIVE!

RaMaSen
Posts: 3
Joined: Sun Jun 11, 2017 7:55 pm

Re: Speed sensor calculation using Python

Hi there,

A year has pased since i posted here.

Wich ble service i use: Pybluez or bluepy.
I get connection wich the metawear sensor but can’t get a sufficient “zero-crossing point” to be registered as Pulse.
Wahoo sensor is a Drag...... can connect but can’t get data. Wahoo tech dept doesn’t want to help either “we have made Apps for that..... “ they say.
Win10 (PC) has option to read whathoo sensor and get data, so does the metawear portal.
Guess what....... raspberry pi 3B+ does only support win10 iot core (or Vice Versa) Not the services to run the win10 sensor portals!

So, for both wuthoo and metawear nothing open source has been developed to run on a rpi3B(+). Note: a metaHub based on a rpi3B has been developed and is to be used as portal to iot services (so i didn’t buy one Yet).

Foremost-> i get data on the Z axis wich i found strange at 1st due to data around +1 and -1 so i had a hard time to find a 0-crossing wich eventually were the +1/-1 crossings then i got lost in how to get these crossing to act as 0 crossings.

For Now it seems i’m phucked by wanting a ble sensor pedal mounted setup.
Go By Wire a friend said........
Nope! I want the freedom of bluetooth to ride Any bike i want and see my RPM with my Blinkt! on my RPI3B+ !!

Okay, enough ranting done......
please post your thoughts
Life is not just "good' when you open your eyes, it's Really GOOD when you realize you have another day to LIVE!

Return to “Teaching and learning resources”