OverviewLogic Supply's CBB-EEProto cape makes it easy to design custom capes for the BeagleBone Black by providing a pre-populated EEPROM circuit compatible with the BeagleBone's capemgr software. The EEPROM can be setup to tell the BeagleBone's Kernel to automatically load a Device Tree overlay on boot, which can be used to configure the IO pins used by the cape. In this tutorial we will use the CBB-EEProto and Logic Supply's prototyping parts kit to make a basic thermostat cape.
What You Will Need
- 10k potentiometer
- 2N7000 MOSFET
- 1x 4-pin screw terminal
- OUAZ-SS-105l relay
- 1N4148 diode
- 5x 330 ohm resistor
- 1x LED
The diode is used as a temperature sensor by taking advantage of the fact that a diode's forward voltage changes with temperature. The potentiometer sets the temperature threshold at which an external load will be switched on or off with the relay. The MOSFET is needed to switch 5V through the relay coil because the GPIO pins cannot source enough power to charge the relay coil by themselves. The LED is used as a flyback diode for the relay coil to protect the MOSFET.
There's plenty of room on the CBB-EEProto to fit the circuit:
And with the bottom side connections shown in red:
Device Tree OverlayThis cape won't work yet because the IO pins it uses will not be configured correctly by default. The Device Tree is a way of abstracting the state of all the processor's peripherals to a well defined data structure, and Device Tree overlays can be used to modify portions of this data structure at run time to reconfigure the peripherals.
We've already written an overlay for this cape, so you'll just need log into your BeagleBone and fetch and compile it:
# wget https://gist.githubusercontent.com/alexanderhiam/9511261/raw/cape-thermostat-00A0.dts
# dtc -O dtb -o cape-thermostat-00A0.dtbo -b 0 -@ cape-thermostat-00A0.dts
# mv cape-thermostat-00A0.dtbo /lib/firmware
Programming The EEPROMWhen the BeagleBone boots it looks to see if it has any capes attached by searching for EEPROM's on the I2C2 bus. If an EEPROM on this bus contains the proper data, it will trigger the BeagleBone to automatically load a Device Tree overlay.
To create the EEPROM data to load the above overlay we'll use Ken Keller's mkeeprom tool described in this post. First fetch and compile it:
# mkdir mkeeprom && cd mkeeprom
# wget http://azkeller.com/blog/wp-content/uploads/2012/08/mkeeprom.c
# make mkeeprom
then run it and enter the following data:
Enter Name of Board in ASCII (max 32): cape-thermostat
Enter HW Version of Board in ASCII (max 4): 00A0
Enter Name of Manufacturer in ASCII (max 16): Me!
Enter Part Number in ASCII (max 16): cape-thermostat
Enter Serial Number in ASCII (max 16): cape-thermostat-00A0
Enter MAX Current (mA) on VDD_3V3EXP Used by Cape (Range 0 to 250mA): 15
Enter MAX Current (mA) on VDD_5V Used by Cape (Range 0 to 1000mA): 40
Enter MAX Current (mA) on SYS_5V Used by Cape (Range 0 to 250mA): 0
Enter Current (mA) Supplied on VDD_5V by Cape (Range 0 to 65535mA): 0
Enter Number of Pins Used by Cape (Range 0 to 74): 0
Note that we told it the cape uses 0 pins. Technically we should enter the configuration for all the pins, but for now we'll skip that step as it's not currently used by the capemgr.
You should now have a data.eeprom file that's ready to be written to the cape's EEPROM. First you'll need to know its address, which is set by the DIP switch marked S1 on the EEProto cape. The two switches set the A1 and A0 bits of the EEPROM's base address of:
0 1 0 1 0 1 A1 A0With the cape oriented so the switch labels are right-side up, moving the switches to the left ("ON") position sets the corresponding bit to 0, and moving them to the right position sets it to 1:
If you've never moved the switches they should both be in the right position, making the address the binary value 01010111. The Linux kernel's I2C driver uses the hex value, so this address will be 0x57.
Boot your BeagleBone with the cape attached (you should always turn it off before adding or removing capes!) and log in. Before you can write any data to the EEPROM you have to disable its write protection. To do this you need to short together the two contacts marked WP on the cape. The I2C EEPROM driver lets you treat EEPROMs like files, so writing the generated data to it is simple:
# cd mkeeprom
# cat data.eeprom > /sys/bus/i2c/devices/1-0057/eeprom
The 1 in 1-0057 indicates which I2C bus it's on (the kernel calls the I2C2 bus bus 1), and the 0057 is the hex address.
It should only take a second or two to write the data, then you will be returned to the command prompt. Once complete the write protect pins can be disconnected from each other.
Using The CapeWith the EEPROM written and the compiled overlay in place, the cape should be ready to use. The next time you reboot your BeagleBone with the cape attached it should automatically load the overlay and configure the pins. You can confirm this by asking the capemgr driver what capes are loaded:
# cat /sys/devices/bone_capemgr.*/slots
You should see cape-thermostat in the list. On some versions of the BeagleBone kernel, the capemgr detects the attached capes before the filesystem is mounted, which means it will not be able to find the overlay in /lib/firmware. If the cape does not show up in the list this is likely the reason. If you are comfortable building your own kernels for the BeagleBone you can build and install a kernel which includes the cape-thermostat overlay. Otherwise you can simply load it at run-time for the time being until the issue is sorted out in a later kernel version with:
# echo cape-thermostat > /sys/devices/bone_capemgr.*/slots
Once the overlay is loaded GPIO2_3 will be ready for use through the sysfs GPIO driver, and there will be two new files for the analog inputs:
Reading from AIN1 will give the microvolts measured at the anode of the 1N4148 diode, and reading from AIN3 will give the microvolts measured at the wiper of the potentiometer.
If you followed the layout above, the pinout of the screw terminals will be:
Calibrating The TemperatureAs the temperature rises, the voltage read at the anode of the diode will decrease at a fairly linear rate (at least within a reasonable temperature range). An approximate function to convert microvolts to degrees Celsius can be generated by taking samples at different temperatures and using a spreadsheet program like LibreOffice Calc to calculate a trend line:
f(x) takes a reading in microvolts and gives an approximate temperature in degrees C.
A Simple Thermostat ProgramWe've already written a simple thermostat program in Python for the cape. You can simply download and run it with:
# wget https://gist.githubusercontent.com/alexanderhiam/9511261/raw/simple-thermostat.py
# python simple-thermostat.py
It will sample the diode and potentiometer voltages twice a second, convert them to degrees Celsius, print them to the terminal and switch on the relay when the temperature is below the set threshold. By turning the potentiometer you can change the temperature at which it switches. It includes a 2 degree hysteresis.
The program allows some configuration, which can be set by editing the file with nano (or your favorite editor):
# nano simple-thermostat.py
The settings that can be changed are all at the top of the file:
# Set to True to have the relay engaged when the temperature falls below # the set threshold: SWITCH_WHEN_COLDER = True # Or set to False to have the relay engaged when the temperature rises # above the set threshold: #SWITCH_WHEN_COLDER = False # Used to avoid rapid switching when the temperature is right at the # threshold. The relay will be engaged when it is this many degrees past # the threshold, and will be disengaged once it has returned this many # degrees past the threshold in the other direction: HYSTERESIS = 2 # in degrees C # The temperature will be sampled once every SAMPLE_INTERVAL seconds SAMPLE_INTERVAL = 0.5 # in seconds # Used to calibrate the measured temperature by offsetting it either # positively or negatively: TEMP_OFFSET = 0 # in degrees CAnd a quick video of the cape in action switching on a 12V fan when the temperature rises above 40°C: