Monday, July 20, 2020

Micropython on the Air602

Lately I have been forgetting to close my garage door. Not fun to find it open in the morning, and wondering if some of my tools might have walked off. There are automatic closers available, but there are times I want to leave the garage open, so I wanted a better solution.

My first attempt was to place a (reverse) push button in the wall above the door, so it would trigger when the door closes. Then I wired it through the wall and put an LED inside the house. I used DC current from the electric eye circuit for the garage door opener. I couldn't draw too much current or the electric eye would trigger and I couldn't close the door. Unfortunately, the LED was not bright enough, and I would sometimes not notice it when I went to bed.

What I really needed was a light in my bedroom at the other end of the house. Now there's no way I'm going to run a wire all that way, so I needed a wireless solution that could be powered from a wall outlet in the garage. Enter the Air602.

The Air602 Development Board is basically a computer the size of a postage stamp with WiFi support that plugs into a USB slot. It's based on the W600 SoC. I can power it with a USB wall charger. It costs only $3 from Seeed Studio but 2 week shipping from China costs $20.

The board comes loaded with a firmware called "AT Instructions Firmware". You can pop the board into a USB slot in your computer, and use a terminal emulator (I used Putty) to connect to the COM port. You may need the CH340 driver. Then type unintelligible commands like AT+WPRT=0 to connect the WiFi and do rudimentary things. The documentation for the AT commands is translated from Chinese, and is usable, but not much fun.

To load a better firmware, we need to enter ROM bootloader mode. This is accomplished with the AT command AT+&FLSW=5000,11 . The firmware can be loaded using a python package called w600tool. For more complete details, visit Get started with MicroPython [W600 series]. Note it can be tricky to push the reset button without disconnecting the USB.

I am using the micropython firmware. When it boots, micropython looks for user code in script called main.py, so we need a way to access the file system. I use pyboard.py which works for the W600 with minor modifications. Specifically, the W600 returns a different number of carriage returns when it communicates, so you have to modify a half dozen strings in pyboard.py . Here's a python script (that runs on the PC) to upload main.py, print a directory from the device, and print the error log:


import pyboard

pyb = pyboard.Pyboard('COM3', 115200)
pyb.enter_raw_repl()
pyb.fs_put('main.py', 'main.py')
pyb.fs_ls(None)
pyb.fs_cat('error.log')
pyb.exit_raw_repl()

print('done')


If you mishandle the board in the USB slot, you may corrupt the file system. You can see this with the fs_ls() command. If this happens, you will need to erase user data with the w600tool and reload the firmware. If you get an error "ENOENT", you have specified a file that doesn't exist.

The Air602 comes with 6 IO pins. I'm using GPIO to tell if the button in my garage door is pushed. The python code to activate the GPIO pin is

pin = Pin(Pin.PB_08, Pin.IN, Pin.PULL_UP)

Note that the PULL_UP resistance is internal and the board does not support PULL_DOWN.

My next challenge requires some explanation. The device runs an infinite loop to call a windows service on my PC. If it can't connect, or has some other problem, it logs an error to its log file. This is expected to happen occasionally. The file system is not huge, so I erase the old log when the device boots. To read the log file, I have to plug the device into the computer, but at that moment the device will boot and run the program and erase the log file. Furthermore, I can't even run the pyboard command to download the error log because the device does not multiprocess. Pyboard just waits forever for the program to complete.

To solve this, I check another GPIO pin before erasing the log file. If I insert the device into the PC with one of the other IO pins grounded, the startup program will append a message to the log and exit.

I won't give the code for the Windows service. It is straightforward if you know those things. At any time, if it received a message in the last minute that the garage door is closed, it turns off a Wemo smart plug attached to a nightlight in my bedroom, otherwise it turns it on. The Wemos have a SOAP interface that has been reverse engineered.

Finally, I 3D printed a case for the Air602. Here is the finished product: