Sunday 21 January 2018

Raspberry Pi Zero W as IoT Bluetooth Gateway Part2: Replacing the Laptop

Raspberry Pi Zero W as Bluetooth IoT Gateway installed in the front porch
The original Bluetooth Autogate Remote used a recycled Acer Aspire F15 laptop as an IoT gateway. The laptop ran an Apache webserver for the html/php program. This went very well until a fortnight ago when we had a cool rainy spell and the garden got waterlogged, which always seem to affect wireless communications at the Autogate control box located in the gatepost.

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 StrengthTL;DRRequired for
-30 dBmAmazingMax 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 dBmVery GoodMinimum signal strength for applications that require very reliable, timely delivery of data packets.VoIP/VoWiFi, streaming video
-70 dBmOkayMinimum signal strength for reliable packet delivery.Email, web
-80 dBmNot GoodMinimum signal strength for basic connectivity. Packet delivery may be unreliable.N/A
-90 dBmUnusableApproaching 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

These files were really a set (startup.elf needed fixup.dat and so on) and in my case I had start.elf but not fixup.dat. In addition I was missing the file:
-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 &

Friday 19 January 2018

Raspberry Pi Zero W as IoT Bluetooth Gateway Part1: Installing Slackware

Power connector is micro USB on far right
I ordered in quick succession a NodeMCU ESP-12E and a Raspberry Pi Zero W. Both came very quickly but the Zero W got off the ground first.

I powered it using its micro USB socket (far right in above picture) with my favourite Slackware distribution in micro SD card, and nothing happened. It drew only 20-30mA current. I used a feisty 2A Samsung USB charger that put out 5.2V.

I had expected a little power LED at the very least. A little concerned I might have got a dud, I shorted the bare 'reset' PCB vias using a pair of steel tweezers.
'Reset' PCB vias (bottom left) marked 'RUN'
Again, nothing.  After 30 years of electronics you get used to having your blinkenlights, chief amongst them is your 'Power' LED.
The usual rats' nest

As a last resort, and just because I had a Sandisk Class 10 32GB microSD card, I loaded it with Ubuntu Mate, a recent Linux distribution for the Raspberry Pi B. And, bingo, after a few seconds I have my little green light. 

So instead of connecting a 'Power' LED directly to the power supply (usually in series with a current-limiting resistor) the designers must have used the CPU's GPIO pin to turn on the power LED. This kind of works, but makes it a little harder to troubleshoot power supply problems, and the Raspberry Pi has no shortage of those.

Nothing much happened after the power LED came on. No WiFi access point, no bluetooth device came up. Hmmm. I bought a mini HDMI adapter and hooked it up to my monitor and, aha, I have a 'kernel panic- Attempted to kill init!' message. Looks like Ubuntu Mate does not run on the Pi Zero W. This is confirmed by this handy article. Rather, the Pi Zero W (and its close relative the Zero) is compatible with the older Raspberry Pi A and A+.

Time to try my trusty Slackware 14.1 Raspberry Pi image. A few years ago I got Slackware running on the Raspberry Pi A by using an Ubuntu kernel with a Slackware root filesystem. I loaded it into my new microSD card, powered up, and nothing happened. No blinkenlight. Not even a kernel panic. Time to dig a little deeper.

A look at my Slackware image showed it consisted of 2 partitions, a Windows-type FAT32 boot partition and a much larger Linux ext4 root partition.

The Windows FAT32 boot partition looks like this:

$ls -l ../slackware/boot
total 31076
-rwxr-xr-x 1 root root     1447 Jan 19 15:29 LICENCE.broadcom
-rwxr-xr-x 1 root root     2013 Jan 19 15:29 README
-rwxr-xr-x 1 root root     1479 Jan 19 15:29 README.initrd
-rwxr-xr-x 1 root root   777094 Jan 19 15:29 System.map
-rwxr-xr-x 1 root root    16536 Jan 19 15:29 bootcode.bin
-rwxr-xr-x 1 root root       82 Jan 19 15:29 cmdline.txt
-rwxr-xr-x 1 root root       91 Jan 19 15:29 config.txt
-rwxr-xr-x 1 root root     5282 Jan 19 15:29 fixup.dat
-rwxr-xr-x 1 root root     2020 Jan 19 15:29 fixup_cd.dat
-rwxr-xr-x 1 root root      137 Jan 19 15:29 issue.txt
-rwxr-xr-x 1 root root  3112676 Jan 19 15:29 kernel.img
-rwxr-xr-x 1 root root  2104952 Jan 19 15:29 kernel_cutdown.img
-rwxr-xr-x 1 root root 16264692 Jan 19 15:29 kernel_emergency.img
-rwxr-xr-x 1 root root   275235 Jan 19 15:29 loader.bin
-rwxr-xr-x 1 root root  2011408 Jan 19 15:29 start.elf
-rwxr-xr-x 1 root root   523144 Jan 19 15:29 start_cd.elf
-rwxr-xr-x 1 root root      101 Jan 19 15:29 version-kernel_raspi.txt
-rwxr-xr-x 1 root root       92 Jan 19 15:29 version-raspi-boot.txt

