These notes are about my first encounter with the Wemos W600-Pico development board that has been available for about 3 years. As is often the case here, this will be an idiosyncratic review. I want to quickly build a Wi-Fi switch that is compatible with my home automation system running on Domoticz. Is it possible to easily mimic a Sonoff Basic based on the Micro Winner W600 module instead of an ESP8266/8285 module? I'll cut to the chase, the answer is yes, after the usual teething problems when approaching something new.
Only read this post if it is necessary to use the MicroPython version supplied with the W600-PICO (version 1.10). A much more recent version of MicroPython is available. Of course, that newer version must be flashed on the board. However, learning to upload the firmware to the W600-PICO is inevitable, so there is no real value in using the original version of MicroPython.
Table of Contents
- The Brief
- The W600-Pico Development Board
- Flashing the MicroPython Firmware
- The Read-eval-print Loop (REPL)
- The FTP Server
- A Blink Example
- A Custom
boot.py
- Polling a Button
- Wi-Fi Switch - Proof of Concept
The Brief
The brief, in the UK usage of the term, meaning a set of instructions that outlines the tasks to be performed, follows.
- Ascertain how digital I/O is done with the W600.
- Use I/O pins as outputs to control an indicator LED and a relay.
- Use an I/O pin as in input to monitor the state of a push button.
- Ascertain how to connect to a Wi-Fi network.
- Ascertain how to publish and subscribe to an MQTT broker.
Once those elements have been dealt with, it will be possible to use the W600-Pico as a Wi-Fi switch that can be turned on and off remotely with the Domoticz home automation system. Furthermore, the relay can be controlled locally with the button and the state of the corresponding home automation virtual switch will be updated automatically.
Before getting to that final destination, it is necessary to learn a bit about the development board and MicroPython which is the obvious choice for programming the board for reasons explained below.
The W600-Pico Development Board>
Is it too obvious to say that the W600-Pico dev board is based on the Winner Micro W600? That microcontroller has a 32-bit ARM M3 processor running at 80 MHz. It comes with 288 KiB of RAM and up to 1 MiB of integrated flash memory. Presenting itself as a cheaper alternative to the Espressif ESP8266 or rather the ESP8285 given its integrated flash memory, it has 2.4 GHz Wi-Fi (802.11b/g/n) wireless connectivity. It also has multiple interfaces: SDIO, SPI, UART, GPIO, I²C, PWM, I²S and so on. This is just a first look at the chip so I will not investigate those capabilities at this time. Here is the pinout of the W600-Pico from Wemos.
The microcontroller on the board is labelled W600-B800. According to the datasheet, this identifies a revision B chip with 1 MiByte of integrated flash memory.
When boards based on the W600 appeared around 2019, they garnered some interest for a year or so and then it waned considerably. Now, contrary to the ESP8266 (or other products from Espressif), there is only a small community coalesced around this chip creating a classic chicken and egg scenario. Hobbyists are less attracted to the device because few hobbyists are using it. Consequently I have relied mostly on three rather old sources for information.
- Get started with MicroPython [W600 series]
- Microcontroller Monday - Wemos W600 Pico by Les Pounder
- W60X MicroPython User Guide V0.3 by the Beijing Winner Microelectronics Co.
There is a two year old software development kit (SDK) from Winner Micro and an unofficial repository based on the 3.04 SDK. However aside from what appears to be an ill-fated attempt at creating an Arduino core, there is no simple way to program the chip in neither the Arduino IDE nor PlatformIO. If there is no strong desire to go through the complicated procedure to install an SDK and to learn how to use it, then using MicroPython which comes preinstalled on the W600-Pico seems to be the only avenue for the hobbyist of my ilk. The Wemos site dedicated to the W600-Pico has a link to the MicroPython firmware V1.10, but that is actually a Winner Micro fork, released on Jan 25, 2019, of version 1.10 of the MicroPython implementation. About 3 months later, wdyichen made a "pull" request to the Micro Python team asking that the Micro Winner W600 be added to the supported ports. From what I can gather, nothing came of that because of the lack of interest in the W600 at the time and the difficulty in implement TLS in the 1 MB memory.
There is a MicroPython port to the W60X by Robert Hammelrath (robert-hh) that is very active. is no release right now, so it would be necessary to install the toolchain to compile the interpreter and then flash the firmware to the dev board. While the last step is rather easy as explained in the next section, I did not want to invest the time and effort needed to compile a binary right now. Perhaps at a later date. New Information: I was wrong back in April, Robert Hammelrath (robert-hh) has released and maintains the image files of various ports of the current MicroPython version in his Shared-Stuff repository. Expect an update of this post at the start of 2023 that will use MicroPython 1.19.
Flashing the MicroPython Firmware
MicroPythons is something new to me and, furthermore, my knowledge of Python leaves a lot to be desired. Unfortunately, I can easily put the board into a tight loop where it seems impossible to get control back. At various times the situation seemed hopeless, and I had to resort to erasing all the flash memory and reinstalling the MicroPython firmware. Here are instructions on how to do that if you ever find yourself in that pickle. It is not necessary to install the tools to do that as explained in the rest of this section, just see this as insurance in case something goes horribly wrong.
Start by installing w600tool by Volodymyr Shymanskyy (vshymanskyy) which is the firmware flashing tool. It is a Python script with some prerequisites. As usual in such a case I prefer installing the tool in a virtual environment. Below I use my bash script from Python 3 virtual environments, but there are other ways of implementing this same idea.
- Create a virtual environment.
michel@hp:~$ mkvenv w600tool creating virtual environment /home/michel/w600tool updating virtual environment /home/michel/w600tool
- Enable the virtual environment and install prerequisites.
michel@hp:~$ ve w600tool (w600tool) michel@hp:~$ cd w600tool/ (w600tool) michel@hp:~/w600tool$ pip install pyserial PyPrind xmodem Collecting pyserial Using cached pyserial-3.5-py2.py3-none-any.whl (90 kB) Collecting PyPrind Downloading PyPrind-2.11.3-py2.py3-none-any.whl (8.4 kB) Collecting xmodem Downloading xmodem-0.4.6.tar.gz (32 kB) Preparing metadata (setup.py) ... done Building wheels for collected packages: xmodem Building wheel for xmodem (setup.py) ... done Created wheel for xmodem: filename=xmodem-0.4.6-py3-none-any.whl size=34564 sha256=9bf5b6a98f495bba128bc93fd6865e113b12b4aeaa78aff340b3a41692e95768 Stored in directory: /home/michel/.cache/pip/wheels/8a/46/14/833413574281b7009c9180fce7c595a7cc1b538e43fcd8b7e7 Successfully built xmodem Installing collected packages: xmodem, pyserial, PyPrind Successfully installed PyPrind-2.11.3 pyserial-3.5 xmodem-0.4.6
- Download the script from the GitHub repository.
(w600tool) michel@hp:~/w600tool$ wget https://raw.githubusercontent.com/vshymanskyy/w600tool/master/w600tool.py ... 2022-04-21 17:08:44 (6,11 MB/s) - «w600tool.py» enregistré [6441/6441]
- Make the script executable.
(w600tool) michel@hp:~/w600tool$ chmod +x w600tool.py (w600tool) michel@hp:~/w600tool$ ls -l w6* -rwxrwxr-x 1 michel michel 6441 avr 21 17:08 w600tool.py
- Check that the script can reach the W600-Pico.
(w600tool) michel@hp:~/w600tool$ ./w600tool.py -p /dev/ttyUSB0 -b 115200 --get-mac Opening device: /dev/ttyUSB0 MAC: 286DCD2C7E89
- Obtain the Micropython firmware for the board.
See Flash firmware at Wemos' Get started with MicroPython [W600 series]. It is a link to an archive on the Micro Winner site that contains the firmware in two formats.(w600tool) michel@hp:~/w600tool$ wget http://www.winnermicro.com/upload/1/editor/1568709203932.zip -O micropython_v1.10.zip ... 2022-04-21 17:31:46 (198 KB/s) - «micropython_v1.10.zip» enregistré [676412/676412] (w600tool) michel@hp:~/w600tool$ unzip -l micropython_v1.10.zip Archive: micropython_v1.10.zip Length Date Time Name --------- ---------- ----- ---- 0 2019-09-17 11:39 W60X_MicroPython_1.10_B1.3_IMG/ 541180 2019-09-17 11:35 W60X_MicroPython_1.10_B1.3_IMG/wm_w600.fls 334480 2019-09-17 11:35 W60X_MicroPython_1.10_B1.3_IMG/wm_w600_gz.img --------- ------- 875660 3 files - Extract the
.fls
format image of the firmware; the W600-Pico cannot handle the compressed image.w600tool) michel@hp:~/w600tool$ unzip -j micropython_v1.10.zip W60X_MicroPython_1.10_B1.3_IMG/wm_w600.fls Archive: micropython_v1.10.zip inflating: wm_w600.fls
No matter if the board is in a "bricked" state or not, it should be possible to erase the flash memory and upload the original MicroPython firmware.
At times one will be requested to Push reset button to enter bootloader...
. And that's it, the W600-Pico will be back to the state it had when it left the factory. How did I know to upload to port /dev/ttyUSB0
? That's explained at the start of the next section.
It is not really necessary to enable the virtual environment to execute the flash tool. All that is necessary to execute the script is to launch the correct Python interpreter found the virtual environment.
Using that fact, I wrote the following short little bash script to avoid having to type that very long command.
That script, named flashW600
, made executable, and stored in the search path, provides a simple means to flash the MicroPython firmware. With that knowledge, it is now safe to embark on an exploration of board confident that we can always recover from a big mistake.
The latest (2022-12-15) non-threading version can be dowloaded from the Robert Hammelrath (robert-hh) Shared-Stuff repository.
That single download replaces steps 6 and 7. Of course, the *.fls
image file name would have to be adjusted in the commands and bash scripts. More importantly, much of what follows would not work properly with the newer version of the firmware without adjustments. Hopefully an amended version of this post will be available soon in the new year to take advantage of the updated MicroPython interpreter.
The Read-eval-print Loop (REPL)
Start monitoring the device manager and then plug the USB (data and power) cable from the Linux system to the W600-Pico.
Press the CtrlC key combination to close the monitor. Clearly, a USB device attached to ttyUSB0
was added. That clever way of finding the device assigned to the USB-serial converter on the board was suggested by Les Pounder. Alternatively, the device can be found in the usual fashion. The onboard USB to serial converter is a CH340 and these usually show up as a ttyUSBx
device. Sometimes, microcontrollers show up as a ttyACMx
device, so let's check both.
I used uc
from the venerable uucp
package as a terminal, others may prefer minicom
, screen
and so on. Once the serial connection is established, I was running in the MicroPyton read-eval-print loop (REPL).
Following the advice, I typed help()
.
Based on the above, let's turn the built-in LED on.
As can be seen, the LED is connected to pin PA0 and is turned on by writing a 0 to the pin, which means it is grounded to 0 volts. Writing a 1, turns the LED off. Those coming from the Arduino world might be surprised by the third mandatory parameter. Even when an I/O pin is set in the output mode, it is necessary to specify if a pull up or pull down resistor or in this case if neither is engaged.
There's a list of available built in modules.
So there is a network
module that, as already seen, can be used to connect to a WiFi network and a JSON module. With an MQTT module, it will be possible to create a WiFi switch.
The FTP Server
Looking at the list of built-in modules, it is not obvious that there is an FTP server. It is in the w600
module.
That the board can run an FTP server is important because the REPL is a rather primitive development environment. With the FTP server it will be possible to upload other Python modules (such as an MQTT module) that can be imported into the main.py
module. We can also create a main.py
Python script with a preferred text editor on the desktop machine and upload it to the board.
At the risk of repeating myself, it is easy to break things in this environment, so I wrote a little script that can be copied and pasted at the REPL prompt to restore the FTP server.
Once the server is in place, the IP address and the FTP user name and password are displayed in the REPL. Note the use of wlan.ifconfig()
to set a static IP address which makes it easier to set up tools to work with the board. If that line is omitted, and the surrounding sleep()
lines which would no longer be needed, then the DHCP server on the local area network will assign an IP address to the board and it will be correctly reported in the REPL.
I find that I can just copy the WIFI/FTP connection script at the REPL prompt and it will work, except for the last line which I sometimes have to complete by hand. The better practice is to put the REPL into paste mode with the CtrlE keyboard combination and then copy and paste the script from the desktop.
Another possibility would be to set up the board as a WI-FI access point and then to start the FTP server. Connecting to the Wi-Fi network created by the W600 with the desktop it should be possible to use the FTP server. This has not been tested.
Once the server is running, an FTP client, such as ftp
on most Linux
machines can be used to transfer files back and forth over the Wi-Fi network. Here is a session showing how this can be done.
This was a trip down memory lane, I hadn't used a command line FTP client in years, but I thought I would make a note here because it could be a way to use Geany or VSCodium as a light IDE for the W600. Let's mention here that Les Pounder suggests using ampy
by Adafruit. However given his description, it looks like a command line utility not much different from ftp
.
I have not had much luck with Thonny as can be seen above. This is unfortunate because that Python IDE does work quite well with ESP32 boards. It was a cursory examination of the IDE and further investigation is waranted if the W600 becomes a chip that is used in many projects. Luckily, Thonny does work well with recent versions of MicroPython. Some mention uPyCraft by DFRobot which does look quite similar to Thonny. While not even mentioned in the introduction, it seems that it is available for Linux assuming the prerequisites are in place (see the source code README.md file).
So far I have used FileZilla which is a well-known FTP client as described in section 5 of the MicroPython User Guide by Winner Micro. On a Linux system, it is also possible to connect to the FTP server with the Caja file manager (and probably others) so that the file system on the W600 shows up as a remote directory. To do this, go to a location as shown below.
Enter the user name and password required by the FTP server on the W600 board.
I shun setting passwords permanently especially for connections that are mostly temporary, but that is a personal choice, of course. As can be seen below, the root directory of the W600 file system is now available as a networked drive.
When I open a script in the remote file system into an editor (done by clicking with the right mouse button and choosing Open with...
) and modify the script, the changes are uploaded to the W600 after closing the editor. Once used to this, I found this approach to be a fluid work environment. The only thing that I could not do with this method was deleting a directory in the remote (W600) file system. This could be done with FileZilla.
Don't forget, this is more than a programming environment; it is a built in over-the-air (OTA) mechanism. No need to add libraries and additional code as done with the ESP chips, although it will be necessary to modify the boot.py
script to always enable the FTP server. More on that later.
A Blink Example
Here is the obligatory Blink script.
I think this is pretty straight forward. We have already seen that the on-board blue LED is connected to the I/O pin labelled PA0 and that the pin must be grounded to turn on the LED. The only other thing worth mentioning is that the blinking does not go on indefinitely so as to fall through to the REPL after a while.
A Custom boot.py
When the W600 reboots, it executes the MicroPython firmware. After the latter has done its initial setup, it executes two Python scripts found in the root of the file system in chip's flash memory. First executed is boot.py
and then if that first script had no syntax error and no programming error such as starting an infinite loop, then the main.py
script is executed. The default boot.py
does very little.
Exactly why it is "best to keep [boot.py] minimal" is not clear. No matter, I decided that this was the best place to connect to the Wi-Fi network and to start the FTP server. Here is my boot.py
.
Again the logic is simple. After a connection to the wireless network is attempted (wlan.connect(secrets.ssid, secrets.psk)
, a check is made every half second for up to 8 seconds to see if the operation succeeded. If a connection is established with the wireless network, then the FTP server is started. If it is preferable to let the DHCP server on the local network assign the IP address dynamically, then comment out or remove the wlan.ifconfig()
command.
There is an accompanying secrets.py
script. Here is a template for it.
Adjust the content of the file, specifying the correct credentials for the Wi-Fi network and for the static IP address to be assigned to the W600 board. Remember to set an unused unique IP address for each board to be connected to the network.
Both boot.py
and secrets.py
need to be copied to the file system of the W600 using the latter's FTP server. The content of the boot.py
cannot be pasted in the REPL to get that first instance of the FTP server up because secrets.py
would have to already copied to the file system. However that was already covered in 5. The FTP Server.
Polling a Button
This will be a first example where a third party module is used. In this case, it is MicroPython-Button by Ubi de Feo (udidefeo). Copy Button.py
into the root directory of the W600 file system. The program will not work if the module is copied into the /lib
directory as one would do with an ESP32 running MicroPython. I have yet to figure out the correct configuration to change this.
The Button
class instance creator has three positional arguments.
- An I/O pin number.
- The I/O pin default state when the button is not pressed (
True = 1
. - The callback function invoked when the button changes state.
Then there are two boolean positional arguments: internal_pullup
and internal_pulldown
. If either is set to True
, then an internal resistor (to Vcc or ground respectively) is engage at the I/O pin. If both are set to true then it is the internal pull up resistor that is set up. If neither positional argument is set or if both are set to False
, then nothing about the internal resistor is specified when the module sets the input pin mode. We have already seen that this causes a problem in the W600 implementation of MicroPython, so at least one of the positional arguments must be set to true. In this case, where the push button ground pin PA1 momentarily, it is internal_pullup
which is set to True
. I have not had any luck with just an internal pull up resistor. There were many spurious signals interpreted as key presses and releases. It remains to determine if this was because the button was connected using long 15 cm leads. In any case an external pull up resistor solved the problem and the script reliably which explains the
Wi-Fi Switch - Proof of Concept
There is an MQTT client module for MicroPython that works with the W600: umqtt.simple2. It is offered as an alternative to the built in umqtt
module included in the MicroPython firmware since version 1.12 but which is not in the version of the firmware installed on the W600. Perhaps the original umqtt
module would work also in MicroPython 1.10, but I have not tested that. Adding the MQTT client module is the only thing that needs to be done to prove that the W600-Pico could be used to create a Wi-Fi switch that works with Domoticz and probably any other home automation system that supports the MQTT protocol.
I didn't actually connect a relay to the pin labeled PA1, only an external LED that will be turned on when the pin is set high. The test circuit is shown on the right.
I was very happy to see that the external LED (i.e. the relay) could be toggled on and off with the push button switch and that the internal LED and the virtual switch in Domoticz would both correshow the state of the relay. And, of course, it worked the other way. Clicking on the bulb icon of the Domoticz virtual switch caused the relay and activity LED to change their state.
There's much more to Theo Arends' Tasmota firmware which is what is running on all the Wi-Fi switches in my home automation system. However, all communication between these IoT devices and the home automation software is done using the two above-mentioned MQTT topics. Consequently, it seems reasonable to conclude that the W600-Pico can be successfully used as the basis of a (dumb) Wi-Fi switch.
More?
I have done a few other things with the I²C capabilities of the W600-Pico: using a DS3231 real time clock and a 0.96" SSD1306 OLED display. These may be made available in the future. For the time being, the source code show in this post is available in a GitHub repository: w600_micropython_examples. I'll end with three other references that could be of help for others starting to use MicroPython on the W600.
- English Product page at Winner Micro with links to SDK, documentation, etc.
- awsome-micropython [a] curated list of awesome MicroPython libraries, frameworks, software and resources.
- MicroPython_Examples [a] temporarily random collection of code for [...] students [of Ubi de Feo].