I am using Python to build a script for a program to be ran by Artisan-Scope roasting software. The program already works with my device (the Phidgets 1045_1B) but I need to do more filtering on the temperature readings. I would like the program to sample at 32ms and organize those 30 samples per second in ascending order. I would then like the lowest 10 samples to be average and returned to Artisan software to be graphed.
This is what I have so far but I need help figuring out how to organize the samples and average them before giving one temperature reading to Artisan.
import sys
import time
import traceback
from Phidget22.Devices.TemperatureSensor import *
from Phidget22.PhidgetException import *
from Phidget22.Phidget import *
from Phidget22.Net import *
try:
from PhidgetHelperFunctions import *
except ImportError:
sys.stderr.write("\nCould not find PhidgetHelperFunctions. Either add PhdiegtHelperFunctions.py to your project folder "
"or remove the import from your project.")
sys.stderr.write("\nPress ENTER to end program.")
readin = sys.stdin.readline()
sys.exit()
def onAttachHandler(self):
ph = self
try:
#If you are unsure how to use more than one Phidget channel with this event, we recommend going to
#www.phidgets.com/docs/Using_Multiple_Phidgets for information
print("\nAttach Event:")
channelClassName = ph.getChannelClassName()
serialNumber = ph.getDeviceSerialNumber()
channel = ph.getChannel()
ph.setDataInterval(32)
ph.setTemperatureChangeTrigger(0)
except PhidgetException as e:
print("\nError in Attach Event:")
DisplayError(e)
traceback.print_exc()
return
def onDetachHandler(self):
ph = self
try:
except PhidgetException as e:
print("\nError in Detach Event:")
DisplayError(e)
traceback.print_exc()
return
def onErrorHandler(self, errorCode, errorString):
sys.stderr.write("[Phidget Error Event] -> " + errorString + " (" + str(errorCode) + ")\n")
"""
* Outputs the TemperatureSensor's most recently reported temperature.
* Fired when a TemperatureSensor channel with onTemperatureChangeHandler registered meets DataInterval and ChangeTrigger criteria
*
* @param self The TemperatureSensor channel that fired the TemperatureChange event
* @param temperature The reported temperature from the TemperatureSensor channel
"""
def onTemperatureChangeHandler(self, temperature):
#If you are unsure how to use more than one Phidget channel with this event, we recommend going to
#www.phidgets.com/docs/Using_Multiple_Phidgets for information
print("[Temperature Event] -> Temperature: " + str(temperature))
"""
* Prints descriptions of how events related to this class work
"""
def PrintEventDescriptions():
print("\n--------------------\n"
"\n | Temperature change events will call their associated function every time new temperature data is received from the device.\n"
" | The rate of these events can be set by adjusting the DataInterval for the channel.\n"
" | Press ENTER once you have read this message.")
readin = sys.stdin.readline(1)
print("\n--------------------")
"""
* Creates, configures, and opens a TemperatureSensor channel.
* Displays Temperature events for 10 seconds
* Closes out TemperatureSensor channel
*
* @return 0 if the program exits successfully, 1 if it exits with errors.
"""
def main():
try:
ch = TemperatureSensor()
ch.setOnAttachHandler(onAttachHandler)
ch.setDeviceSerialNumber(424909)
ch.setChannel(0)
ch.openWaitForAttachment(5000)
ch.setTemperatureChangeTrigger(0)
ch.setOnDetachHandler(onDetachHandler)
ch.setOnErrorHandler(onErrorHandler)
#This call may be harmlessly removed
PrintEventDescriptions()
ch.setOnTemperatureChangeHandler(onTemperatureChangeHandler)
try:
ch.openWaitForAttachment(5000)
except PhidgetException as e:
PrintOpenErrorMessage(e, ch)
raise EndProgramSignal("Program Terminated: Open Failed")
time.sleep(1)
return 0
except PhidgetException as e:
sys.stderr.write("\nExiting with error(s)...")
DisplayError(e)
traceback.print_exc()
print("Cleaning up...")
ch.close()
return 1
except EndProgramSignal as e:
print(e)
print("Cleaning up...")
ch.close()
return 1
except RuntimeError as e:
sys.stderr.write("Runtime Error: \n\t" + e)
traceback.print_exc()
return 1
finally:
print("Press ENTER to end program.")
readin = sys.stdin.readline()
main()
The first thing that you need is some kind of buffer to hold recorded values until you have enough of them to process them. You can for instance use a python list::
In onTemperatureChangeHandler, store the values in the buffer. Once the buffer is full, calculate your average, then pass that value on.
That said, global variables as used here are considered bad style for good reasons. The code should be improved by defining a class, which has the buffer and all the handlers as attributes. There are plenty of Python tutorials about this.