How to connect ESP32 to Amazon AWS IoT Core using MQTT

This tutorial covers how to connect ESP32 to Amazon AWS IoT Core. During this tutorial, we will connect the ESP32 to Amazon AWS using MQTT. In short, as you may already know AWS IoT Core is an enterprise cloud platform that provides several services. If you don’t have an account you can create it for free here. It is free the first year, so you can try the AWS IoT. During this step by step tutorial, we will use the PubSub MQTT library. At the end of this project, the ESP32 will send data to Amazon AWS IoT using MQTT (for more information about MQTT read MQTT Protocol Tutorial: Technical description).

What will you learn in this ESP32 AWS IoT tutorial?

  • Configuring a AWS IoT thing that represents the ESP32
  • Creating a AWS IoT certificate and how to attach it to our thing
  • Connecting to AWS IoT using MQTT

Let’s begin! Below the link to download the ESP32 source code to connect it to Amazon AWS.

Required components

Before starting this ESP32 tutorial, you need the following components:

In this project, we will send to the Amazon AWS the current temperature and the humidity, for this reason, you need a DHT11 sensor. Anyway, you can use different sensors and you can send other data to AWS.

How to configure Amazon AWS IoT to use with ESP32

Below the steps to connect ESP32 to Amazon AWS IoT:

1. Creating an Amazon AWS IoT Things

Firstly, it is necessary to create the AWS IoT Things that is something like a “shadow” of our physical device. Once you have created the account go to the AWS IoT Console and select IoT Core. Now select Manage and then Thing and start creating a new AWS IoT Things:

How to create a AWS IoT Thing

Now give a name (my-esp32) to your things:

give a name to the thing

Now we have created a record representing our physical device.

2. Provisioning an AWS Certificate

After we have configured the thing, the next step is creating a AWS Certificate. This step is necessary so that AWS IoT Core can trust our physical device. The certificate, we are creating in this step, will be used later when the ESP32 connects to AWS MQTT. Using this certificate the ESP32 will authenticate the connections to AWS. Click on Secure and then Certificates:

How to create a AWS certificate for a thing

Now, we can download the certificate for our thing:

There are three different certificates but only two are necessary:

  • A Certificate for this thing xxxxx.cert.pem
  • A private key xxxxx.private.key

Moreover, it is necessary to download the root certificate for AWS IoT. This project use RSA 2048 bit key: Amazon CA root 1.

3. Creating a AWS policy

AWS IoT Policy is a JSON document that describes what a device can do. Therefore, it defines a set of authorized actions. For example, for this project, we can use a very large authorization, authorizing all. In your real project, you should pay attention when creating this policy. Select Secure and then Policy:

AWS IoT Policy creation

4. Attaching the Policy to the Certificate

In the certificate dashboard select the certificate you have created in the previous step and click on the three dots and select attach policy:

Attach Policy to Certificate in Amazon AWS IoT

How to test the AWS MQTT connection

Before going on, it is useful to test if all the configuration, are correct and the AWS IoT thing is configured correctly. For this reason, you can download and install MQTT.fx. In short, in this step, it is necessary to use the certificates downloaded before.

Therefore, open MQTT.fx and configure a new MQTT connection as shown below:

Test AWS MQTT using MQTT.fx

If you are wondering where you get the broker address, then you have to go to the things dashboard. Next, select your thing and then Interact item on the left menu: the HTTPS URL is the URL you have to use. Once you have configured your MQTT client try to connect:

As you can see, the MQTT client can establish a connection to AWS IoT Core.

How to connect ESP32 to AWS IoT Core

After we have configured the AWS Thing in AWS Console, we can focus our attention on how to connect the ESP32 to AWS IoT using MQTT. As you know, there are several MQTT library ready to use. In this tutorial we will use PubSubClient a very simple to use MQTT library:

#include <Arduino.h> #include <WiFi.h> #include <WiFiClientSecure.h> #include <PubSubClient.h> const char *SSID = "your_wifi_ssid"; const char *PWD = "your_wifi_pwd"; WiFiClientSecure secureClient = WiFiClientSecure(); PubSubClient mqttClient(secureClient); void connectToWiFi() { Serial.print("Connecting to "); Serial.println(SSID); WiFi.begin(SSID, PWD); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); // we can even make the ESP32 to sleep } Serial.print("Connected - "); } void connectToAWS() { mqttClient.setServer(AWS_END_POINT, 8883); secureClient.setCACert(AWS_PUBLIC_CERT); secureClient.setCertificate(AWS_DEVICE_CERT); secureClient.setPrivateKey(AWS_PRIVATE_KEY); Serial.println("Connecting to MQTT...."); mqttClient.connect(DEVICE_NAME); while (!mqttClient.connected()) { Serial.println("Connecting to MQTT....Retry"); mqttClient.connect(DEVICE_NAME); delay(5000); } Serial.println("MQTT Connected"); } void setup() { Serial.begin(9600); connectToWiFi(); connectToAWS(); }
Code language: PHP (php)

