Servizi AWS, IoT core e MQTT: connettere i dispositivi esp8266 – 3

Spread the love

Come ho già detto, collegheremo un esp8266, un esp32 e un Arduino SAMD al server MQTT che avevamo configurato. Per fare ciò, è necessario il relativo dispositivo.

Amazon AWS IoT Core MQTT connect esp8266 devices
Amazon AWS IoT Core MQTT connects esp8266 devices.

Dispositivi esp8266

Innanzitutto, è necessario il dispositivo, quindi è necessario configurare il dispositivo per creare e caricare il codice. Per fare ciò, puoi fare riferimento a questo articolo “WeMos D1 mini (esp8266): piedinatura, caratteristiche e configurazione dell’Arduino IDE“.

Puoi trovare degli esp8266 su WeMos D1 mini - NodeMCU V2 V2.1 V3 - esp01 - esp01 programmer

Codice sorgente

Puoi trovare il codice sorgente nella cartella

alexa-skill-manage-relay-nodejs/esp8266_relay_iot_core/aws_iot_core_esp8266/

all’interno trovi quattro file

aws_certificate.h
aws_parameter.h
wifi_credential.h
aws_iot_core_esp8266.ino

Configurazione

E devi andare a inserire queste informazioni

  • wifi_credential.h: inserisci il tuo SSID WiFi e password.
char WIFI_SSID[] = "<YOUR-SSID>";
char WIFI_PASSWORD[] = "<YOUR-PASSWD>";
  • aws_parameter.h: hai questo file precompilato in alcune parti
    • THINGNAME è il nome dell’oggetto esp8266_relay;
    • AWS_IOT_ENDPOINT: è il valore che avevi messo su [IoT MQTT EndPoint], lo trovi nella sezione Impostazioni della Console AWS IoT ;
    • AWS_IOT_PUBLISH_TOPIC: è l’argomento di pubblicazione [IoT MQTT publish topic], per la nostra policy è relay/pub;
    • AWS_IOT_SUBSCRIBE_TOPIC: è l’argomento di pubblicazione [IoT MQTT subscribe topic], per la nostra policy è 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:
    questo file ha 3 sezioni una per ogni certificato e chiave che abbiamo scaricato
#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

Ricordati di scaricare la libreria ArduinoJSON e MQTT

Dopo la configurazione, lo sketch è pronto per essere caricato.

/*
 *   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;
	}
}

Il codice è completamente commentato, ma diamo un’occhiata alla parte centrale.

Stabilire un canale

La funzione per stabilire un canale su AWS IoT è questa

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;
}

La prima parte

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));

imposta il parametro di sicurezza/autenticazione, quindi prova la connessione

// 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);
}

alla porta AWS è 8883 e imposta la funzione messageCallback che viene eseguita ogni volta che un messaggio viene inviato all’argomento.

Sottoscrivi un argomento

Se hai l’autorizzazione (policy) per iscriverti a un argomento, puoi farlo con

clientMQTT.subscribe(AWS_IOT_SUBSCRIBE_TOPIC)

Inviare un messaggio su un topic

Se vuoi inviare un messaggio su un argomento, devi disporre dell’autorizzazione (politica) e puoi farlo con questo codice.

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;
	}
}

Grazie

  1. Servizi AWS IoT core e MQTT: introduzione e prerequisiti
  2. Servizi AWS IoT core e MQTT: creazione di oggetti AWS con certificato e policy
  3. Servizi AWS IoT core e MQTT: connettere i dispositivi esp8266
  4. Servizi AWS IoT core e MQTT: connettere i dispositivi esp32
  5. Servizi AWS IoT core e MQTT: connettere i dispositivi Arduino SAMD (WiFiNINA).
  6. Servizi AWS IoT core e MQTT: test da console e MQTT.fx

Spread the love

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *