Native Development for the ESP8266 Using Sming

In previous posts, I've talked about using the ESP8266 module to add WiFi to hardware projects. The ESP8266 is a neat little chip, and recently I've spent some time learning how to write native programs for it, ie - code that runs directly on the ESP8266 itself without having to connect it to an Arduino.

I've been using Sming, an open source framework built on top of the official Espressif SDK. Sming makes writing native applications a breeze, and supports most existing Arduino libraries which means that you can connect and use almost any sensor/device that works with Arduino!

Although documentation is a bit sparse, I followed the Windows Quickstart for setting it up and had no problems at all. Where it lacks in documentation, it easily makes up in code examples, with dozens of example projects to get you started. The framework, and the applications you build with it, are written in C++. With my C++ being a bit rusty, I found the exmpales a great way to learn the API and brush up on areas of C++ that I am not overly familiar with (mostly templates).

To create a new project, I copied the folder for one of the example projects, renamed it and then imported it into Eclipse. After reading through example uses of the TcpServer class, and modifying the TcpClient example project a little, I was able to successfully write a simple echo-server, which accepts TCP connections on port 123, and sends back any data sent to it. The code is as follows:

#include <user_config.h>
#include <SmingCore/SmingCore.h>

#define WIFI_SSID "MY_WIFI_SSID"
#define WIFI_PWD "MY_WIFI_PASSWORD"

TcpServer myTcpServer;

bool onClientData(TcpClient& client, char* data, int size) {
    return client.send(data, size, false);
}

void connectedToWifi() {
    Serial.println("Connected!");

    String ip = WifiStation.getIP().toString();
    Serial.println(ip);

    myTcpServer.listen(123);
}

void connectFail() {
    Serial.println("Connect failed, retrying");
    WifiStation.waitConnection(connectedToWifi, 10, connectFail);
}

void init() {
    Serial.begin(115200);

    myTcpServer = TcpServer(onClientData);
    WifiAccessPoint.enable(false);
    WifiStation.config(WIFI_SSID, WIFI_PWD);
    WifiStation.enable(true);

    WifiStation.waitConnection(connectedToWifi, 30, connectFail);
}

It consists of four simple methods: init() runs once after the device has started up, and initialises the connection to my local wifi network. connectedToWifi() gets called when the WiFi connection is established, starts the TCP server listening on port 123, and prints out the IP address to the serial connection. connectFail() gets called on failure to connect to the WiFi and attempts to re-connect. onClientData() get calls when a connected client sends us data over the TCP socket which we send directly back to the conected client.

Getting the code onto the device itself is a bit fiddly, you'll need a USB to TTL adapter, and then it's just a matter of wiring everything up and flashing it. To flash code onto the ESP8266 you'll need to either run make flash from the command line or select the flash option from the Make Targets menu in Eclipse.

With the basics sorted, it should be easy enough to port some of my existing Arduino projects to native ESP8266. Doing so for the sous-vide project would be really cool, as it would open up the possiblity of controlling it from a smartphone via WiFi. I'm also looking into clustering several ESP8266 to see if I can implement some interesting distributed algorithms, more on that soon.


Comments

Building a Nest Thermostat With Arduino Part 1 - Control

The idea of a fully automated smart-home is an appealing one, and having a computer take care of repetitive tasks makes sense not only because it lets you be lazy, but also because a computer can make decisions based on data that you might not think or care about. One good example of a computer that can make smart decisions is the Nest Thermostat. Nest learns your schedule, how long it takes to heat up your home, and uses this data to decide when to turn your heating on or off. As a result, your home is heated to the temperature you want it to be, when you need it to be, without wasting energy.

Nest is the main motivation for my next Arduino project, which is to automate control of my appartment's central heating. In order to automate it, I need some way of controlling it, a way of turning my heating on and off programatically. The way that Nest does this is through a heat link device which connects directly to the boiler's thermostat cables. My existing thermostat is wireless, and I didn't want to dig around to find or play with thermostat cables, so I looked for an less intrusive option. I found a post on Steven Hale's blog which describes how he intercepted the on/off messages sent by his wireless thermostat to his boiler, and then re-transmitted those same messages to programatically control his central heating. I follow this same approach, but make use of a cheap USB TV tuner and Software Defined Radio to capture the control signals, instead of a soundcard based logic analyser.