The code is quite simple: after connecting to the WiFi, the ESP32 code defines a WifiSecureClient used to store the certificate downloaded from AWS IoT Core in the provisioning step. Then, it is defined the mqttClient that will handle all the details about connecting the ESP32 to AWS IoT MQTT. Notice that in the connectToAWS() method, we reference the certificate.

How to encode AWS IoT certificate for ESP32

In the previous code, we have referenced the AWS certificate, anyway it is not possible to use these certificates as we have downloaded before. It is necessary to encode them. For this reason, let us define certs.h file with the following content:

const char AWS_PUBLIC_CERT[] = "-----BEGIN CERTIFICATE-----\n" \ "xxxxxxxxxxxxx\n" \ "yyyyyyyyyyyyyy\n" \ "-----END CERTIFICATE-----"; const char AWS_PRIVATE_KEY[] = "-----BEGIN RSA PRIVATE KEY-----\n" \ "bbbbbbbbbbbbbb\n" \ "ffffffffffffff\n" \ "-----END RSA PRIVATE KEY-----"; const char AWS_DEVICE_CERT[] = "-----BEGIN CERTIFICATE-----\n" \ "zzzzzzzzzzzz\n" \ "aaaaaaaaaaaa\n" \ "-----END CERTIFICATE-----\n";
Code language: JavaScript (javascript)

Do not forget to add the following line at the beginning of the file:

#include <certs.h>
Code language: CSS (css)

Sending sensor readings to AWS IoT using MQTT

In this last step, once the connection is established, the ESP32 using a DHT11 sensor sends the data to the AWS IoT using MQTT. You can skip this step or you can send different information to AWS IoT.

Connecting the ESP32 to the DHT11

The schematic is shown below:

Getting started with ESP32: Build a weather station (BMP280 + SSD1306)
Send Email using ESP32 with SMTP Server: Plain and HTML email

Sending JSON data through AWS IoT MQTT

In this step, we create the JSON data with the readings coming from the sensor. To create the JSON we will use Arduino JSON Library:

void loop() { float temperature = dht.readTemperature(); float humidity = dht.readHumidity(); // Compute the hit Index using celsius float heatIndex = dht.computeHeatIndex(temperature, humidity, false); Serial.print("Temperature:"); Serial.println(temperature); Serial.print("Humidity:"); Serial.println(humidity); Serial.print("Heat Index:"); Serial.println(heatIndex); StaticJsonDocument<128> jsonDoc; JsonObject eventDoc = jsonDoc.createNestedObject("event"); eventDoc["temp"] = temperature; eventDoc["hum"] = humidity; eventDoc["hi"] = heatIndex; char jsonBuffer[128]; serializeJson(eventDoc, jsonBuffer); mqttClient.publish("mychannel/", jsonBuffer); delay(10000); }
Code language: PHP (php)

Do not forget to add the following lines at the beginning:

// DHT #include <Adafruit_Sensor.h> #include <DHT.h> #define DHT_TYPE DHT11 #define DHT_PIN 4 DHT dht(DHT_PIN, DHT_TYPE); void setup() { ..... dht.begin(); }
Code language: PHP (php)

Testing the connection between ESP32 and AWS IoT

If you want to test the JSON data sent by ESP32 to AWS IoT Core, it is possible to use the Test item in the left menu. In this case, it is necessary to subscribe to the mychannel. This is the channel used when connecting ESP32 to AWS IoT Core:

Connect ESP32 to AWS IoT Core using MQTT

This is the result of this project.

If you prefer to use another IoT Cloud Platform, you can experiment on how to use ESP32 with Google Cloud Platform

Wrapping up…

At the end of this ESP32 tutorial, you discovered how to connect the ESP32 to AWS IoT Core using MQTT. You learned how to configure AWS IoT thing that represents your physical device and how to create AWS Certificate. Finally, in the end, after ESP32 connects to AWS IoT, it sends JSON data.