Difference between revisions of "BBB and OneWire"
(→Enabling the DS18B20 thermometer) |
|||
Line 51: | Line 51: | ||
Finally in order to enable this part of the device tree perform at every boot this command | Finally in order to enable this part of the device tree perform at every boot this command | ||
+ | |||
+ | == Newer Debian Distributions == | ||
+ | |||
+ | For the 2019 and probably later distributions things are a little bit different. The device tree is loaded completely by the boot loader, hence you have to modify the /boot/uEnv.txt file to add a line like this: | ||
+ | |||
+ | uboot_overlay_addr0=/lib/firmware/BB-W1-P9.12-00A0.dtbo | ||
+ | |||
+ | and reboot. | ||
+ | |||
+ | === Verify the presence === | ||
+ | |||
+ | The thermometer should now show up in the /sys/bus/w1/devices folder | ||
+ | |||
+ | drwxr-xr-x 2 root root 0 Jan 1 2000 . | ||
+ | drwxr-xr-x 4 root root 0 Jan 1 2000 .. | ||
+ | lrwxrwxrwx 1 root root 0 Feb 21 10:49 28-000005a7ce64 -> ../../../devices/w1_bus_master1/28-000005a7ce64 | ||
+ | lrwxrwxrwx 1 root root 0 Feb 21 10:49 w1_bus_master1 -> ../../../devices/w1_bus_master1 | ||
+ | |||
+ | the 28-00000nnnnnnn is the thermometer - they are all uniquely identified, so the n's will vary. | ||
+ | |||
+ | == Older Debian Distributions == | ||
+ | |||
+ | In older distributions one had to do thing manually by issuing this command: | ||
<source lang=bash> | <source lang=bash> | ||
echo DS1820 > /sys/devices/bone_capemgr.*/slots | echo DS1820 > /sys/devices/bone_capemgr.*/slots | ||
</source> | </source> | ||
+ | |||
+ | === Verify the presence === | ||
The thermometer should now show up in the /sys/bus/w1/devices folder | The thermometer should now show up in the /sys/bus/w1/devices folder | ||
Line 65: | Line 90: | ||
the 28-00000nnnnnnn is the thermometer - they are all uniquely identified, so the n's will vary. | the 28-00000nnnnnnn is the thermometer - they are all uniquely identified, so the n's will vary. | ||
− | ==Enabling@boot== | + | ==== Enabling@boot==== |
Create a file called '''enable-DS18B20''' in /etc/init.d wtih this content: | Create a file called '''enable-DS18B20''' in /etc/init.d wtih this content: |
Latest revision as of 16:34, 23 November 2020
OneWire is a simple, yet powerful, communication bus that allows us to connect several peripheral devices to a micro computer.
Contents
Enabling the DS18B20 thermometer
The version of Debian that my board was supplied with uses the Flattened Device Tree in order to ease the access to GPIO's and other hardware. This is so for the most modern Linux distributions for the ARM processors. The reason for this is mainly because Linus Thorvalds did not want to include the large amount of device drivers for the ARM processor family in the kernel. Se more about the Flattened Device Tree (FDT) on this site.
From this site I was inspired to set-up the correct dts file enabling the usage of GPIO pin 2 for the 1Wire interface.
Create a file name DS1820-00A0.dts with this content
/dts-v1/; /plugin/; / { compatible = "ti,beaglebone", "ti,beaglebone-black"; part-number = "DS1820"; version = "00A0"; exclusive-use = "P9.12"; fragment@0 { target = <&am33xx_pinmux>; __overlay__ { ds1820_pins: pinmux_ds1820_pins { pinctrl-single,pins = <0x78 0x37>; }; }; }; fragment@1 { target = <&ocp>; __overlay__ { onewire@0 { status = "okay"; compatible = "w1-gpio"; pinctrl-names = "default"; pinctrl-0 = <&ds1820_pins>; gpios = <&gpio2 28 0>; }; }; }; };
Compile the specification into a dtbo binary file
dtc -O dtb -o /lib/firmware/DS1820-00A0.dtbo -b 0 -@ DS1820-00A0.dts
Finally in order to enable this part of the device tree perform at every boot this command
Newer Debian Distributions
For the 2019 and probably later distributions things are a little bit different. The device tree is loaded completely by the boot loader, hence you have to modify the /boot/uEnv.txt file to add a line like this:
uboot_overlay_addr0=/lib/firmware/BB-W1-P9.12-00A0.dtbo
and reboot.
Verify the presence
The thermometer should now show up in the /sys/bus/w1/devices folder
drwxr-xr-x 2 root root 0 Jan 1 2000 . drwxr-xr-x 4 root root 0 Jan 1 2000 .. lrwxrwxrwx 1 root root 0 Feb 21 10:49 28-000005a7ce64 -> ../../../devices/w1_bus_master1/28-000005a7ce64 lrwxrwxrwx 1 root root 0 Feb 21 10:49 w1_bus_master1 -> ../../../devices/w1_bus_master1
the 28-00000nnnnnnn is the thermometer - they are all uniquely identified, so the n's will vary.
Older Debian Distributions
In older distributions one had to do thing manually by issuing this command:
echo DS1820 > /sys/devices/bone_capemgr.*/slots
Verify the presence
The thermometer should now show up in the /sys/bus/w1/devices folder
drwxr-xr-x 2 root root 0 Jan 1 2000 . drwxr-xr-x 4 root root 0 Jan 1 2000 .. lrwxrwxrwx 1 root root 0 Feb 21 10:49 28-000005a7ce64 -> ../../../devices/w1_bus_master1/28-000005a7ce64 lrwxrwxrwx 1 root root 0 Feb 21 10:49 w1_bus_master1 -> ../../../devices/w1_bus_master1
the 28-00000nnnnnnn is the thermometer - they are all uniquely identified, so the n's will vary.
Enabling@boot
Create a file called enable-DS18B20 in /etc/init.d wtih this content:
#! /bin/sh ### BEGIN INIT INFO # Provides: enable-DS18B20 # Required-Start: $all # Required-Stop: $all # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Enables the DS18B20 1-wire on P9 pin 12 # Description: Conneting the 1-wire driver to the P9 pin 12 ### END INIT INFO case "$1" in start) echo "Enabling 1-Wire DS18B20 on P9 Pin 12" echo DS1820 > /sys/devices/bone_capemgr.9/slots ;; stop) #no-op ;; *) #no-op ;; esac exit 0
After creating the file execute
root@beaglebone $] chmod 755 enable-pwm root@beaglebone $] update-rc.d enable-DS18B20 defaults
The first command set the file permissions and the second updates the init system to execute the file at a correct time depending on the information given in the first part of the script.
Testing the thermometer
Find below two tests that will verify that the thermometer work in your setup.
Test with Python
To check that the thermometer work correct prepare this short test program in a file named test.py where you of course will adjust the thermometer ID to suit your set-up:
import time w1="/sys/bus/w1/devices/28-000005a7ce64/w1_slave" while True: raw = open(w1, "r").read() print "Temperature is "+str(float(raw.split("t=")[-1])/1000)+" degrees" time.sleep(1)
Execute the program
python test.py
you should get something similar to this
root@klaus-BBB:~/ds18b20# python test.py Temperature is 24.0 degrees Temperature is 24.0 degrees Temperature is 24.062 degrees Temperature is 24.062 degrees ^CTraceback (most recent call last): File "test.py", line 8, in <module> time.sleep(1) KeyboardInterrupt root@klaus-BBB:~/ds18b20#
Test using Bonescript
This source first locates the attached thermometer and then uses it for temperature reading.
This code is only able to handle one thermometer at a time, or in fact, only one 1-wire device at at time.
// // Interface for the thermometer // Author : Klaus Kolle // Date : 2015 02 22 // Revision : 0.0.3 var b = require('bonescript'); var f = require('fs'); //console.log('Hello, Thermostate.'); var temperature; // Read from the 1-wire thermometer // The 28-00000nnnnnnn will change depending of the device connected // var oneWireDir; locateThermometer(); function locateThermometer() { var initialDir = '/sys/bus/w1/devices/'; var regExpr = '28-00000'; var dir = []; var i; // Get all files and directories in the dir var dirs = f.readdirSync(initialDir); // Did we gat anything - if not the cape manager is probably not initialised // with the dtbo compiled device tree if (dirs.length > 0) { for (i = 0; i < dirs.length; i++) { // Only select the directories matching the pattern if(dirs[i].match(regExpr)) { dir.push (dirs[i]); } } // Currently the code only accepts one thermometer oneWireDir = initialDir + dir + "/w1_slave"; } } function readTemp() { // Callback function for the timer b.readTextFile(oneWireDir, printTemp); } // The 1-wire returs this when reading the device // klaus@klaus-BBB:~$ cat /sys/bus/w1/devices/28-000005a7ce64/w1_slave // a5 01 4b 46 7f ff 0b 10 f7 : crc=f7 YES // a5 01 4b 46 7f ff 0b 10 f7 t=26312 // Therefore a split is needed. We need the string after the second = function printTemp(x) { // We receive the data i x if (x.data != '') { var stringToSplit = x.data; // Split at = - three resulting strings are returned var arrayOfStrings = stringToSplit.split('='); // We are only interesd in the last temperature = (arrayOfStrings[2]) / 1000; console.log("Temp: " + temperature); } } setInterval(readTemp, 5000);
Expect a readout like this
Temp: 24.687 Temp: 24.75 Temp: 24.75 Temp: 24.687 Temp: 24.75 Temp: 24.75 Temp: 24.75 Temp: 24.687