RTL-SDR is a project for building a Software Defined Radio using the RTL2832U chip found in most USB TV tuners. The basic setup will set you back less than £10, and allows you view and record radio signals in the frequency range of 20 MHz to 1.7 GHz. This range includes AM/FM/DAB radio, digital TV, GSM channels used by mobile phones, and most importantly for this project, the un-licensed (at least in the UK) 433 MHz channel for short range devices such as central heating thermostats.

Capturing the Messages

Using SDRSharp, I was able to set the listening frequency to 433 MHz and watch radio traffic stream in real-time. To check that I had tuned into the same frequency as that used by my thermostat, I turned up the temperature setting on the thermostat so that it would transmit an ON signal to the boiler. I noticed three spikes show up in SDRSharp in short succession, and similarly when forcing the corresponding OFF signal. To capture the data being sent, I futher tuned the frequency in SDRSharp to that at which I saw the spikes, and clicked record.

Analysing the Messages

I opend up the recorded waveforms in Audacity, an audio editor that happens to work well for analysing radio signals. Here we can see three spikes, where the ON signal is repeated three times.

Waveform

Zooming in a bit closer, we can see that the radio signal is composed of on/off bursts of varying lengths. This is known as on-off keying, where a digital 1 bit is represented by a high signal of a given duration, and a 0 bit is represented by a high signal of a different duration. In this example, we can see two pulse lengths, one which is ~ 1000 microseconds long and the other ~ 500 microseconds, and the gap between bits is ~ 400 microseconds. If you think of the long pulse as representing a digital bit 1, and the short pulse representing the digital bit 0, then this signal represents the 31 bit binary string 0000001000100001000010000100000.

Close-up

Re-transmitting the messages

To replicate the signal sent by my thermostat to the boiler, I attached a cheap 433 MHz radio transmitter (with a make-shift antenna) to my Arduino Nano, and had it send out pulses of the same duration as measured in Audacity.

Arduino Transmitter

The standard Arduino delay(x) method pauses the application for x milliseconds, which doesn't quite give us enough resolution to reproduce the signal, as the durations we require are on the order of 100s of microseconds. Instead I use the delayMicroseconds() method, which accurately pauses the application for a given number of microseconds. With constants defined for the durations of a 1 bit and a 0 bit pulse, as well as the gap between bits, the code for replicating the signal essentially consists of a sequence of calls to sendOne() and sendZero(), where sendOne() is simply:

void sendOne() {}
    digitalWrite(TRANSMITTER_PIN, HIGH);
    delayMicroseconds(DATA_ONE);
    digitalWrite(TRANSMITTER_PIN, LOW);
    delayMicroseconds(GAP);
}

The code did take a fair bit of tweaking however, with the main issue being that the gap between bits isn't the same for the whole signal, but once I had accounted for that it worked!

Next Steps

Now that I can control my central-heating programatically, the next steps toward building this project into something useful will include adding a temperature probe, and building a web interface for monitoring and configuring it. I could port the code to the ESP8266 WiFi platform, and have that run the web server as well as send the control signals. I should then be able to track data such as how long it takes to heat the house, have it learn my schedule, and eventually make it fully autonomous.


Comments

Adding WiFi to Your Hardware Projects Using The ESP8266

Having built several Arduino based projects over the last year, the next step for me was to add WiFi connectivity to open up the possiblity for buidling things that can be controlled wirlessly, things that might actually be usfeul as opposed to just fun projects.

Looking at the options, the easiest way to add Wifi to your project might be a shield such as the official Arduino WiFi Shield, or a CC3000 Based Shield, which will set you back in the region of £15 - £20. The advantage of using a shield is that they snap straight onto the Arduino board, and don't require a messay array of jumper wires. However, a bit more searching lead me to some interesting alternatives. In particular the ESP8266 module stands out as a very cheap (~£1.70 shipped from China) and surprisingly performant option.

