Wednesday 27 June 2018

Raspberry Pi Zero W as WiFi Repeater

No extra WiFi dongles used. The dongle shown is a wireless keyboard used for development only
The ESP-01S WiFi Repeater works well for IoT use. It can be daisy-chained maybe 5 times for a maximum range of 200m, but I found it a little slow for normal use. In particular youtube stuttered even on an old Rolling Stones video in black and white.

It would be nice to see how the Raspberry Pi Zero W fared as a WiFi repeater. At RM40 (the microUSB cable is RM2) from cytron, it is about double the price of the ESP-01S Repeater and close to the RM52 retail price for a D-Link DMG-112A.

Even so the Raspberry Pi WiFi Repeater will come out ahead if it can also be used as an IoT device, such as a WiFi autogate remote controller.

Albert Chaharbakshi: had last word on the Raspi WiFi Repeater


I could not find anything to add to Albert Chaharbakhshi's classy post.

Well, except this youtube video to prove his post really works. Even the Raspberry Pi website's version requires another WiFi interface or at least a wired Ethernet interface to work.

Youtube video of Raspi Zero W WiFi repeater feeding a laptop with a video stream
The Pi is shown connected to a monitor and keyboard but is set for "headless" operation with a static IP address. A laptop was able to play a reasonable youtube video (Porcelain Black's Naughty Naughty) at 480p with no difficulty.

There you have it, a practically commercial grade WiFi Repeater. Happy Trails.


Tuesday 19 June 2018

ESP8266 IoT Low-cost WiFi Repeater

Left: NodeMCU EPS-12E, right: ESP-01S with CH340 adapter
The ESP8266, especially the ESP-01S board can be used as a low-cost WiFi repeater. Add a CH340 USB serial port adapter(RM6.50) for the ESP-01S (RM14.90) and it is still only RM21.40.

A WiFi Range Extender like the D-Link DMG-112A can be bought for RM45, but the ESP8266 is especially cost-effective if the WiFi repeater software can be included in your ESP8266 IoT device. Such an IoT device can be meshed with others to form a WiFi net, extending the IoT cloud's reach.

D-Link DMG-112A WiFi Range Extender is only RM45
Hasten then to Martin Ger's superlative site.

I used Expressive's esptool.py successfully with all three of my programmers, the CH340 ESP-01S adapter, my makeshift ESP-01S programmer, as well as the built-in programmer in the NodeMCU ESP-12E Lua.

I had already upgraded my Slackware 14.2's python to version 2.7.11. This made installing esptools.py easy. Just do:

# pip install esptool

Download's Martin Ger's firmware/0x00000.bin and firmware/0x10000.bin from here. I started with the NodeMCU ESP-12E:

$esptool.py --port /dev/ttyUSB0 write_flash -fs 4MB -ff 80m -fm dio 0x00000 ./0x00000.bin 0x10000 ./0x10000.bin
esptool.py v2.4.1
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
MAC: 60:01:94:70:54:1b
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Flash params set to 0x024f
Compressed 37072 bytes to 25809...
Wrote 37072 bytes (25809 compressed) at 0x00000000 in 2.3 seconds (effective 126
.9 kbit/s)...
Hash of data verified.
Compressed 262916 bytes to 178828...
Wrote 262916 bytes (178828 compressed) at 0x00010000 in 15.8 seconds (effective
133.0 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

And that was it; it reset the ESP-12E and the firmware started without fuss.

My ESP-01S took a lot longer as the programming baud rate is only 9600. Remember to put the ESP-01S into 'program' mode manually:

$esptool.py --baud 9600 --port /dev/ttyUSB1 write_flash -fs 4MB -ff 80m -fm dio 0x00000 ./0x00000.bin 0x10000 ./0x10000.bin
esptool.py v2.4.1
Serial port /dev/ttyUSB1
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
MAC: ec:fa:bc:1c:c6:0d
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Flash params set to 0x024f
Compressed 38048 bytes to 26400...
Wrote 38048 bytes (26400 compressed) at 0x00000000 in 27.8 seconds (effective 11
.0 kbit/s)...
Hash of data verified.
Compressed 265860 bytes to 181152...
Wrote 265860 bytes (181152 compressed) at 0x00010000 in 190.5 seconds (effective
 11.2 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

Power-cycle (or reset) the ESP-01S to start the firmware running.

I had no problems accessing the WiFi repeater Access Point. It is a little slow, and my test youtube video stuttered a bit, but it played to completion. For IoT use, especially the built-in MQTT, it should be sufficient.

Happy Trails.


Tuesday 12 June 2018

Raspberry Pi Zero W as IoT Bluetooth Gateway Part3: Replacing Slackware with Raspbian

Something's missing ... yes the USB bluetooth dongle

Nowadays I use the iterative development method. Following Part 1 and Part 2, we used the Raspberry Pi Zero W as an IoT Bluetooth Gateway daily for about six months. It was more secure than using the smartphone to directly pair to the autogate bluetooth module HC-06 - the PIN is only 4 digits and easily brute-forced.. Using a WiFi repeater, its range was much better. We could now reliably operate the autogate without getting out of the car.

In addition the Pi Zero W gateway hogged the HC-06 all the time, and prevented any intruder from pairing to it. To gain access the intruder would now have to brute-force the WPA2 passphrase in the WiFi repeater, a much tougher opponent.

It also got turned on and off a lot to avoid being damaged by lightning, and sometimes it would fail to start up properly. This is usually due to HC-06 connectivity issues- perhaps it was not unpaired properly or was later that usual being discovered. This allowed the startup to be adjusted using my bash script in /etc/rc.d/rc.local.

Now that it was stable enough it was time to improve it further. From Part 2, Slackware 14.2 did not recognize the Raspberry Pi Zero W's builtin bluetooth module. Perhaps the Raspbian kernel I used was not current enough or perhaps my Slackware installation lacked something, but having to use an RM32 bluetooth dongle with an RM42.20 Raspberry Pi Zero W rankled.

I downloaded the Raspberry Pi NOOBS, and following the installation guide, installed the latest Raspbian OS into by Pi Zero W. Make sure to set up the WiFi connection to your broadband. The builtin bluetooth controller worked first time and had no trouble working with the HC-06 in the autogate. I repeated the procedure in Part 1, and upgraded the firmware/BIOS in the Slackware 14.1 image, but the builtin bluetooth controller did not come up.

Now I could have gone further and upgraded the Linux kernel as well, but perhaps it is time to work with Raspbian/Debian for a while. At least I would not have to keep up with the updates.

To use Raspbian for the IoT Bluetooth Gateway, I needed pymodbus, apache, and php. In Slackware, pymodbus needed upgrades to python 2.7, pip and pysetuptools. Checked in Raspbian:

root@raspi-0-w-2:/root# pip --version
pip 9.0.1 from /usr/lib/python2.7/dist-packages (python 2.7)
root@raspi-0-w-2:/root# python --version
Python 2.7.13

Now that was a pleasant surprise: no upgrades necessary. Now for pysetuptools: Make sure your WiFi connection is working before you try this:

root@raspi-0-w-2:/root# apt-get upgrade python-setuptools
Reading package lists... Done
Building dependency tree
Reading state information... Done
python-setuptools is already the newest version (33.1.1-1).
python-setuptools set to manually installed.
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Again, no upgrades necessary. Might as well go ahead with pymodbus:

root@raspi-0-w-2:/root# pip install -U pymodbus

Installed successfully, no fuss. Now my Modbus server program needed twisted, so:

root@raspi-0-w-2:/root# pip install twisted

No problems there. Also required is cryptography:

root@raspi-0-w-2:/root# pip install cryptography

Now for apache. Before that just to be sure I checked for upgrades to Raspbian:

root@raspi-0-w-2:/root# apt-get update

No upgrades necessary- I am beginning to like Debian. Now for apache:

root@raspi-0-w-2:/root# apt-get install apache2 -y

No fuss, apache ran right out of the box (check using http://localhost/index.html):

root@raspi-0-w-2:/root# find /var -name index.html
/var/www/html/index.html

root@raspi-0-w-2:/root# ps -ef
root     20567     2  0 14:14 ?        00:00:00 [kworker/0:3]
root     21396     1  0 14:16 ?        00:00:00 /usr/sbin/apache2 -k start
www-data 21398 21396  0 14:16 ?        00:00:00 /usr/sbin/apache2 -k start
www-data 21399 21396  0 14:16 ?        00:00:00 /usr/sbin/apache2 -k start
root     21723  1705  0 14:18 pts/1    00:00:00 ps -ef

Similarly, php just worked, striaght from the box:

root@raspi-0-w-2:/root# apt-get install libapache2-mod-php php

The web server was linked to pymodbus using the same method as before. Now Raspbian defaults to using dynamic IP, and ssh disabled, which is not very useful if you are using the Pi in "headless" (ie without monitor, mouse or keyboard). ssh is easily enabled via the Raspbian desktop or using raspi-config. To get it to use static IP simply add the following lines to /etc/dhcpcd.conf:

interface wlan0
static ip_address=192.168.1.2/24
static routers=192.168.1.1
static domain_name_servers=8.8.8.8

Lastly Raspbian uses the much improved bluetoothctl, which is an interactive program and not easily included in a bash script like bluez. Luckily Linux has just the thing we need: 'expect' can be used to fool bluetoothctl into thinking it is interacting with a human via the keyboard.

root@raspi-0-w-2:/root# apt-get install expect

Put it in a little bash script and you have a much more robust startup script than simple-agent:

root@raspi-0-w-2:/root# cat ./hc-06.sh
#!/usr/bin/expect -f

set prompt "#"
set address [lindex $argv 0]

spawn sudo bluetoothctl -a
expect -re $prompt
send "remove $address\r"
sleep 1
expect -re $prompt
send "scan on\r"
send_user "\nSleeping\r"
sleep 5
send_user "\nDone waiting for controller\r"
expect "Controller"
send_user "\nSleeping ... waiting for autogate\r"
sleep 5
send_user "\nDone waiting for autogate\r"
expect "HC-06"
send "scan off\r"
send "trust $address\r"
sleep 2
send "pair $address\r"
sleep 2
send "0000\r"
sleep 3
send_user "\nShould be paired now.\r"
send "quit\r"
expect eof

Note: replace '0000' with your password and launch the script thus:

root@raspi-0-w-2:/root# ./hc-06.sh 12:34:56:78:9A:BC

Lastly bind to your bluetooth device to get the serial port /dev/rfcomm0:
rfcomm bind 0 12:34:56:78:9A:BC 1

And you are ready for the pymodbus program, which I launched in the background and captured its output to a log file:

root@raspi-0-w-2:/root# python ./autogate_server.py >> ./autogate.log 2>> ./autogate.log &

Raspbian turned out to be quite pleasant to use, but then it is Linux, so we expect nothing less. 

Happy Trails.