Home > BeagleBone > BeagleBone – How hot is it?

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.

BeagleBone with Temperature Sensor

BeagleBone with Temperature Sensor

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
1670
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.
Here’s some sample output.


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

Advertisements
Categories: BeagleBone Tags:
  1. Mike
    July 7, 2012 at 10:56 pm

    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

    • July 8, 2012 at 1:02 am

      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.

      • Mike
        July 8, 2012 at 9:09 am

        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?

      • July 10, 2012 at 8:37 pm

        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.

  2. August 5, 2012 at 4:10 am

    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

  3. August 5, 2012 at 3:13 pm

    NM I found it here:

    cat /sys/devices/platform/omap/tsc/ain2

    1433

  4. August 5, 2012 at 4:00 pm

    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

  5. August 5, 2012 at 4:06 pm

    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.

  6. Ben
    April 24, 2013 at 2:00 pm

    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!

    • April 24, 2013 at 2:11 pm

      I don’t recall doing anything special. I just used the standard compiler/linker that comes with the UNIX distribution. What is confusing?

  7. vinay
    May 29, 2013 at 11:59 am

    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…!

  8. weirD
    June 7, 2013 at 1:11 am

    Let’s try that again…

    #include <stdio.h>
    #include <fcntl.h>

  9. Travis
    June 7, 2013 at 4:16 am

    I also was wondering, what are the two #includes?
    Thanks, and good tutorial.

  10. MarkH
    June 20, 2013 at 6:37 pm

    It would be great if you could update this for the BeagleBone Black.

  11. Fatih
    July 18, 2013 at 7:21 am

    What is the meaning of 500 and 10 in the above temperature formula?

  12. sajeesh kumar
    November 19, 2013 at 7:19 am

    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…..

    • November 19, 2013 at 7:40 am

      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.

  13. ea
    May 4, 2014 at 1:33 pm

    If I have to connect LM35 then how can I convert voltage to Celsius value.
    Appreciate help on this.

  14. ea
    May 4, 2014 at 1:36 pm

    Why you use below equatino?

  1. March 28, 2016 at 4:19 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: