Introduction: Raspberry Pi Temperature Sensor
Introduction
The following will show you how to build and program the Raspberry Pi to use a thermistor to take temperature measurements of a room. A thermistor is a type of resistor whose resistance is based on temperature. There are two different types of thermistors: Negative Temperature Coefficient (NTC) and Positive Temperature Coefficient (PTC). NTC’s resistances decrease with temperature, whereas PTC resistances increase with temperature to protect against over current conditions. For this project we’ll be using a NTC thermistor, specifically a 10K ohm, manufactured by Therm-O-Disc. Because we are using a thermistor for our sensor, an analog to digital converter will have to be used. For this project, I chose to use the Raspberry Pi High-Precision AD/DA Expansion Board along with tkinter to design my Graphical User Interface and also Matplotlib to graph the current temperature and display it in real time.
Other features in this project include the ability for the Pi to measure the Thermal Time Constant, (which is the time required for a thermistor to change 63.2% of the total difference between its initial and final body temperature), and real time display of the temperature. Lastly, I programmed various LEDs to light up depending on the temperature using red, yellow and blue colors to indicate the current temperature.
Initially I wanted to program the whole project in Python, however the Raspberry Pi High- Precision AD/DA Expansion Board is only compatible in C. There are people out there that have written Python wrappers for it, but I chose to not go down that route. Instead, I wrote the information I needed to a file and then read that file from my Python program.
Step 1: Parts List
- 1 Raspberry Pi 3 (Pi 2 would also work)Raspberry Pi
- Raspberry Pi High-Precision AD/DA Expansion Board Waveshare High-Precision AD/DA Expansion Board
- To save time I purchased this kit Pi 3 Starter Kit
- 10K Thermistor: Therm-O-Disc part number APO3201, style/order number 473832
- SparkFun PI Wedge
- Various LEDS (Colors: 2 blue, 2 yellow, 2 red)
- 1 Resistor for each LED (I used 300 ohm)
- 1 breadboard
- 10 jumper wires (9 male to male, 1 female to male)
Touch Screen interface I used and programmed for so that the project would be more portable on a more permanent setup:
Equipment for installing the Raspberry Pi software:
- HDMI capable computer monitor
- USB keyboard
- USB Mouse
- Wi-Fi
Step 2: Installing Libraries
Assuming that you already have you the Raspberry Pi operating system installed for this project, we now need to install libraries to interface with GPIO pins, tkinter and Matplotlib. To enable interfacing with GPIOs we first need to install some python libraries. It should also be noted that the Python program is running on version 2.7.9.
Enter these commands into your terminal:
- sudo apt-get update
- sudo apt-get -y install python-rpi.gpio
- sudo apt-get install python-tk (tkinter should already be installed but just in case)
- sudo apt-get install python-matplotlib
Step 3: Configuring Waveshare AD Board
Now for using the AD expansion board we need to
install software for the board first one being bcm2835-1.50 and also wiring Pi. Screenshots above were taken from this Raspberry Pi forum
Note: If you are getting failures when you run make check, try putting “sudo” in front of the commands. You can also download the software on your pc and transfer it with a usb here.
Before you run the test code, you need to first move the jumpers on the board.
The instructions for this are shown on the board’s user manual, but I have also included it below:
1)Connect the High-Precision AD-DA Board to the Raspberry Pi. (Board plugs directly on top of the Raspberry Pi) 2) Jumper settings: Set the Power Supply to 5V: connect the pin 5V and VCC. Set the Reference Input Voltage to 5V: connect the pin 5V and VREF. Set the Potentiometer output as an Analog Input: connect the pin ADJ and AD0. Make sure the left side Sensor Interface AD0 is disconnected. Set the LDR output as an Analog Input: connect the pin LDR and AD1. Make sure the left side Sensor Interface AD1 is disconnected. Connect AINCOM to AGND. When using AD for differential measurements, the common input AINCOM does not need to be tied to ground.
3) When using SSH for terminal control, please connect the network cable. The software PuTTY should be installed. See the section 1.2.
4) Power up.
5) Copy (using a USB drive as a carrier) the software directory, ADS1256, to the Raspbian OS. Note: the system will detect the USB drive directly under GUI, else if using SSH Connection, the USB drive cannot be operated until it is mounted to the Linux. Search the key words “Linux mount” for more details.
6) Make the files: Enter the directory ADS1256, and execute make to compile it.
7) Execute sudo ./ads1256_test Note: if it prompts command not found, please use chmod +x ads1256_test to add execute permission.
8) Block the LDR from light and then the voltage of channel AD1 will be changed.
9) Turn the potentiometer and the voltage of channel AD0 will be changed.
10) In the end, press Ctrl+C to suspend the current process.
For more clarity I included a picture above where the jumpers should be placed:
To test code directly to the pi:
#install 7z package
apt-get install p7zip-full
#reboot
#get test cpdes:
wget <a href="http://www.waveshare.com/w/upload/5/5e/High-Precision-AD-DA-Board-Code.7z" rel="nofollow"> http://www.waveshare.com/w/upload/5/5e/High-Preci...</a>
7z x High-Precision-AD-DA-Board-Code.7z <p>cd High-Precision-AD-DA-Board-Code/Raspberry/ADS1256</p><p>make</p><p>./ads1256_test</p>
again these instructions can be found the this forum
When you run the test program you should output like the picture above:
Step 4: Hardware Setup
To get the output voltage from the thermistor, we include it in a voltage divider circuit shown below with Vdd going to a power pin on the Raspberry Pi and Vout going to an a/d channel on the expansion board. In this case, we use AD4 with ground going to one of the ground pins on the board.
The circuit then gives us the following equation:
Vout= (R1/(R(T)+R1)*Vin
Which we can then rewrite and solve for R(T) given that we know that R1 is equal to 3268 ohms( I measured my resistor to get my equation as accurate as possible) or whatever you decide to use):
R(T)=((Vin/Vout)-1)*R1
Now that we know the resistance of the thermistor we can plug that into the Steinhart- Hart equation which is:
1/T= A+Bln(R)+C[ln(R)]^3
It should be noted that A,B and C are coefficients that are specific to each thermistor and can most likely be found in the thermistor’s datasheet. However, there are Steinhart-Hart coefficients calculators online that can come up with them for you, although you may have to play around with the values to get accurate temperature readings. If you are using the thermistor specified above then you should have to mess with the coefficients. I tested the accuracy from 0 degress Celcius to over 80 using Temperature Baths at my work and it was accurate within 0.2 degrees.
Pins used for the LEDs in the program are G16, G13, G12, G6, G5, G4 with G16 being connected to the first blue LED and G4 to the last red LED. Note that there are two GPIO modes with the Raspberry Pi board mode and BCM. The Sparkfun wedge using BCM mode so if you’re not using that and your connecting them directly to the pins on the board, then you need to either look up the corresponding pins or change the mode to “board mode.” (Note: If you change to “board mode” then you will need to edit the pin assignments in the code).
Step 5: Code
Below is a screenshot of a method in my adcon.c program which is a modified version of the ads1256_test.c program ran earlier. This method is responsible for writing the temperature to the tempdata file so that it can be read from the ThermoProj.py program.
<p>*********************************************************************************************************<br>* name: fifio * function:writes data to tempdata.tmp file Code obtained from stackoverflow.com/questions/23635576/send-data-from-c-program-to-python-program-using-pipe * parameter: NULL * The return value: NULL ********************************************************************************************************* */ int fifo(float temp){ int s_write; char filename[] = "tempdata.tmp"; int s_fifo = mkfifo(filename, S_IRWXU); if(s_fifo !=0){ int s_fifo = remove(filename); printf("mkfifo() error: %d\n" , s_fifo); return -1; </p><p> } s_fifo = mkfifo(filename, S_IRWXU); FILE * wfd = fopen(filename, "w"); if(wfd < 0){ printf("open() error: %d\n", wfd); return -1; } /* Write to FIFO */ s_write = fprintf(wfd, "%f",temp);</p><p> if(s_write <0){ printf("fprintf() errpr: %d\n", s_write); } /* Close FIFO*/ fclose(wfd); unlink(filename); }</p>
<p>iTemp = volt[i]; /* uV */</p><p> iTempTot= (float)iTemp/1000000; /* Steinhart-Hart Coefficients */ a= 1.279336835E-3; b= 2.045395490E-4; c= 2.537322864E-7; /*Voltage Divder */ R1 = (((3.304)/(iTempTot))-1)*R2;</p><p> /* Steinhart - Hart Equation */ y = powf(log(R1),3); temp = a + (b*(log(R1)))+ (c*y);</p><p> /*Temperature Conversions */ tempK = 1/temp; //Kalvin tempC = tempK-273.15; //Celcius tempF = (tempK * 1.8)-459.67; //Fahrenheit //write data from channel 4 to file if(i%4==0 && i>0 &&j>5){ /*Note I choose to write the Fahrenheit Temp to the file, other may just as easily be used*/ fifo(tempC); } if (iTemp < 0) { iTemp = -iTemp; R1 = ((3.3/volt[i])-1)*R2; //printf(" (-%ld.%03ld %03ld D) \r\n", iTemp /1000000, (iTemp%1000000)/1000, iTemp%1000); } else { printf("%f V %f Ohms %f C %f F\r\n",iTempTot, R1, tempC, tempF);</p>
This segment of code is used to calculate the resistance of R1 and to also calculate the temperature using the Steinhart-Hart Equation. Note if using different coefficients they can be easily added by changing the values of a,b or c. I also chose to leave all analog to digital channels open, so that later on more sensors could be easily added. Lastly, if you’re using a different resistor for R2, then the value for it will have to be changed up top in the main method where all the variables are declared.
To run the programs you first need to open two terminals and navigate to the directory that each program is in. You then want to run the C program first so that tempdata file will be created and can be read by the Python program. After that is running, you can then run the Python program. You should be aware that the C program will run, and then appear to stop. However, it is just waiting for the Python program to start. I have included the commands that need to be entered below. I have also including a zip file containing my Python and C code along with the pdf instructions for the Waveshare High-Precision AD board.
#C program gcc -o therm adcon.c -l bcm2835 -lm sudo ./therm
#Python Program sudo python ThermoProj.py
Attachments
Step 6: Conclusion
After finishing this project there are some things that I would have liked to do a little differently, the first one would have been to use Matplotlib. This application is good for graphing data, however it is not the best for animating graphs. I used this because of the network security where I work, I was unable to connect my Raspberry Pi to the Wi-Fi, which limited my application choices. If I had internet access I would have used Plotly, this to me looked like a better alternative because it allowed the data to be viewed online and seemed easier to setup. Also, there are temperature sensors out there that are easier to work with the Raspberry Pi and the main reason I used this thermistor was that the company I am interning at, Therm-O-Disc, makes a variety of sensors including thermistors, and wanted to show how some of their products could be implemented. Also, other temperature sensor may have been easier to setup, but most would not have been as accurate. Finally, there are also cheaper options for the Analog to digital converter, like the MCP 3008, but I chose this board because of its ability to allow me to easily attach all the components to the Pi touch case making the project more portable.
Hope You Enjoy It
2 Comments
Question 4 years ago on Step 6
Hi. I made this project but when i run the adcon.c i get an ID error. Can you tell me what should be? You dont have the images of the conection? Thanks
6 years ago
Well done, great write-up.