Site icon Renzo Mischianti

AWS IoT core and MQTT services: connect esp8266 devices – 3

Spread the love

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.

Amazon AWS IoT Core MQTT connects esp8266 devices.

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

char WIFI_SSID[] = "<YOUR-SSID>";
char WIFI_PASSWORD[] = "<YOUR-PASSWD>";
#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"
#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

  1. AWS IoT core and MQTT services: introduction and prerequisite
  2. AWS IoT core and MQTT services: creating AWS thing with certificate and policy
  3. AWS IoT core and MQTT services: connect esp8266 devices
  4. AWS IoT core and MQTT services: connect esp32 devices
  5. AWS IoT core and MQTT services: connect Arduino SAMD (WiFiNINA) devices
  6. AWS IoT core and MQTT services: test with console and MQTT.fx


Spread the love
Exit mobile version