And an ext4 Slackware 14.1 root partition:

$ls -l ../slackware/root
total 164
drwxr-xr-x  2 root root  4096 Jan 19 15:30 bin
drwxr-xr-x  2 root root  4096 Jan 19 15:30 boot
drwxr-xr-x 17 root root 69632 Jan 19 15:30 dev
drwxr-xr-x  3 root root  4096 Jan 19 15:30 doc
drwxr-xr-x 89 root root 12288 Jan 19 15:30 etc
drwxr-xr-x  6 root root  4096 Jan 19 15:30 home
drwxr-xr-x  7 root root  4096 Jan 19 15:30 lib
drwx------  2 root root  4096 Jan 19 15:30 lost+found
drwxr-xr-x 16 root root  4096 Jan 19 15:30 media
drwxr-xr-x 11 root root  4096 Jan 19 15:30 mnt
drwxr-xr-x  2 root root  4096 Jan 19 15:30 opt
drwxr-xr-x  2 root root  4096 Jan 19 15:30 proc
drwx--x---  9 root root  4096 Jan 19 15:30 root
drwxr-xr-x  2 root root  4096 Jan 19 15:30 run
drwxr-xr-x  2 root root 12288 Jan 19 15:30 sbin
drwxr-xr-x  2 root root  4096 Jan 19 15:30 srv
drwxr-xr-x  2 root root  4096 Jan 19 15:30 sys
drwxr-xr-t  5 root root  4096 Jan 19 15:30 tmp
drwxr-xr-x 20 root root  4096 Jan 19 15:40 usr
drwxr-xr-x 18 root root  4096 Jan 19 15:41 var

A quick look at the Ubuntu Mate image showed a similar organization, a FAT32 boot partition followed by a Linux ext4 root partition. The boot partition is:

$ls -l ../ubuntu_mate/flash
total 20432
-rwxr-xr-x 1 root root   18693 Jan 19 15:11 COPYING.linux
-rwxr-xr-x 1 root root    1494 Jan 19 15:11 LICENCE.broadcom
-rwxr-xr-x 1 root root   14273 Jan 19 15:11 bcm2708-rpi-b-plus.dtb
-rwxr-xr-x 1 root root   14010 Jan 19 15:11 bcm2708-rpi-b.dtb
-rwxr-xr-x 1 root root   13964 Jan 19 15:11 bcm2708-rpi-cm.dtb
-rwxr-xr-x 1 root root   15356 Jan 19 15:11 bcm2709-rpi-2-b.dtb
-rwxr-xr-x 1 root root   15992 Jan 19 15:11 bcm2710-rpi-3-b.dtb
-rwxr-xr-x 1 root root   15350 Jan 19 15:11 bcm2710-rpi-cm3.dtb
-rwxr-xr-x 1 root root   17932 Jan 19 15:11 bootcode.bin
-rwxr-xr-x 1 root root     223 Jan 19 15:11 cmdline.txt
-rwxr-xr-x 1 root root   36783 Jan 19 15:11 config.txt
-rwxr-xr-x 1 root root    6622 Jan 19 15:11 fixup.dat
-rwxr-xr-x 1 root root    2535 Jan 19 15:11 fixup_cd.dat
-rwxr-xr-x 1 root root    9753 Jan 19 15:11 fixup_db.dat
-rwxr-xr-x 1 root root    9753 Jan 19 15:11 fixup_x.dat
-rwxr-xr-x 1 root root 4130008 Jan 19 15:11 kernel.img
-rwxr-xr-x 1 root root 4231256 Jan 19 15:11 kernel7.img
drwxr-xr-x 2 root root    4096 Jan 19 15:11 overlays
-rwxr-xr-x 1 root root 2823396 Jan 19 15:11 start.elf
-rwxr-xr-x 1 root root  634532 Jan 19 15:11 start_cd.elf
-rwxr-xr-x 1 root root 4956996 Jan 19 15:11 start_db.elf
-rwxr-xr-x 1 root root 3906116 Jan 19 15:11 start_x.elf

