Overview

Skill Level: Any Skill Level

Easy

Ingredients

An ESP8266

Step-by-step

  1. First you’ll need an ESP8266

    There are a variety of types to choose from, all of them should work, here i’m using a NodeMCU style board which is easy to prototype with because it has USB support built in for programming and powering the ESP8266.

  2. Next, install the Arduino IDE

    Get the Arduino IDE here. Using a recent version of the IDE – 1.6.4 or later – makes it easy to add the ESP8266 support to the IDE. With the Arduino IDE installed use the Board Manager function to add support for the ESP8266, see here for how to do that.

  3. Add the MQTT PubSubClient library

    The IBM Watson IoT Platform uses the MQTT protocol so next add the MQTT PubSubClient library to the Arduino IDE. This needs to be a recent version of the library to work with the ESP8266, i’m using version 2.3, from here.

  4. Signup to Bluemix and the IBM Watson IoT Platform

    Next you need to signup on the IBM Watson IoT Platform and create an “organization” and a “device”. This is described in detail at the IBM website and involves signing up to Bluemix and the Internet of Things Platform and in the Bluemix Catalog add an Internet of Things Service. This will create your Organization and then in the IoT Dashboard you can add a Device. There are lots of configuration options, nearly all can be left blank, you just need a device type, i used “ESP8266”, and a device ID, i used “Test1”.

    When the device has been created you’ll see the Device Credentials page and you need to save those details which are used to customise your Arduino sketch in the next step.

  5. The Arduino Sketch

    Copy the following sketch to the Arduino IDE:

     /**
    * Helloworld style, connect an ESP8266 to the IBM IoT Foundation
    *
    * Author: Ant Elder
    * License: Apache License v2
    */
    #include <ESP8266WiFi.h>
    #include <PubSubClient.h> // https://github.com/knolleary/pubsubclient/releases/tag/v2.3

    //-------- Customise these values -----------
    const char* ssid = "<yourSSID>";
    const char* password = "<yourPassword>";

    #define ORG "<yourOrganization>"
    #define DEVICE_TYPE "ESP8266"
    #define DEVICE_ID "Test1"
    #define TOKEN "<yourToken>"
    //-------- Customise the above values --------

    char server[] = ORG ".messaging.internetofthings.ibmcloud.com";
    char topic[] = "iot-2/evt/status/fmt/json";
    char authMethod[] = "use-token-auth";
    char token[] = TOKEN;
    char clientId[] = "d:" ORG ":" DEVICE_TYPE ":" DEVICE_ID;

    WiFiClient wifiClient;
    PubSubClient client(server, 1883, NULL, wifiClient);

    void setup() {
    Serial.begin(115200);
    Serial.println();

    Serial.print("Connecting to "); Serial.print(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    }
    Serial.println("");

    Serial.print("WiFi connected, IP address: "); Serial.println(WiFi.localIP());
    }

    int counter = 0;

    void loop() {

    if (!!!client.connected()) {
    Serial.print("Reconnecting client to ");
    Serial.println(server);
    while (!!!client.connect(clientId, authMethod, token)) {
    Serial.print(".");
    delay(500);
    }
    Serial.println();
    }

    String payload = "{"d":{"myName":"ESP8266.Test1","counter":";
    payload += counter;
    payload += "}}";

    Serial.print("Sending payload: ");
    Serial.println(payload);

    if (client.publish(topic, (char*) payload.c_str())) {
    Serial.println("Publish ok");
    } else {
    Serial.println("Publish failed");
    }

    ++counter;
    delay(10000);
    }

    Customise the lines after “//——– Customise these values ———–” with your WiFi network SSID and password and with the IoT Device Credentials from the previous step.

  6. Upload and run the sketch

    Upload the sketch to you ESP8266 and then open the Serial Monitor and you should see the values being published to the Watson IoT.

  7. View the published data on the IBM Watson IoT Platform Dashboard

    You can see the published events and data from your device on the Watson IoT Dashboard at this URL: https://<yourOrganization>.internetofthings.ibmcloud.com/dashboard/#/devices/browse

  8. Thats it!

    Hope you found this a useful introduction to using the ESP8266 with Arduino support with the IBM Watson IoT Platform.

