For reading out sensors in a production environment, I need to transmit data via MQTTS. I did this before with an ESP32, using WifiSecureClient. For the connection, I need to provide authentication and a root certificate.
Now, I need to use an Arduino MKR Wifi 1010 device, as I intend to utilize the M-BUS shield for data readout of an energy meter. This part already works fine.
But, I have trouble to get MQTTS up and running. At the end I switched to the test.mosquitto.org MQTT server to test my sketch/code.
What I did so far:
1. upload of the root certificate:
I did this like described on the arduino website with help of the firmware updater and the root certificate uploader from the IDE 2.0.3. No errors occured during this operation.
I used test.mosquitto.org:8883
as address.
2. preparation of the sketch:
With the code below I managed to connect unencrypted to the mosquitto test server, with and without authentication. For that the port has to be changed to 1883 and the mqttClient
uses the wifiClient
, not the sslClient
.
However, I didn't manage to connect with encryption (unauthenticated on port 8883), providing the root certificate on the device.
I always got error -2
after the connect attempts.
Is some reference required in the sketch / code to make it work? What am I making wrong??
I spent almost the complete day with this topic and am a bit frustrated about the missing results. I'd be very happy if someone has a solution!!
This is the code I used:
#include <ArduinoBearSSL.h>
#include <ArduinoECCX08.h>
#include <ArduinoMqttClient.h>
#include <WiFiNINA.h> // change to #include <WiFi101.h> for MKR1000
//#include "arduino_secrets.h"
/////// Enter your sensitive data in arduino_secrets.h
const char ssid[] = "SuperWifi";
const char pass[] = "***";
const char broker[] = "test.mosquitto.org";
const int port = 8883;
// const char* certificate = SECRET_CERTIFICATE;
WiFiClient wifiClient; // Used for the TCP socket connection
BearSSLClient sslClient(wifiClient); // Used for SSL/TLS connection, integrates with ECC508
MqttClient mqttClient(sslClient);
unsigned long lastMillis = 0;
void setup() {
Serial.begin(115200);
while (!Serial);
if (!ECCX08.begin()) {
Serial.println("No ECCX08 present!");
while (1);
}
// Set a callback to get the current time
// used to validate the servers certificate
ArduinoBearSSL.onGetTime(getTime);
// Set the message callback, this function is
// called when the MQTTClient receives a message
mqttClient.onMessage(onMessageReceived);
}
void loop() {
if (WiFi.status() != WL_CONNECTED) {
connectWiFi();
}
if (!mqttClient.connected()) {
// MQTT client is disconnected, connect
connectMQTT();
}
// poll for new MQTT messages and send keep alive
mqttClient.poll();
// publish a message roughly every 5 seconds.
if (millis() - lastMillis > 5000) {
lastMillis = millis();
publishMessage();
}
}
unsigned long getTime() {
// get the current time from the WiFi module
return WiFi.getTime();
}
void connectWiFi() {
Serial.print("Attempting to connect to SSID: ");
Serial.print(ssid);
Serial.print(" ");
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
// failed, retry
Serial.print(".");
delay(5000);
}
Serial.println();
Serial.println("You're connected to the network");
Serial.println();
}
void connectMQTT() {
Serial.print("Attempting to MQTT broker: ");
Serial.print(broker);
Serial.println(" ");
//mqttClient.setUsernamePassword("rw", "readwrite");
while (!mqttClient.connect(broker, port)) {
// failed, retry
Serial.print("connect error: ");
Serial.println(mqttClient.connectError());
delay(5000);
}
Serial.println();
Serial.println("You're connected to the MQTT broker");
Serial.println();
// subscribe to a topic
mqttClient.subscribe("arduinot/incoming");
}
void publishMessage() {
Serial.println("Publishing message");
// send message, the Print interface can be used to set the message contents
mqttClient.beginMessage("arduinot/outgoing");
mqttClient.print("hello ");
mqttClient.print(millis());
mqttClient.endMessage();
}
void onMessageReceived(int messageSize) {
// we received a message, print out the topic and contents
Serial.print("Received a message with topic '");
Serial.print(mqttClient.messageTopic());
Serial.print("', length ");
Serial.print(messageSize);
Serial.println(" bytes:");
// use the Stream interface to print the contents
while (mqttClient.available()) {
Serial.print((char)mqttClient.read());
}
Serial.println();
Serial.println();
}