|BeagleBone Green temperature alarm|
Saving on labour can only be done by either under-paying yourself or through automation, so I have been looking at platforms for telemetry and automation. There are of course many commercial and quasi-industrial platforms, but those are closed, proprietary systems that often come with high price tags.
I am interested in open source platforms, which could upend the industry like the PC did in the 1980s. If the specs are open source and the platform itself becomes so ubiquitous that its crazy cheap, a market disruption is bound to happen.
So, to get started, I ordered a BeagleBone Green computer with a set of accessories (relay, button, LED, buzzer, OLED display, sound sensor, accelerometer). This computer is shipped with a Debian Linux operating system and costs around $39 US.
Yesterday I finally received my kit and my first test was to evaluate how complicated getting started with it is. Caveat emptor: I have an engineering background so my experience may not translate to everyone.
I had not read anything about the hardware configuration or the software prior to unwrapping my beaglebone kit; a friend had recommended it and I had read that it combines all the good features of Arduino and Raspberry PI and that it has a platform to step up to (beagle board) for larger systems.
I decided to attempt making a simple temperature alarm and see how long it would take me to get this up and running. My code should continuously monitor the temperature and make a beeper go off when the temperature is below 20 Celcius.
Now this is not a complex project, nor is it new by any means, lots of people have done this before. I found great code snippets in wikis from Adafruit and wiki.seeed.cc, and had it up and running in around 3 hours, which was pretty good! I used the cloud9 web IDE that runs on the beaglebone itself and wrote the code in python.
Here is my code:
import Adafruit_BBIO.GPIO as GPIO
from Adafruit_I2C import Adafruit_I2C
# HARDWARE SETUP
# Buzzer Grove v1.2 in Uart grove interface
# J1 on I2C ADC v1.2 grove conneced to BBG's I2C grove interface, and J2 on I2C ADC v1.2 connected to temperature sensor v1.2
BUZZER = "P9_22" # UART2_RXD (P9 pin 22) is yellow cable, connected to buzzer's SIG
I2C_ADDR_ADC121 = 0x50 # ADC121 has a default address of 0x50. Check with "i2cdetect -r 2".
I2C_BUS_ADC121 = 0x02 # The I2C grove connector is wired to I2C bus 2.
THRESHOLD_TEMPERATURE = 20 # The threshold to turn the buzzer on 20 Celsius
# ADC constants, from spec sheet at https://raw.githubusercontent.com/SeeedDocument/Grove-I2C_ADC/master/res/ADC121C021_Datasheet.pdf
ADC_REG_ADDR_CONFIG = 0x02
ADC_REG_ADDR_RESULT = 0x00
# Set up pin connected to buzzer's SIG pin for output
# Set up the ADC on the I2C bus
i2c = Adafruit_I2C(I2C_ADDR_ADC121, I2C_BUS_ADC121)
i2c.write8(ADC_REG_ADDR_CONFIG, 0x20) # Write 0x20 to the ADC121's configuration register to set automatic conversion mode with a simple rate of 32.
"Read ADC data 0-4095."
data_list = i2c.readList(ADC_REG_ADDR_RESULT, 2) # read two bytes from the result register
data = ((data_list & 0x0f) << 8 | data_list) & 0xfff # read bits D0 through D11 and zero bits D12 through D15, which are used for other things.
# From http://wiki.seeedstudio.com/wiki/Grove_-_Temperature_Sensor
# The argument in the read_temperature() method defines which Grove board(Grove Temperature Sensor) version you have connected.
# Defaults to 'v1.2'. eg.
# temp = read_temperature('v1.0') # B value = 3975
# temp = read_temperature('v1.1') # B value = 4250
# temp = read_temperature('v1.2') # B value = 4250
def read_temperature(model = 'v1.2'):
"Read temperature values in Celsius from Grove Temperature Sensor"
# each of the sensor revisions use different thermistors, each with their own B value constant
if model == 'v1.2':
bValue = 4250 # sensor v1.2 uses thermistor ??? (assuming NCP18WF104F03RC until SeeedStudio clarifies)
elif model == 'v1.1':
bValue = 4250 # sensor v1.1 uses thermistor NCP18WF104F03RC
bValue = 3975 # sensor v1.0 uses thermistor TTC3A103*39H
total_value = 0
# Measure temperatures for one second.
# Get 20 measurements, each 50 ms apart, then average all samples
for index in range(20):
sensor_value = read_adc()
total_value += sensor_value
average_value = float(total_value / 20)
# See http://wiki.seeed.cc/Grove-Temperature_Sensor_V1.2/#reference
sensor_value_tmp = (float)(average_value / 4095 * 2.95 * 2 / 3.3 * 1023)
resistance = (float)(1023 - sensor_value_tmp) * 10000 / sensor_value_tmp
# Convert from Kelvin to Celcius and round to 2 decimals.
temperature = round((float)(1 / (math.log(resistance / 10000) / bValue + 1 / 298.15) - 273.15), 2)
if __name__ == '__main__':
temperature = read_temperature('v1.2')
# When the temperature is below the threshold, turn the buzzer on.
print "temperature = ", temperature
if temperature < THRESHOLD_TEMPERATURE:
except KeyboardInterrupt: # Turn the buzzer off when program is interrupted
except IOError as e:
print "Error: ", e
I had to figure out how to log into the
To write this, I had to learn about the pin mapping and had to troubleshoot an I2C bus issue (all the sample code leaves out the bus number and defaults to bus 0, but my setup used bus 2). I also downloaded the spec sheets of the analog-digital converter and the temperature monitor to figure out which registers to poke. None of that took very long, thanks to very detailed documentation and examples.
My conclusion for today: beagleboard green is awesome, you can get tinkering in half a day.