2017-07-03 8 views
0

私はモーターのために妥当なRPMを得ようとしています。私はそれを通過するスリットを検出すると0または1を送信するフォトインタラプタを持っています。私のコードは次のようなものです。私が必要とするのは、0〜60秒の時間を計測し、1が検出された回数を加算し、60で割り算することです。Pythonのカウントダウンタイマー(モーターRPM用ラズベリーパイ)

私は自分のコードを複雑にしたくありません。また、これは多くの他のスクリプトとWebサーバが背後にあるラズベリーパイで実行されていることに注意してください。だから、 "スリープ"のような悪いコードではなく、CPU全体を奪うだろう。

私は狂った正確な測定を探しているわけではありません。モーターがどのくらい速く回転しているかについての合理的な考え方です。スリットのサイズも違いますか?私は、Pythonを使用してRPIをプログラムしたことがない、これは私がこの仕事に取り組むことを試みる方法で予約して

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

「スリープ」は、CPUをホッギングするのと反対です。それは他のタスクのために解放します。だから、それは 'sleep'を使う良い解決策になるでしょうが、あなたはちょうど60秒の睡眠を取ることは確かではありません。もう少し時間がかかる可能性がありますので、より正確な値が必要な場合は、タイムスタンプを取得してオフセットを修正するようにしてください。 – JohanL

+0

@JohanLありがとうございます。しかし、どうすれば実装できますか? –

答えて

1

:見ることができるように

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が1,000を下回る必要があることを意味するか、一部のスリットが見逃されることを意味します。これを除去することで実験することが可能です。分数バウンス時間を与えることが可能かどうかはわかりません。それは別の選択肢かもしれません。

メインプログラムは、増分を1分間実行した後、RPMを計算し、システムをリセットして新しいカウントを開始するタイマーをタイマーします。 (ここで競合状態が発生する可能性がありますが、計算中にスリット割り込みが発生する可能性があります)。

メインループでは、プログラムを待っている以外は何も起こりません割り込み(スリット、タイマ、またはctrl-c)。これは、何もしないで、passステートメントを継続的に実行するため、ビジーな待機です。おそらく、パフォーマンスを向上させ、プログラムを完全にイベント駆動にする方法がありますが、私はここで試行しているよりも大きな作業です。

関連する問題