In an old-fashioned desktop or laptop, the startup process is controlled by a non-volatile flash, eeprom or eprom program called the BIOS. The ARM CPU in the Pi has a much smaller BIOS and has the rest of it stored on the microSD card. Now since I got a kernel panic from Ubuntu Mate, this meant that the ARM CPU managed to load the kernel and run it, only to have the kernel fail later. Since it is the job of the BIOS to load the kernel, this mean my Ubuntu Mate image had the correct BIOS files.

This link provides a good summary: 

The boot sequence of the Raspberry Pi is basically this:

  1. Stage 1 boot is in the on-chip ROM. Loads Stage 2 in the L2 cache
  2. Stage 2 is bootcode.bin. Enables SDRAM and loads Stage 3
  3. Stage 3 is loader.bin. It knows about the .elf format and loads start.elf
  4. start.elf loads kernel.img. It then also reads config.txtcmdline.txt and bcm2835.dtb If the dtb file exists, it is loaded at 0×100 & kernel @ 0×8000 If disable_commandline_tags is set it loads kernel @ 0×0 Otherwise it loads kernel @ 0×8000 and put ATAGS at 0×100
  5. kernel.img is then run on the ARM.

The Ubuntu Mate image did not have loader.bin or bcm2835.dtb but it did have a kernel7.img in addition to the kernel.img file.  So I copied the files bootloader.bin, start.elf, kernel.img and kernel7.img over to my Slackware image, taking care to keep my Slackware config.txt and cmdline.txt. Since the Slackware image did not have any dtb files at all, I copied them as well.

Updated 2018-01-21. See next post for corrections to files list.

Now the image worked, and Slackware was able to start. A little problem is it did not recognize the WiFi hardware and its WiFi interface did not come up. But that is a problem for another post.


If you would like to run Slackware on your Raspberry Pi Zero or Zero W, leave me a comment in this blog post and I will put up the 8GB image for download.  

Happy Trails.

Thursday 11 January 2018

The ESP8266 NodeMCU: the ultimate IoT system?

NodeMCU ESP-12E Development Kit
In my previous posts I started making IoT devices from full Linux systems, like the Raspberry Pi solar battery voltmeter. Then we progressed to a bluetooth sensor/actuator with a Linux IoT gateway like the IoT Autogate remote.

The NodeMCU development kit promises to provide both: a remote sensor/actuator that provides it own WiFi IoT gateway. The NodeMCU is open source firmware based on Expressif System's ESP8266, a System-on-a-Chip (SoC) which has an 80MHz  32-bit Tensilica CPU paired with a full-stack WiFi networking at an extraordinarily low cost. The Lua ESP-12E NodeMCU costs a mere RM21.80

ESP-12E prices online in Malaysia
Watch out for the ESP-12E V1, and V2 versions; their physical sizes are different! There is a write-up here.

Be careful of the ESP-12 V1 and V2 differences

While my previous Microchip PIC18F14K50 plus Arduino HC-06 IoT can be commercialized, no one else has done it like that. The reason may be something like the ESP8266. ITEAD's Sonoff mains power switches and sockets actually uses the ESP8266.

I am starting with the ESP-01 and a CH340 USB to RS232 TTL dongle. Just because I happen to have them lying around. Okay maybe it was because the ESP-01 cost me a mere RM14. The CH340 is even better at RM7.90.
Earlier ESP modules


ESP-01 at RM14
CH340 at RM7.90

The ESP-01 and CH340 setup provides a bridge from my Linux comfort zone to explore the ESP8266, after which I fully expect the ESP8266 to be a standalone IoT system. For this I will need NodeMCU, which is the software framework to base future IoT work.

First we plug the CH340 dongle into my laptop. Slackware 14.2 Linux recognized the device immediately:

