How to Setup and Run Azure SDK for Embedded C IoT Hub Client on Espressif ESP8266 NodeMCU

Introduction

This is a "to-the-point" guide outlining how to run an Azure SDK for Embedded C IoT Hub telemetry sample on an Esp8266 NodeMCU microcontroller. The command line examples are tailored to Debian/Ubuntu environments.

What is Covered

  • Configuration instructions for the Arduino IDE to compile a sample using the Azure SDK for Embedded C.
  • Configuration, build, and run instructions for the IoT Hub telemetry sample.

The following was run on Windows 10 and Ubuntu Desktop 20.04 environments, with Arduino IDE 1.8.12 and Esp8266 module 2.7.4.

Prerequisites

  • Have an Azure account created.

  • Have an Azure IoT Hub created.

  • Have a logical device created in your Azure IoT Hub using the authentication type "Symmetric Key".

    NOTE: Device keys are used to automatically generate a SAS token for authentication, which is only valid for one hour.

  • Have the latest Arduino IDE installed.

  • Have the ESP8266 board support installed on Arduino IDE. ESP8266 boards are not natively supported by Arduino IDE, so you need to add them manually.

    • ESP8266 boards are not natively supported by Arduino IDE, so you need to add them manually.
    • Follow the instructions in the official Esp8266 repository.
  • Have one of the following interfaces to your Azure IoT Hub set up:

    NOTE: This guide demonstrates use of the Azure CLI and does NOT demonstrate use of Azure IoT Explorer.

