ESP8266 happiness

It just goes to show that perseverance sometimes pays off. It turns out that the reason I couldn’t get the Olimex esp8266 to work properly was that my USB/serial converter was faulty. The replacement one arrived today, and now I can program the wifi module using the arduino IDE with no problem. Five seconds after programming it, it had connected to my home network and was sending temperature readings via MQTT to my raspberry pi server. There are plenty of IO pins exposed on the Olimex module, so I can do lots more with it than with the wi07c module I was using before. Watch this space.

ESP8266 disappointment

I found a very promising new ESP8266 module, from Olimex (a Bulgarian company).

MOD-WIFI-ESP8266-DEV-1

It’s a breadboard-friendly board with an ESP8266 and 512k of flash memory on it, and it’s dead cheap. There’s even a carrier board for it, with a relay and a reset button, also dead cheap. I bought a couple, because it exposes all the pins from the microcontroller, so I can (a) use more than one I/O, and (b) hook up the reset pin so that I can put the device into (and, more importantly, wake it up from) deep sleep mode to extend battery life. There are videos on line of how simple it is to program these devices using the new arduino IDE.

The (insert strong adjective here) problem is that I can’t (insert strong adjective here)-well get it to work. I can connect it up to my PC fine. I can even put it into flash mode perfectly well. In neither case will it respond coherently to anything sent to it from the PC. In ‘normal’ mode, it just repeatedly sends the word ‘Error’ over the serial link, and does not respond to any AT commands.

Olimex ESP8266 errors

In reflashing mode, it simply fails to respond to the reprogramming commands. I’ve tried two of these modules, and both behave the same. I’ve contacted Olimex both by email and on their forum, and had no response. It’s a shame, but I think these modules are destined for the rubbish bin. At least they weren’t expensive.

Update: Olimex have got back to me, and have made some helpful suggestions. They don’t know what the problem is, though, and it’s not one they have seen before. It may well be something to do with my serial adapter. I have another on order, so I guess I’ll find out in due course.

The King is dead. Long live the king!

For a while now, I’ve been playing with the super-cheap esp8266 WiFi module. It’s been a bit of an uphill struggle, mostly because of the poor documentation (actually, that’s not fair – the documentation may well be excellent, but my understanding of Chinese isn’t) and the lack of easy programming tools. Until now, there have been essentially three ways of using the module:

Serial for breakfast

The initial method was to control the module via a serial link. As supplied, it can communicate with an arduino (or anything else) using a simple serial connection, using AT-style commands which will be familiar to anyone who has worked with modems, especially GSM ones. It works, but it’s a bit clunky. By and large, I think people have stopped doing this.

C for elevenses

Pretty soon after it became available, smarter people than me figured out that the module is powered by a general-purpose microprocessor (and a pretty powerful one at that). It also became apparent that you could reprogram this directly, and use its spare capacity (and spare I/O pins). Thanks to the manufacturer’s release of an SDK, it became possible to write code directly on the module, without the need for an arduino or any other processor. For less than five pounds, you could have a general-purpose microcontroller with build in WiFi.

Of course, there’s a catch. The tool chain required to do this programming is hard to set up and complicated to use. It also means programming in C and understanding a pretty complex SDK. It’s not particularly friendly. There were some valiant efforts to make this easier, notably Mikhail Grigorev’s bundling of everything into the eclipse IDE. This works well, but it still requires you to program at quite a low level.

lua for lunch

More recently, there has been nodemcu. This is a new set of firmware for the esp8266, which builds in an implementation of the lua language, with the SDK functions wrapped and easy to use. Nodemcu allows you to write programs in lua, upload them to the esp8266 and run them on it. This works pretty well. I’ve had temperature sensors in my house using it for a while, It has some drawbacks, principle amongst which is that the nodemcu firmware takes up quite a lot of the available memory, leaving fairly little for your programs. Add to this the fact that your programs are sent to the device as source code, and interpreted (or compiled) in place, and you find that there really isn’t much space to write more than simple programs. This shouldn’t be an issue for small sensor nodes, but I found myself scratching around trying to save a byte here and a byte there just to get my code to run.

Arduino for dinner

What everyone has been secretly waiting for, of course, is the ability to program the esp8266 like an arduino. And now we can. There’s a new version of the arduino ide 1.6.1 which gives you the ability to program the esp8266 using familiar arduino code. The wifi functions are easily available, as are most other arduino functions. It’s insanely easy to write something which connects to a wifi router, gets an ip address and sends data to a server. Or indeed to run a server on the device. Because the arduino language is compiled to native code before being uploaded, there’s loads of space for programs. Some of the normal arduino libraries have not been ported yet, but I’m sure they will be in the coming weeks. I won’t be going back to any of the other methods. Long live the king!

