Raspberry Pi Zero W as Bluetooth IoT Gateway installed in the front porch |
The Bluetooth Autogate Remote started to fail, first on individual button presses, then the laptop bluetooth controller lost the link to the HC-06 in the gatepost. A typical bluetoothctl command sequence and output now goes something like this:
[bluetooth]# scan on
Discovery started
[CHG] Controller C8:FF:28:27:7D:2C Discovering: yes
[CHG] Device 98:D3:32:20:BB:7B RSSI: -90
[bluetooth]# devices
Device 98:D3:32:20:BB:7B HC-06
[bluetooth]# pair 98:D3:32:20:BB:7B
Attempting to pair with 98:D3:32:20:BB:7B
Failed to pair: org.bluez.Error.ConnectionAttemptFailed
When RSSI value got to about -86 the pairing would work but dropped every few days or so. This handy link explained quite well that RSSI meant 'Received Signal Strength Indicator' and has an RSSI table:
Acceptable Signal Strengths
Signal Strength | TL;DR | Required for | |
---|---|---|---|
-30 dBm | Amazing | Max achievable signal strength. The client can only be a few feet from the AP to achieve this. Not typical or desirable in the real world. | N/A |
-67 dBm | Very Good | Minimum signal strength for applications that require very reliable, timely delivery of data packets. | VoIP/VoWiFi, streaming video |
-70 dBm | Okay | Minimum signal strength for reliable packet delivery. | Email, web |
-80 dBm | Not Good | Minimum signal strength for basic connectivity. Packet delivery may be unreliable. | N/A |
-90 dBm | Unusable | Approaching or drowning in the noise floor. Any functionality is highly unlikely. | N/A |
So my RSSI went from 'Not Good' to 'Unusable'. Now the laptop's bluetooth controller had 2 walls and a plastic enclosure between it and the Autogate Bluetooth HC-06, so I though it might be a good idea to have the IoT Gateway on the front porch, which not only is only 30m away but had line-of-sight to the HC-06.
That was the purpose of the Raspberry Pi Zero W. My last post showed Slackware 14.1 can run on it. This is handy because my laptop ran Slackware 14.2.
First I need to get the WiFi running on the Raspberry Pi Zero W. That was easy enough. It turned out I was missing some bios files:
-rwxr-xr-x 1 root root 6551 Oct 30 18:36 fixup.dat
-rwxr-xr-x 1 root root 2578 Oct 30 18:36 fixup_cd.dat
-rwxr-xr-x 1 root root 9694 Oct 30 18:36 fixup_db.dat
-rwxr-xr-x 1 root root 9694 Oct 30 18:36 fixup_x.dat
-rwxr-xr-x 1 root root 2820196 Oct 30 18:36 start.elf
-rwxr-xr-x 1 root root 667460 Oct 30 18:36 start_cd.elf
-rwxr-xr-x 1 root root 4956676 Oct 30 18:36 start_db.elf
-rwxr-xr-x 1 root root 3904228 Oct 30 18:36 start_x.elf
-rwxr-xr-x 1 root root 15830 Oct 30 18:36 bcm2708-rpi-0-w.dtb
Once corrected the WiFi interface came up and was connected to my home WiFi hotspot with no fuss. I could now ssh into the Zero W and use it without the monitor or USB keyboard.
The bluetooth controller was a whole different ballgame. After spending a whole Sunday on it, I gave up and decided to use a Vztech bluetooth dongle instead. This I connected to the micro USB OTG connector and worked straight out of the box.
The bluetooth software was the same Bluez used in Slackware 14.2, but being the 14.1 version did not have bluetoothctl. The function I missed most was the bluetooth agent required to pair the HC-06 to the Pi Zero W. Happily a little digging showed that Bluez tarball for Slackware 14.1 has a workable agent, simple-agent which was built but not included when the Slackware upgradepkg program installed Bluez.
I just needed to unpack the tarball and install it:
root@rpi-0-w:~# cp /tmp/bluez-4.99/test/simple-agent /usr/bin/
Now without bluetoothctl the commands are a little different but still quite straightforward:
root@rpi-0-w:~# chmod +x /etc/rc.d/rc.bluetooth
Reboot, taking care to first plug in the bluetooth dongle, then do:
root@rpi-0-w:~# hcitool dev
Devices:
hci0 00:1A:7D:DA:71:13
And more important:
root@rpi-0-w:~# hciconfig
hci0: Type: BR/EDR Bus: USB
BD Address: 00:1A:7D:DA:71:13 ACL MTU: 310:10 SCO MTU: 64:8
DOWN
RX bytes:574 acl:0 sco:0 events:30 errors:0
TX bytes:368 acl:0 sco:0 commands:30 errors:0
root@rpi-0-w:~# hciconfig hci0 up
And now the bluetooth controller is running:
root@rpi-0-w:~# hciconfig hci0
hci0: Type: BR/EDR Bus: USB
BD Address: 00:1A:7D:DA:71:13 ACL MTU: 310:10 SCO MTU: 64:8
UP RUNNING
RX bytes:1148 acl:0 sco:0 events:60 errors:0
TX bytes:736 acl:0 sco:0 commands:60 errors:0
Next you need to find the bluetooth channel:
root@rpi-0-w:~# sdptool browse local
Which produced output like this (look for RFCOMM):
Service Name: Dial-Up Networking
Service RecHandle: 0x10005
Service Class ID List:
"Dialup Networking" (0x1103)
"Generic Networking" (0x1201)
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 1
Profile Descriptor List:
"Dialup Networking" (0x1103)
Version: 0x0100
Which means we are channel 1. We then look for the HC-06:
root@rpi-0-w:~# hcitool scan
Scanning ...
98:D3:32:20:BB:7B HC-06
Next we launch the bluetooth agent:
root@rpi-0-w:~simple-agent hci0 98:D3:32:20:BB:7B
RequestPinCode (/org/bluez/481/hci0/dev_98_D3_32_20_BB_7B)
Enter PIN Code: 1234
Release
New device (/org/bluez/481/hci0/dev_98_D3_32_20_BB_7B)
The last step is then:
root@rpi-0-w:~/bluez# rfcomm bind /dev/rfcomm0 98:D3:32:20:BB:7B 1
And the all-important RSSI is now in 'Amazing' category:
root@rpi-0-w:~# hcitool rssi 98:D3:32:20:BB:7B
RSSI return value: -19
The next steps involve setting up python, pymodbus and apache in Slackware 14.1, and are best treated separately. You can also refer to other online links for this. The end result is much the same as the previous post, and worked about the same. Not bad for the RM42 Raspberry Pi Zero W, which replaced an RM3,200 Acer AspireF15 as the IoT Bluetooth Gateway.
Now all this seemed a little fly-by-the-seat-of-your-pants, but this is the nature of DevOps/Rapid Development. It is iterative and relies on incremental redesigns with the emphasis on putting out the prototype as quickly as possible. Notice it took a few weeks operating the prototype for the bluetooth wireless problem to be obvious.
Some problems are immediately obvious: the Pi Zero W does not have battery backup while the laptop did. Installing a battery would require other things: a proper enclosure, perhaps a shelf. But in the meantime up goes the latest prototype to fish for other problems.
Perhaps one of the most important things about Rapid Development is customer involvement. One indication the project is going well is the wife got quite used to opening the autogate from her car, and complained immediately when the Bluetooth Autogate stopped working in wet weather.
Happy Trails.
Update: as feared, every few days or so the Raspberry Pi Zero W rebooted by itself. This was tracked by having the pymodbus server program print out regular heatbeat messages:
Cmd z, voltages are [3, 255, 2, 157]
stored values= [3, 252, 2, 154]
address= 0 answer: [3, 255, 2, 157]
CPU 1023 Battery 669
CPU 5.00 Battery 13.88 Volts 2018-01-26 04:34:13
Reply: ÿHCM¡LJP len 10
Cmd z, voltages are [3, 255, 2, 161]
stored values= [3, 255, 2, 157]
address= 0 answer: [3, 255, 2, 161]
CPU 1023 Battery 673
CPU 5.00 Battery 13.97 Volts 2018-01-26 04:46:14
Reply: ïHCMLJP len 10
Cmd z, voltages are [3, 239, 2, 156]
stored values= [3, 255, 2, 161]
address= 0 answer: [3, 239, 2, 156]
CPU 1007 Battery 668
CPU 4.92 Battery 13.86 Volts 2018-01-26 04:58:15
packet_write_wait: Connection to 172.16.1.25 port 22: Broken pipe
We had gotten really used to that WiFi autogate remote, so to keep it going (while I am trying to figure out what went wrong) I simply added this to /etc/rc.d/rc.local so that the IoT gateway program restarted itself. Not using bluetoothctl had a silver lining after all:
echo "1234" | simple-agent hci0 98:D3:32:20:BB:7B release
rfcomm bind 0 98:D3:32:20:BB:7B 1
sleep 2
python ./autogate_server.py > /dev/null &
Update: as feared, every few days or so the Raspberry Pi Zero W rebooted by itself. This was tracked by having the pymodbus server program print out regular heatbeat messages:
Cmd z, voltages are [3, 255, 2, 157]
stored values= [3, 252, 2, 154]
address= 0 answer: [3, 255, 2, 157]
CPU 1023 Battery 669
CPU 5.00 Battery 13.88 Volts 2018-01-26 04:34:13
Reply: ÿHCM¡LJP len 10
Cmd z, voltages are [3, 255, 2, 161]
stored values= [3, 255, 2, 157]
address= 0 answer: [3, 255, 2, 161]
CPU 1023 Battery 673
CPU 5.00 Battery 13.97 Volts 2018-01-26 04:46:14
Reply: ïHCMLJP len 10
Cmd z, voltages are [3, 239, 2, 156]
stored values= [3, 255, 2, 161]
address= 0 answer: [3, 239, 2, 156]
CPU 1007 Battery 668
CPU 4.92 Battery 13.86 Volts 2018-01-26 04:58:15
packet_write_wait: Connection to 172.16.1.25 port 22: Broken pipe
We had gotten really used to that WiFi autogate remote, so to keep it going (while I am trying to figure out what went wrong) I simply added this to /etc/rc.d/rc.local so that the IoT gateway program restarted itself. Not using bluetoothctl had a silver lining after all:
echo "1234" | simple-agent hci0 98:D3:32:20:BB:7B release
rfcomm bind 0 98:D3:32:20:BB:7B 1
sleep 2
python ./autogate_server.py > /dev/null &