Arduino Nano ESP32 - AWS IoT

This tutorial instructs you how to connect Arduino Nano ESP32 to AWS IoT Core. In detail, we will learn:

Arduino Nano ESP32 AWS IoT

Hardware Preparation

1×Arduino Nano ESP32
1×USB Cable Type-C
1×Breadboard
1×Jumper Wires
1×(Recommended) Screw Terminal Adapter for Arduino Nano

Or you can buy the following sensor kit:

1×DIYables Sensor Kit 30 types, 69 units
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you. We appreciate your support.

Overview of Arduino Nano ESP32 and AWS IoT

Arduino Nano ESP32 connects to AWS IoT Core via the MQTT protocol. This is not a big deal because the libraries are available, making it easy to use.

However, it is not as easy as connecting the Arduino Nano ESP32 to an MQTT broker like Mosquitto installed on your PC. This is because AWS IoT Core strictly enforces security measures. Configuration is necessary on AWS IoT Core to obtain authentication credentials and authorization before writing the Arduino Nano ESP32 code. In summary, we need to take two major steps:

  • Step 1: Configuring AWS IoT Core. After this step, we will obtain the authentication credentials, which will be used in the Arduino Nano ESP32 code.
  • Step 2: Writing the Arduino Nano ESP32 code.

Let's go into detail

Configuring AWS IoT Core for use with Arduino Nano ESP32

The purposes of this step are:

  • Creating a representation of the Arduino Nano ESP32 on AWS IoT Core (called a Thing).
  • Configuring the authorization that gives permission for the Arduino Nano ESP32 to connect/publish/subscribe to/from AWS IoT Core (called a Policy).
  • Generating the AWS credentials that will be used for authentication (called Certificates). Once created, we will download the credentials and place them in the Arduino ESP32 code.

The below show how to configure the AWS IoT Core for use with Arduino Nano ESP32 via AWS IoT Console. Please note that User Interface may be changed by AWS over time, but it will be similar to the below:

  • Sign in to the AWS IoT Console
  • Create a Thing by navigating to Manage All devices Things
AWS IoT creates Things
  • Click the Create things button.
  • Select Create single things and click the Next button.
AWS IoT Core creates Things
  • Specify the Thing name, for example, ESP32-thing and click the Next button at the bottom of the page.
AWS IoT Core Thing name
  • Generate the credentials by selecting the Auto-generate a new certificate option, and click the Next button.
AWS IoT Core generates certificate
  • Now, a Certificate is created and linked to the Thing.
  • Create a policy by clicking the Create policy button.
AWS IoT Core Create policy
  • A new tab will be opened
AWS IoT Core Create policy ESP32
  • Specify the Policy name, for example, ESP32-policy and click the JSON button.
  • Copy the below JSON policy content and paste it to the Policy document area:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "*", "Resource": "*" } ] }
  • Click the Create button at the bottom of the page to create the policy.
  • Now, a Policy is created and attached to the Certificate. Close that page and back to the Thing page.
  • Check the the ESP32-policy and Click the Create thing button to create the Thing.
AWS IoT Core creates Thing ESP32
  • A popup window appears that allows you to download the credentials files. Download all files and store them in a safe location on your PC and keep them confidentially.
AWS IoT Core credentials file
  • Then, click the Done button.

Among downloaded files, there are three files will be used in the Arduino Nano ESP32 code in the next steps:

  • xxxxxxxxxx-certificate.pem.crt
  • xxxxxxxxxx-private.pem.key
  • AmazonRootCA1.pem

These files can be opened with any text editor, such as Notepad or Notepad++.

Writing the Arduino Nano ESP32 code to connect to AWS IoT Core

/* * This Arduino Nano ESP32 code was developed by newbiely.com * * This Arduino Nano ESP32 code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano-esp32/arduino-nano-esp32-aws-iot */ #include "secrets.h" #include <WiFiClientSecure.h> #include <MQTTClient.h> #include <ArduinoJson.h> #include "WiFi.h" // The MQTT topics that this device should publish/subscribe #define AWS_IOT_PUBLISH_TOPIC "esp32/esp32-to-aws" #define AWS_IOT_SUBSCRIBE_TOPIC "esp32/aws-to-esp32" #define PUBLISH_INTERVAL 4000 // 4 seconds WiFiClientSecure net = WiFiClientSecure(); MQTTClient client = MQTTClient(256); unsigned long lastPublishTime = 0; void setup() { Serial.begin(9600); WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.println("Arduino Nano ESP32 connecting to Wi-Fi"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(); connectToAWS(); } void loop() { client.loop(); if (millis() - lastPublishTime > PUBLISH_INTERVAL) { sendToAWS(); lastPublishTime = millis(); } } void connectToAWS() { // Configure WiFiClientSecure to use the AWS IoT device credentials net.setCACert(AWS_CERT_CA); net.setCertificate(AWS_CERT_CRT); net.setPrivateKey(AWS_CERT_PRIVATE); // Connect to the MQTT broker on the AWS endpoint we defined earlier client.begin(AWS_IOT_ENDPOINT, 8883, net); // Create a handler for incoming messages client.onMessage(messageHandler); Serial.print("Arduino Nano ESP32 connecting to AWS IOT"); while (!client.connect(THINGNAME)) { Serial.print("."); delay(100); } Serial.println(); if (!client.connected()) { Serial.println("Arduino Nano ESP32 - AWS IoT Timeout!"); return; } // Subscribe to a topic, the incoming messages are processed by messageHandler() function client.subscribe(AWS_IOT_SUBSCRIBE_TOPIC); Serial.println("Arduino Nano ESP32 - AWS IoT Connected!"); } void sendToAWS() { StaticJsonDocument<200> message; message["timestamp"] = millis(); message["data"] = analogRead(0); // Or you can read data from other sensors char messageBuffer[512]; serializeJson(message, messageBuffer); // print to client client.publish(AWS_IOT_PUBLISH_TOPIC, messageBuffer); Serial.println("sent:"); Serial.print("- topic: "); Serial.println(AWS_IOT_PUBLISH_TOPIC); Serial.print("- payload:"); Serial.println(messageBuffer); } void messageHandler(String &topic, String &payload) { Serial.println("received:"); Serial.println("- topic: " + topic); Serial.println("- payload:"); Serial.println(payload); // You can process the incoming data as json object, then control something /* StaticJsonDocument<200> doc; deserializeJson(doc, payload); const char* message = doc["message"]; */ }

