title: How to use Python to measure speed of bike like a digital speedometer, using a Raspberry Pi?
body: <p>I am working on a project using a Raspberry Pi and done code in Python. My project is to measure the distance from all side of bike and speed of bike. I am able to measure distance using an ultrasonic sensor, but trying to measure speed using hall effect sensor but I am getting abnormal speed readings.</p>
  
  <p>For instance, I get 10km/h for another instance it give 99km/h and so on. I want reading like original speedometer which gives gradual incremental or decremental readings.And one more thing I am using multiple functions in the same file and working on multiple GPIO pins is that make my program slow.</p>
  
  <p>How to improve the speed so I would not miss any pulse from any GPIO? Here is my code and output file.</p>
  
  <p>Code for distance measurement </p>
  
  <pre><code>import RPi.GPIO as GPIO
  import time
  import sys
  import csv
  from time import sleep
  import math
  GPIO.setmode(GPIO.BOARD)
  
  TRIG1=7    #front ultrasonic sensor configuration
  ECHO1=12
  
  TRIG2=11  #back ultrasonic sensor configuration
  ECHO2=15
  
  TRIG3=13  #left ultrasonic sensor configuration
  ECHO3=16
  
  TRIG4=18    #right ultrasonic sensor configuration
  ECHO4=22
  
  j=10000    # maximum number of readings
  data=[]
  
  
  GPIO.setup(7,GPIO.OUT)
  GPIO.output(TRIG1,0)        #front us sensor setup
  GPIO.setup(12,GPIO.IN)
  time.sleep(0.0001)
  
  GPIO.setup(11,GPIO.OUT)
  GPIO.output(TRIG2,0)   #back us sensor setup
  GPIO.setup(15,GPIO.IN)
  time.sleep(0.0001)
  
  GPIO.setup(13,GPIO.OUT)
  GPIO.output(TRIG1,0)   #left us sensor setup
  GPIO.setup(16,GPIO.IN)
  time.sleep(0.0001)
  
  GPIO.setup(18,GPIO.OUT)
  GPIO.output(TRIG2,0)  #right us sensor setup
  GPIO.setup(22,GPIO.IN)
  time.sleep(0.0001)
  
  print ("starting measurements...........")
  
  def front():
        GPIO.output(TRIG1,1)
        time.sleep(0.0001)#distance from front sensor
        GPIO.output(TRIG1,0)
        start1=time.time()
        stop1=time.time()
        while GPIO.input(ECHO1) == 0:
              start1=time.time()
        while GPIO.input(ECHO1) == 1:
              stop1=time.time()
        time1=stop1-start1
        distance1=time1 * 17000
        return distance1
  
  def back():
        GPIO.output(TRIG2,1)
        time.sleep(0.0001) 
        GPIO.output(TRIG2,0)    #distance from back sensor
        start2=time.time()
        stop2=time.time()
        while GPIO.input(ECHO2) == 0:
              start2=time.time()
        while GPIO.input(ECHO2) == 1:
              stop2=time.time()
        time2=stop2-start2
        distance2=time2 * 17000
        return distance2
  def left():
        GPIO.output(TRIG3,1)
        time.sleep(0.0001)
        GPIO.output(TRIG3,0)#distance from left sensor
        start3=time.time()
        stop3=time.time()
        while GPIO.input(ECHO3) == 0:
              start3=time.time()
        while GPIO.input(ECHO3) == 1:
              stop3=time.time()
        time3=stop3-start3
        distance3=time3 * 17000
        return distance3
  
  def right():
        GPIO.output(TRIG4,1)
        time.sleep(0.0001)
        GPIO.output(TRIG4,0)  #distance from right sensor
        start4=time.time()
        stop4=time.time()
        while GPIO.input(ECHO4) == 0:
              start4=time.time()
        while GPIO.input(ECHO4) == 1:
              stop4=time.time()
        time4=stop4-start4
        distance4=time4 * 17000
        return distance4
  
  with open('test.csv','w') as testfile:
        csv_writer = csv.writer(testfile)
        while j:
              distance1=front()
              distance2=back()
              distance3=left()
              distance4=right()
              data.append([distance1,distance2,distance3,distance4,time.ctime()])
              csv_writer.writerow([distance1,distance2,distance3,distance4,time.ctime()])
              time.sleep(0.5)
              j=j-1
  
  lenth=len(data)
  print (data) 
  GPIO.cleanup ()
  </code></pre>
  
  <p>and for speed measurement:</p>
  
  <pre><code>#!/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 = 29
  pulse = 0
  start_timer = time.time()
  
  def init_GPIO():               # initialize GPIO
     GPIO.setmode(GPIO.BOARD)
     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(24)   # 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)
  </code></pre>
  
  <p>I am getting output for speed like this</p>
  
  <pre><code>rpm:0-RPM kmh:0-KMH dist_meas:0.00m pulse:0
  
  rpm:4-RPM kmh:0-KMH dist_meas:1.51m pulse:1
  
  rpm:4-RPM kmh:0-KMH dist_meas:1.51m pulse:1
  
  rpm:4-RPM kmh:0-KMH dist_meas:1.51m pulse:1
  
  rpm:4-RPM kmh:0-KMH dist_meas:1.51m pulse:1
  
  rpm:4-RPM kmh:0-KMH dist_meas:1.51m pulse:1
  
  rpm:104-RPM kmh:9-KMH dist_meas:3.02m pulse:2
  
  rpm:433-RPM kmh:39-KMH dist_meas:4.52m pulse:3
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:365-RPM kmh:33-KMH dist_meas:6.03m pulse:4
  
  rpm:22-RPM kmh:2-KMH dist_meas:7.54m pulse:5
  
  rpm:22-RPM kmh:2-KMH dist_meas:7.54m pulse:5
  
  rpm:229-RPM kmh:21-KMH dist_meas:9.05m pulse:6
  
  rpm:388-RPM kmh:35-KMH dist_meas:10.56m pulse:7
  
  rpm:388-RPM kmh:35-KMH dist_meas:10.56m pulse:7
  
  rpm:971-RPM kmh:88-KMH dist_meas:13.57m pulse:9
  
  rpm:627-RPM kmh:57-KMH dist_meas:15.08m pulse:10
  
  rpm:318-RPM kmh:29-KMH dist_meas:16.59m pulse:11
  
  rpm:1949-RPM kmh:176-KMH dist_meas:19.60m pulse:13
  
  rpm:656-RPM kmh:59-KMH dist_meas:21.11m pulse:14
  </code></pre>