[Tue Jan  9 06:38:49 2018] usb 1-4.5.4: new full-speed USB device number 113 using xhci_hcd
[Tue Jan  9 06:38:49 2018] usb 1-4.5.4: New USB device found, idVendor=1a86, idProduct=7523
[Tue Jan  9 06:38:49 2018] usb 1-4.5.4: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[Tue Jan  9 06:38:49 2018] usb 1-4.5.4: Product: USB2.0-Serial
[Tue Jan  9 06:38:50 2018] usbcore: registered new interface driver usbserial
[Tue Jan  9 06:38:50 2018] usbcore: registered new interface driver usbserial_generic
[Tue Jan  9 06:38:50 2018] usbserial: USB Serial support registered for generic
[Tue Jan  9 06:38:50 2018] usbcore: registered new interface driver ch341
[Tue Jan  9 06:38:50 2018] usbserial: USB Serial support registered for ch341-uart
[Tue Jan  9 06:38:50 2018] ch341 1-4.5.4:1.0: ch341-uart converter detected
[Tue Jan  9 06:38:50 2018] usb 1-4.5.4: ch341-uart converter now attached to ttyUSB0

The pinouts are:



The wiring will be (in format ESP-01 to CH340):

RX to TX, VCC to VCC, GPIO0 to VCC (Note this is different from the following picture), RST to GND, GPIO2 No connection (N/C), CH_PD to VCC, GND to GND, and TX to RX.

Next I will need to make a cable to connect the ESP-01. The connection should be similar to that for the other USB to serial dongle, the FTDI:
The ESP-01 and the FTDI USB to Serial TTL dongle. Note GPIO0 should be high and not as shown.
The ESP-01 will draw power from the CH340 which in turn gets its power from the laptop's USB socket. The important thing to remember is the ESP-01 is a 3.3V device. Luckily the CH340 (like the PIC18F14K50) can be set to run at 3.3V. The ESP-01 can draw a non-trivial 170mA(a typical external USB drive will draw 300mA), so I plan to use the laptop's USB2 connector and connect the setup via an externally-powered DLINK USB hub as a backup and for additional safety.

I powered on, and ... nothing happened. Oh the power LED in the CH340 came on. So did the red power LED in the ESP-01. Now disconnect RST from GND and the ESP-01's blue LED flashed like it was supposed to, but the CH340 would not respond. Its Linux device file, /dev/ttyUSB0 would come up when the CH340 is powered on.

But when I hooked up the ESP-01 the file disappeared.

[Wed Jan 10 12:23:34 2018] usb 1-4.5.4: USB disconnect, device number 38
[Wed Jan 10 12:23:34 2018] ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
[Wed Jan 10 12:23:34 2018] ch341 1-4.5.4:1.0: device disconnected

The ESP-01 appeared OK though and I noticed a new WiFi Access Point had appeared:

          Cell 05 - Address: 5E:CF:7F:FD:1D:EB
                    Channel:1
                    Frequency:2.412 GHz (Channel 1)
                    Quality=70/70  Signal level=-23 dBm
                    Encryption key:off
                    ESSID:"AI-THINKER_FD1DEB"
                    Bit Rates:5.5 Mb/s; 11 Mb/s; 1 Mb/s; 2 Mb/s; 6 Mb/s
                              12 Mb/s; 24 Mb/s; 48 Mb/s
                    Bit Rates:54 Mb/s; 9 Mb/s; 18 Mb/s; 36 Mb/s
                    Mode:Master
                    Extra:tsf=00000000027d8f4a
                    Extra: Last beacon: 5705ms ago
                    IE: Unknown: 001141492D5448494E4B45525F464431444542
                    IE: Unknown: 01088B9682840C183060
                    IE: Unknown: 030101
                    IE: Unknown: 32046C122448
                    IE: Unknown: DD0918FE34030100000000

I could connected the laptop to it, as there is no password required, and once in a little probing showed an active IP address 192.168.4.1:

$nmap -O 192.168.4.1-254

