Securely Connecting an Arduino NB 1500 to Azure IoT Hub
In this tutorial, you'll learn how to connect your Arduino MKR NB 1500 board securely to Microsoft Azure IoT Hub.
Components and Supplies
- Arduino MKR NB 1500
- Micro-USB to USB Cable (Generic)
- 3.7V Lipo Battery
- Micro SIM card
Apps and Online Services
About This Project
Introduction
Azure IoT Hub allows you to "securely connect, monitor, and manage billions of device to develop Internet of Things (IoT) applications."
Devices can connect to Azure IoT Hub using the following protocols: HTTPS, AMPQ and MQTT - Azure also provides SDKs for many programming languages to abstract these protocols. In addition, you can connect to IoT Hub via an MQTT client. This page has more information on IoT Hub’s MQTT support.
This tutorial will walk you through how to connect an Arduino MKR NB 1500 board securely to Azure IoT Hub using an MQTT client. MQTT (Message Queuing Telemetry Transport) is a M2M (machine-to-machine) connectivity protocol which provides a messaging subscription and publish transport.
Devices can use SAS tokens or X.509 certificates for authentication with Azure IoT Hub, more information can be found here. In this tutorial, we'll use an X.509 certificate to authenticate the board.
Every Arduino MKR board with on-board connectivity, including the MKR NB 1500, is equipped with a Microchip ATECC508A or ATECC608A crypto element. This crypto element can be used to securely generate and store a 256-bit ECC (Elliptic Curve Cryptography) key.
Software and Hardware Setup
If you don't have the Arduino IDE installed on your computer, download and install it.
Once it is installed, make sure you have the latest "Arduino SAMD Boards" package installed. You can check by opening the Arduino IDE, and opening the Tools -> Board: "..." -> Board Manager... menu entry, and searching for "Arduino SAMD". At the time of writing 1.6.20 was the latest version.
Next you'll need to install the Arduino libraries that will be used, using the Arduino IDE's library manager. Open the Sketch -> Include Library -> Manage Libraries... menu, search for and individually install each of the following libraries:
- MKRNB
- ArduinoBearSSL
- ArduinoECCX08
- ArduinoMqttClient
- Arduino Cloud Provider Examples
Now insert the micro SIM card in the slot on the bottom of the MKR NB 1500 board and attach the 3.7V Lipo battery to the JST PH connector. Then plug in the MKR NB 1500 with the micro USB cable to your computer, select the serial port in the Arduino IDE using the Tools -> Port "..." menu and also select Arduino MKR NB 1500 in the Tools -> Board "..." menu.
Configuring and Adding the Board to Azure IoT Hub
As mentioned above, Azure IoT Hub allows devices that connect using the MQTT protocol and use X.509 certificates for authentication. We'll use a sketch to generate a self signed X.509 Certificate on the board and then add the SHA1 of this certificate to Azure IoT Hub portal.
The self signed certificate can be generated using an example sketch from the ArduinoECCX08 library. Open the sketch in the Arduino IDE using the File -> Examples -> ArduinoECCX08 -> Tools -> ECCX08SelfSignedCert. Click the "Upload" button to build and upload the sketch to your board, then open the Serial Monitor. Make sure the line ending configuration is set to "Both NL & CR."
This sketch will prompt you to permanently configure your ATECC508A to ECC608A crypto element if it is not configured and locked.
Note: This locking process is permanent and irreversible, but is needed to use the the crypto element - the configuration the sketch sets allows to use 5 private key slots with any Cloud provider(or server) and a private key can be regenerated any time for any of the 5 private key slots (0 - 4).When the board is shipped from the factory, the crypto element is in an un-configured and unlocked state.
After this, you will be prompted for information to include in the self signed certificate, including the issue year, month, day and hour of the certificate and the expiry period in years. For this tutorial we'll be using slot 0 to generate and store the private key used to sign the self signed certificate (slots 1 to 4 can be used to generate and store additional private keys if needed) - then slot 8 will be used to store the issue and expiry date of the certificate along with it's signature.
Note: Since the private key is generated inside the crypto element it never leaves the device and is stored securely and cannot be read.
Copy the generated SHA1 value (in this screenshot "99d6d96fa55bdf08b4040a142a8d0d934bc9d12b"). We will use it in a later step as a fingerprint for the self signed certificate for the device in Azure IoT Hub.
Now that we have a self signed certificate and the SHA1 fingerprint to identify the board, we need to login into the Azure IoT Hub portal and create a new device for it.
1) Open a web browser and goto portal.azure.com.
2) If you don't already have an Azure account, click the "Create one!" link on the page to create an account. Otherwise, enter your email address and click "Next" and follow the login process.
3) On the navigation panel on the left click "Create a resource".
4) Then click "Internet of Things" and "IoT Hub".
5) You will be prompted to select a Subscription, Resource group, Region and IoT Hub Name. In the screenshot below, "Free Trial", "MKR", "East US", and "ArduinoProjectHubTutorial" were used as input. Click "Review + Create" to continue.
6) A confirmation screen will appear click "Create".
7) You will have to wait a few minutes for the IoT Hub to be created and deployed.
8) Once deployment is complete a "Go to resource" button will appear, click it.
9) Now we can create a new IoT device, click "IoT Devices" under the "Explore" heading.
10) Click the "Add" button to add a new device.
11) Enter a name for the device, below "MyMKRNB1500" was entered, then click the "X.509 Self-Signed" tab. Paste the SHA1 from the Arduino IDE's serial monitor for both the Primary and Secondary Thumbprint. Then click the "Save" button to create the device.
12) You will now see a new entry on the IoT Devices page.
Connecting the Board to Azure IoT Hub
1) Open the Azure IoT Hub NB sketch in the Arduino IDE using File -> Examples -> Arduino Cloud Provider Examples -> AzureIoTHub-> Azure_IoT_Hub_NB.
2) In the arduino_secrets.h tab, fill in the pin (if required) for the SIM card.
1// NB settings2#define SECRET_PINNUMBER ""
3) Update the broker value with the endpoint created in the Azure IoT Hub portal.
1// Fill in the hostname of your Azure IoT Hub broker2#define SECRET_BROKER "<hub name>.azure-devices.net"
4) Update the device id value, with the name of the device you created in the Azure IoT Hub portal.
1// Fill in the device id2#define SECRET_DEVICE_ID "<device id>"
5) Upload the sketch to your board and open the serial monitor. The board will attempt to connect to the cellular network and if successful try to connect to Azure IoT Hub using MQTT.
Interacting with the Board on Azure IoT Core
Now that your board has successfully connected to Azure IoT Hub, we can use the Azure IoT Hub portal to interact with it. The sketch sends a message to the devices/{deviceId}/messages/events/ topic every 5 seconds and listens for messages on the devices/{deviceId}/messages/devicebound/# topic.
In the Azure IoT Hub portal, click the device id row in the IoT Devices table for your board. Then click the "Message to device" button in the toolbar.
You can now enter a message body to send to the device, in the screenshot below "Hello there :)" was entered. Click the "Send Message" button in the toolbar to send the message.
When the board receives the message, the Serial Monitor in the Arduino IDE will display it.
To view the messages the board is sending:
1) Log into shell.azure.com (select "Bash" if this is your first time when prompted).
2) Install the IoT Hub Extension:
1az extension add --name azure-cli-iot-ext
3) Run the following command, replace
<hub name>
with the name of your hub (enter y if prompted for dependency update):1az iot hub monitor-events --hub-name <hub name>
4) You will see messages printed to the shell:
Complete Sketch
1*2 Azure IoT Hub NB3 This sketch securely connects to an Azure IoT Hub using MQTT over NB IoT/LTE Cat M1.4 It uses a private key stored in the ATECC508A and a self signed public5 certificate for SSL/TLS authentication.6 It publishes a message every 5 seconds to "devices/{deviceId}/messages/events/" topic7 and subscribes to messages on the "devices/{deviceId}/messages/devicebound/#"8 topic.9 The circuit:10 - MKR NB 1500 board11 - Antenna12 - SIM card with a data plan13 - LiPo battery14 The following tutorial on Arduino Project Hub can be used15 to setup your Azure account and the MKR board:16 https://create.arduino.cc/projecthub/Arduino_Genuino/securely-connecting-an-arduino-nb-1500-to-azure-iot-hub-af647017 This example code is in the public domain.18*/19
20#include <ArduinoBearSSL.h>21#include <ArduinoECCX08.h>22#include <utility/ECCX08SelfSignedCert.h>23#include <ArduinoMqttClient.h>24#include <MKRNB.h>25
26#include "arduino_secrets.h"27
28/////// Enter your sensitive data in arduino_secrets.h29const char pinnumber[] = SECRET_PINNUMBER;30const char broker[] = SECRET_BROKER;31String deviceId = SECRET_DEVICE_ID;32
33NB nbAccess;34GPRS gprs;35
36NBClient nbClient; // Used for the TCP socket connection37BearSSLClient sslClient(nbClient); // Used for SSL/TLS connection, integrates with ECC50838MqttClient mqttClient(sslClient);39
40unsigned long lastMillis = 0;41
42void setup() {43 Serial.begin(9600);44 while (!Serial);45
46 if (!ECCX08.begin()) {47 Serial.println("No ECCX08 present!");48 while (1);49 }50
51 // reconstruct the self signed cert52 ECCX08SelfSignedCert.beginReconstruction(0, 8);53 ECCX08SelfSignedCert.setCommonName(ECCX08.serialNumber());54 ECCX08SelfSignedCert.endReconstruction();55
56 // Set a callback to get the current time57 // used to validate the servers certificate58 ArduinoBearSSL.onGetTime(getTime);59
60 // Set the ECCX08 slot to use for the private key61 // and the accompanying public certificate for it62 sslClient.setEccSlot(0, ECCX08SelfSignedCert.bytes(), ECCX08SelfSignedCert.length());63
64 // Set the client id used for MQTT as the device id65 mqttClient.setId(deviceId);66
67 // Set the username to "<broker>/<device id>/api-version=2018-06-30" and empty password68 String username;69
70 username += broker;71 username += "/";72 username += deviceId;73 username += "/api-version=2018-06-30";74
75 mqttClient.setUsernamePassword(username, "");76
77 // Set the message callback, this function is78 // called when the MQTTClient receives a message79 mqttClient.onMessage(onMessageReceived);80}81
82void loop() {83 if (nbAccess.status() != NB_READY || gprs.status() != GPRS_READY) {84 connectNB();85 }86
87 if (!mqttClient.connected()) {88 // MQTT client is disconnected, connect89 connectMQTT();90 }91
92 // poll for new MQTT messages and send keep alive93 mqttClient.poll();94
95 // publish a message roughly every 5 seconds.96 if (millis() - lastMillis > 5000) {97 lastMillis = millis();98
99 publishMessage();100 }101}102
103unsigned long getTime() {104 // get the current time from the cellular module105 return nbAccess.getTime();106}107
108void connectNB() {109 Serial.println("Attempting to connect to the cellular network");110
111 while ((nbAccess.begin(pinnumber) != NB_READY) ||112 (gprs.attachGPRS() != GPRS_READY)) {113 // failed, retry114 Serial.print(".");115 delay(1000);116 }117
118 Serial.println("You're connected to the cellular network");119 Serial.println();120}121
122void connectMQTT() {123 Serial.print("Attempting to MQTT broker: ");124 Serial.print(broker);125 Serial.println(" ");126
127 while (!mqttClient.connect(broker, 8883)) {128 // failed, retry129 Serial.print(".");130 Serial.println(mqttClient.connectError());131 delay(5000);132 }133 Serial.println();134
135 Serial.println("You're connected to the MQTT broker");136 Serial.println();137
138 // subscribe to a topic139 mqttClient.subscribe("devices/" + deviceId + "/messages/devicebound/#");140}141
142void publishMessage() {143 Serial.println("Publishing message");144
145 // send message, the Print interface can be used to set the message contents146 mqttClient.beginMessage("devices/" + deviceId + "/messages/events/");147 mqttClient.print("hello ");148 mqttClient.print(millis());149 mqttClient.endMessage();150}151
152void onMessageReceived(int messageSize) {153 // we received a message, print out the topic and contents154 Serial.print("Received a message with topic '");155 Serial.print(mqttClient.messageTopic());156 Serial.print("', length ");157 Serial.print(messageSize);158 Serial.println(" bytes:");159
160 // use the Stream interface to print the contents161 while (mqttClient.available()) {162 Serial.print((char)mqttClient.read());163 }164 Serial.println();165
166 Serial.println();167}
Conclusion
In this tutorial, we covered how to securely use an Arduino MKR NB 1500 board with Azure IoT Hub. A self signed X.509 certificate was used to authenticate with Azure IoT Hub using the MQTT protocol with the ATECC508A or ATECC608A storing the private key associated with the certificate. MQTT messages were sent to and from the board.
This is just the beginning, you can use Azure IoT Hub with many of the other services Azure provides!
Suggest changes
The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.
License
The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.