As I already said, we will connect an esp8266, an esp32, and an Arduino SAMD to the MQTT server that we had configured. To do that, you need the relative device.
esp8266 devices
First, you need the device, and then you need to configure your device to build and upload the code. To do this, you can refer to this article “WeMos D1 mini (esp8266), pinout, specs and IDE configuration“.
You can find esp8266 on WeMos D1 mini - NodeMCU V2 V2.1 V3 - esp01 - esp01 programmer
Source code
You can find the source code in the folder
alexa-skill-manage-relay-nodejs/esp8266_relay_iot_core/aws_iot_core_esp8266/
inside you find four file
aws_certificate.h
aws_parameter.h
wifi_credential.h
aws_iot_core_esp8266.ino
Configuration
And you have to go and enter this information
wifi_credential.h
: put inside your WiFi SSID and password.
char WIFI_SSID[] = "<YOUR-SSID>";
char WIFI_PASSWORD[] = "<YOUR-PASSWD>";
aws_parameter.h
: you have this file precompiled in some partTHINGNAME
is the name of thingesp8266_relay
;- AWS_IOT_ENDPOINT: is the value you had put on [IoT MQTT EndPoint], you find It in Settings section of AWS IoT Console;
- AWS_IOT_PUBLISH_TOPIC: is the publish topic [IoT MQTT publish topic], for our policy is
relay/pub
; - AWS_IOT_SUBSCRIBE_TOPIC: is the publish topic [IoT MQTT subscribe topic], for our policy is
relay/sub
;
#define THINGNAME "esp8266_relay"
char AWS_IOT_ENDPOINT[] = "XXXXXXXXXXXXXX-ats.iot.eu-west-1.amazonaws.com";
#define AWS_IOT_PUBLISH_TOPIC "relay/pub"
#define AWS_IOT_SUBSCRIBE_TOPIC "relay/sub"
aws_certificate.h
:
this file have 3 section one for every certificate and key we have download
#include <pgmspace.h>
// Amazon Root CA 1 (AmazonRootCA1.pem)
static const uint8_t AWS_CERT_CA[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
)EOF";
// Device Certificate (XXXXXXXXXX-certificate.pem.crt)
static const uint8_t AWS_CERT_CRT[] PROGMEM = R"KEY(
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----
)KEY";
// Device Private Key (XXXXXXXXXX-private.pem.key)
static const uint8_t AWS_CERT_PRIVATE[] PROGMEM = R"KEY(
-----BEGIN RSA PRIVATE KEY-----
[...]
-----END RSA PRIVATE KEY-----
)KEY";
Sketch
Remember to download ArduinoJSON and MQTT library
After the configuration, the sketch is ready to upload.
/*
* Amazon AWS IoT core connection from esp32 boards
*
* This sketch securely connects to an AWS IoT using MQTT over WiFi.
* With MQTT library.
*
* It publishes a message every 5 seconds to arduino/pub
* topic and subscribes to messages on the arduino/sub
* topic.
*
* by Mischianti Renzo <https://mischianti.org>
*
* https://mischianti.org
*
*/
#include "Arduino.h"
#include "aws_certificate.h"
#include "aws_parameter.h"
#include "wifi_credential.h"
#include "ESP8266WiFi.h"
#include <MQTTClient.h>
#include <ArduinoJson.h>
// Secure connection
WiFiClientSecure client = WiFiClientSecure();
// Client MQTT
MQTTClient clientMQTT = MQTTClient(256);
// Callback for every message on the topic subscribed
void messageCallback(String &topic, String &payload);
// Establish connection to MQTT
bool manageAWSConnection();
// Subscribe topic
bool manageAWSSubscription();
// Publish message to topic
bool publishMessage();
void setup()
{
Serial.begin(115200);
while(!Serial){}
Serial.flush();
Serial.println();
// WIFI_SSID, WIFI_PASSWORD Stored on wifi_credential.h file
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to ");
Serial.print(WIFI_SSID); Serial.println("");
int i = 0;
while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect
delay(1000);
Serial.print(++i); Serial.print('.');
}
Serial.println('\n');
Serial.println("Connection established!");
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // Send the IP address of the ESP8266 to the computer
if (manageAWSConnection()){
manageAWSSubscription();
}
}
unsigned long lastSendingTime = millis();
unsigned long sendMessageEveryMillis = 5000;
void loop()
{
clientMQTT.loop();
if (lastSendingTime+sendMessageEveryMillis<millis()){
publishMessage();
lastSendingTime = millis();
}
}
bool manageAWSConnection(){
// Configure WiFiClientSecure for the AWS IoT device certificate
client.setCACert(AWS_CERT_CA, sizeof(AWS_CERT_CA));
client.setCertificate(AWS_CERT_CRT, sizeof(AWS_CERT_CRT));
client.setPrivateKey(AWS_CERT_PRIVATE, sizeof(AWS_CERT_PRIVATE));
// Connect to the MQTT broker on the AWS endpoint
clientMQTT.begin(AWS_IOT_ENDPOINT, 8883, client);
// Create a message handler
clientMQTT.onMessage(messageCallback);
Serial.print("Connecting to AWS IOT");
while (!clientMQTT.connect(THINGNAME)) {
Serial.print(".");
delay(100);
}
if(!clientMQTT.connected()){
Serial.println("AWS IoT Timeout!");
return false;
}
return true;
}
bool manageAWSSubscription(){
// Subscribe to a topic
if (clientMQTT.subscribe(AWS_IOT_SUBSCRIBE_TOPIC)){
Serial.println("AWS IoT Connected!");
return true;
}else{
Serial.print("AWS IoT ERROR: ");
Serial.println(clientMQTT.lastError());
return false;
}
}
void messageCallback(String &topic, String &payload) {
Serial.println("incoming: [" + topic + "]" );
Serial.println("---------------------------" );
StaticJsonDocument<200> doc;
deserializeJson(doc, payload);
serializeJsonPretty(doc, Serial);
Serial.println();
Serial.println("---------------------------" );
}
bool publishMessage()
{
// Create simple message
DynamicJsonDocument doc(512);
doc["time"] = millis();
doc["deviceName"] = "esp8266";
doc["status"] = "OK";
char jsonBuffer[512];
serializeJson(doc, jsonBuffer); // print to client
Serial.print("Message on ");
Serial.print(AWS_IOT_PUBLISH_TOPIC);
Serial.print(" topic... ");
// Publish message to AWS_IOT_PUBLISH_TOPIC
if (clientMQTT.publish(AWS_IOT_PUBLISH_TOPIC, jsonBuffer)){
Serial.println("Published!");
return true;
}else{
Serial.println("Error!");
return false;
}
}
The code is fully commented, but let’s look at the core part.
Establish a channel
The function to establish a channel versus the AWS IoT is this
bool manageAWSConnection(){
// Configure WiFiClientSecure for the AWS IoT device certificate
client.setCACert(AWS_CERT_CA, sizeof(AWS_CERT_CA));
client.setCertificate(AWS_CERT_CRT, sizeof(AWS_CERT_CRT));
client.setPrivateKey(AWS_CERT_PRIVATE, sizeof(AWS_CERT_PRIVATE));
// Connect to the MQTT broker on the AWS endpoint
clientMQTT.begin(AWS_IOT_ENDPOINT, 8883, client);
// Create a message handler
clientMQTT.onMessage(messageCallback);
Serial.print("Connecting to AWS IOT");
while (!clientMQTT.connect(THINGNAME)) {
Serial.print(".");
delay(100);
}
if(!clientMQTT.connected()){
Serial.println("AWS IoT Timeout!");
return false;
}
return true;
}
The first part
client.setCACert(AWS_CERT_CA, sizeof(AWS_CERT_CA));
client.setCertificate(AWS_CERT_CRT, sizeof(AWS_CERT_CRT));
client.setPrivateKey(AWS_CERT_PRIVATE, sizeof(AWS_CERT_PRIVATE));
sets the security/authentication parameter, then tries the connection
// Connect to the MQTT broker on the AWS endpoint
clientMQTT.begin(AWS_IOT_ENDPOINT, 8883, client);
// Create a message handler
clientMQTT.onMessage(messageCallback);
Serial.print("Connecting to AWS IOT");
while (!clientMQTT.connect(THINGNAME)) {
Serial.print(".");
delay(100);
}
to the AWS port is 8883 and sets the function messageCallback that becomes executed every time a message is pushed to the topic.
Subscribe a topic
If you have the permission (policy) to subscribe to a topic, you can do that with
clientMQTT.subscribe(AWS_IOT_SUBSCRIBE_TOPIC)
Send message on topic
If you want to send a message on a topic, you must have permission (policy), and you can do that with this code.
bool publishMessage()
{
// Create simple message
DynamicJsonDocument doc(512);
doc["time"] = millis();
doc["deviceName"] = "esp8266";
doc["status"] = "OK";
char jsonBuffer[512];
serializeJson(doc, jsonBuffer); // print to client
Serial.print("Message on ");
Serial.print(AWS_IOT_PUBLISH_TOPIC);
Serial.print(" topic... ");
// Publish message to AWS_IOT_PUBLISH_TOPIC
if (clientMQTT.publish(AWS_IOT_PUBLISH_TOPIC, jsonBuffer)){
Serial.println("Published!");
return true;
}else{
Serial.println("Error!");
return false;
}
}
Thanks
- AWS IoT core and MQTT services: introduction and prerequisite
- AWS IoT core and MQTT services: creating AWS thing with certificate and policy
- AWS IoT core and MQTT services: connect esp8266 devices
- AWS IoT core and MQTT services: connect esp32 devices
- AWS IoT core and MQTT services: connect Arduino SAMD (WiFiNINA) devices
- AWS IoT core and MQTT services: test with console and MQTT.fx