Setup and Run Instructions

  1. Create an Arduino library for the Azure SDK for Embedded C.

    On Windows: Use the PowerShell commands below.

    PS C:\> Invoke-WebRequest -Uri https://raw.githubusercontent.com/Azure/azure-sdk-for-c/master/sdk/samples/iot/aziot_esp8266/New-ArduinoZipLibrary.ps1 -OutFile New-ArduinoZipLibrary.ps1
    
    PS C:\> .\New-ArduinoZipLibrary.ps1
    

    Note that in several cases, script execution is restricted by default for security reasons. If you can't run the script above, then run PowerShell as Administrator and set the execution policy:

    Set-ExecutionPolicy Unrestricted
    

    In this case, don't forget to move the security settings back once you complete the setup if you wish:

    Set-ExecutionPolicy Restricted
    

    On Linux:

    $ wget https://raw.githubusercontent.com/Azure/azure-sdk-for-c/master/sdk/samples/iot/aziot_esp8266/generate_arduino_zip_library.sh
    $ chmod 777 generate_arduino_zip_library.sh
    $ ./generate_arduino_zip_library.sh
    

    This will create a local file named azure-sdk-for-c.zip containing the entire Azure SDK for Embedded C repository as an Arduino library.

    NOTE: If you are using WSL, do not run these commands from the Windows system drive (e.g. /mnt/c/).

  2. Run the Arduino IDE.

  3. Install the Azure SDK for Embedded C zip library.

    • On the Arduino IDE, go to Sketch, Include Library, Add .ZIP Library....
    • Search for the azure-sdk-for-c.zip created on step 1.
    • Select the file azure-sdk-for-c.zip and click on OK.
  4. Install the Arduino PubSubClient library. (PubSubClient is a popular MQTT client for Arduino.)

    • On the Arduino IDE, go to menu Sketch, Include Library, Manage Libraries....
    • Search for PubSubClient (by Nick O'Leary).
    • Hover over the library item on the result list, then click on "Install".
  5. Create a sketch on Arduino IDE for the IoT Hub telemetry sample.

    • Clone the Azure SDK for Embedded C repository locally

    • Generate the ca.h header (in the ESP8266 sample folder!) with the public root CA for server certificate validation

      • Navigate to the ESP8266 sample in your local cloned repo

        cd <cloned repo root>/sdk/samples/iot/aziot_esp8266
        
      • Run the script to generate the ca.h header.

        On Windows (using Poweshell):

        .\New-TrustedCertHeader.ps1
        

        On Linux:

        ./create_trusted_cert_header.sh
        
    • Open the ESP8266 sample (from the local clone) on the Arduino IDE.

    • Edit the following parameters in iot_configs.h, filling in your own information:

      // Wifi
      #define IOT_CONFIG_WIFI_SSID            "SSID"
      #define IOT_CONFIG_WIFI_PASSWORD        "PWD"
      
      // Azure IoT
      #define IOT_CONFIG_IOTHUB_FQDN          "[your host name].azure-devices.net"
      #define IOT_CONFIG_DEVICE_ID            "Device ID"
      #define IOT_CONFIG_DEVICE_KEY           "Device Key"
      
    • Save the file.

  6. Connect the Esp8266 NodeMCU microcontroller to your USB port.

  7. On the Arduino IDE, select the board and port.

    • Go to menu Tools, Board and select NodeMCU 1.0 (ESP-12E Module).
    • Go to menu Tools, Port and select the port to which the microcontroller is connected.
  8. Upload the sketch.

    • Go to menu Sketch and click on Upload.

      Expected output of the upload:

      Executable segment sizes:
      IROM   : 361788          - code in flash         (default or ICACHE_FLASH_ATTR)
      IRAM   : 26972   / 32768 - code in IRAM          (ICACHE_RAM_ATTR, ISRs...)
      DATA   : 1360  )         - initialized variables (global, static) in RAM/HEAP
      RODATA : 2152  ) / 81920 - constants             (global, static) in RAM/HEAP
      BSS    : 26528 )         - zeroed variables      (global, static) in RAM/HEAP
      Sketch uses 392272 bytes (37%) of program storage space. Maximum is 1044464 bytes.
      Global variables use 30040 bytes (36%) of dynamic memory, leaving 51880 bytes for local variables. Maximum is 81920 bytes.
      /home/user/.arduino15/packages/esp8266/tools/python3/3.7.2-post1/python3 /home/user/.arduino15/packages/esp8266/hardware/esp8266/2.7.1/tools/upload.py --chip esp8266 --port /dev/ttyUSB0 --baud 230400 --before default_reset --after hard_reset write_flash 0x0 /tmp/arduino_build_826987/azure_iot_hub_telemetry.ino.bin
      esptool.py v2.8
      Serial port /dev/ttyUSB0
      Connecting....
      Chip is ESP8266EX
      Features: WiFi
      Crystal is 26MHz
      MAC: dc:4f:22:5e:a7:09
      Uploading stub...
      Running stub...
      Stub running...
      Changing baud rate to 230400
      Changed.
      Configuring flash size...
      Auto-detected Flash size: 4MB
      Compressed 396432 bytes to 292339...
      
      Writing at 0x00000000... (5 %)
      Writing at 0x00004000... (11 %)
      Writing at 0x00008000... (16 %)
      Writing at 0x0000c000... (22 %)
      Writing at 0x00010000... (27 %)
      Writing at 0x00014000... (33 %)
      Writing at 0x00018000... (38 %)
      Writing at 0x0001c000... (44 %)
      Writing at 0x00020000... (50 %)
      Writing at 0x00024000... (55 %)
      Writing at 0x00028000... (61 %)
      Writing at 0x0002c000... (66 %)
      Writing at 0x00030000... (72 %)
      Writing at 0x00034000... (77 %)
      Writing at 0x00038000... (83 %)
      Writing at 0x0003c000... (88 %)
      Writing at 0x00040000... (94 %)
      Writing at 0x00044000... (100 %)
      Wrote 396432 bytes (292339 compressed) at 0x00000000 in 13.0 seconds (effective 243.4 kbit/s)...
      Hash of data verified.
      
      Leaving...
      Hard resetting via RTS pin...
      

  9. Monitor the MCU (microcontroller) locally via the Serial Port.

    • Go to menu Tools, Serial Monitor.

      If you perform this step right away after uploading the sketch, the serial monitor will show an output similar to the following upon success:

      Connecting to WIFI SSID buckaroo
      .......................WiFi connected, IP address:
      192.168.1.123
      Setting time using SNTP..............................done!
      Current time: Thu May 28 02:55:05 2020
      Client ID: mydeviceid
      Username: myiothub.azure-devices.net/mydeviceid/?api-version=2018-06-30&DeviceClientType=c%2F1.0.0
      Password: SharedAccessSignature sr=myiothub.azure-devices.net%2Fdevices%2Fmydeviceid&sig=0VFwGiXlIVPeCmPStJ4Fb1wbS8o2W8p1vzIOt%2B8K2eE%3D&se=1590620105
      MQTT connecting ... connected.
      
  10. Monitor the telemetry messages sent to the Azure IoT Hub using the connection string for the policy name iothubowner found under "Shared access policies" on your IoT Hub in the Azure portal.

    $ az iot hub monitor-events --login <your Azure IoT Hub owner connection string in quotes> --device-id <your device id>
    
    Expected telemetry output:

    Starting event monitor, filtering on device: mydeviceid, use ctrl-c to stop...
    {
        "event": {
            "origin": "mydeviceid",
            "payload": "payload"
        }
    }
    {
        "event": {
            "origin": "mydeviceid",
            "payload": "payload"
        }
    }
    {
        "event": {
            "origin": "mydeviceid",
            "payload": "payload"
        }
    }
    {
        "event": {
            "origin": "mydeviceid",
            "payload": "payload"
        }
    }
    {
        "event": {
            "origin": "mydeviceid",
            "payload": "payload"
        }
    }
    {
        "event": {
            "origin": "mydeviceid",
            "payload": "payload"
        }
    }
    ^CStopping event monitor...
    

Certificates - Important to know

The Azure IoT service certificates presented during TLS negotiation shall be always validated, on the device, using the appropriate trusted root CA certificate(s).

For the Node MCU ESP8266 sample, our script generate_arduino_zip_library.sh automatically downloads the root certificate used in the United States regions (Baltimore CA certificate) and adds it to the Arduino sketch project.

For other regions (and private cloud environments), please use the appropriate root CA certificate.

Additional Information

For important information and additional guidance about certificates, please refer to this blog post from the security team.

Troubleshooting

  • The error policy for the Embedded C SDK client library is documented here.
  • File an issue via GitHub Issues.
  • Check previous questions or ask new ones on StackOverflow using the azure and c tags.

Contributing

This project welcomes contributions and suggestions. Find more contributing details here.

License

Azure SDK for Embedded C is licensed under the MIT license.