Flashing the Sonoff TH16 Wireless Switch

The Sonoff TH16 is an inexpensive piece of hardware that can be controlled over WiFi. Apart from the switch (that's capable of handling electrical currents up to 16A) there's an interface for temperature and humidity. The actual temp/humid sensor is sold separately (in most cases).

By default, the device is controlled by a proprietary app (available on iOS and Android), but since the device is based on the popular ESP8266 chip it can be flashed with a custom firmware. And with the new firmware you can add the device to your average home-automation setup (in my case: Domoticz).

But before we get there, there's some (hardware) tinkering involved. For this we need some tools:

The Hardware

The 4 pin header is soldered to the Sonof, and those pins are going to be connected to the USB-to-Serial adapter. Just make sure that the adapter has a 3.3V output, because 5V will fry the ESP8266 chip on the Sonoff device.

The entire procedure is done while the Sonoff is disconnected from the AC power-source. Mixing 110/230VAC while tinkering with 3.3V and USB connections to a PC is never a good idea.

When connecting the Adapter to the 4 header pins, the following pins need to be connected to each other:

The VCC and GND are indicated on the Sonoff board. The Rx and Tx pins not so much, but mixing up Rx and Tx isn't going to blow up the device. Just make sure that the Rx on the USB device is connected to the Tx on the Sonoff, and Tx on the USB to Rx on the Sonoff. The pins on the USB-to-Serial adapters are clearly visible, so mixing things up can easily be avoided. Just make sure you don't connect the 5V pin to the Sonoff!


When everything is connected the flashing can begin.


To start the flashing procedure, you need to disconnect the USB adapter. Press the white button on the Sonoff. Hold this button, and connect the USB dongle to the PC. Release the button after the USB adapter is connected. This should put the ESP8266 chip in flash-mode.

There is a small caveat if you're using MacOS with the CH340G adapter, because the official driver driver will crash MacOS (a nice kernel panic). So don't use the official driver, but use the modified version available on Github.

When the correct driver is installed there should be a device under /dev/ with a name similar to mine ($ ls /dev/tty*):


That name (tty.wchsbserialfa14140) is used during the actual flashing, so remember it.


The flashing part of this project was something that wasn't exactly straightforward (for me). Information is fragmented and in many cases based on old software. The following worked for me, but doesn't guarantee anything.

Note that I did everything on my Mac (MacOS High Sierra), and not on Linux or Windows. I also didn't use the Arduino IDE which is mentioned all over the Internet. I did try it though, because my initial efforts ended in a device that didn't have wireless enabled for some reason. I also had the incorrect CH340G drivers installed.

After installing the ESPTool from Github, and downloading and unzipping the new firmware the following command will flash the device.

esptool.py --port /dev/tty.wchusbserialfa14140 --baud 115200 write_flash --flash_size=1MB -fm dout 0 ~/Downloads/ESPEasy_v2.0.0-dev12/ESPEasy_v2.0.0-dev12_normal_1024.bin

Important in the one-liner is the baudrate (--baud) parameter, which needs to be 115200 and NOT anything higher. A higher value will result in communication errors. Also, the 'dout' parameter is important. Many older tutorials still mention 'dio', but when that one is used the wireless part won't work.

The following output shows a successful flash.

Detecting chip type... ESP8266
Chip is ESP8266EX
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Flash params set to 0x0320
Compressed 566528 bytes to 373351...
Wrote 566528 bytes (373351 compressed) at 0x00000000 in 33.4 seconds (effective 135.9 kbit/s)...
Hash of data verified.

Hard resetting...

Note that when something goes wrong, chances are that you can just start over. I did many things wrong (apart from using 5V instead of 3.V), and I was still able to re-flash the device. Just power it down, and reconnect it (while holding the white button), and start over.

Accessing and configuring the flashed Sonoff

When the flashing has succeeded, the wires to the header pins can be removed, and the Sonoff can be powered on (110/230V). After a couple of seconds, a default SSID (ESP_Easy_0) will become available. Connect to the SSID (password: configesp) and configure the device to connect to your existing wireless network. Whether you use a fixed IP address, or DHCP depends on your (wireless) network design. In my case, DHCP was preferable.

Now you can access the Sonoff by surfing to the IP address, and configure the communications with Domoticz.

The configuration of the Sonoff was a trail and error exercise. The problem is that I didn't have a clue on how to enable/configure the temp/humid sensor, or the wireless switch. Apparently, everything is connected to GPIO pins, but there's no mapping available online (not that I could find).

Eventually I found that the temp/humid sensor is attached to GPIO-15 (D5), and that the hardware type (AM2301) works when selecting the DHT22 type in the gui.

The IDX values are related to Domoticz and will be discussed later on.

The internal switch can be access through GPIO-12 (D6).

When the settings have been completed, the Temp/Humid sensor should give some feedback on the Device overview page. This might take a minute or so.

Connecting the Sonoff to Domoticz

Now that the wireless switch is up and running, you can connect it to Domoticz. Communication between Domoticz and the Sonoff is done over MQTT, and for that to work, a MQTT server needs to be installed. I added that service on the Raspberry Pi running Domoticz by following the instructions here. Even though the instructions also mention Node-RED, it's not required, but can be used for other purposes.

When MQTT has been set-up, and has been tested with a commandline command and a dummy device in Domoticz, the Sonoff can be added to Domoticz.

First add 2 new pieces of hardware to Domoticz:

  1. MQTT CLient Gateway with LAN Interface with an address of localhost (if the MQTT was installed on the same PC as Domoticz. Otherwise the IP address of the MQTT server) and its port.
  2. A dummy device for representing the Sonoff device

The MQTT Broker connection is also something that needs to be configured in the Sonoff in the Controllers menu.

The IP address used ( is the IP address where the MQTT Broker service is installed.


Note that there is username password, but I haven't configured MQTT Broker for authentication, so this is ignored on the MQTT server side. From a security perspective, authentication should be enabled, and is something I will add later on.

Now the Virtual sensors/switches can be made in Domoticz, and this is where the IDX values are created that are configured in the Sonoff devices menu.

The temperature and humidity sensor should be giving some values after a couple of seconds. The switch needs to be configured in Domoticz, and this is where I started to doubt some things.

For some reason I thought that everything ran through the MQTT Broker service, but for some reason the switch part of the Sonoff couldn't be controlled. The only way to control the switch was to communicate directly with the Sonoff by using URL's with commands. Could be that I used an incorrect switch-type in Domoticz. Not sure yet. It just feels counter-intuitive.

Turning the switch on: http://<SONOFF_IP>/control?cmd=GPIO,12,1
Turning the switch off: http://<SONOFF_IP>/control?cmd=GPIO,12,0

Not really elegant if you ask me.

This is something I need to investigate.

Anyway, if there's something I missed/forgot/whatever, please leave a comment.

UPDATE: I added a follow-up post on the Domoticz integration where there's more intelligence in the Sonoff by using some scripting. The post can be found here.

Posted on December 31, 2017 and filed under Gadgets, Hardware, Programming, Raspberry Pi, Tips'n Tricks, Domotica.