我使用霍尔效应传感器和附在车轮上的小磁铁来测量旋转车轮的速度,单位为m / s。
代码是用python编写的,在测量速度,距离,转速等时工作得相当好。但是当车轮停止时,速度永远不会恢复到0m / s。
我尝试修改if语句,这样如果经过的时间(即旋转所需的时间)大于3秒,我们可以假设轮子处于静止状态。
这可能是一个简单的修复,但我似乎无法弄清楚,有人可以建议吗?提前谢谢。
我的代码
Distance = 0.00
mps = 0
rpm = 0
elapse = 0
sensor = 5
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_m,Distance,mps
if elapse !=0 and elapse < 3: # to avoid DivisionByZero error
rpm = 1/elapse * 60
circ_cm = (2*math.pi)*r_cm # calculate wheel circumference in CM
dist_m = circ_cm/100 # convert cm to m
mps = dist_m / elapse # calculate m/sec
Distance = (dist_m*pulse) # measure distance
return mps
else:
mps = 0
return mps
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(3.4) # call this function with wheel radius as parameter
print('{0:.0f}rpm {1:.2f}m/s {2:.2f}m Counter:{3}'.format(rpm,mps,Distance,pulse))
sleep(0.1)
答案 0 :(得分:0)
如果车轮没有转动,则不会调用calculate_elapse
。这意味着elapse
永远不会设置为“大”(&gt; = 3)值,因此永远不会触发mps = 0
短路。
你使用全局变形让我心烦意乱,所以我有机会重写这个...这是未经测试的,但希望你会明白为什么这会更好一些:
import math
import time
import RPi.GPIO as GPIO # This is my best guess :-)
SENSOR_ID = 5
WHEEL_RADIUS_CM = 3.4
class UnknownRotationError(Exception):
pass
class WheelTimer:
MAX_ACCEPTABLE_DURATION = 3.0
def __init__(self, wheel_radius_cm):
self.wheel_radius_cm = wheel_radius_cm
self._wheel_circ_m = ((2 * math.pi) * self.wheel_radius_cm) / 100
self.num_full_rotations = 0
self.total_distance_m = 0.0
self.last_rotation_duration_s = None
self._rotation_started_time = time.time()
def complete_rotation(self):
"""Record a completed revolution."""
self.num_full_rotations += 1
self.total_distance_m = self._wheel_circ_m * self.num_full_rotations
now = time.time()
self.last_rotation_duration_s = self.rotation_started_time - now
self._rotation_started_time = now
@property
def current_rotation_duration(self):
return self.rotation_started_time - time.time()
def _validate_rotation(self):
if not self.last_rotation_duration_s:
raise UnknownRotationError()
if self.last_rotation_duration_s > self.MAX_ACCEPTABLE_DURATION:
raise UnknownRotationError()
if self.current_rotation_duration > self.MAX_ACCEPTABLE_DURATION:
raise UnknownRotationError()
@property
def current_speed_ms(self):
self._validate_rotation()
return self._wheel_circ_m / self.last_rotation_duration_s
@property
def current_rpm(self):
self._validate_rotation()
return (1.0 / self.last_rotation_duration_s) * 60.0
def init_GPIO(): # initialize GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(SENSOR_ID, GPIO.IN, GPIO.PUD_UP)
def init_interrupt(callback_func):
GPIO.add_event_detect(SENSOR_ID, GPIO.FALLING, callback=callback_func, bouncetime=20)
if __name__ == '__main__':
init_GPIO()
wheel_timer = WheelTimer(WHEEL_RADIUS_CM)
init_interrupt(callback_func=wheel_timer.complete_rotation)
while True:
time.sleep(0.1)
try:
print('{0:.0f}rpm {1:.2f}m/s {2:.2f}m Counter:{3}'.format(
wheel_timer.current_rpm,
wheel_timer.current_speed_ms,
wheel_timer.total_distance_m,
wheel_timer.num_full_rotations,
))
except UnknownRotationError:
print("Wheel moving too slowly to measure!")