Wednesday, January 8, 2014

BeagleBone Black as temperature sensor

Ok, having BeagleBone Black ready (Beaglebone, Beaglebone, Beagle all the way...) let's add some functionality to it.

Let's start with measuring temperature. Why?

  1. I have LM34 sensor in my sensor's box 
  2. I am going to use my BBB card in closed box or in my future robot. 
  3. I cam monitor the temperature everywhere using the temperature sensor and remote access to it.
From these I have few questions and points:

  1. Can BBB be overheated? 
  2. Does BBB have CPU built-in temp sensor? Do we have access to it?
  3. CPU temp sensor it is not exactly what I need now. I want to measure temperature in the box/robot that can be the reason of overheated CPU but it is not the same values.
So let's start with connecting LM34 and reading the values from it. It has to be some very simple task as LM34 uses analog output and our BBB has analog input.  

I suggest to keep the following pins map from BeagleBoard.org site.

You can see that analog inputs AINx are P9_33 and P9_35-P9_40 pins. I will connect output from LM34 to pin P9_39 that is AIN0. But...

Before connecting LM34 output let's do some calculations.

Maximum allowed input value for BBB analog input is limited up to 1.8V. I am going to use the LM34 as the follwoing on the Figure 1. In this case LM34 can measure temperature range from +5F to +300F and output will be from 50mV to 300mV. Not sure that +300F will be something real we need to measure but in any case let's do it right and protect our BBB from high voltage.
So, I will use voltage divider. We will have to limit the LM34 output to 50% so the highest value will be 150mV. I will use two similar resistors 10kOm each one.

Let's have everything connected and tested. I just measured the output on LM34 and got 0.74V that is 74F. Giving touch to LM34 I hot raising voltage that is indication we are on right way.

Our divider is also working fine and I am getting on the white wire exactly the half of LM34 output voltage - 0.37V.


So, now it is time to connect output to BBB analog input. As I said I have connected it to AIN0 that is P9_39.

Let's ask BBB about measured temperature. First of all let's read the value using BBB Device Tree Overlay (DTO).

root@arm:/sys/class# find /sys -name *AIN*
/sys/devices/ocp.3/helper.15/AIN0
/sys/devices/ocp.3/helper.15/AIN1
/sys/devices/ocp.3/helper.15/AIN2
/sys/devices/ocp.3/helper.15/AIN3
/sys/devices/ocp.3/helper.15/AIN4
/sys/devices/ocp.3/helper.15/AIN5
/sys/devices/ocp.3/helper.15/AIN6
/sys/devices/ocp.3/helper.15/AIN7

Read value

Note, you have to run these commands with root user privileges. You can do it by adding sudo prefix before each command or run sudo -s to start sudo session (to exit from it execute exit command).

root@arm:/sys/class# cat /sys/devices/ocp.3/helper.15/AIN0
362
root@arm:/sys/class# cat /sys/devices/ocp.3/helper.15/AIN0
362

Touching sensor and read again

root@arm:/sys/class# cat /sys/devices/ocp.3/helper.15/AIN0
363
root@arm:/sys/class# cat /sys/devices/ocp.3/helper.15/AIN0
368

Hey! It is working! But what is the output value? It is voltage. So we have 0,362 on the analog pin. As we had the voltage divided we have to multiply it. So the voltage on sensor output leg has to be 0.724V that has to be representation of 74.2F. Checking all with voltmeter. The values are right.

Let's try to use python. And again, to have access to the pins, run python with sudo.

root@arm:~# python
Python 2.7.5+ (default, Sep 19 2013, 14:17:30) 
[GCC 4.8.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import Adafruit_BBIO.ADC as ADC
>>> ADC.setup()
>>> ADC.read("P9_39")
0.1966666728258133
>>> 

What? What does this value mean? Is something wrong?

No, all is fine.To read the voltage we have to use ADC.read_raw method

>>> ADC.read_raw("P9_39")
353.0
>>>

Method ADC.read we used before returns the value between 0 and 1 where 1 is maximum allowed voltage (1.8V). So, value 0.1966666728258133 is the same as value 0.35400001108646394 (1.8 * 0.1966666728258133 ) in raw reading.

Final python script

import time
import Adafruit_BBIO.ADC as ADC

ADC.setup()

def read_temp_values_cont():
        while(1):
                f = read_sensor()

                c = (f - 32) * 5 /9

                print "%3.1fF, %3.1fC" % (f, c)

                time.sleep(1)

def read_sensor():
        ain_value = ADC.read("P9_39")

        ain_voltage = 1.8 * ain_value

        sensor_output_voltage = ain_voltage * 2

        f = sensor_output_voltage * 100

        return f

if __name__ == '__main__':
        read_temp_values_cont()

Run it

ubuntu@arm:~/scripts/py/lm34$ sudo python temp.py 
70.8F, 21.6C
70.6F, 21.4C
70.8F, 21.6C
70.8F, 21.6C
70.8F, 21.6C
70.8F, 21.6C
Touching sensor
71.0F, 21.7C
71.6F, 22.0C
72.4F, 22.4C
72.8F, 22.7C
73.2F, 22.9C
73.6F, 23.1C
74.0F, 23.3C
74.2F, 23.4C
74.6F, 23.7C
Releasing sensor
74.4F, 23.6C
74.2F, 23.4C
74.0F, 23.3C
74.0F, 23.3C
73.8F, 23.2C
73.6F, 23.1C
73.4F, 23.0C
73.2F, 22.9C
73.2F, 22.9C

All done. Now we have working temperature sensor ready to be applied in any project.

You can clone script from GitHub

To be continued...


No comments:

Post a Comment