Send data from NodeMCU to Azure IoT Hub

In this post we would see how to send data from NodeMCU to Azure IoT Hub.We would be sending temperature and humidity data from  DHT11 sensor .Previous post explains how to measure temperature and humidity  using DHT11 sensor.Azure IoT team has done some good documentation on various Azure IoT Hub topics and the credit of this blogpost goes to this page.

I assume you already have an Azure subscription to use.If not please visit this page and signup for an account.The first step is to create an IoT Hub.Like all Azure components we can search for it from portal if not added in favorites and then create a hub.You can search for IoT Hub from All services and then proceed with creating an IoT Hub.

Creating a hub involves giving a unique name,selecting region and resource group.Please enter or select the resource group and Region. Then proceed with giving a name for our IoT Hub.On the next tab ‘size and scale’ choose your pricing and scale tier.Please select Free tier(F1) if it’s available on your subscription.

Once Hub is created we can then create a device.When I say ‘create a device’ its just a way of letting Azure IoT Hub  know about devices which would connect.We can create a new device by clicking on the Add button.

Please proceed with entering a DeviceId and then select the Authentication Type that you want your device to use while connecting to the Hub.By default symmetrical key is selected which can be changed to X509 certificate if you intend to use a certificate while authenticating your devices.We would cover that later once we see how to use Device Provisioning Service (DPS) in Azure IoT.For now let’s select symmetric key and have the option Auto-generate-key checked which would generate the keys for us.

Click on the device created to see the details about keys and connection string.

This shows details about the device which we just created.It shows ConnectionString info as well.Please make sure you keep this information secure and don’t share it in public since this is the id which your device would use to connect to Azure IoT hub. You can see the options like Message to Device, Direct Method,Device twin etc., which can be ignored for now.We would cover these later  in our next post.

Here you go.You have just created your device in Azure IoT Hub.Next is to make our device talk with IoT Hub we have just created.

You can go to my github repo and clone  it. The folder “dht_temperature_AzureIotHub_New” contains three files.Please open “dht_temperature_AzureIotHub_New.ino” file in ArduinoIDE which should load all the three files as shown below.

Header file “dht_temperature_AzureIotHub_config.h” has details  about connection string and WiFi SSID and password.Please update these config and  then flash your NodeMCU .Please make sure you are giving updated connection string in  IOT_CONFIG_CONNECTION_STRING.

You can open Serial Monitor from Arduino IDE to view the details of data being send to Azure IoT Hub.

 

Now I would introduce you to another tool called Device Explorer which I find very useful to monitor and do some basic operations in Azure IoT hub. You can read more about this free  tool from link  and download the setup from here.

This tool runs on your  machine and connects to  IoT hub in Azure. So you need to get the connection details which tool would use to connect to your hub.For that we need to go back to Azure portal and copy the connection string value for iothubowner from Shared access policies in Azure IoT hub.Please be aware of the fact  that this is like admin account so watch out before sharing it with someone and avoid doing this with production secrets.

Configure the ConnectionString  in Configuration tab of Device Explorer as shown and click on Update button.

Once ConnectionString is updated, please go to the Data tab in Device Explorer and select the Event Hub. Ideally, there should be an EventHub and the name would match with name of our IoT Hub.Please select that and then click on the Monitor button.You can now have a real time view of data being sent to the Azure IoT hub. These details are pulled from the Azure IoT hub and is displayed in local  machine on which DeviceExplorer runs.

There you go.We have been successful in sending data from our NodeMCU to Azure IoT hub.Let’s see what the code does.

This code is  modified  version of the samples that comes along with Azure IoT hub C SDK  (here). My friends in the Azure IoT team have done some excellent documentation on Azure IoT C SDK and I strongly recommend you to read those. Please don’t miss “Use the IoTHub Client” and “Use the serializer” section as well.This link has some portion of code which we are using.These are the few AzureIoT libraries which you need to import: AzureIoTHub,AzureIoTProtocol_MQTT and AzureIoTUtility.Since we use JSON in this code we have ArduinoJson library which simplify JSON handling for us.

First, you need to create a handle using IoTHubClient_LL_CreateFromConnectionString method which  initializes the library.Then you call readMessage and passes a variable messagecount and a char array.We then call our wrapper sendMessage passing the handle and message we need to send.

In our wrapper we create a messagehandle and then use IoTHubClient_LL_SendEventAsync to send these data to Azure IoT.We also register a callback function sendCallback to be called when data is successfully sent.In this example we aren’t using serializer library .

We need to pass the protocol  in IoTHubClient_LL_CreateFromConnectionString method which is MQTT in this case.AQMP and HTTPS is also supported.

A few things to note here with C SDK, for Azure IoT hub. There are two sets of API methods one with LL and one without LL (low level).The corresponding methods are :

  • IoTHubClient_LL_SendEventAsync
  • IoTHubClient_LL_SetMessageCallback
  • IoTHubClient_LL_Destroy
  • IoTHubClient_LL_DoWork

When we use the method in LL API’s we have explicit control over network transmissions.To actually send the data we use IoTHubClient_LL_DoWork method  while IoTHubClient_LL_SendEventAsync just places the message in a buffer.Last but  not the least like with any native code don’t forget to clean up resources using IoTHubMessage_Destroy method.

This is what documented in the doc

“When you call IoTHubClient_CreateFromConnectionString, the underlying libraries create a new thread that runs in the background. This thread sends events to, and receives messages from, IoT Hub. No such thread is created when working with the LL APIs. The creation of the background thread is a convenience to the developer. You don’t have to worry about explicitly sending events and receiving messages from IoT Hub — it happens automatically in the background. In contrast, the LL APIs give you explicit control over communication with IoT Hub, if you need it“.

I haven’t tested non LL methods in NodeMCU.My assumption is multiple threads doesn’t make sense in ESP as long as it’s single core or have a single core of computing.I may be wrong and don’t know if anyone has ported it to FreeRTOS to support multi-threading yet .