类中的Python pigpio回调为线程

时间:2017-04-27 14:14:18

标签: python multithreading callback

所以这就是我想要做的。我有一个我正在研究的硬件,它使用覆盆子pi上的Adafruit ADS1115模数转换器分线板。这个概念是使用Pigpio以100到500 Hz的速率创建一个波,其中包括以特定的微秒时间触发GPIO引脚,以便在n秒(2到10)的时间内从ADS1115读取数据,然后执行一些numpy和scipy函数(中位数,sem)并返回中位数和sem值。

我遇到的问题是在等待n秒时让pigpio回调运行。我知道我需要将pigpio回调放在一个线程中,但我很难理解如何使其工作。现在发生的是线程启动,getSample函数等待n秒,然后回调开始仅在n秒时间结束后开始。

那么,如何在一个线程中运行pigpio回调并在n秒后将其数据输出加载到_data变量进行后处理?

当用户单击按钮开始收集数据时,将调用getSample方法。 allOff方法只关闭了pigpio波。 setFrequency方法只是启动一个pigpio波。 readData是从ADS1115收集数据并将其附加到_data变量的方法。 _gain变量与tkinter组合框相关联,用于设置ADS芯片的增益值。

我无法使用简单的time.sleep循环来收集数据,因为我需要在波形脉冲打开GPIO引脚时在微秒时收集的数据,当然time.sleep不会提供可靠的微秒精度。

我已尝试合并Python Threading inside a class中的第一个答案,但显然我在方法中初始化时错过了一些关于线程如何工作的重要内容。

pigpio回调参考:http://abyz.co.uk/rpi/pigpio/python.html#callback

以下是较长班级的缩短版本:

class sampling:
  #SETUP GPIO PINS    
  _PWM2=17 #RECEIVER SIGNAL PIN
  _PWM3=18 #RECEIVER INPUT TEST PIN
  _pi = pigpio.pi()
  _wave=""
  _pi.set_mode(_PWM2, pigpio.OUTPUT)#RX TRIGGER PIN
  _pi.set_mode(_PWM3, pigpio.INPUT)#RX MONITOR PIN
  _pi.set_pull_up_down(_PWM3, pigpio.PUD_UP)
  _callback=""
  _data=[]
  _ADS1115 = 0x01   # 16-bit ADC
  # Initialise the ADC using the default mode (use default I2C address)
  try:
      _ADC = ADS1x15(ic=_ADS1115, debug=False)
  except:
      print "ADS1115 Could not be started.  Check address"
  _SPS=IntVar()
  _SPS.set(860)
  _gain=StringVar()
  _gain.set("256")
  _delay=float(1/_SPS.get())+float(0.001)

  def getSample(self, frequency, seconds, gain):
      self._delay=float(1/self._SPS.get())+float(0.0005)
      datasample=[None]*3
      self._data=[]
      print "Starting SetFrequency"
      self.setFrequency(int(frequency))
      datathread=threading.Thread(target=self._pi.callback, args=(self._PWM3, pigpio.RISING_EDGE, self.readData, )).start()
      print "Waiting %s Seconds" % str(seconds)
      time.sleep(int(seconds))
      print "Shutting down frequencies"
      self.allOff()
      ##Lengthy POST PROCESSING OF _data array goes here

  def allOff(self):
      self._pi.wave_tx_stop()
      self._pi.wave_clear()
      self._pi.write(self._PWM1, 0)
      self._pi.write(self._PWM2, 0)
      self._pi.write(self._PWM4, 0)

  def readData(self, gpio, level, tick):
      print "Reading Data"
      self._data.append(round(self._ADC.readADCDifferential(2, 3, int(self._gain.get()), int(self._SPS.get())), 0))

1 个答案:

答案 0 :(得分:0)

我在Pi上的ADS1115上写了一篇文章,其中我将“纯香草”的Raspbian smbus Rpi.GPIO 库与Python3结合使用。 在一个示例程序和一个测试电路中,我提供了4种不同的配置,其中三种使用 GPIO.add_event_detect(),以便在发生数据转换时在GPIO引脚上获得通知。后期可以被触发,例如通过一个阈值。我不能完全肯定,如果这有助于实现你的目标(读在特定微秒的值),但至少回调正常工作。 https://smartypies.com/projects/ads1115-with-raspberrypi-and-python/