So here's what I'm trying to do. I have a piece of hardware I'm working on that uses an Adafruit ADS1115 analog to digital converter breakout board on a raspberry pi. The concept is to create a wave using pigpio at a rate of 100 to 500 Hz, which, among many other things, triggers a GPIO pin at specific microsecond times to read data from the ADS1115 over a period of n seconds (2 to 10), then perform some numpy and scipy functions (median, sem) and return the median and sem values.
The problem I am running into is getting the pigpio callback to run while waiting the n seconds. I know I need to put the pigpio callback in a thread, but I'm stumped on how to make that work. What happens now is that the thread starts, the getSample function waits n seconds, then the callbacks start occurring only after the n seconds time is completed.
So, how do I get the pigpio callback to run in a thread and load its data output to the _data variable for the post processing after n seconds?
The getSample method is called when a user clicks a button to begin collecting data. The allOff method just shuts down the pigpio wave. The setFrequency method just starts a pigpio wave. The readData is the method that collects the data from the ADS1115 and should append it to the _data variable. The _gain variable is tied to a tkinter combo box to set the gain value for the ADS chip.
I can't use a simple time.sleep loop to collect the data because I need the data collected at the microsecond time when the GPIO pin is turned on from the wave pulse, and of course time.sleep won't provide reliable microsecond accuracy.
I've tried incorporation the first answer from Python Threading inside a class, but obviously I'm missing something important on how the threading works when initialized within a method.
pigpio callback reference: http://abyz.co.uk/rpi/pigpio/python.html#callback
Here's a shortened version of the longer class:
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))