The ESP8266 Module

The module is essentially a System-on-a-Chip (SoC) that contains a 32-bit CPU clocked to 80 MHz, a WiFi transmitter/reciever, some internal RAM and ROM, plus an external flash memory chip. All in all it's a pretty nifty little thing, and provides a really simple way of adding WiFi connectivity to your hardware projects.

Wireless Serial Port

The default firmware lets you treat the ESP8266 as a wireless serial port, ie - you can send data in the same way as you would print to a serial USB sconnection. Simply connect up the Tx and Rx ports of the ESP8266 to the Rx and Tx ports of your Arduino or similar device, and then tell it what to do by executing commands using Serial.write(command). The commands are pretty straightforward, you can reset the module, set it up as an access point, connect to an access point, send data to connected clients, etc. The full list is available here.

I wrote a very basic server example which runs on an Arduino connected to the ESP8266. It repeatedly sends the text 'Hello world' to clients connected on port 23. To find the IP address of your module, you can run the command AT+CIFSR on it. When the server is running you should then be able to connect to this IP on port 23 using a network client terminal such as telnet or PuTTY, and see 'Hello world' repeatedly being printed to your terminal. Here's the code:

void setup() {
  //set baud rate to match module
  Serial.begin(115200);
  //reset the module
  Serial.println("AT+RST");
  //give it time to reboot
  delay(5000);
  
  //time-out a Serial.find after 5 seconds
  Serial.setTimeout(5000);

  //set module into access point and client mode
  sendCommandToESP("AT+CWMODE=3");  
  //connect to my home wifi
  sendCommandToESP("AT+CWJAP=\"WIFI_NETWORK_NAME\",\"PASSWORD\"");
  //allow multiple connections
  sendCommandToESP("AT+CIPMUX=1");  
  //run server on port 23
  sendCommandToESP("AT+CIPSERVER=1,23"); 
}

void sendCommandToESP(String command) {
  Serial.println(command);
  Serial.find("OK");
}

//send data to connected device every 4 seconds
void loop() {
  //send 11 bytes on connection '0'
  Serial.println("AT+CIPSEND=0,11");  
  delay(1000);
  //send the data
  Serial.println("Hello world");
  delay(3000);
}

To play around with the AT commands, it's worth getting a USB to Serial TTL converter, and running the commands directly from your computer using a serial port terminal such as CoolTerm. For wiring everything up, I followed this tutorial from the ESP8266 community wiki.

Self-Contained Application Platform

The integrated processor is used for running the TCP/IP stack as well as all of the additional networking software, separating the low-level network implementation details from your application and hardware by providing an easy to use serial interface.

Impressively, it is also possible to load and run your own application code on the device. There is an active community of developers and hobbyists using the ESP8266, who have collectively released several SDKs targetting the ESP8266 as a WiFi application platform. There is even an Arduino port for the ESP8266, allowing you to run your Arduino code directly on the module itself, all via the Arduino IDE!

I've been looking at using the Sming Framework for writing efficient native applications for the ESP8266 in C++. I've had a few ideas related to clustering these modules (seeing as they're so cheap) and Sming looks like a pretty good option for implementing them. The framework has a similar API to the Arduino SDK, and in addition is compatible with most Arduino libraries, which is a huge plus. I'll post an update if aything interesting comes of it :)


Comments

Building a Simple Sous-Vide Cooker Using Arduino

Sous-vide is a method for cooking food in a very precise manner to achieve consistently perfect results. The food is vacuum-sealed in a plastic bag and submerged in a temperature-controlled bath of water for a pre-determined amount of time, after which it is either ready to serve, or as in the case of steak, quickly seared in a hot cast-iron pan before serving. The result is food cooked to perfection, steak that's just as rare as you want it and slices like butter, or eggs poached to exactly the right consistency (at least in theory - in practice it can get a bit messy).

Conventional Sous-Vide machines are expensive, typically costing at least £100 for a low-end model. With my trusty Arduino UNO, a cheap slow-cooker, and some basic electronic components, I was able to achieve something pretty similar for a fraction of the cost. I followed this instructable for the most part, using the same temperature probe and LED display, but with much simplified code.