It’s worth repeating that the esp8266 gives you a tiny board with a 32 bit processor running at 80MHz, at least half a megabyte of memory (my recent olimex ones have 2MB), multiple IO pins and wifi for less than five pounds. If I were arduino (whichever half of arduino you care to pick) I’d be worried.

More tiny WiFi success

As I have posted before, I have been playing with the super-cheap WI07C WiFi module based on the ESP8266 chip. I’ve now had sufficient success with it that I can publish a post on a working project. This simple setup uses an Arduino nano to read temperatures from to 18BS20 sensors, formats the data as JSON and then sends it over WiFi to a server on my home network. It’s cheap and simple. Here’s the fritzing diagram:

WI07C_bb

You may notice the Adafruit level shifter board in there too. That’s because the digital IO from the arduino is 5V, but the WiFi module needs 3.3V. The Adafruit module is a dead easy way of joining the two. The temperature sensors use a three-wire protocol which allows you to connect many in parallel and address each one individually. there’s a software library which takes care of this.

Here’s the Arduino sketch. It uses Miles Burton’s temperature control library to read from the sensors, so you’ll need to download that. NB: this code is not a shining exaple of style or completeness. It’s a quick hack to get something working. It does no error checking or reconnection if there are problems. You may find yourself pressing the reset button a lot.

You might also note that the hardware serial port is required for the WiFi module, which needs 115200 baud. This means that you can’t upload a new sketch to the arduino while it’s connected to the WiFi module. I just whip out the wires to the TXD and RXD pins on the arduino while I’m uploading, and all is well.

The sketch tries to join the WiFi network, and then tries to establish a simple TCP connection to a server IP address and port of your choice. Once the connection is established, it checks the temperature sensors every 10 seconds or so and sends the temperatures to the server in JSON format, thus: {"temp":[22.63,22.81]}. That’s all it does. You’ll need a TCP server listening on your chosen IP address and port, of course. It seems to work quite reliably for me.

#include <SoftwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define SSID        "MyHomeSSID"
#define PASS        "MyPassword"
#define TARGET_IP   "192.168.1.xx"
#define TARGET_PORT 5000
#define TEMPERATURE_PIN 9

SoftwareSerial dbgSerial(10,11); // RX,TX
OneWire wire(TEMPERATURE_PIN);
DallasTemperature sensors(&wire);

