AWS IoT for ESP32 v1.0.0
An ESP-IDF based solution
Publish-Subscribe

AWS IoT Publish-Subscribe

In this guide we will see how to connect the device (thing) to AWS IoT by writing a simple application that will publish a message every 10 seconds and prints the received message whenever it is received. When initiating a connection request AWS IoT requires authentication using X.509 certificate as authentication credentials to uniquely identify your device.

We shall use thing certificate for this application. You need the following certificate files which we commonly refer it as thing certificates.

  1. AWS Root CA certificate.
  2. Client certificate.
  3. Client private key.

If you do not have them, then follow the steps as described here to create a thing and attach a policy that will allow your device to Connect, Publish and Subscribe MQTT messages on AWS IoT.

Here we have used thing certificates, you may use other two ways instead. If you want to use other two methods then please read the Provisioning methods of Lib AWS under Overview section.

Implementation steps

The steps below explains the necessary configuration and initialization required to use our library. Ensure you have downloaded the thing certificates.

1. Initialize the system configuration

To use thing certificates initialize the System configuration and AWS configuration by configuring the following information in the variable of type systemInitConfig_st.

  • Your WiFi SSID and Password.
  • Your AWS IoT endpoint as hostname, and Port number as 8883.

    Note: You can find your AWS IoT end-point from the AWS IoT Dashboard > Settings using the navigation menu.

  • Your Thing Name.
  • Your Thing Certificates. Inside the _Certificates/thingCerts folder, copy the thing certificate files. Rename the files respectively as follows.
    • Rename the AWS Root CA file as aws-root-ca.pem
    • Rename the Client certificate file as thing-certificate.pem
    • Rename the Client private key file as thing-private.pem.key

Here is the sample configuration that uses thing certificates:

extern const uint8_t aws_root_ca_pem_start[] asm("_binary_aws_root_ca_pem_start");
extern const uint8_t thing_certificate_pem_crt_start[] asm("_binary_thing_certificate_pem_crt_start");
extern const uint8_t thing_private_pem_key_start[] asm("_binary_thing_private_pem_key_start");
void app_eventsCallBackHandler(systemEvents_et eventId)
{
switch (eventId)
{
print_info("EVENT_AWS_CONNECTED");
break;
print_info("EVENT_AWS_DISCONNECTED");
break;
}
}
systemInitConfig_st s_sysConfig = {
.pDeviceNamePrefixStr = DEVICE_NAME_PREFIX,
.systemEventCallBack = app_eventsCallBackHandler,
.pWifiSsid = <your wifi ssid>,
.pWifiPwd = <your wifi password>,
.awsConfig = {
.pHostNameStr = <your aws iot endpoint>,
.port_u16 = 8883,
.pThingNameStr = <your thing name>,
.pRootCaStr = (char *)aws_root_ca_pem_start,
.pThingCertStr = (char *)thing_certificate_pem_crt_start,
.pThingPrivateKeyStr = (char *)thing_private_pem_key_start
}
};
systemEvents_et
Definition: lib_system.h:46
@ EVENT_AWS_DISCONNECTED
Definition: lib_system.h:50
@ EVENT_AWS_CONNECTED
Definition: lib_system.h:49
System configuration structure. The application should define the system configuration variable and c...
Definition: lib_system.h:72

2. Connect to AWS

Using the above configuration initialize the system and connect to AWS.

bool systemInitSuccess = SYSTEM_init(&s_sysConfig);
bool SYSTEM_init(systemInitConfig_st *s_pConfig)
Initiliaze the system with given configuration.

3. Implement application logic

Implement an application logic that will publish a message every 10 seconds and print the received message whenever it is received.

Sample code that subscribes to a topic:

if (systemInitSuccess)
{
SYSTEM_start();
// subscribe to a topic
AWS_subscribe("testSub/ESP32", QOS0_AT_MOST_ONCE);
}
bool AWS_subscribe(char *pTopicStr, uint8_t qos_e)
Subscribe to a given Topic on AWS IoT.
@ QOS0_AT_MOST_ONCE
Definition: lib_msg.h:25

Sample code to publish a message:

// publish message
mqttMsg_st pubMsg = {0};
pubMsg.payloadLen_u16 = sprintf(pubMsg.payloadStr, "Hello from device - counter: %d", counter++);
pubMsg.topicLen_u8 = sprintf(pubMsg.topicStr, "testPub/ESP32");
AWS_publish(&pubMsg);
printf(" PUB Message => topic:%s payload:%s", pubMsg.topicStr, pubMsg.payloadStr);
bool AWS_publish(mqttMsg_st *ps_msg)
Publish given message to AWS IoT. The message is queued in a Publish buffer, then gets published.
Structure to represent MQTT message.
Definition: lib_msg.h:48
char payloadStr[LENGTH_MQTT_PAYLOAD]
Definition: lib_msg.h:50
uint8_t topicLen_u8
Definition: lib_msg.h:52
uint16_t payloadLen_u16
Definition: lib_msg.h:51

Sample code to print the received message:

mqttMsg_st subMsg = {0};
// message received? print it
if(AWS_subMsgRead(&subMsg))
{
printf(" SUB Message => topic:%s payload:%s", subMsg.topicStr, subMsg.payloadStr);
}
bool AWS_subMsgRead(mqttMsg_st *ps_msg)
Read the available message from the subscription message buffer.

4. Create application task

Sample application task code:

void app_task(void *param)
{
while (1)
{
switch (SYSTEM_getMode())
{
{
// publishes a message every 10 seconds
// message received? print it
}
break;
default:
break;
}
TASK_DELAY_MS(100);
}
}
TaskHandle_t tHandle_appTask = NULL;
xTaskCreate(&app_task, "app_task", 1024, NULL, 4, &tHandle_appTask);
bool AWS_isConnected()
Check if the device is connected state.
systemMode_et SYSTEM_getMode()
Get the system mode.
@ SYSTEM_MODE_NORMAL
Definition: lib_system.h:34

5. Build and flash your application

# build the project
idf.py build
# build and flash it
idf.py flash monitor -p <your serial port>