Python 基于火花塞驱动的内燃机状态获取

Python 基于火花塞驱动的内燃机状态获取,python,raspberry-pi,data-acquisition,Python,Raspberry Pi,Data Acquisition,正在为定制越野车创建数据采集系统。使用Raspberry Pi和定制转速表(经过测试并确认正常工作)测量转速。在下面的代码中使用中断来获取RPM值 def get_rpm(): GPIO.wait_for_edge(17, GPIO.FALLING) start = time.time() GPIO.wait_for_edge(17, GPIO.FALLING) end = time

正在为定制越野车创建数据采集系统。使用Raspberry Pi和定制转速表(经过测试并确认正常工作)测量转速。在下面的代码中使用中断来获取RPM值

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()
时,如果代码正在等待边缘,则会导致其他进程挂起

我打算在另一个进程中获得引擎的状态。我认为它将在两个部分中起到最好的作用

第1部分,在单独线程中运行(循环):

GPIO.wait_for_edge(17, GPIO.RISING)
last = time.time
第2部分,根据需要作为函数调用运行:

def get_state():
    while time.time - last < .5:
        engine_state = true
    else:
        engine_state = false
    return engine_state
def get_state():
当time.time-last<.5时:
发动机状态=真
其他:
发动机状态=错误
返回引擎状态
第1部分将
last
保存到第2部分可访问的存储器中,第2部分将根据火花塞上次点火的时间确定汽车是否正在运行。使用
engine\u state
作为比较器,仅当
engine\u state
为真时,数据采集系统才会从
get\u RPM()
获取并存储RPM值

如何实现第1部分,以便使用第2部分中的
last
变量<代码>最后一个将非常、非常迅速地更改。我不想每次更新
last
时都将其存储到Raspberry Pi SD卡上的文本文件中。我想把
last
存储在RAM中


非常感谢

这只是为了灵感。我手头没有我的Pis,所以这是根据记忆盲目写的

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()
"""
将RPi.GPIO导入为GPIO
导入时间
GPIO.setmode(GPIO.BCM)
GPIO.setup(17,GPIO.IN)
#下面这一行很重要。它会在上升边缘和下降边缘都开火
#而且它是非阻塞的
GPIO.add\u event\u detect(17,GPIO.BOTH,callback=callback\u func)
最后一个\u高的长度\u=0
最后一个的长度=0
最后上升=0
最后一个秋天=0
上次回调=0
def回调函数(pin):
#不需要所有这些全局变量
#但我把它们放在里面是为了演示
全球最后升幅
全球去年秋天
全局最后一次回调
最后一个高度的全局长度
最后一个低的全局长度
last_callback=time.time()
如果GPIO.input(17):
打印“针脚17正在上升!”
最后高度的长度=最后回叫-最后上升
最后上升=最后回调
其他:
打印“针脚17掉落!”
最后一次回调的长度=最后一次回调-最后一次下跌
最后一次坠落=最后一次回调
#上次作为参数传递(如果可行,则为首选解决方案)。
#你测试一下,我现在不行
def get_状态(最后一次=最后一次上升):
发动机状态=错误
如果time.time()-last<.5:
发动机状态=真
返回引擎状态
#最后作为全局变量。
#这也行得通,但如果可以避免的话,这是一种不好的做法
#(乱丢垃圾)
def get_state2():
全球最后升幅
发动机状态=错误
如果time.time()-最后一次上升<.5:
发动机状态=真
返回引擎状态
def main():
尽管如此:
打印“不阻塞!此循环可以永久休眠。不会影响读数”
时间。睡眠(1)
打印获取状态()
"""
GPIO.cleanup()
"""

last
已在RAM中,我想您只需将其作为变量传递给
get\u state(last)
time.time
应该是
time.time()
我想您是否在其他地方设置了pin配置?你不能改用中断回调吗?它们天生就有螺纹,不会堵塞。我认为你不必等待边缘。有趣的项目顺便说一句:)@jDo是的,管脚都是在其他地方配置的。没有将其包括在问题中,因为它已经确定可以工作。能否提供一个中断回调实现的快速示例?我是Python新手,非常感谢您的帮助@IronFist感谢您重新格式化我的代码片段。请举例说明“将其作为变量传递”是什么意思?我是Python新手,不熟悉所有的术语。非常感谢!这是一个关于如何使用线程回调的非常好的例子,肯定会有帮助。有一件事我一直在想,那就是如何使用这种方法精确地获得RPM。我们的信号处于高位的时间并不等于处于低位的时间。火花之间的时间(从低到高)大于火花从高到低所需的时间。占空比可能约为20%。()因此,我们需要找到两个上升沿之间或两个下降沿之间的时间来计算RPM。我们不能用上升沿和下降沿之间的时间来计算RPM。使用线程回调,每次检测到下降(或上升)边缘时,回调都会运行。这与我们目前确定RPM的方法不兼容。引脚17上的Wait_for_边缘不能与同一代码文件中的add_event_detect一起使用。有什么想法吗@jDo get_state功能工作得很好,但我们不能以当前实现的方式在同一代码中同时使用它。@Bobothetti顺便说一句,我没有忘记你的问题。我刚刚阅读了它,例如,使用线程和随机性来模拟转速表输入,并做了一些测试。当占空比为20%时,您大致知道转速应该是多少吗?(它会告诉我我的测试是否偏离了轨道,或者是否真的产生了有用的东西)。@Bobothet我想我理解你“(…)需要找到两个上升沿之间或两个下降沿之间的时间来计算RPM。”。如果你把上升时的时间和下降时的时间保存起来,然后从另一个中减去一个,你就得到了脉冲宽度;这不是你想要的,对吧?相反,您需要测量正弦数学中的wav