在python中将速度传感器读数归零

2024-03-29 13:14:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我用霍尔效应传感器和连接在轮子上的小磁铁来测量一个旋转的轮子的速度,单位为米/秒。你知道吗

代码是用python编写的,在测量速度、距离、转速等时工作得相当好,但是当车轮停止时,速度将永远不会回到0米/秒

我已经尝试修改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)

Tags: gpiotimeinitdistdefcmstartmps
2条回答

如果轮子没有转动,那么calculate_elapse就不会被调用。这意味着elapse将永远不会被设置为“大”(>;=3)值,因此您的mps = 0短路将永远不会被触发。你知道吗

你对globals的使用让我很不安,所以我有机会重写这个。。。这是未经测试,但希望你会看到为什么这是一个更好的:

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!")

相关问题 更多 >