Quantcast
Channel: Analysis – Tinkerman
Viewing all 23 articles
Browse latest View live

Manage and persist settings with Embedis

$
0
0

For months I’ve been searching for a settings manager for my Arduino and ESP8266 projects. There are basically two issues to take care of:

  • On memory settings or how do you access to the configuration values from your code
  • Persistence or how do you store the configuration across reboots

For the first issue common solutions in high level languages are key-value solutions in the form of containers or hash arrays. But C++ is not so high level and the ATMega328 or the ESP8266 are nothing more than microcontrollers so resources are limited. Common patterns are simple variables, container classes or structures. They all have the same problem: they are mostly static, if you want to add a new setting you have to change the code and flash it to your controller.

For the second issue some microcontrollers have some type of EEPROM, like the ATMega328 in the Arduinos. The ESP8266 doesn’t have one so it needs an external SPI Flash memory. Using the file system partition in the ESP modules to store a configuration file with all the project settings is feasible. It is persistent across reboots but it gets deleted when you upload a new file system binary. You could use an external memory or make use of “reserved” memory space for you own purposes like Peter Scargill proposes in a recent post.  But if you are using Arduino Core for ESP8266 it already defines a memory layout that reserves a 4Kb block to emulate EEPROM and provides a library to access it that it’s (mostly) API compatible with the Arduino EEPROM library.

Meet Embedis

The Embedis library is the magic trick that solves all the issues above. It provides a key-value type access to your settings, you can set (both updates or creates), get and delete them, list them, query if a certain key exists,… and you can persist them in different storage solutions, in particular in the (emulated) EEPROM.

Embedis commands

Listing commands, querying dictionaries and keys

The library is really easy to use. Just initialize an embedis object and throw this code in your setup and loop methods and you are good to go (if you don’t need console management you can forget the loop part).

Embedis embedis(Serial);

void setup() {

    ...

    EEPROM.begin(SPI_FLASH_SEC_SIZE);
    Embedis::dictionary( F("EEPROM"),
        SPI_FLASH_SEC_SIZE,
        [](size_t pos) -> char { return EEPROM.read(pos); },
        [](size_t pos, char value) { EEPROM.write(pos, value); },
        []() { EEPROM.commit(); }
    );

    ...

}

void loop() {

    ...

    embedis.process();

    ...

}

The previous code works on ESP8266 devices, if you are using an Arduino you don’t need any parameter in the “begin” method but you will need to define a proper size for the dictionary.

Then you just have to get and set your settings and they are automatically persisted to EEPROM:

String ssid;
Embedis::get("ssid", ssid);

... (the user changes the ssid from the web interface, for instance) ...

Embedis::set("ssid", ssid);

The library stores the settings in the EEPROM starting from the end of it backwards. So you can still use the beginning of the memory to store your own values (relay statuses, for instance) provided that you use less than the available EEPROM size between both.

Goodies

The library comes with some nice bonus features, like console management and custom commands. You can modify all your settings from your terminal connection or eventually create your own commands to manage your wifi, reboot the board or execute any administrative options on your device.

Some of the built in commands let you manage your key-value database directly from console or publish o subscribe to topics. This last feature could be used, for instance, to enable specific debug messages. Instead of simply dump debug messages to console we can:

Serial.println("[WEBSERVER] Request /index.html");
Embedis::publish("webserver", "[WEBSERVER] Request /index.html");

The message won’t be displayed unless you subscribe to the “webserver” topic from the console with:

subscribe webserver

You will then receive only the messages for that topic (and not the “wifi” or “sensor” ones, for instance).

subscribe

Credits

The Embedis library is an open source, community supported project, initially developed by David Turnbull, Tom Moxon and PatternAgents, LLC as part as the thingSoC initiative.

thingsoc_model

I’m not associated in any way to Embedis, thingSoC or PatternAgents, nor I had any previous contact with them. My intention with this post is to give credit to a tool that has solved me a problem in a way that I find both elegant and efficient. A perfect match.

The post Manage and persist settings with Embedis appeared first on Tinkerman.


4Duino-24 upside down

$
0
0

A few weeks ago the 4D Systems announced one of its latest products: the 4Duino-24, an Arduino compatible display module with built in 240×320 resolution TFT LCD Display with Resistive Touch and an ESP8266 ESP-06 module on board.