Starting Nmap 7.12 ( https://nmap.org ) at 2018-01-10 20:14 MYT
Nmap scan report for 192.168.4.1
Host is up (0.0010s latency).
All 1000 scanned ports on 192.168.4.1 are closed
MAC Address: 5E:CF:7F:FD:1D:EB (Unknown)
Warning: OSScan results may be unreliable because we could not find at least 1 o
pen and 1 closed port
Aggressive OS guesses: Philips Hue Bridge (lwIP stack v1.4.0) (95%), 2N Helios I
P VoIP doorbell (91%), Advanced Illumination DCS-100E lighting controller (91%),
 British Gas GS-Z3 data logger (91%), Espressif WiFi system-on-a-chip (91%), Gra
ndstream GXP1105 VoIP phone (91%), LaSAT satellite receiver (91%), lwIP 1.4.0 li
ghtweight TCP/IP stack (91%), m3 muvid IR 715-2 Internet radio receiver (91%), M
ilight WiFi Receiver bridge (91%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 1 hop

Voltage seems normal at 3.3V and only 70mA current was being drawn. A little digging in the datasheets of the ESP8266 and CH340 showed the minimum operating voltage of the ESP8266 was 3V and the CH340 3.3V. It is possible that on power up the power surge of the ESP8266 dragged the voltage down enough for the CH340 to panic and go to bed, but I could not be sure without hooking up the oscilloscope.

Instead I popped out one of those deliciously cheap Arduino LM2596 buck converters and set it to take in 5V and put out 3.3V just for the ESP8266. I now needed to connect the GND of the CH340 and the ESP8266 to provide a common signal reference, and did not change any other connections.
Rats' nest: clockwise from top LM2956, CH340 and ESP-01

I connected the CH340 to my laptop, and ran minicom, setting it to /dev/ttyUSB0 and baud rate 115200. And lo and behold, on turning on the ESP-01:

ESP-01 screen on power on
And just to make sure it is no fluke I type 'AT' followed by Ctrl-M and Ctrl-J, and it replied with 'OK'.

And to connect it to the Internet like any good IoT device (the commands are in bold and the ESP-01's replies in normal font; at the end of every command line type Ctrl-M and Ctrl-J):

AT

OK
AT+CWMODE=3

OK
AT+CWLAP
+CWLAP:(1,"AP1",-83,"xx::xx::xx:xx:xx:xx",1,-17,0)
+CWLAP:(3,"......",-80,"yy:yy:yy:yy:yy:yy",8,-21,0)
+CWLAP:(3,"AP2",-65,"zz:zz:zz:zz:zz:zz",9,-14,0)

AT+CWJAP="AT2","verysecretpassword"
WIFI CONNECTED
WIFI GOT IP

OK

AT+CIFSR
+CIFSR:APIP,"192.168.4.1"
+CIFSR:APMAC,"5e:cf:7f:fd:1d:eb"
+CIFSR:STAIP,"172.16.1.105"
+CIFSR:STAMAC,"5c:cf:7f:fd:1d:eb"

OK

It connected to my home WiFi network, assigned it an IP address different from its own () access point; 172.16.1.105. And to make doubly sure we launch a network probe at the new IP address:

$nmap -O 172.16.1.105

Starting Nmap 7.12 ( https://nmap.org ) at 2018-01-11 19:39 MYT                 
Nmap scan report for 172.16.1.105                                               
Host is up (0.012s latency).
All 1000 scanned ports on 172.16.1.105 are closed                               
MAC Address: 70:62:B8:A9:C0:CA (D-Link International)
Warning: OSScan results may be unreliable because we could not find at least 1 o
pen and 1 closed port
Aggressive OS guesses: Philips Hue Bridge (lwIP stack v1.4.0) (95%), 2N Helios I
P VoIP doorbell (91%), Advanced Illumination DCS-100E lighting controller (91%),
 British Gas GS-Z3 data logger (91%), Espressif WiFi system-on-a-chip (91%), Gra
ndstream GXP1105 VoIP phone (91%), LaSAT satellite receiver (91%), lwIP 1.4.0 li
ghtweight TCP/IP stack (91%), m3 muvid IR 715-2 Internet radio receiver (91%), M
ilight WiFi Receiver bridge (91%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 1 hop

OS detection performed. Please report any incorrect results at https://nmap.org/
submit/ .
Nmap done: 1 IP address (1 host up) scanned in 4.43 second

And there you have it. The ESP-01 with its ESP8266 SoC certainly lived up to its reputation. Next I shall try to program it to control a relay from WiFi, much like the IoT bluetooth Autogate Remote project.

Happy trails.