2017-07-03 221 views
0

我想获得一个合理的电机转速。如果侦测到一个穿过的缝隙,我会有一个光电断续器发送0或1。我的代码如下,我只需要时间0-60秒,并添加检测次数1,然后除以60,即RPM。Python中的倒数计时器(树莓派电机每分钟转数)

我不想让我的代码复杂化,也请记住,这是在Raspberry Pi上运行的,其中包含许多其他脚本和Web服务器。所以不是一个糟糕的代码,比如“睡眠”会占用整个CPU。

我不是在寻找疯狂的准确测量,只是一个合理的想法,即电机旋转的速度。狭缝尺寸是否也有所不同?

import RPi.GPIO as GPIO 
import time 
signal = 21 

from time import sleep  # this lets us have a time delay (see line 15) 
GPIO.setmode(GPIO.BCM)  # set up BCM GPIO numbering 
GPIO.setup(signal, GPIO.IN) # set GPIO21 as input (signal) 
GPIO.add_event_detect(signal,GPIO.BOTH) 


try: 
    while True:   # this will carry on until you hit CTRL+C 
     if GPIO.event_detected(signal): # if port 21 == 1 
      print "Port 21 is 1/HIGH/True - LED ON" 
      slit=slit+1  # Counts every time slit passes 

     else: 
      print "Port 21 is 0/LOW/False - LED OFF" 
     rpm = slit/60   # Calculates the RPM 
     sleep(0.0001)   # wait 0.0001 seconds 

finally:     # this block will run no matter how the try block exits 
    GPIO.cleanup()   # clean up after yourself 
+1

'sleep'与CPU占用相反。它将释放它来完成其他任务。所以,这将是一个很好的解决方案,但是你不能确定你准确地睡了60秒。它可能会更多一些,所以如果你想得到更精确的值,你应该尝试去获得一些时间戳和校正偏移量。 – JohanL

+0

@JohanL谢谢,但我将如何实现它? –

回答

1

有了,我从来没有编程使用Python的RPI保留,这是我怎么会尽力解决这个任务:

import RPi.GPIO as GPIO 
import threading 

signal = 21 
GPIO.setmode(GPIO.BCM)  # set up BCM GPIO numbering 
GPIO.setup(signal, GPIO.IN) # set GPIO21 as input (signal) 

slit = 0 
rpm = 0 

def increment(): 
    global slit 
    print("Port 21 is 1/HIGH/True - LED ON") 
    slit += 1 

def count_complete(): 
    global slit 
    global rpm 
    rpm = slit/60 
    print ("RPM = {}".format(rpm)) 
    # reset and restart timer 
    slit = 0 
    t = threading.Timer(60, count_complete) 

# Bounce will prevent double detection of the same rising edge (for 1 ms) 
GPIO.add_event_detect(signal, GPIO.RISING, callback=increment, bounce=1) 

t = threading.Timer(60, count_complete) 
try: 
    while True:   # this will carry on until you hit CTRL+C 
     pass    # Do nothing but wait for callbacks and timer 
finally:     # this block will run no matter how the try block exits 
    t.cancel()    # stop the timer 
    GPIO.cleanup()   # clean up after yourself 

可以看出,我添加了一个回调函数将在输入端检测到上升沿后立即被调用。这里,clit计数器递增。反弹参数是一种保护功能,可以阻止程序计算相同的裂缝倍数。

设置为1毫秒表示RPM需要低于1000,否则某些狭缝将被遗漏。可以通过删除它来进行试验。我不知道是否有可能提供一个分数弹跳时间。这可能是另一种选择。

然后,主程序计算一个计时器,使增量运行1分钟,然后计算RPM并重新启动系统并重新计数。 (在这里存在竞争条件的风险,在计算时可能会发生狭缝中断,在这种情况下可能会漏掉)。

然后在主循环中,除了程序正在等待中断(狭缝,计时器或ctrl-c)。这是一个忙碌的等待,因为它会持续运行pass声明,无所事事。也许有一种方法可以提高性能,并使程序完全事件驱动,同时释放CPU,但这是一个比我在这里尝试的更大的任务。