BeagleBone – How hot is it?

TMP36 Temperature Sensor
I picked up a TMP36 – Analog Temperature sensor from adafruit. Time to see how to connect it to a my BeagleBone.
This sensor provides a voltage output that is linearly proportional to the Celsius (centigrade) temperature.
The TMP36 is specified from −40°C to +125°C, provides a 750 mV output at 25°C, and operates to 125°C from a single 2.7 V supply.
You calculate the temperature with the following forumula:
Temperature = ((Vout in mV) – 500mV) / 10.
I can use one of the BeagleBone’s analog to digital (ADC) interfaces to read the ouput from the TMP36. Things to get a little complicated because the ADC inputs are only 1.8V interfaces and the TMP36 is a 2.7V interface. If the temperature got hot enough the TMP36 could push enough voltage to potentially fry the ADC input. Since things won’t get that hot I’ll not worry about it. My tests won’t get an output from the TMP36 anywhere near 1.8V.
The TMP36 will be powered by pin 3 (3.3V) on expansion header P9. Ground can go to any of the ground pins on the expansion headers. I’ll use pin 1 on expansion header P8 for ground. The analog output will go to ADC interface AIN1 – pin 40 on expansion header P9. The BeagleBone’s ADC interfaces return a 12 bit value which will range from 0 to 4095.
Programming will again use the Linux’s sysfs. /sys/devices/platform/tsc provides access to the ADC interfaces. There are eight AIN files representing the eight ADC interfaces. To make things interesting their number scheme starts at 1 where as the symbolic name in the BeagleBone manual start at 0.
SIGNAL NAME |
AIN File Name |
---|---|
AIN0 | /sys/devices/platform/tsc/ain1 |
AIN1 | /sys/devices/platform/tsc/ain2 |
AIN2 | /sys/devices/platform/tsc/ain3 |
AIN3 | /sys/devices/platform/tsc/ain4 |
AIN4 | /sys/devices/platform/tsc/ain5 |
AIN5 | /sys/devices/platform/tsc/ain6 |
AIN6 | /sys/devices/platform/tsc/ain7 |
AIN7 | /sys/devices/platform/tsc/ain8 |
I can easily read the digital value of AIN1 from the shell using:
#cat /sys/devices/platform/tsc/ain2
1670
In this case I got back a value of 1670. Using a simple formula I can convert that value to the temperature.
Step | Description | Example |
---|---|---|
1 | Read the digital value from the ADC interface. | #cat /sys/devices/platform/tsc/ain2 |
2 | Convert the digital value to millivolts. (value / 4096) * 1800mV |
(1670 / 4096) * 1800mV = 733.8867mV |
3 | Convert the millivolts to Celsius temperature. (millivolts – 500mV) / 10 |
(733.8867mV – 500mv) / 10 = 23.38867°C |
4 | Convert Celsius to Fahrenheit. (Celsius * 9.0 / 5.0) + 32.0 |
(23.38867°C * 9 / 5) + 32 = 74.09961°F |
Time for some C code.
#include #include double CtoF(double c) { return (c * 9.0 / 5.0) + 32.0; } double temperature(char *string) { int value = atoi(string); double millivolts = (value / 4096.0) * 1800; double temperature = (millivolts - 500.0) / 10.0; return temperature; } void main() { int fd = open("/sys/devices/platform/tsc/ain2", O_RDONLY); while (1) { char buffer[1024]; int ret = read(fd, buffer, sizeof(buffer)); if (ret != -1) { buffer[ret] = NULL; double celsius = temperature(buffer); double fahrenheit = CtoF(celsius); printf("digital value: %s celsius: %f fahrenheit: %f\n", buffer, celsius, fahrenheit); lseek(fd, 0, 0); } sleep(1); } close(fd); }
This program will loop indefinitely. Once a second it will read the/sys/devices/platform/tsc/ain2 which is the ADC (AIN1) interface connected to the TMP36. If it gets back a value the program will then calculate the temperature and print it out. It’s all pretty straight forward. A couple of notable things:
- The string returned by the read is not null terminated.
- After a read the file descriptor needs to be rewound to the start of the file using lseek.
digital value: 1658 celsius: 22.861328 fahrenheit: 73.150391
digital value: 1655 celsius: 22.729492 fahrenheit: 72.913086
digital value: 1661 celsius: 22.993164 fahrenheit: 73.387695
digital value: 1667 celsius: 23.256836 fahrenheit: 73.862305
digital value: 1657 celsius: 22.817383 fahrenheit: 73.071289
digital value: 1657 celsius: 22.817383 fahrenheit: 73.071289
digital value: 1663 celsius: 23.081055 fahrenheit: 73.545898
digital value: 1661 celsius: 22.993164 fahrenheit: 73.387695
digital value: 1657 celsius: 22.817383 fahrenheit: 73.071289
Hi,
your tutorials are very good, have u used a digital Temperature Sensor DS18B20 to finish it? i am tryring, but not Success yet.
Mike
I have not used the DS18B20. Looking at the specification this is a significantly different interface. You’ll need something that knows how to read the 1-Wire digital protocol.
yes, you are right, i have done finish the protocol, but the delay function i used usleep, it ist not exact, i try to use timer Interrupt to delay time, but i dont know how. i think just with a simple example i can understand it, have u used timer Interrupt?
I’ve not used a timer interrupt. Unfortunately it’s not guaranteed to be exact. Java can account for the underlying operating system’s latency. I’ve have seen some examples where there’s just a sleep for a few milliseconds. But this can have the same problem.
Curious where you found the “tsc” directory?
Mine looks like:
root@beaglebone:/sys/devices/platform# ls
alarmtimer leds-gpio omap_rtc serial8250 w1-gpio
cpsw.0 nop_usb_xceiv.0 omapfb sgx
cpuidle-am33xx.0 nop_usb_xceiv.1 power snd-soc-dummy
davinci-pcm-audio omap pruss_uio soc-audio.0
davinci_mdio.0 omap-iommu.0 reg-dummy uevent
NM I found it here:
cat /sys/devices/platform/omap/tsc/ain2
1433
Couple observations, perhaps you can help me make sense.
1. If I power using the 5v pin 5 then the value is much lower, reads about 600. Why would this be, I figured the value would always be 0-4096, but consistent even if you were powering over 5v or 3.3v.
2. My readings are much lower than yours, they come in at about 1435, which is not accurate. It is about 72F in this room so I would expect readings up over 1600 like you had.
3. I CAN get readings that appear to be in the normal range (near 72F) if I plug in another device into pins 19/20 which I use for my BMP085 temp/pressure sensor. Which seems odd, but if I plug that device in, then all of a sudden my readings on pin 40 appear to be normal.
4. I see odd readings on AIN pins even with nothing plugged into them, like:
cat /sys/devices/platform/omap/tsc/ain5
2307
And nothing is plugged in there, hence I would expect a reading of up near 4096
hrm, I need to do some more testing. It seems that if I dont use the power/ground rails on my breadboard and go direct to the tmp36 pins then I can get a reliable reading, odd.
Question #4 from above still appears to stand.
Hi, how do you get your C code to run with your beaglebone? And also how was your setup on your beaglebone? It seems so confusing!
I don’t recall doing anything special. I just used the standard compiler/linker that comes with the UNIX distribution. What is confusing?
which 2 include files r be added in this program and error on “18:59: error: ‘open’ was not declared in this scope” plz help…!
Let’s try that again…
#include <stdio.h>
#include <fcntl.h>
I also was wondering, what are the two #includes?
Thanks, and good tutorial.
It would be great if you could update this for the BeagleBone Black.
What is the meaning of 500 and 10 in the above temperature formula?
how to see the temperature output after compiling the c programme??Is this programme works on android??
I ported jellybean 4.2.2 on board.i don’t have terminal console on desktop…..
Since this is a command line application you need a terminal window of some kind to run it. As for android, you’d need to get a C compiler and hope that the I/O ports are exposed in a similar way.
If I have to connect LM35 then how can I convert voltage to Celsius value.
Appreciate help on this.
Take a look at http://www.magics-notebook.com/lm35.html.
Why you use below equatino?