Detailed Instructions

  • If this is the first time you use Arduino Nano ESP32, see how to setup environment for Arduino Nano ESP32 on Arduino IDE.
  • Open the Library Manager by clicking on the Library Manager icon on the left navigation bar of Arduino IDE
  • Type MQTT on the search box, then look for the MQTT library by Joel Gaehwiler.
  • Click Install button to install MQTT library.
Arduino Nano ESP32 MQTT library
  • Type ArduinoJson on the search box, then look for the ArduinoJson library by Benoit Blanchon.
  • Click Install button to install ArduinoJson library.
Arduino Nano ESP32 Json library
  • Copy the above code and paste it to Arduino IDE.
  • Create the secrets.h file On Arduino IDE by:
    • Either click on the button just below the serial monitor icon and choose New Tab, or use Ctrl+Shift+N keys.
    Arduino IDE 2 adds file
    • Give file's name secrets.h and click OK button
    Arduino IDE 2 adds file secrets.h
    • Copy the below code and paste it to the created secrets.h file.
    #include <pgmspace.h> #define SECRET #define THINGNAME "ESP32-thing" const char WIFI_SSID[] = ""; const char WIFI_PASSWORD[] = ""; const char AWS_IOT_ENDPOINT[] = "xxxxx.amazonaws.com"; // Amazon Root CA 1 static const char AWS_CERT_CA[] PROGMEM = R"EOF( -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- )EOF"; // Device Certificate static const char AWS_CERT_CRT[] PROGMEM = R"KEY( -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- )KEY"; // Device Private Key static const char AWS_CERT_PRIVATE[] PROGMEM = R"KEY( -----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY----- )KEY";
    • Update the following information in the secrets.h
      • The WIFI_SSID and WIFI_PASSWORD of your WiFi network
      • The AWS_CERT_CA, AWS_CERT_CRT, and AWS_CERT_PRIVATE. These infornation are in the files you downloaded in the previous step.
      • The AWS_IOT_ENDPOINT. This information can be found on AWS IoT Console by navigating to Setting as below image:
      AWS IoT endpoint
      • Compile and upload code to Arduino Nano ESP32 board by clicking Upload button on Arduino IDE

Sending data from Arduino Nano ESP32 to AWS IoT

The above Arduino Nano ESP32 code periodically read data from an analog pin and send it to AWS IoT every 4 seconds. If opening the Serial Monitor on Arduino IDE, you will see the log like below:

COM6
Send
Arduino Nano ESP32 connecting to AWS IOT. Arduino Nano ESP32 - AWS IoT Connected! sent: - topic: esp32/esp32-to-aws - payload:{"timestamp":12743,"data":0} sent: - topic: esp32/esp32-to-aws - payload:{"timestamp":16745,"data":130}
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

To check if the data are received by AWS IoT or not, do the following steps:

  • In AWS IoT Console, navigate to Test MQTT Test Client
AWS IoT MQTT Test Client ESp32
  • Click the Subcribe to a topic button.
  • Type esp32/esp32-to-aws to the Topic filter. You can change the topic but MUST be matched the topic on the Arduino Nano ESP32 code.
  • Click the Subcribe button.
  • You will be able to see the data sent from Arduino Nano ESP32 on the AWS IoT Console.

Sending data from AWS IoT to Arduino Nano ESP32

You are able to send the data from AWS IoT Console to the Arduino Nano ESP32 by doing the following steps:

  • On Arduino IDE, Open the Serial Monitor
  • On AWS IoT Console, navigate to Test MQTT Test Client
AWS IoT MQTT Test Client ESp32
  • Click the Publish to a topic button.
  • Type esp32/aws-to-esp32 to the Topic name. You can change the topic but MUST be matched the topic on the Arduino Nano ESP32 code.
  • Optionally, you can change the message payload, or just keep it as default.
  • Click the Publish button.
  • Check out the Serial Monitor on Arduino IDE, you will see the message sent from AWS IoT Console.
COM6
Send
received: - topic: esp32/aws-to-esp32 - payload: { "message": "Hello from AWS IoT console" }
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Do more with AWS

Now you are able to send data from the Arduino Nano ESP32 to the AWS IoT Core and vice versa. Then, you can set up IoTRule to connect the Arduino Nano ESP32 to other AWS services such as Lambda, DynamoDB, Amplify, RDS...