Hey All,
I've been following quite a few different posts over the last 2 days trying to get my MKR 1500 on AWS IoT core.
Today I realised there's no way to just pass Certificates as strings (as one youtube vid suggested).
Theres a tutorial which has a lot of details: https://docs.arduino.cc/tutorials/mkr-wifi-1010/securely-connecting-an-arduino-mkr-wifi-1010-to-aws-iot-core/
A few have referenced this. But my changes to it for my LTE-M Mkr 1500 dont work.
- My LTE-M module connects to the internet
- Connects to another MQTT broker (HiveMQ mqtt-dashboard.com port 443)
- Freezes at connecting to AWS
I followed the tutorial precisely, ran the encryption on board, generated a Cert, uploaded it, created a policy allowing all to the ARN of * And still not working/frozen at "connecting to AWS.
Code:
// Library imports
#include <ArduinoMqttClient.h>
#include <ArduinoBearSSL.h>
#include <ArduinoECCX08.h>
#include <MKRNB.h>
// Secrets: AWS IoT Core and SIM settings
#define SECRET_PINNUMBER "" // Your SIM PIN (leave empty if none)
#define SECRET_BROKER "XYZXYZXYZ-ats.iot.eu-north-1.amazonaws.com" // AWS IoT Core endpoint
const char SECRET_CERTIFICATE[] = R"(
-----BEGIN CERTIFICATE-----
MIICzjCCAbagAwIBAgIVAMoFbPBneSsNWCTM35knoJXmdXXLMA0GCSqGSIb3DQEB....
(Generated using the ECCX8 example sketch, ask to create private key and
then upload to AWS. Then when policy is done click download
and you get a device cert - this is the device cert section.)
....
iFQpqumjDWXeZx02QXDuguzPWnE4lKMvxh8CBIXAbCXfsX6b2LVd503zpHyE+iW3
XHw=
-----END CERTIFICATE-----
)";
// AWS IoT Core and MQTT variables
const char apn[] = "iot.1nce.net"; // Your APN for the 1NCE SIM card
const char* broker = SECRET_BROKER;
const char* certificate = SECRET_CERTIFICATE;
const char* client_id = "Hopper2"; // Set your client ID here
// Cellular network objects
NB nbAccess(false); // Use for non-blocking mode
NBClient nbClient; // For the TCP connection
BearSSLClient sslClient(nbClient); // SSL client using BearSSL and ECC508
MqttClient mqttClient(sslClient); // MQTT client using BearSSL
GPRS gprs; // GPRS object for handling cellular connections
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println("Connecting to cellular network...");
// Connect to the cellular network (NB-IoT or LTE-M)
if (nbAccess.begin(apn) != NB_READY) {
Serial.println("Failed to connect to cellular network. Check SIM card or APN settings.");
while (1); // Stay in loop for debugging
}
Serial.println("Connected to cellular network.");
// Attach GPRS (Data connection) using the APN and passing NULL for username and password
if (gprs.attachGPRS(apn) != GPRS_READY) {
Serial.println("Failed to attach GPRS. Check APN settings.");
while (1); // Stay in loop for debugging
}
Serial.println("Connected to LTE-M with internet access.");
// Initialize ECC508 chip
if (!ECCX08.begin()) {
Serial.println("No ECCX08 present!");
while (1);
}
// Set the SSL callback for the current time (used to validate server certificates)
ArduinoBearSSL.onGetTime(getTime);
// Set the ECCX08 slot to use for the private key and the certificate
sslClient.setEccSlot(0, certificate);
// Optional, set the client ID used for MQTT, if not set it will use a default ID
mqttClient.setId(client_id); // Setting client ID to "Hopper2"
// Set the message callback function
mqttClient.onMessage(onMessageReceived);
}
void loop() {
// Keep the MQTT client connected
if (!mqttClient.connected()) {
connectMQTT();
}
// Poll for incoming messages
mqttClient.poll();
// Publish a simple message to AWS IoT Core
publishMessage();
// Delay to avoid publishing too frequently
delay(10000); // Send a message every 10 seconds
}
void connectMQTT() {
Serial.print("Attempting to connect to MQTT broker: ");
Serial.println(broker);
while (!mqttClient.connect(broker, 8883)) {
// Failed, retry
Serial.print(".");
delay(5000);
}
Serial.println();
Serial.println("You're connected to the MQTT broker");
mqttClient.subscribe("arduino/incoming");
}
unsigned long getTime() {
// Get the current time from the cellular network (LTE-M)
return nbAccess.getTime();
}
void publishMessage() {
Serial.println("Publishing message");
// Send message, the Print interface can be used to set the message contents
mqttClient.beginMessage("arduino/outgoing");
mqttClient.print("Hello from Hopper2! Current millis: ");
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 message contents
while (mqttClient.available()) {
Serial.print((char)mqttClient.read());
}
Serial.println();
}
This method of cert - generates an on board private key, you copy that private key from serial and then save it in a txt file and upload it to AWS. Then create policy allow all and attach and activate.
That should be it.
If any of you can solve this, please let's post the final code as working code for 1500.
Thank you so much to anyone who can help