2016-04-05 1 views
2

カスタムオフロード車用のデータ収集システムを作成する作業。 RPMを測定するためにラズベリーパイとカスタムタコメータを使用しました。次のコードで割り込みを使用してRPM値を取得します。点火プラグの作動に基づいて燃焼機関の状態を得るためにPythonを使用する

def get_rpm():           
    GPIO.wait_for_edge(17, GPIO.FALLING) 
    start = time.time() 
    GPIO.wait_for_edge(17, GPIO.FALLING) 
    end = time.time() 
    duration = end - start 
    rpm = (1/duration)*60 
    return rpm 

このコードは、エンジンが動作してスパークを生成している場合にのみ機能します。スパークがなければ、コードはその縁を待って座って進み、進まない。コードget_rpm()を呼び出すとき、コードがエッジを待っている場合、これにより他のプロセスがハングします。

これは、別のプロセスでエンジンの状態を取得することを目的としています。私はそれが2つの部分で一番うまくいくと思います。別のスレッドで

パート1、実行されている(ループ型):必要に応じて

GPIO.wait_for_edge(17, GPIO.RISING) 
last = time.time 

パート2は、関数と呼ばれる実行:パート1では

def get_state(): 
    while time.time - last < .5: 
     engine_state = true 
    else: 
     engine_state = false 
    return engine_state 

がにアクセス可能なメモリにlastを保存します第2部、第2部では、スパークプラグが最後に発火したときに車両が走行しているかどうかを判断します。比較器としてengine_stateを使用すると、engine_stateが真の場合にのみ、データ収集システムはget_rpm()からRPM値を取得して格納します。

パート2でlast変数を使用できるようにパート1を実装するにはどうすればよいですか? lastは非常に迅速に変更されます。私はlastが更新されるたびに、それをラズベリーパイのSDカードのテキストファイルに保存したくありません。 lastをRAMに保存します。

ありがとうございます!

+0

'last'はRAMに既にある、私は' .. –

+0

'time.time'は、')( 'time.timeする必要がありますあなたが必要とするすべては' GET_STATE(最後)の変数として、それを渡すことだと思います私は思う。 – jDo

+0

あなたはどこか他の場所にピン配置を設定していますか、まったく設定していませんか?代わりに割り込みコールバックを使用できませんでしたか?それらは本質的にスレッド化されており、ブロックされません。私はあなたがエッジを待つ必要はないと思う。面白いプロジェクトbtw。 :) – jDo

答えて

1

これはインスピレーションのためです。私は自分のピスを手にしていないので、これは記憶から盲目的に書かれています。

import RPi.GPIO as GPIO 
import time 

GPIO.setmode(GPIO.BCM) 
GPIO.setup(17, GPIO.IN) 
# the line below is important. It'll fire on both rising and falling edges 
# and it's non-blocking 
GPIO.add_event_detect(17, GPIO.BOTH, callback=callback_func) 

length_of_last_high = 0 
length_of_last_low = 0 

last_rise = 0 
last_fall = 0 
last_callback = 0 

def callback_func(pin): 
    # all of these global variables aren't needed 
    # but I left them in for demo purposes 
    global last_rise 
    global last_fall 
    global last_callback 
    global length_of_last_high 
    global length_of_last_low 
    last_callback = time.time() 
    if GPIO.input(17): 
     print "Pin 17 is rising!" 
     length_of_last_high = last_callback - last_rise 
     last_rise = last_callback 
    else: 
     print "Pin 17 is falling!" 
     length_of_last_low = last_callback - last_fall 
     last_fall = last_callback 


# last passed as parameter (the preferred solution if it works). 
# You test it - I can't at the moment 
def get_state(last=last_rise): 
    engine_state = False 
    if time.time() - last < .5: 
     engine_state = True 
    return engine_state 

# last as global variable. 
# This works too but global is bad practice if it can be avoided  
# (namespace littering) 
def get_state2(): 
    global last_rise 
    engine_state = False 
    if time.time() - last_rise < .5: 
     engine_state = True 
    return engine_state 


def main(): 
    while True: 
     print "Not blocking! This loop could sleep forever. It wouldn't affect the readings" 
     time.sleep(1) 
     print get_state() 

""" 
GPIO.cleanup() 
""" 
+0

これは、スレッドコールバックを使用する方法の本当に素晴らしい例であり、確かに役立ちます。私が立ち往生していることの1つは、この方法を使って正確にRPMを取得する方法です。私たちの信号が高い時間を費やす時間は、それが低い時間を過ごす時間と同じではありません。スパーク(低〜高)間の時間は、スパークが高から低になる時間よりも長くなります。デューティサイクルは20%のようなものかもしれません。 (https://en.wikipedia。 このため、RPMを計算するために、2つの立ち上がりエッジ間または2つの立ち下がりエッジ間の時間を見つける必要があります。 – Bobothetwit

+0

RPMを計算するために、立ち上がりエッジと立ち下がりエッジの間の時間を使用することはできません。スレッドコールバックを使用すると、立ち下がり(または上昇)エッジが検出されるたびにコールバックが実行されます。これは現在のRPMの決定方法と互換性がありません。 17番ピンのWait_for_edgeは、同じコードファイル内のadd_event_detectと一緒に使用することはできません。ここにどんなアイデア? @jDo get_state機能はうまく機能しますが、現在実装されている方法と同じコードでget_RPMと同時に使用することはできません。 – Bobothetwit

+0

@Bobothetwit私はあなたの質問btwを忘れていませんでした。私はちょうどそれを読んでいる。 [here](http://forums.hybridz.org/topic/14725-pulsewidth-vs-dutycycle-vg30et-ecu/)、タコメータ入力をエミュレートするためにスレッドとランダム性を使用していくつかのテストを行います。デューティサイクルが20%のときに、RPMがどのくらいあるべきかをお知りになりますか? (私のテストが途方に暮れているか、実際に役に立つものを実際に作り出しているかどうかは分かります)。 – jDo

関連する問題