void setup()
{
   // WiFi module needs fast serial, so must use the hardware port which is also used for
   // uploading sketches
   Serial.begin(115200);
   Serial.setTimeout(5000);

   // For debugging, we therefore need a software serial port.  This can be much slower.
   dbgSerial.begin(9600);
   dbgSerial.println("Starting");

  delay(1000);

  // Connect to the wirelsess network
  dbgSerial.println("Joining network...");
  Serial.print("AT+CWJAP="");
  Serial.print(SSID);  
  Serial.print("","");
  Serial.print(PASS);
  Serial.println(""");
  receive();

  // Just check that the WiFi module is joined to the network
  dbgSerial.println("Check connection...");
  Serial.println("AT+CWJAP?");
  receive();

  dbgSerial.println("Initialising sensors...");
  sensors.begin();


  dbgSerial.println("Connecting to server...");
  Serial.print("AT+CIPSTART="TCP","");
  Serial.print(TARGET_IP);
  Serial.print("",");
  Serial.print(TARGET_PORT);
  receive();
  delay(5000);

  dbgSerial.println("Ready to rumble!");
}

int incomingByte=0;
bool echoLocal = true;

// Get the data from the WiFi module and send it to the debug serial port
void receive(){
  delay(500);
  while (Serial.available() >0) {
    incomingByte = Serial.read();
    dbgSerial.write(incomingByte);
  }
  dbgSerial.println();
}

char temp1[10];
char temp2[10];

void loop()
{

  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  dbgSerial.print("Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  dbgSerial.println("DONE");

  dtostrf(sensors.getTempCByIndex(0),1,2,temp1);
  dtostrf(sensors.getTempCByIndex(1),1,2,temp2);  

  String json="{"temp":[" + String(temp1) + "," + String(temp2) + "]}";
  dbgSerial.print("Sending ");
  dbgSerial.println(json);

  // Send the data to the WiFi module
  Serial.print("AT+CIPSEND=");
  Serial.println(json.length());
  delay(500);
  Serial.print(json);
  receive();


  delay(10000);
}

This is a work in progress. I’ll be updating it soon. But for now, I’m very pleased with the simplicity of the WiFi modules, and even more pleased with their low cost (I am a Yorkshireman, after all).

Wifi success, for a change!

I’m actually having success in connecting the super-cheap WI07C wifi module to my home network, so that an arduino can send data anywhere.

WI07C module featuring esp8266 chipset

WI07C module featuring esp8266 chipset

I can now reliably establish a TCP connection and send data back and forth. It works rather well, with some limitations. It helps that I came across some slightly better documentation, sourced from this esp8266.com forum post which lists a few more AT commands and some more illuminating explanations.

AT+CIPMODE

AT+CIPMODE=1 or 0 (1 is default) sets the data receiving mode of the socket. If it’s 0, received data is simply sent to the serial port. If it’s 1, data gets “+IPD,c,n,” prepended to it, where c is the channel number and n is the number of bytes received. c is omitted if you are in single-channel mode. If you have multiple connections going in, this mode is logical. If you have only one, it may be simpler to use the transparent mode (AT+CIPMODE=0). But see AT+CIPSEND below, because this is affected by AT+CIPMODE!

AT+CIPSEND

The usual documentation about this is a bit pants. Here’s how it works. When you issue an AT+CIPSEND command, you normally tell it the channel you want to send it over (the chip can keep four IP connections going at once) and the number of bytes you want to send (call it n). The module then responds with a “>” character. It will then take the next n bytes you give it and send them over the TCP link. Then it responds with “SEND OK” and returns to normal, waiting for your next command. There are three variants of the AT+CIPSEND command, however:

AT+CIPSEND=channel,length is used if you have multiple connections open (AT+CIPMUX=1)
AT+CIPSEND=length is used for a single channel (if you have previously issued AT+CIPMUX=0 to tell it that you will only use one connection at a time)
AT+CIPSEND can be used without any parameters if you are using a single channel and transparent data mode (AT+CIPMODE=0). Note that there is no channel or length specified in this variant. After you issue the command, it will simply send every byte you throw at it directly to the receiving socket. This includes AT+ commands. Note that I have as yet found no way of exiting this mode other than resetting the module.

Also note that if you are in transparent data mode (AT+CIPMODE=0) and you try to use the variant of AT+CIPSEND which uses a length value, it won’t just fail or ignore it, it will actually reboot the module.

Lesser known AT commands not in other documentation

AT+GMR

AT+GMR retrieves the firmware ID of the module. There are at least two versions in the wild.

AT+CIPSTO

AT+CIPSTO=60 Sets the socket timeout period to 60 seconds
AT+CIPSTO? gets the current timeout value
You might want to change this value because if the server closes the socket, and your timeout value is too high, there appears to be nothing you can do from the client end other than do a hardware reset. I’m thinking it’s probably going to be necessary to tie the CH_PD line of the module to an output from the arduino, as I’m bound to want to reset from software at some point.

It’s good to make some progress. I’m going to look at the using the module as a server next.

WiFi for less than a fiver

Last week, the excellent hackaday ran a story about a new WiFi module (the Wi07c) based on the ESP8266 chip. It is eminently suitable for attaching to an arduino or similar, but it only costs $5. As I’ve been whining for some time about the high cost of WiFi shields for arduino, this piqued my interest. I bought a couple from the electrodragon store and have now had a bit of time to play with them. It seems that for once I’m a little ahead of the game – other people seem to be waiting a long time to receive theirs. The documentation is a little sparse, but enough to be going on with. There are three main sources, mostly community-supported: electrodragon, a hackaday.io project and nurdspace. The device is serial-driven, using a limited set of AT commands which will feel familiar to anyone who has worked with GPRS modems.

I’ve connected one of the modules to an arduino, and done some testing. I’ve also driven it directly from a serial terminal on my PC. These are my findings so far:

  1. The module runs at 3.3V, not 5V. The 3.3V available from an arduino can’t provide enough current to power it (though it may seem to). The WiFi module won’t even respond to commands without a separate power supply. Powering it from one of these works fine.
  2. In the version of the module I have, you must connect the CH_PD pin to +3.3V. Don’t be put off by the suggestion in the diagrams on Nurdspace.com that the four pins in the middle of the connector are not connected to anything. CH_PD is the pin next to the TXD pin.
  3. The AT commands mostly work. AT+CWLAP briskly returns a list of visible access points. AT+CWJAP connects to my home router (or claims to). Beyond that, things get flaky. Actually setting up a TCP connection to a running server does not seem to work. Nor does sending UDP. both allow me to get to the point of sending data, but then simply respond ‘busy’ to any further command or data until the device is rebooted (by unplugging it from the power supply). I’m not convinced that the device is ever genuinely connected to my router: the router doesn’t show it in the list of active clients.

I’ll keep experimenting with it, but I’m frustrated. It seems so close to being functional, but isn’t quite there yet. It feels like the firmware is missing some useful commands and diagnostic information. Or maybe it’s the documentation. Perhaps if my Chinese was better…