it looked like a great product for a home automation control panel, although the screen could have been bigger. Anyway I contacted the people at 4D Systems and they were kind enough to send me a sample to review, and hack!

I love getting packages in the mail

I love getting packages in the mail

A conversation with the tech team

When I looked at the 4Duino-24 architecture there was something that rang a bell in my head. Well, here we have again en ESP8266 being used as a mere serial to wifi bridge.

Block diagram of the 4Duino-24 board, as you can see the main processor is the ATMega32u4

Block diagram of the 4Duino-24 board, as you can see the main processor is an ATmega32u4, the same one in the Arduino Leonardo

The central microcontroller of the board is the Atmel ATmega32u4, the same one the Arduino Leonardo has. It’s a good 8-bit controller but nothing compared to the ESP8266 that sits a few milimeters away.

ATmega32u4

The ATmega32u4 and the ESP-06 module side by side

I quickly raised an inquiry to the 4D Systems tech team and Doff Deponio, BEng. Electronics and Communication Technical Engineer at 4D Systems, responded as follows:

Well, there are all sorts of ways to look at it.

The ESP8266 is the most powerful processor, the Picaso is second and the ATmega32U4 is the least. But the ESP8266 has limited I/O, so using it as the main processor is not ‘optimal’ as it restricts users in the I/O they can add to the configuration.

The way it is designed each processor is being used in the best way to play up eachs strengths. The ESP8266 for its ability to do WiFi, Picaso for its graphics capabilities and the ATmega32U4 for its rich hardware connectivity and available code libraries.

And it makes perfect sense. Needless to say the Arduino community is the biggest by far so placing the ATmega32u4 as the main controller makes it easier for a lot more people to use the board. The ATmega32u4 has plenty of GPIOs, digital and analog, to plug your sensors and two hardware serial ports, one of them used for the USB interface and the other one to communicate with the Picaso controller that drives the display.

Still… the ESP8266 is way more powerful. And you know what? A lot of the “available code libraries” for Arduino can be ported “as is” to the ESP8266 platorm using the Arduino Core for ESP8266 project. Including 4DSystems Picaso Serial Library for Arduino.

I want this guy to rule the board

I want this guy to rule the board

First things first

And the first thing is to test the board with the provided example code. The board is really well documented, and everything is downloadable from the product page. The most important documents to start with are:

Also, you might want to check the 4D Workshop4 IDE that integrates code editing and tools to design the graphical interface of your application. It’s a Windows only application (me sad) and freeware except for the PRO version (trial-ware) that integrates a code-less development environment named ViSi-Genie.

This is the default screen message when the Picaso doesn't get any instructions

This is the default screen message when the Picaso doesn’t get any instructions

If you have been reading me you would know I’m a PlatformIO fan. It freed me from the Arduino IDE and provides a whole lot of goodies and support for tons of boards and frameworks aside from Arduino ones. It’s a truly one-tool-drives-them-all!!

Flash the 4Duino-24 using PlatformIO

So my first thing was to add 4Duino support to PlatformIO. It basically comprises two steps: adding the required definitions and code the same way the Arduino IDE would do and adding an entry for the board in the Atmel AVR package for PlatformIO to know about the board.

Setting things up

The 4Duino-24 board has some specificities compared to its close cousin the Arduino Leonardo. Both have the same processor and speed but they have two small differences:

  • In the Leonardo PB0 and PD5 pins in the ATmega32u4 are connected to RX and TX LEDs respectively, but on the 4Duino-24 these pins are connected to the RESET lines of the ESP8266 and the PICASO controllers
  • The device has a different USB signature (VID and PID)

These two differences mean changes in the bootloader, the coreUSB libraries and the pin definitions file. So 4D Systems maintains a board description file for the Arduino IDE board manager that automates the process of downloading and installing custom files for the 4Duino-4D board. We will have to do the same.

The latest version of the board description file defines two packages for Arduino IDE versions 1.6.7 and 1.6.10. I downloaded the 4Duino-24 package for the Arduino IDE 1.6.10 and decompressed it. It contains several files and folders. This is what I did:

