如何衡量一个值是否在一段时间内保持不变?

2024-04-28 13:37:50 发布

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

我正在做一个智能自行车背光灯,上面有覆盆子皮和一个传感器

我正在测量传感器加速度计的输出值。实际上有三个值被报告为x,y,z,我想知道的是我的自行车是否静止了15秒或更长时间。因此,如果这些值保持不变超过15秒,我将关闭背光。然后,如果他们开始改变,并像那样保持15秒以上,我希望它能启动并重新开始工作

到目前为止,我已经实现了当自行车处于空闲状态时自动激活的选通效应。转向检测-我根据我放在车把附近的物体检测传感器向左右显示箭头动画。我还实现了刹车检测。一旦加速计检测到制动,我就会显示全红灯

如果你检查代码,你会发现这有点棘手,因为整个事情都在while循环中,我需要将此检测作为If条件,然后在下面添加else,将我现有的If条件的其余部分放在那里(例如取消加速或转向检测)

那么,如何让Python在不使用time.delay的情况下连续15秒测量某些值,并根据它们是更改还是保持不变来执行操作?

while True:
    
    ser.flushInput()
    ser.flushOutput()
    
    x, y, z = sense.get_accelerometer_raw().values()
    x = round(x, 2)
    y = round(y, 2)
    z = round(z, 2)
    print("x=%s, y=%s, z=%s" % (x, y, z))
    
    input = ser.read() #serial input i'm getting from arduino, it tells me if my left or right steering sensors are triggerred.
    yon = input.decode("utf-8")
    int(yon)

    if (z > 0.20): #If deacceleration is detected
        fren() # brake function is called
    else: # if no breaking is detected...
        if (yon == "1"): #if left turn sensor triggered
            sag_ok() #show left turn animation on led matrix
        elif (yon =="2"): # if right turn sensor triggered
            sol_ok() #show right turn animation on led matrix
        else: #anything else
            strobe() #show strobe effect if nothing else is detected

Tags: rightinputifisshow自行车传感器left
2条回答

基本思想是跟踪上次检测到运动(或非运动)的时间。如果时间超过15秒,则关闭(打开)灯

大概是这样的:

from time import monotonic

TAIL_LIGHT_DELAY = 15

time_of_last_motion = monotinic()
time_of_last_stop = monotonic()

while True:
    now = monotonic()

    motion = (abs(x) > 0.2) or (abs(y) > 0.2) or (abs(z) > 0.2)

    if motion:
        time_of_last_motion = now

        if now - time_of_last_stop > TAIL_LIGHT_DELAY:
            turn_on_tail_light()

    else:
        time_of_last_stop = now

        if now - time_of_last_motion > TAIL_LIGHT_DELAY:
            turn_off_tail_light()

首先需要解决一些较小的问题:

  1. input = ser.read()input实际上是一个builtin,不应该用作变量名
  2. int(yon)什么也不做。您可以将其转换为int,但结果会丢失,因为您没有将结果重新分配给名称
  3. if (z > 0.20)和所有其他的{}检查-括号在这里实际上什么都不做;你可以放下它们

需要解决的一个更大的问题是:这个循环完全没有理由地在CPU核心上运行。每秒数千次,持续不断。您应该引入time.sleep来减少负载

鉴于此,您可以通过混合使用布尔标志和加速度计上次给出0值的记录来实现所需的输出

import time

import datetime as dt

last_zeros = None
countdown_started = False

while True:
    
    ser.flushInput()
    ser.flushOutput()
    
    x, y, z = sense.get_accelerometer_raw().values()
    x = round(x, 2)
    y = round(y, 2)
    z = round(z, 2)
    print("x=%s, y=%s, z=%s" % (x, y, z))
    
    if x == 0 and y == 0 and z == 0:
        if countdown_started:
            duration = (dt.datetime.utcnow() - last_zeros_time).total_seconds()
            if duration > 15:
                # Do something to turn the light off here
                continue
        else:
            countdown_started = True
            last_zeros_time = dt.datetime.utcnow()
    else:
        countdown_started = False
        
    
    sensor_input = ser.read() 
    yon = sensor_input.decode("utf-8")
    
    if (z > 0.20): 
        fren() 
    else: 
        if (yon == "1"): 
            sag_ok() 
        elif (yon =="2"): 
            sol_ok() 
        else: 
            strobe() 
    
    time.sleep(0.5)

相关问题 更多 >