37 comments on"Connect an ESP8266 with the Arduino SDK to the IBM Watson IoT Platform"

  1. travisclaypool October 15, 2015

    I am getting an error on line 62 when I try to compile. What am I doing wrong?

    Arduino: 1.6.5 (Mac OS X), Board: “SparkFun ESP8266 Thing, 80 MHz, 115200”

    thingtest1.ino:62:49: warning: invalid suffix on literal; C++11 requires a space between literal and identifier [-Wliteral-suffix]
    thingtest1.ino: In function ‘void loop()’:
    thingtest1:62: error: expected ‘,’ or ‘;’ before ‘d’
    expected ‘,’ or ‘;’ before ‘d’

    • The problem is on line 62 of the code the escaping of the quote characters had been lost in the web page formatter. I’ve updated the web format so they appear correctly in the code listing now, so if you re-copy the code (or just the line 62: String payload = …) it should compile correctly now.

  2. I’ve got the code uploaded and running on my ESP8266 and it connects to my IoT Foundation Service instance but after 3 posts the connection dies and when i check the “recent events” for my device no events appear despite the ESP8266 code logging that its successfully posted. The only indications of issues I can see are that the it appears the “Server” has terminated the connection as I see the message “Closed connection from 165.120.165.35. The connection was closed by the server.”. In my past experiments with IoT and ESP8266 I did have to tweak with my MQTT libraries to change the protocol version but based on the fact the ESP8266 reports a successful connection I don’t think this is the issue. Any ideas where I should look?

    • Retested the code this evening and it now appears to be working. I know there was some maintenance work on various service etc over the weekend so I guess this may be related. One remaining question… I don’t see any call of the PubSubClient loop function which I thought was supposed to be called to maintain the server connection and allow the client processing cycles to process incoming messages. Is this an omission in the code or is it unnecessary?

      • Was trying to keep the code as simple and clear as possible but you’re right it should really include the PubSubClient loop / reconnect logic. I’ll have go at adding that to make the example more robust.

        • Actually I think it works ok without PubSubClient.loop call in this example as its doing a publish frequently enough to prevent the timeout, So the loop call would only be necessary if it was doing something like waiting for incoming messages instead, which is a bit of a different example. I might do another recipe about that…

  3. […] Connect an ESP8266 with the Arduino SDK to the IBM IoT Foundation : https://developer.ibm.com/recipes/tutorials/connect-an-esp8266-with-the-arduino-sdk-to-the-ibm-iot-f… […]

  4. How to subscribe msg from IOTF with this example

  5. Did you tried this code before posting?
    1. You do not have callback function
    // Callback function header
    void callback(char* topic, byte* payload, unsigned int length);
    2. If statement invokes type conversing error, so I commented it
    //if (strcmp(WiFi.SSID(), ssid) != 0) {
    WiFi.begin(ssid, password);
    //}
    3. If you’d add links on all things you talk about like dashboard with devices and so on, It would be much more informative
    Thanks

    • Hi tiot, thanks for looking. I did try to include links to most of the things mentioned here, tell me what links you’d like to see that are missing and i will go add them. The callback isn’t needed in this scenario with the v2.3 version of the MQTT client used here, and the strcmp(WiFi.SSID(), ssid) comparison has changed in the very latest ESP/Arduino release so you now need to do strcmp(WiFi.SSID().c_str(), ssid).

      • KiranShashi March 25, 2016

        I am getting “error: ‘callback’ was not declared in this scope
        PubSubClient client(server, 1883, callback, wifiClient);
        ^
        exit status 1 ”

        So – I commented it – as I read that it was not needed ( including the call back function )
        Now, I am getting this error.

        sketch_mar25b:50: error: ‘client’ was not declared in this scope
        if (!!!client.connected()) {
        ^
        sketch_mar25b:67: error: ‘client’ was not declared in this scope
        if (client.publish(topic, (char*) payload.c_str())) {
        ^
        exit status 1
        ‘client’ was not declared in this scope

        I am using pubsub client version 2.3

      • KiranShashi March 25, 2016

        I got this error , sketch_mar25b:27: error: ‘callback’ was not declared in this scope
        PubSubClient client(server, 1883, callback, wifiClient);
        So, I commented this as well as the call back as I read that it was not needed.

        Now, I am getting another error.

        sketch_mar25b.ino: In function ‘void loop()’:
        sketch_mar25b:50: error: ‘client’ was not declared in this scope
        if (!!!client.connected()) {
        ^
        sketch_mar25b:67: error: ‘client’ was not declared in this scope
        if (client.publish(topic, (char*) payload.c_str())) {
        ^
        exit status 1
        ‘client’ was not declared in this scope

        • The problem around the callback function is due to a bug with the ESP8266 support in the Arduino IDE which means from the 1.6.6 release functions need to be defined before they are used – so closer to the top of the source code file. There are some other issues with the later releases so this recipe was written using the 1.6.5 release of the Arduino IDE, and thats still the release I still use for most of the ESP work I do as it seems most stable. If you want to use more recent releases then until the bug is fixed you can just remove the callback function and change the client definition to use NULL. In fact, as it isn’t used in the example and keeps causing people grief I’ll go do that here in the recipe code.

  6. SteveStrutt January 31, 2016

    I was getting the same error as reported in 1, so perhaps the formatting of the example code has been corrupted again.
    Though I resolved it by changing the code to:
    String payload = “{“;
    payload += “d:{myName:ESP8266.ESPSPS1,counter:”;
    payload += counter;
    payload += “}}”;
    Which the compiler is OK with.

    • Yes the formatting had been corrupted again losing the escaped quote characters, i’ve corrected it again. It does highlight the awkwardness of having to hand craft JSON payloads, think i’ll go look at writing a IoTF library for the ESP that simplifies this…

  7. […] PubSubClient library the 8266 is able to use the mqtt protocol and publish the data. You can follow this recipe that contains the simple […]

  8. Is anyone have been able to connect to Bluemix throught secure port ?

  9. Dear antelder,

    I tryied the lastest code version and everything is OK with that, thank you for this useful information. I need a help from you and is the following: when I send a short string, with 2 variables (the counter with millis() and a temperature value) like this:
    String payload = “{\”d\”:{\”Antonio Martinez\”:\”ESP8266 Test\”,\”Execution Time (s)\”:”;
    payload += millis() / 1000;
    payload += “,\”Temperature in °C\”:”;
    payload += t;
    payload+= “}}”;

    It publish all the data with no problem, and everything is OK, but… When I try to send more parameters in the same string “payload”, like this:

    String payload = “{\”d\”:{\”Antonio Martinez\”:\”ESP8266 Test\”,\”Execution Time (s)\”:”;
    payload += millis() / 1000;
    payload += “,\”Temperature in °C\”:”;
    payload += t;
    payload += “,\”Temeperature in °F\”:”;
    payload += f;
    payload += “,\”Humidity in %\”:”;

    payload += “}}”;

  10. Dear antelder,

    I tryied the lastest code version and everything is OK with that, thank you for this useful information. I need a help from you and is the following: when I send a short string, with 2 variables (the counter with millis() and a temperature value) like this:
    String payload = “{\”d\”:{\”Antonio Martinez\”:\”ESP8266 Test\”,\”Execution Time (s)\”:”;
    payload += millis() / 1000;
    payload += “,\”Temperature in °C\”:”;
    payload += t;
    payload+= “}}”;

    It publish all the data with no problem, and everything is OK, but… When I try to send more parameters in the same string “payload”, like this:

    String payload = “{\”d\”:{\”Antonio Martinez\”:\”ESP8266 Test\”,\”Execution Time (s)\”:”;
    payload += millis() / 1000;
    payload += “,\”Temperature in °C\”:”;
    payload += t;
    payload += “,\”Temeperature in °F\”:”;
    payload += f;
    payload += “,\”Humidity in %\”:”;
    payload += h
    payload += “}}”;

    The serial monitor show me “publish failed” I do not know why. Can you help please? I want to publish as many variables as I want to the cloud. Thanks

  11. #define ORG “ql79fd”
    #define DEVICE_TYPE “IOTPulse_01”
    #define DEVICE_ID “IOTPulse”
    #define TOKEN “xl8BXYzNJu8MZ(Rsql”

    char server[] = ORG “.messaging.internetofthings.ibmcloud.com”;
    char topic[] = “iot-2/evt/status/fmt/json”;
    char authMethod[] = “use-token-auth”;
    char token[] = TOKEN;
    char clientId[] = “d:” ORG “:” DEVICE_TYPE “:” DEVICE_ID;

    WiFiClient wifiClient;
    PubSubClient client(server, 1883, NULL, wifiClient);

    void setup() {
    Serial.begin(115200);
    Serial.println();

    Serial.print(“Connecting to “); Serial.print(ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(“.”);
    }
    Serial.println(“”);

    Serial.print(“WiFi connected, IP address: “); Serial.println(WiFi.localIP());
    }

    int counter = 0;

    void loop() {

    if (!!!client.connected()) {
    Serial.print(“Reconnecting client to “);
    Serial.println(server);
    while (!!!client.connect(clientId, authMethod, token)) {
    Serial.print(“.”);
    delay(500);
    }
    Serial.println();
    }

    String payload = “{“d”:{“myName”:”ESP8266.Test1″,”counter”:”;
    payload += counter;
    payload += “}}”;

    Serial.print(“Sending payload: “);
    Serial.println(payload);

    if (client.publish(topic, (char*) payload.c_str())) {
    Serial.println(“Publish ok”);
    } else {
    Serial.println(“Publish failed”);
    }

    ++counter;
    delay(10000);
    }

    • WiFi connected, IP address: 192.168.0.104
      Reconnecting client to ql79fd.messaging.internetofthings.ibmcloud.com
      ……………………………..
      It doesn’t seem to connect

      • Hi s10163741. Sorry for the delay replying, I’ve been away. Its not connecting due to a problem with your clientId. Could you check the values of your ORG , DEVICE_TYPE, DEVICE_ID and TOKEN?

  12. Trying to connect with 2 different devices, I cannot connect and keep getting loggings in the dashboard like: Closed connection from x.x.x.x. The operation is not authorized.
    I verified ORG , DEVICE_TYPE, DEVICE_ID and TOKEN.
    Is there a way to verify that the platform itself is correctly configured?

  13. Hi,
    I try to connect my nodemcu esp8266 to bluemix, but i found this message “Closed connection from 190.156.172.114. The operation is not authorized.”,
    I check the custom values. I have no idea what the fault might be.

  14. i can’t be able to access the ibm server and it just printing the dots while i up loading the program.

    Connecting to Casual…nWiFi connected, IP address: 10.11.116.142
    Reconnecting MQTT client to t24682.messaging.internetofthings.ibmcloud.com
    ………………………………………………………..

    what are the changes are done in ibm and where should i change the code.please inform me i am trying so many times with so many ways……..now i feel bad about it please help me

  15. i can’t be able to access the ibm server and it just printing the dots while i up loading the program.As i created application in united kingdom not in US south is this problem comes because of that and it is not getting the ibm server .

    Connecting to Casual…nWiFi connected, IP address: 10.11.116.142
    Reconnecting MQTT client to t24682.messaging.internetofthings.ibmcloud.com
    ………………………………………………………………………………………………………………………………………….

    what are the changes are done in ibm and where should i change the code.please inform me i am trying so many times with so many ways……..now i feel bad about it please help me

  16. I tried this tutorial and isnt working in my NODEMCU ESP 8266.

    I wrote everything correct and my in using monitor serial my device stay stuck in this while:
    while (!!!client.connect(clientId, authMethod, token)) {
    Serial.print(“.”);
    delay(500);

  17. Hmm, the code work perfectly fine for me, 1st run. Thanks!!

Join The Discussion