action from to
copy bootloaders/* ~/.platformio/packages/framework-arduinoavr/bootloaders/
copy cores/* ~/.platformio/packages/framework-arduinoavr/cores/
copy libraries/* ~/.platformio/packages/framework-arduinoavr/libraries/__core__/4duino/
copy variants/* ~/.platformio/packages/framework-arduinoavr/variants/
append boards.txt ~/.platformio/packages/framework-arduinoavr/boards.txt

Next add a 4duino.json file to the `~/.platformio/platforms/atmelavr/boards/` folder with these contents:

{
  "build": {
    "core": "4duino",
    "extra_flags": "-DARDUINO_ARCH_AVR -DARDUINO_AVR_4DUINO",
    "f_cpu": "16000000L",
    "hwids": [
      [
        "0x04D8",
        "0xF110"
      ] 
    ],
    "mcu": "atmega32u4",
    "usb_product": "4D Systems 4Duino",
    "variant": "4duino"
  },
  "frameworks": [
    "arduino"
  ],
  "name": "4DSystems 4Duino",
  "upload": {
    "disable_flushing": true,
    "maximum_ram_size": 2560,
    "maximum_size": 28672,
    "protocol": "avr109",
    "require_upload_port": true,
    "speed": 57600,
    "use_1200bps_touch": true,
    "wait_for_upload_port": true
  },
  "url": "http://wwww.4duino.com",
  "vendor": "4D Systems"
}

And start a new project

Now I am ready to start a new project by typing:

pio init -b 4duino

The Picaso Serial Library for Arduino is already installed (comes with the 4Duino package for the Arduino IDE) and has two example sketches to help you start with it. One of them, the “BigDemo” example, requires you to format and copy some files to the SD Card but I found that it fails compiling because the resulting image is too big 🙁

The other example, “Display_print”, works just fine. I copied the “Display_print.ino” file to the “src” folder and:

pio run -t upload

Done 😀

Doing it upside down

Now. What if I want the ESP8266 to be my main controller? It doesn’t have direct access to the Picaso controller but I could use the ATmega32u4 as a bridge for the Picaso and also as a data provider for any sensors it may have attached. It can be tricky but it’s doable. What do I win? A lot of power and connectivity options using the ESP8266 at full potential. What do I lose? Basically display responsiveness and speed, but depending on the product it is not noticeable at all…

The ATMega32u4 as a Man-in-the-middle

The Picaso microcontroller can be controlled through serial commands and the Picaso Serial Library encapsulates these commands in a more human-friendly API. But they are just serial data flowing up and down, so it can be easily forwarded to another destination.

One of the first examples when using an Arduino is the serial passthrough sketch:

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() {
  if (Serial.available()) {      // If anything comes in Serial (USB),
    Serial1.write(Serial.read());   // read it and send it out Serial1 (pins 0 & 1)
  }

  if (Serial1.available()) {     // If anything comes in Serial1 (pins 0 & 1)
    Serial.write(Serial1.read());   // read it and send it out Serial (USB)
  }
}

That’s just what we need. Easy, no? All the encoding and decoding will be done somewhere else (in the ESP8266) so the ATmega32u4 does not need to know what it is forwarding. There is one caveat, thou.

About serial speeds

I said the ATmega32u4 has two hardware serial ports, but one is already used by the USB connection, the other goes to the Picaso board and we need a third one the ESP8266. This third one will have to be a SoftwareSerial port. SoftwareSerial allows you to use almost any 2 pins as TX/RX, but since the protocol is implemented in code it’s slower than its Hardware counterpart. At 57600 bauds it is reliable, but that’s almost 4 times slower than the 200kbauds of the connection between the atmega32u4 and the Picaso.

Custom commands

Also, if we don’t want to lose the possibilities of the plethora of GPIOs of the ATmega32u4 (and shields) we should put a mechanism in place to query them from the ESP8266. The good thing about it is that we already have one. The Picaso Serial Library. All the messages for the Picaso controller start with a 2 bytes (a word) command identifier. The first of those bytes can be 0x00, 0xFF or 0xFE. When the Picaso receives a valid message it responds with an acknowledge (0x06), an encoded response (like touch screen status or coordinates) or some kind of error.

So what if I implement my own commands and monitor the messages from the ESP8266 to the Picaso controller intercepting those that start with my own starting code? Here you have a first version of the bridge code that runs on the ATmega32u4, forwarding messages between the ESP8266 and the Picaso controller and intercepting those that start with a 0xF0. As an example the only custom command implemented allows the ESP8266 to control the builtin LED attached to GPIO 13 of the Atmel IC.

/*

4DUINO-24

Picaso Bridge Demo
ATMEGA32u4 Code

Copyright (C) 2016 by Xose Pérez <xose dot perez at gmail dot com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/
#include <Arduino.h>
#include <SoftwareSerial.h>

#define ESP8266_RX          8
#define ESP8266_TX          9
#define DEBUG_BAUDRATE      115200
#define ESP8266_BAUDRATE    57600
#define PICASO_BAUDRATE     200000

#define DEBUG_SERIAL        Serial
#define PICASO_SERIAL       Serial1
#define ESP8266_SERIAL      EspSerial

#define ESP_RESET_PIN       17
#define PICASO_RESET_PIN    30

#define COMMAND_LENGTH      3
#define COMMAND_HEADER      0xF0
#define COMMAND_LED_STATUS  0x01
#define RESPONSE_ACK        0x06
#define RESPONSE_ERROR      0x01

SoftwareSerial EspSerial(ESP8266_RX, ESP8266_TX);
boolean header = true;
uint8_t position = 0;
uint8_t command[COMMAND_LENGTH];

// -----------------------------------------------------------------------------
// UTILS
// -----------------------------------------------------------------------------

void reset(uint8_t pin) {
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
    delay(100);
    digitalWrite(pin, LOW);
}

// -----------------------------------------------------------------------------
// LOCAL COMMANDS
// -----------------------------------------------------------------------------

void commandLoop() {

    // All builtin commands are 3 bytes long (including the 0xF0 header)
    if (position != COMMAND_LENGTH) return;

    // Check command signature
    switch (command[1]) {

        // led_Status
        case COMMAND_LED_STATUS:

            // Set the LED
            digitalWrite(LED_BUILTIN, command[2]);

            // send ACK like a PICASO command
            ESP8266_SERIAL.write(RESPONSE_ACK);

            break;

        default:

            // send ERROR
            ESP8266_SERIAL.write(RESPONSE_ERROR);

            break;

    }

    // reset buffer position
    position = 0;
    header = true;

}

// -----------------------------------------------------------------------------
// SERIAL BRIDGE
// -----------------------------------------------------------------------------

void serialLoop() {

    // Request from the ESP8266
    if (ESP8266_SERIAL.available()) {

        // Intercept message
        uint8_t data = ESP8266_SERIAL.read();

        // Debug messages
        #if DEBUG
            if (header) DEBUG_SERIAL.println();
            char b[3];
            sprintf(b, "%02X\0", data);
            DEBUG_SERIAL.print(b);
        #endif

        // If it is a new message and the header matches 0xF0
        // or it's a message already flagged as mine,
        // the process it locally
        if ((position > 0) || (header && (data == COMMAND_HEADER))) {

            // Buffer the message
            command[position++] = data;

        // else it's for the PICASO controller
        } else {

            // Forward it to the PICASO controller
            PICASO_SERIAL.write(data);

        }

        // Flag the forecoming bytes as not new
        header = false;

    }

    // Response from the PICASO controller
    if (PICASO_SERIAL.available()) {

        // Forward message to ESP8266
        ESP8266_SERIAL.write(PICASO_SERIAL.read());

        // Ready for a new command
        header = true;

    }

}

// -----------------------------------------------------------------------------
// SETUP & LOOP
// -----------------------------------------------------------------------------

void setup() {

    #if DEBUG
        DEBUG_SERIAL.begin(DEBUG_BAUDRATE);
    #endif

    PICASO_SERIAL.begin(PICASO_BAUDRATE);
    ESP8266_SERIAL.begin(ESP8266_BAUDRATE);

    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);

    reset(PICASO_RESET_PIN);
    reset(ESP_RESET_PIN);

}

void loop() {
    serialLoop();
    commandLoop();
}

As a note aside: you may have noticed that when the sketch starts it resets the Picaso AND the ESP8266…

Running the Picaso Serial Library on the ESP8266

This section might look a bit empty but, actually, there is nothing to say. It just compiles and works without modifications.

Extending the Picaso Serial Library

Now on the ESP8266 side I just have to copy the Display_print.ino example and run it. If I want to use the custom command I implemented in the ATmega32u4 side I could just send it manually but extending the Picaso Serial Library is a more elegant option.

So I created a Picaso Bridge LIbrary that extends the Picaso Serial Library adding the new commands. This is what the “Picaso_Bridge.h” file looks like:

/*

Picaso Bridge

This library extends Picaso_Serial_4DLib by 4D Systems
with custom commands that can be interpreted by a
MIM microcontroller like the atmega32u4 in the 4Duino24

Copyright (C) 2016 by Xose Pérez <xose dot perez at gmail dot com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef _PICASO_BRIDGE_H_
#define _PICASO_BRIDGE_H_

#include <Picaso_Serial_4DLib.h>

//------------------------------------------------------------------------------
// Custom commands
//------------------------------------------------------------------------------

#define F_led_Status            0xF001

//------------------------------------------------------------------------------
// Library declarations
//------------------------------------------------------------------------------

class Picaso_Bridge : public Picaso_Serial_4DLib {

    public:

        Picaso_Bridge(Stream * virtualPort) : Picaso_Serial_4DLib(virtualPort) {};
        void led_Status(bool status);

};

#endif

And here the code (Picaso_Bridge.cpp):

/*

Picaso Bridge

This library extends Picaso_Serial_4DLib by 4D Systems
with custom commands that can be interpreted by a
MIM microcontroller like the atmega32u4 in the 4Duino24

Copyright (C) 2016 by Xose Pérez <xose dot perez at gmail dot com>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "Picaso_Bridge.h"

void Picaso_Bridge::led_Status(bool status) {
    _virtualPort->write((char)(F_led_Status >> 8));
    _virtualPort->write((char)(F_led_Status));
    _virtualPort->write(status ? 1 : 0);
    GetAck();
}

Simple and elegant. I like it! Only one thing. For this wrapper library to work I had to do a minor change to the Picaso Serial Library. I had to change the private methods to protected, so I could use them from the inherited class.

Now I can just copy any code meant for the ATmega32u4 and use my own commands:

/*

4DUINO-24

Picaso Bridge Demo
ESP8266 Code

Xose Pérez <xose dot perez at gmail dot com>
based on example code by 4D Systems

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Picaso_Bridge.h>

#define DISPLAY_SERIAL          Serial
#define SERIAL_BAUDRATE         57600
#define DISPLAY_CHECK_INTERVAL  100

// Using my Picaso_Bridge class here
Picaso_Bridge Display(&DISPLAY_SERIAL);

word buttonState = BUTTON_UP;
word x, y;

// -----------------------------------------------------------------------------
// DISPLAY
// -----------------------------------------------------------------------------

void mycallback(int ErrCode, unsigned char Errorbyte) {}

void displaySetup() {

    Display.Callback4D = mycallback;
    Display.TimeLimit4D = 5000;
    DISPLAY_SERIAL.begin(SERIAL_BAUDRATE);

    // Required for the display to warm up (!!)
    delay(5000);

    Display.touch_Set(TOUCH_ENABLE);
    Display.gfx_ScreenMode(PORTRAIT);
    Display.gfx_Cls();

    Display.gfx_Button(buttonState, 20, 40, GRAY, WHITE, FONT3, 3, 3, (char *) "Press Me");
    Display.txt_Width(2);
    Display.txt_Height(2);
    Display.gfx_MoveTo(10,120);
    Display.putstr((char *) "LED State: OFF");

}

void displayLoop() {

    // We are checking the status every 100ms
    static unsigned long last = 0;
    if (millis() - last < DISPLAY_CHECK_INTERVAL) return; last = millis(); byte state = Display.touch_Get(TOUCH_STATUS); if ((state == TOUCH_PRESSED) || (state == TOUCH_MOVING)) { x = Display.touch_Get(TOUCH_GETX); y = Display.touch_Get(TOUCH_GETY); } if (state == TOUCH_RELEASED) { if ((x >= 20) && (x <= 220) && (y >= 40) && (y <= 100)) {

            buttonState = !buttonState;
            Display.gfx_MoveTo(10,120);

            // If button state is pressed
            if (buttonState == BUTTON_UP) {
                Display.gfx_Button(buttonState, 20, 40, GRAY, WHITE, FONT3, 3, 3, (char *) "Press Me");
                Display.putstr((char *) "LED State: OFF");
            } else {
                Display.gfx_Button(buttonState, 20, 40, RED, WHITE, FONT3, 3, 3, (char *) "Press Me");
                Display.putstr((char *) "LED State: ON ");
            }

            // Calling my custom command to change the LED state
            Display.led_Status(buttonState == BUTTON_DOWN);

        }

    }

}

// -----------------------------------------------------------------------------
// SETUP & LOOP
// -----------------------------------------------------------------------------

void setup() {
    displaySetup();
}

void loop() {
    displayLoop();
    delay(5);
}

Flash it and enjoy. Two things about flashing the ESP-06 module in the 4Duino-24. First remember that even thou the ESP8266 is a 3V3 IC the programming connector brings out the 5V line, so connect it to a 5V supply. Second: once flashed disconnect the RX line, I noticed that it runs unbearably slow if connected.

Flashing the ESP8266 in the 4Duino-24

Flashing the ESP8266 in the 4Duino-24

There is a lot of work to do but the foundations are there. You can use the 4Duino-24 the original way or you can do it upside down.

The post 4Duino-24 upside down appeared first on Tinkerman.

Sonoff TH10 & TH16: sensors, displays, actuators,…

$
0
0

Itead Studio keep on creating interesting products for the hacker community. A few weeks ago a new version of the already classic Sonoff TH came to life. This new version comes in two flavours: the Sonoff TH10 and TH16.

In this article I will briefly talk about what’s new in this device to quickly go to explore one of those novelties: it’s external interface.

What’s new?

The first thing I noticed is it’s size. The new Sonoff TH10 (or TH16, they are the same except for the relay) It’s a lot bigger than the old Sonoff TH. The old case is 87.5×38.8×23.5mm while the new one is 114×51.6×32.2mm. It’s bigger in every dimension and it they were cubes (they are not) the new Sonoff would be 2.37 times bigger in volume!!

"Classic" Sonoff TH (right) versus the new Sonoff TH10 (left). Does size matter?

“Classic” Sonoff TH (right) versus the new Sonoff TH10 (left). Does size matter?

Maybe we can find an explanation for this growth in the inside but my first though is that one of the good things about the Sonoff was it’s relatively small size (compared to it’s competitor by Electrodragon, for instance).

In the inside we have a completely different PCB layout. The PCB is also 1.82 times bigger (64.8×33.9mm versus 88.9x45mm) but it certainly breathes. Having all the connectors on the same side reduces trace distance and improves the separation between high and low voltage sides of the board. High voltage traces are a lot thicker and also have an extra of tin on top. All in all it looks like they have tried to answer people concerns about the safety of the device. But they still don’t have the CE mark (actually the CE mark in the case means “China Export”, check for the right Conformité Européene mark).

UPDATE 2016/10/08: Itead has contacted me to say that they are working on the CE certification and they expect to have it in no more than a month.

UPDATE 2016/10/20: Itead has contacted me again to communicate that some of their Sonoff line has now officially the CE certification (document of the CE certificate for new Sonoff products). The certification covers Sonoff TH10 and TH16 and also Sonoff DUAL and POW. They have also been certified as RoHS compliant.

Now the same comparison from the inside...

Now the same comparison from the inside…

The only difference between the Sonoff TH10 and TH16 is the relay. The TH10 uses a Hui Ke HK3FF-DC5V-SHG subminiature high power relay rated 10A while the TH16 uses a Honfa HF152F-005-1HTQ(104). The old Sonoff TH uses a HKE HRS3FNH-S-DC5V-A. They are all driven with GPIO12 through a transistor labeled 12W59. Don’t know enough about relays to know which one is better and why, what I know that none of them is a SPDT relay actually the Hul Ke is a SPDT relay, but the NC pole is not exposed and connected to the input line…. So crossover switching is still not possible

Then there are these new push terminals. I guess they are easy to use while sticking the cable in the hole. Also the designers have added two neutral and two ground terminals so the user does not need a terminal bar to power the device and the load. There is also a very welcome F20AL250V 20A fuse.

The new push terminals and the fuse in the Sonoff TH10

The new push terminals and the fuse in the Sonoff TH10

The user interface has also improved with a new LED that can be driven with GPIO13 (the other one is tied to GPIO12, so it follows the relay state). The enclosure is thin enough so the LEDs are visible through it. Also the new button is much better in terms of usability and aesthetic pleasure. And finally there is the new external interface… which I will explore in the next sections.

The new interface

Using an audio jack as an interface is quite common. I used it in my Smartmeter pulse counter years ago. It’s also good news for anyone willing to add their own sensors. But it has two caveats: first they have decided to go for a 2.5mm jack, which is not as common as the 3.5mm one. Harder to find and more expensive. Second, even thou they are using a 4 channels jack (or TRRS for tip-ring-ring-sleeve) they are only using 3 of them for 3V3, GND and GPIO14. So what happened to the fourth?

Named pads, headers and test points in the Sonoff TH10 board

Named pads, headers and test points in the Sonoff TH10 board

Well as you can see in the image the engineering team at Itead Studio actually thought about it. Only it’s not enabled. In the image above you can see that GPIO14 is tied to the jack tip with a 0Ohm resitor and a 5KOhm pull-up (actually two 10k in parallel). Side by side to this 0Ohm resistor there is a pad ready to connect the first ring in the jack to GPIO4 and another one to add a pull-up too. So you just have to solder a 0Ohm SMD resistor to that pad (the one with the GPIO4 label) to bring out a second IO to connect the sensor…

I don't have 0603 SMD parts (too small for me) but a 0805 resistor fits just fine.

I don’t have 0603 SMD parts (too small for me) but a 0805 resistor fits just fine.

Have you read pull-up resistors? Me too. Do you know any 2 wire protocol that needs pull-ups? Me too!! So now we have a whole bunch of digital sensors we can attach to the Sonoff TH10/TH16.

A zillion of sensors, actuators, displays…

Itead Studio sells two sensors for the Sonoff TH10/TH16: an AMD2301 temperature and humidity sensor (DHT22 compatible) and a DS18B20 waterproof temperature sensor.

AM2301 and DS18B20 sensors for the Sonoff TH10/TH16

Look at the size of that AM2301 enclosure!

But now we can connect any digital device that requires one or two GPIO pins to drive it. And that includes I2C devices. We still have a limitation: the interface has a 3V3 channel, so we won’t be able to power 5V sensors with it… unless we hack that too (cut that thick trace going to the “3V3 / SLEEVE” point and solder a wire to any of the 5V test points in the image).

First I worked my testing cable. A 2.5mm TRRS jack to 4-channels Dupont connector.

Wooden clothes pins rocks

Sometime ago a friend told me I should always carry a wooden clothes pin with me…

Testing cable for the Sonoff TH10 sensor interface

Now ready to test sensors…

So let’s start playing! A BMP085 pressure sensor, a HC-SR04 ultrasonic range module, a PIR, an I2C LED display or an nice little 0.96″ I2C OLED display

BMP085 with the Sonoff TH10/TH16

A BMP085 sensor using I2C protocol

HC-SR04 ultrasonic range module with the Sonoff TH10/TH16

The HC-SR04 ultrasonic range module needs two GPIOs to drive the trigger and echo pins, but it only works with 5V.

Using a PIR with the Sonoff TH10/TH16

This PIR works great with 3V3 and can be driven with just one GPIO. This is actually quite useful for a light switch…

I2C LED display with the Sonoff TH10/TH16

You will need 5V to drive this I2C LED display…

An I2C OLED display with the Sonoff TH10/TH16

But this 0.96″ I2C OLED is a perfect match!

What else… well, almost anything digital out there: displays, humidity sensors, distance sensors, touch sensors, encoders, magnetometers, gyroscopes, accelerometers, tilt switches, reed switches, real time clocks,… and also servos, external relays, buzzers, and WS2812 strips!

Sensors and actuators for the Sonoff TH10/TH16

A zillion of sensors AND actuators

Flashing it

Last note before letting you go to find something to attach to your new Sonoff TH10/TH16. Tech people at Itead Studio know some of their clients will open the product enclosure and own the device by flashing their own firmware into it. They even use it as an advertising slogan: “For hackers, Sonoff Pow is another exciting board.”. So go ahead. The programming header is labelled and goes like this (check the picture above): VCC, RX, TX, GND. The button is tied to GPIO0 so just press it while powering the board and you are in flash mode.

If you don’t know what to flash give a try to the Espurna firmware. It’s a work in progress but will soon support I2C devices or two relays (for the Electrodragon or the Sonoff Dual) in different configuration modes including crossover switching.

By the way: I hope I will have a Sonoff Pow soon in my hands…

The post Sonoff TH10 & TH16: sensors, displays, actuators,… appeared first on Tinkerman.

Viewing all 23 articles
Browse latest View live