### Speed sensor calculation using Python

Posted:

**Tue Jun 14, 2016 6:25 am****There are 2 methods for calculating speed using Python.**

**The first method is using "pre-defined interval".**

The second method is using "calculated 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.

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)
```

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

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!