Tutorial: IoT Datalogger with ESP8266 WiFi Module and FRDM-KL25Z

DZone 's Guide to

Tutorial: IoT Datalogger with ESP8266 WiFi Module and FRDM-KL25Z

· IoT Zone ·
Free Resource

In my earlier post “Tutorial: Web Server with the ESP8266 WiFi Module” I used the ESP8266 WiFi module to run a local web server. This is a cool way to control devices inside my network. But to use that web page from the internet, I would need to open up my router which I don’t want to do for obvious reasons. Why not going the other way: host the web page in the internet, and have my board communicating with that internet page? This is exactly what this hype around IoT (Internet of Things) is all about :-).

ThingSpeak Channel for ESP8266

ThingSpeak Channel for ESP8266


In this article I continue to use the foundation I have made in my earlier “Tutorial: Web Server with the ESP8266 WiFi Module“: The FRDM-KL25Z board with the ESP8266 WiFi module.


I stumbled over ThingSpeak (https://thingspeak.com/) while searching for an IoT cloud platform where I could store my data. There are many ones available, but the this one really stand out in my view: open, free and good infrastructure, including visualization tools.

:idea: There is another IoT data server which I recommend to look at:https://data.sparkfun.com/. This one is simple and easy to use, but does not come with visualization out of the box.

Before using ThingSpeak, you need to set up an account:

  1. Sign up for a free account at https://thingspeak.com/
  2. Go to Channels and create New Channel. It will assign a Channel ID (we will use later). Provide a name and description. You can leave the other fields with the defaults for now. Press Save at the bottom of the Channel Settings page.
    New ThingSpeak Channel

    New ThingSpeak Channel

  3. Go to API Keys: it has generated an API key we will use in the communication.
    new API Key

    new API Key

  4. Now I can test the connection by putting this in my browser http://api.thingspeak.com/update?key=API_KEY&field1=0after replacing API_KEY with the API key from above:
    This will add the data ‘0’ to ‘field1′. The browser responds with the number of data points:
    Testing Channel

    Testing Channel

  5. I can check the result with http://api.thingspeak.com/channels/CHANNEL_ID/feed.json?key=API_KEYwhere now again use my API key plus the channel ID I have been assigned from above:
    Data Added to System

    Data Added to System

  6. This way I can add multiple data points, and I can view the data in a graphical view:
    Visualized Data

    Visualized Data

Now all what is needed to get the ESP8266 to connect to the ThingSpeak server and send the data :-).

Manual ESP8266 Command Sequence

First, let me show the command sequence using the command line shell.

At this point, I assume the ESP8266 module is connected to the access point. Then I set it up to allow multiple connections with CIPMUX:


Then, start a TCP connection to the ThingSpeak server (, using http port 80. Because I’m allowing multiple connections with CIPMUX, I pass a channel (4):


The ESP8286 should respond with:


Next, I’m using the CIPSEND to send my data. The first value is the channel id from above (4), followed by the size of the string I’m going to send (44 characters in my case):


:!: The size needs to include/count the “\r\n” at the end of the string!

Then the module should respond with


to show it is ready to receive the data. The data is sent directly, in my case with

GET /update?key=J4P1LICZI6ZF0YWG&field1=60

The GET command sends the data. ‘/update’ is the command to the data site to update the data points, followed by the API key, the field name and the value (60 in my case).

Finally, I close the TCP connection at the end with


And the new data point shows up in ThingSpeak:

Sent Data with ESP8266

Sent Data with ESP8266

And here the full command line log:

ESP8266 Data Sending to ThingSpeak

ESP8266 Data Sending to ThingSpeak

Sending Data from Program

Because sending the data with the command line shell takes time, it makes sense to automate it in a function.

#define THING_SPEAK_IP_STR      "" /* thingspeak.com IP Address */
#define THINK_SPEAK_IP_PORT     80 /* port number */
#define THING_SPEAK_KEY_STR     "J4P1LICZI6ZF0YWG" /* API key */
#define THING_SPEAK_CHANNEL     20696 /* channel ID */
#define THING_SPEAK_LABEL_STR   "field1"

 * \brief Sends a value to the ThingSpeak server
 * \param value Value to be sent
 * \param io Shell I/O handler or NULL if not used
 * \return Error code, ERR_OK for no failure
uint8_t THINK_SendValue(int32_t value, const CLS1_StdIOType *io) {
  /* Does the same as the following shell commands:
   ESP send AT+CIPMUX=1
   ESP send AT+CIPSTART=4,"TCP","",80  // 4 is the channel ID
   ESP send AT+CIPSEND=4,44                           // size with \r\n!
   ESP send GET /update?key=J4P1LICZI6ZF0YWG&field1=60
  uint8_t res = ERR_OK;
  uint8_t buf[64];
  uint8_t ch_id = 4;

  res = ESP_SetNumberOfConnections(1, io, ESP_DEFAULT_TIMEOUT_MS);
  if (res==ERR_OK) {
    res = ESP_OpenConnection(ch_id, TRUE, THING_SPEAK_IP_STR, THINK_SPEAK_IP_PORT, 5000, io);
    if (res==ERR_OK) {
      UTIL1_strcpy(buf, sizeof(buf), "GET /update?key=");
      UTIL1_strcat(buf, sizeof(buf), THING_SPEAK_KEY_STR);
      UTIL1_chcat(buf, sizeof(buf), '&');
      UTIL1_strcat(buf, sizeof(buf), THING_SPEAK_LABEL_STR);
      UTIL1_chcat(buf, sizeof(buf), '=');
      UTIL1_strcatNum32s(buf, sizeof(buf), value);
      UTIL1_strcat(buf, sizeof(buf), "\r\n");
      res = ESP_PrepareMsgSend(ch_id, UTIL1_strlen(buf), 3000, io);
      if (res==ERR_OK) {
        /* sending data */
        res = ESP_SendATCommand(buf, NULL, 0, NULL, ESP_DEFAULT_TIMEOUT_MS, io);
        if (res!=ERR_OK) {
          CLS1_SendStr("Sending page failed!\r\n", io->stdErr); /* copy on console */
        } else {
          for(;;) { /* breaks */
            res = ESP_ReadCharsUntil(buf, sizeof(buf), '\n', 1000);
            if (res==ERR_OK) { /* line read */
              if (io!=NULL) {
                CLS1_SendStr(buf, io->stdOut); /* copy on console */
            if (UTIL1_strncmp(buf, "SEND OK\r\n", sizeof("SEND OK\r\n")-1)==0) { /* ok from module */
    (void)ESP_CloseConnection(ch_id, io, ESP_DEFAULT_TIMEOUT_MS);
  return res;

All the other ESP8266 functions are in the ESP8266.c driver file. And a ‘send’ command have been implemented to automate sending data:

Command line Interface

Command line Interface

With this, I can send data interactively or automatically in given interval:

ThingSpeak Channel for ESP8266

ThingSpeak Channel for ESP8266


With the right steps and know-how, it is really easy to send data to the internet and host it on an IoT server. I this example I used ThingSpeak to post data points and visualize them, but any other IoT host can be used. ThingSpeak has other API’s, plugins and apps which can be used for different applications, e.g. tweeting messages to Twitter, line up requests at predetermined times or execute queued commands. I guess I have to explore all this in the next days and weeks :-).

The project and sources for this tutorial are available on GitHub:https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/KDS/FRDM-KL25Z/FRDM-KL25Z_ESP8266_ThingSpeak.

Happy Logging :-)


internet of things, iot, java, tutorial

Published at DZone with permission of Erich Styger , DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}