Want to know how to use a thermistor with your arduino via pyfirmata? Look no further…
I’ve been playing with thermistors as part of a home monitoring system I’ve been building and for an upcoming sous vide project. Thermistors are cheap and can be highly accurate for a pretty wide range of temperatures. I’m using an epoxy coated and waterproofed thermistor for my sous vide project.
- an arduino
- a thermistor
- a resistor that matches your thermistor (ie: 10k ohm resistor with 10 k ohm thermistor)
- a breadboard with jumper wires
Code available for download
### THERMISTOR TEMPERATURE READINGS VIA PYFIRMATA ### JS Kouri 2/1/2014, no rights reserved ### In this example, I am using a 4.7 kΩ resistor ### (Digi-Key Part Number NTCLE400E3472H) ### Values for Steinhart-Hart equation calculated ### at http://bit.ly/1nPiOLv from datasheet info import pyfirmata from math import log from time import sleep n = 0 #first port number to try ie: ttyACM0 PORT = '/dev/ttyACM' + str(n) # device location, yours may very. if unable to connect, try /dev/USB or check dmesg connected = False def connection(): global board board = pyfirmata.Arduino(PORT) print 'Port found, connecting...' it = pyfirmata.util.Iterator(board) # start iterator thread it.start() # ATTEMPT TO CONNECT TO ARDUINO. ITERATE THROUGH PORT NUMBERS UNTIL CONNECTED while connected == False: try: print 'Trying' + PORT connection() connected = True print "Connection established" except: n = n+1 PORT = '/dev/ttyACM' + str(n) pass # WAIT UNTIL INPUT RECEIVED AT ANALOG PIN pin0 = board.get_pin('a:0:i') # edit to reflect your setup print 'Waiting on reading...' while pin0.read() is None: # ignore input until pin is active pass while True: analog_value = pin0.read() #print analog_value # optional debug info # VOLTAGE DIVIDER CALCULATION analog_value = analog_value * 5 # we multiply by 5 (volts) to get the true voltage read at pin (ie: we get 3 v instead of 0.6. pyfirmata reports analog values in the range of 0 to 1. analog_value = 4700.0 * ((5.0/analog_value) -1.0) # solve for resistance at thermistor. change 4700 to match your resistor used. #print str(analog_value) + ' this is calculated resistance in ohms at thermistor' # optional debug info # STEINHART-HART EQUATION temp = (1 / (0.001308463361 + 0.0002344771590 * log(analog_value) + 0.0000001041772095 * log(analog_value)**3)) # substitute your thermistor's unique values for A, B, C. # TEMP IN KELVIN print str(temp) + ' kelvin' #TEMP IN CELSIUS t_celsius = temp - 273.15 print str(temp) + ' degrees celsius' #TEMP IN FAHRENHEIT t_fahrenheit = 9/5.0*temp + 32 print str(t_fahrenheit) + ' degrees fahrenheit\n\n' sleep(30) # wait 30 seconds between polling pin
The code features a few important aspects that understanding will be helpful.
Converting Pyfirmata Analog Values to Voltage
Pyfirmata reports analog values as a float of 0 to 1. We need to determine what the voltage is at the analog pin. We’re using 5 VDC so we multiply it by 5. This will provide Va for the next portion.
The Voltage Divider
A neat little explanation of why we use voltage divider circuits with thermistors and other sensors can be found here. No need to rehash it.
In order to obtain the resistance of the thermistor, we need to calculate it based off the voltage readings from the analog pin. (Which we just adjusted). We use an equation derived from Ohm’s Law that lets us calculate the resistance in a voltage divider.
RT = R [1 / (V / VA – 1) ]
Where RT = thermistor resistance in ohms, R = resistor resistance, V = input voltage, VA = voltage reading from analog pin (Read more at Wikipedia Voltage Divider)
Armed with the resistance at the thermistor, we can finally calculate the temperature.
There are a couple ways of calculating this, I chose the Steinhart-Hart equation, but you can also use the simpler β equation. (See Wikipedia)
It is very important to have your datasheet in order to accurately calculate the values needed for this equation. If you don’t have the datasheet, you can determine your own values by obtaining resistance in ohms at three known temperatures.
Once you get your resistance values for three known temperatures from your datasheet or experimental data, plug them into a Steinhart-Hart calculator and build your equation.
Replace my values in the code above with yours. Be sure to format the coefficients properly. The calculator I linked to above gives coefficients in scientific notation. Convert scientific notation to the long form decimal notation. (n-1 preceding decimal places for E to the n power)
Now run it and get your temperature!
Sky’s The Limit
And there you have it. From here you can easily save your values in a text file or a database, build cool charts with matplotlib (if you don’t pull your hair out first trying to get it to work), or do something more dynamic like create feedback loops and control things based on temperature.