Here's how I did it.

Step 1: Components

You'll need the following:

  • MAX7219 based LED display
  • DS18B20 based waterproof temperature probe
  • 5V relay module
  • 2 push buttons
  • 4.7k ohm resistor
  • Arduino
  • Breadboard/protoyping board
  • Rice cooker or slow cooker
  • Project container (preferrably water/splash-proof)
  • Mains extension cable

Step 2: Wiring it together

Tthe temperature sensore will sit in the cooker filled with hot water, which will be connected to the mains extension. Our circuit will control the mains extensions cable, turning the cooker on and off, forming a basic feedback loop.

The wiring is fairly straightforward, and shouldn't require any soldering if you have a breadboard and a bunch of jumper wires. The trickiest part is connecting the relay to the mains extension cable.

Arduino Wiring Diagram

The relay will act as a switch for the slow cooker, and is controlled by a digital pin on the Arduino. For the relay module I am using, sending the pin a digital value of 0 (LOW), will activate the switch, in our case turning the cooker on, and a value of 1 (HIGH) will turn it off. This is known as Normally Open (NO) mode, where you have to activate the relay to connect the switch. The fact that you have to send a LOW signal to activate the switch can be a bit confusing.

To connect the relay to your mains extension cable, split it open using a craft knife and you should find three coloured wires - Earth, Neutral, and Live. The wire that we want attached to the relay is the Live cable, as this is the main line responsible for sending power to the cooker. The colour of this cable will vary depending on country, in the UK the live cable is brown. Cut this cable and strip each end, attaching one to the NO terminal of the relay, and the other to the COM terminal.

Step 3: Code

My code is available on GitHub, you'll need to install the following Arduino libraries for it to work: LedControl, OneWire and DallasTemperature.

Step 4: Safety and Testing

Once you've wired everything up and loaded up the code, it should be ready to test. When you power it up, you'll see two numbers appear on the display. The first number is the desired temperature, which initially is 65°C, and the second number is the measured temperature. The push buttons are used to control the desired temperature in increments of 0.5°C. Initially, the relay will be active because room temperature will be less than 65°C. To test everything works, set the desired tempreature to lower than the current temperature, and you should hear a click as the relay turns off.

The final product

Because we are dealing with high voltages, it is important to keep the electronics away from the cooker so that they don't get wet. I created a waterproof container by stacking two plastic take-away boxes, sandwiching the relay and exposed mains cables in the bottom compartment and the Arduino in the top, with holes cut between them for the wires. You might want to use some kind of water-tight sealant to be extra safe. I also used a battery pack to power the Arduino, connected directly to the 5V pin, which fits nicely inside the sealed box.

Step 5: Get Coooking!

Now that your cooker is set up, it's time to get cooking! So far I've tried steak and poached eggs, with varying results. One thing I've found to work well is to fill the cooker up with boiling water from a kettle and let it cool to the desired temperature, rather than filling it with cold water and waiting for it to heat up. It might take a few attempts before you get it right, but when you do it is well worth it.

Enjoy!


Comments

Arduino Projects

I've had an interest in electronics and programming from an early age, but until recently had never really put the two together. Last Christmas I received an Arduino UNO as a present, and for the first time was able to write code that made real stuff happen, from simple things like making an LED blink, to more practical projects such as building a Sous-Vide cooker and controlling my central heating using a radio transmitter! That's not to say the code I write in my every day job doesn't do 'real stuff', but there is something special about seeing the direct physical effects of code that I wrote executing on a tiny chip right in front of me.

The Arduino makes it super easy to connect up hardware components and tell them what to do, which is one major advantage over boards such as the Raspberry PI, which require a fair bit more set-up and configuration before you can begin talking to arbitrary hardware perhipherals through the GPIO pins. The Arduino does have somewhat limited memory and processing speed (16MHz), but for most hardware projects this is not an issue.

In the next couple of posts I'll go into details about some of the Arduino projects I've been working on.


Comments