Skill Level: Any Skill Level

Makers and Developers who are interested in connecting inexpensive IoT devices to the cloud with basics knowledge on microcontroller



  1. Introduction

    The ESP8266 is a small serial-to-WiFi microcontroller that costs as low as $2. It has processing and storage capabilities that allow it to be integrated with the sensors and other application specific devices through its GPIOs with minimal development up-front and minimal loading during runtime. While the ESP8266 cant do everything you could do with an Arduino or Raspberry Pi but for $2 its a bargain and makes it suitable for mass deployment of small and lightweight IoT devices.

    This is inexpensive enough to be very much in the territory of thousands of sensors-launched-out-of-a-cannon-cheap. Brian Jepson.

    To program ESP8266, we will use lua based NodeMCU firmware that has built-in MQTT functions required to communicate with Watson IoT service. Lua is lightweight interpreter language specifically intended for microcontroller. The recipe is basically few lines of lua script that periodically publish emulated data to the Watson IoT. In real application, the data will be obtained from external sensor such as temperature, humidity, etc through ESP8266 GPIOs.

  2. Prepare

    If you are first time user of ESP8266, familiarize yourself with flashing the NodeMCU firmware, loading and running the lua scripts. There are many tutorials in the net that serve the purpose, this is one of them. Complete links and API documentation to write your own lua scripts are available in the NodeMCU wiki.

    1. Wire ESP8266 to the FTDI USB to Serial adapter. Connect the USB to Serial adapter to the windows PC using USB cable.
    2. Download NodeMCU flasher, latest version of the NodeMCU firmware and LuaLoader.
    3. Flash the NodeMCU firmware to the ESP8266. Make sure you connect GPIO0 pin to ground during flashing.
    4. Create init.lua and mainIoTF.lua scripts provided below.
      • Modify macID, SSID and wifiPWD accordingly
    5. Using LuaLoader, load init.lua and mainIoTF.lua scripts..
    6. Restart the ESP8266. Here it goes!!!
  3. init.lua

    -- Executed everytime it restarts or power on
    tmr.alarm(0, 10000, 0, function() dofile(mainIoTF.lua) end)

  4. mainIoTF.lua


    orgID = "quickstart" -- IoT Foundation organization ID
    broker = orgID..".messaging.internetofthings.ibmcloud.com" -- IP or hostname of IoTF service
    mqttPort = 1883 -- MQTT port (default 1883: non-secure)
    userID = "" -- blank for quickstart
    userPWD = "" -- blank for quickstart
    macID = "18fe349e543f" -- unique Device ID or Ethernet Mac Address <==== Modify this!
    clientID = "d:"..orgID..":esp8266:"..macID -- Client ID
    count = 0 -- Test number of mqtt_do cycles
    mqttState = 0 -- State control

    topic = "iot-2/evt/status/fmt/json"

    t0 = tmr.time()

    -- Wifi credentials
    SSID = "xxxxxxxxxxxx" -- <========== Modify this!
    wifiPWD = "xxxxxxxxx" -- <========== Modify this!

    function wifi_connect()

    function mqtt_do()
    count = count + 1 -- tmr.alarm counter

    if mqttState < 5 then
    mqttState = wifi.sta.status() --State: Waiting for wifi

    elseif mqttState == 5 then
    print("Starting to connect...")
    m = mqtt.Client(clientID, 120, userID, userPWD)

    m:on("offline", function(conn)
    print ("Checking IoTF server...")
    mqttState = 0 -- Starting all over again

    m:connect(broker , mqttPort, 0,
    print("Connected to " .. broker .. ":" .. mqttPort)
    mqttState = 20 -- Go to publish state

    elseif mqttState == 20 then
    mqttState = 25 -- Publishing...
    t1 = tmr.time() - t0
    if t1 > 100 then
    t1 = 0
    t0 = tmr.time()
    -- t1 is used as emulated sensor data, real application will use GPIOx to sense external sensor

    m:publish(topic ,'{"d": {"data":'..t1..'}}', 0, 0,

    -- Print confirmation of data published
    print("Sent message #"..count.." data:"..t1)
    mqttState = 20 -- Finished publishing - go back to publish state.

    else print("Waiting..."..mqttState)
    mqttState = mqttState - 1 -- takes us gradually back to publish state to retry


    tmr.alarm(2, 10000, 1, function() mqtt_do() end) -- send data every 10s

  5. Visualize (Quickstart)

    To view the data real-time, simply visit Quickstart and type in macID of mainIoTF.lua (MAC address of ESP8266) then click ‘Go’.

    It should show emulated sawtooth waveform.

  6. Signing up registered connection with IBM Bluemix

    The quickstart service that we have used above is a public sandbox instance of IBM Watson IoT Platform that runs 24 hours a day. It is used to test device connectivity and to visualise data flowing from the device quickly whithout having to check for any security credentials.

    Once basic connectivity has been proven, you need to sign up and create registered connection to IoT service. This IoT service enables connectivity from the device to the cloud to be secured and access to both the device and data from the device to be controlled.

    You can sign up and register devices to an IBM Watson IoT Platform organization by using IBM Bluemix.

    • Go to IBM Bluemix. If you are an existing Bluemix user log in as usual. If you are new to Bluemix you can sign up for their free 30 day trial.
    • To register devices, you must first create an Watson IoT organization. To do this, create an instance of the Internet of Things Platform Service, which is found by scrolling to the Internet of Things section of the Catalog in Bluemix. When you have added the service, select it in your dashboard to open the service page. Launch the IoT portal, where you can add your devices and obtain the security credentials for your IoT organization.
    • Once you have access to an IBM Watson IoT Platform organization through Bluemix, you can click to Add a new device on the IoT organization dashboard.
    • During the device registration process you will receive the following information.
      • Organization ID
      • Device Type (pls use esp3822 in the device registration)
      • Device ID (pls use macID in the device registration)
      • Authentication Method
      • Authentication Token
    • Use this information to update parameters in mainIoTF.lua
      • orgID = “xxxxxxx” <===== fill in Organization ID to replace xxxxxxxxx
      • userID = “use-token-auth”
      • userPWD = “xxxxxxxxxxxxxx” <===== fill in Authentication Token to replace xxxxxxxxxx

    You can start to build the application in Bluemix to process the device data. A temperature alarm application that takes less than 15 minutes to build with Node-Red is described in “Cloud-ready temperature & humidity sensor for IBM Watson IoT Platform” recipe.

8 Comments on "Connect Espressif ESP8266 to IBM Watson IoT Platform"

  1. Hey, thanks for doing this, I got connected in no time!

    I noticed that something tried to “pretty” up your code by adding curtly-quotes and other things that break the script, so I published a cleaned up version to github that has all of that fixed + a tweak to make it automatically read and report the chip’s built-in mac address: https://gist.github.com/nfriedly/228188d6929f421b3d93

    • @nfriedly, that’s great, thanks… Btw, that ‘quickstart’ in broker and clientID should be replaced with value of orgID, not hardcoded…

      • Right, thanks. Although it looks like yours is cleaned up now, so I’ll probably just take mine down.

        On a related note, I could get it to send data but not receive any (I did set up my own IoTF service and connect my device to that) – can you show an example of it working in the other direction?

        (I ended up switching to Arduino software and there I got it working in both directions. I should probably clean that up and post a separate recipe…)

      • BTW, the one improvement I might suggest is running wifi.sta.getmac():gsub(‘-‘,”) for the MAC and then printing it to the console instead of telling people to modify the line themselves 😉

    • For folks using the ESP8266 NodeMCU 12E (With WiFi and USB port):
      These instructions work well. Just ignore the part about pins and flashing. The NodeMCU firmware can flash directly from the application without the need for grounding any pins or pressing buttons on the board.
      @nfriedly Thank you for the updated code and adding the MAC lookup. Works great.
      Mayur Gundecha

      • To clarify: If using the NodeMCU 12E V1.0, ignore the following instruction: “Make sure you connect GPIO0 pin to ground during flashing.”.

  2. Excellent recipe 🙂 I did something similar a earlier this year but took the approach of using the ESP8266 as IoT hub for a number of Arduino’s but using I2C. I got the basics working but ran out of time to get all the bug’s worked out. If this approach is of any interest my efforts can be found in my developer works blog https://www.ibm.com/developerworks/community/blogs/hickmat – there are a few posts here relating to my ESP8266 experiments.

Join The Discussion