I am using ESP32 c3 mini1 and EC200U and task is sending hello through mqtt with help of AT commands and in that i am using ssl implimentation in that i am facing issue of +QMTOPEN: 0,5
i am using isrgroot.pem ( lets encrypt certificate )
code -
/**
- ESP32-C3 MQTTS EC200U Example (SPIFFS Version - Merged)
- This version uses the user’s robust loop and AT command functions,
- combined with all the necessary SSL fixes.
- *** FINAL FIX APPLIED ***
- This version now FORCE-DELETES all old/conflicting certificates from
- the modem’s UFS on boot to prevent SSL stack confusion.
- It includes fixes for:
-
- Correct command order: Config SSL/MQTT before activating network.
-
- Force-deletes ALL old certs from modem on boot.
-
- Uses the full “UFS:” path for the certificate.
-
- Uses “seclevel 1” (Server auth only).
-
- Forces “sslversion 3” (TLS 1.2 only).
-
- Forces a specific modern cipher suite (0XC02F).
-
- Enables SNI (“sni”, 1).
-
- Ignores modem’s local time (“ignorelocaltime”, 1).
-
- Links MQTT to the correct PDP context (“pdpcid”, 1).
-
- Waits for the correct URCs (e.g., “+QMTOPEN: 0,0”).
-
- Removes the failing “clientid” command.
- PLATFORMIO SPIFFS PREPARATION:
-
- Create a ‘data’ folder in your project’s root.
-
- Place ‘isrgroot.pem’ inside the ‘data’ folder.
-
- Run ‘pio run -t uploadfs’ to upload the file to the ESP32’s SPIFFS.
- HARDWARE CONNECTIONS (ESP32-C3 ↔ EC200U):
-
- ESP32 3.3V → EC200U VCC
-
- ESP32 GND → EC200U GND
-
- ESP32 TXD1 (19) → EC200U Main RX
-
- ESP32 RXD1 (18) → EC200U Main TX
*/
- ESP32 RXD1 (18) → EC200U Main TX
#include <Arduino.h> // Required for PlatformIO
#include <HardwareSerial.h> // Include for HardwareSerial communication
#include <string.h> // Include for strlen
#include “SPIFFS.h” // Include SPIFFS library
// — User Configuration —
// Modem communication pins and baud rate
#define MODEM_RX 18
#define MODEM_TX 19
#define MODEM_BAUD 115200
#define MStat 2 // Status LED
// APN Configuration
#define APN “www”
// MQTT Broker Details
#define MQTT_SERVER “mqtts.lets.balwaan.com”
#define MQTT_PORT 8883
#define MQTT_USERNAME “lets-balwaan-mqtts”
#define MQTT_PASSWORD “Balwaanletsmqtts”
#define MQTT_CLIENT_ID “esp32-c3-device-01” // MUST be unique
#define MQTT_TOPIC “balwaan/test”
// Certificate file paths
#define CERT_FILENAME_ON_SPIFFS “/isrgroot.pem” // Path on ESP32
#define CERT_FILENAME_ON_MODEM “isrgroot.pem” // Filename on Modem
#define CERT_FULLPATH_ON_MODEM “UFS:isrgroot.pem” // Full path on Modem
#define SSL_CONTEXT_ID 0 // We’ll use SSL context 0
// Create a HardwareSerial instance for the modem
HardwareSerial modem(1);
// Global flag to track MQTT connection status
bool mqttConnected = false;
// — Utility Functions —
// Sends an AT command and waits for a specific expected response
String sendATCommand(String command, int timeout, String expectedResponse) {
while (modem.available()) modem.read();
if (command != “”) modem.println(command);
String response = “”;
long startTime = millis();
Serial.print(">>> “);
Serial.println(command);
Serial.print(”<<< ");
while (millis() - startTime < timeout) {
if (modem.available()) {
char c = (char)modem.read();
response += c;
Serial.print(c);
if (expectedResponse != "" && response.indexOf(expectedResponse) != -1)
return response;
if (response.indexOf("ERROR") != -1)
return response;
}
}
Serial.println();
if (expectedResponse == “” && response.indexOf(“ERROR”) == -1) return “OK”;
return response;
}
bool waitForActivation(uint32_t timeout = 30000) {
Serial.println(“\n[INFO] Waiting for PDP Context Activation (30s timeout)…”);
long startTime = millis();
while (millis() - startTime < timeout) {
String response = sendATCommand(“AT+QIACT?”, 2000, “+QIACT: 1,1,1”);
if (response.indexOf(“+QIACT: 1,1,1”) != -1) {
Serial.println(“[INFO] PDP Context is active.”);
return true;
}
Serial.println(“[INFO] Waiting… (PDP context not active yet)”);
delay(2000);
}
Serial.println(“[ERROR] PDP Context activation timed out!”);
return false;
}
// Check file on modem
bool checkFileOnModem(const char* filename) {
Serial.println(“\n[INFO] Checking for file on modem…”);
String response = sendATCommand(“AT+QFLST”, 5000, “OK”);
if (response.indexOf(filename) != -1) {
Serial.println(“[INFO] File found in modem file list.”);
return true;
}
Serial.println(“[INFO] File not found in modem file list.”);
return false;
}
// Upload certificate from SPIFFS to modem
bool uploadFileToModem(const char* spiffsFilename, const char* modemFilename) {
Serial.println(“\n[INFO] Uploading file from SPIFFS to modem…”);
File file = SPIFFS.open(spiffsFilename, “r”);
if (!file) {
Serial.print("[ERROR] Failed to open file: ");
Serial.println(spiffsFilename);
return false;
}
size_t fileSize = file.size();
Serial.print("[INFO] File size: ");
Serial.println(fileSize);
String cmd = “AT+QFUPL=“” + String(modemFilename) + “”,” + String(fileSize) + “,100”;
if (sendATCommand(cmd, 5000, “CONNECT”).indexOf(“CONNECT”) == -1) {
Serial.println(“!! Cert upload failed: No CONNECT”);
file.close();
return false;
}
Serial.println(“[INFO] Sending file…”);
uint8_t buffer[256];
size_t bytesSent = 0;
while (bytesSent < fileSize) {
size_t bytesToRead = file.read(buffer, sizeof(buffer));
if (bytesToRead == 0) break;
modem.write(buffer, bytesToRead);
bytesSent += bytesToRead;
Serial.print(“.”);
}
file.close();
if (sendATCommand(“”, 10000, “OK”).indexOf(“OK”) != -1) {
Serial.println(“\n>> Cert Uploaded Successfully”);
delay(1000);
return true;
}
Serial.println(“!! Cert upload failed”);
return false;
}
// Initialize modem and network
bool initAndCheckNetwork() {
if (sendATCommand(“AT”, 2000, “OK”).indexOf(“OK”) == -1) {
Serial.println(“[ERROR] Modem not ready.”);
return false;
}
sendATCommand(“ATE0”, 500, “OK”);
sendATCommand(“AT+CFUN=1”, 10000, “OK”);
if (sendATCommand(“AT+CPIN?”, 5000, “READY”).indexOf(“READY”) == -1) return false;
if (sendATCommand(“AT+CSQ”, 1000, “+CSQ:”).indexOf(“+CSQ:”) == -1) return false;
String reg = sendATCommand(“AT+CREG?”, 2000, “OK”);
if (reg.indexOf(“+CREG: 0,1”) == -1 && reg.indexOf(“+CREG: 0,5”) == -1) return false;
if (sendATCommand(“AT+CGATT=1”, 1000, “OK”).indexOf(“OK”) == -1) return false;
return true;
}
bool configureSSL() {
sendATCommand(“AT+QFDEL=“” CERT_FULLPATH_ON_MODEM “””, 5000, “”);
if (!checkFileOnModem(CERT_FILENAME_ON_MODEM))
if (!uploadFileToModem(CERT_FILENAME_ON_SPIFFS, CERT_FILENAME_ON_MODEM))
return false;
if (sendATCommand(“AT+QSSLCFG=“sslversion”,0,3”, 1000, “OK”).indexOf(“OK”) == -1) return false;
if (sendATCommand(“AT+QSSLCFG=“ciphersuite”,0,0XC02F”, 1000, “OK”).indexOf(“OK”) == -1) return false;
if (sendATCommand(“AT+QSSLCFG=“seclevel”,0,1”, 1000, “OK”).indexOf(“OK”) == -1) return false;
if (sendATCommand(“AT+QSSLCFG=“cacert”,0,“” CERT_FULLPATH_ON_MODEM “””, 1000, “OK”).indexOf(“OK”) == -1) return false;
if (sendATCommand(“AT+QSSLCFG=“ignorelocaltime”,0,1”, 1000, “OK”).indexOf(“OK”) == -1) return false;
if (sendATCommand(“AT+QSSLCFG=“sni”,0,1”, 1000, “OK”).indexOf(“OK”) == -1) return false;
return true;
}
bool configureMQTT() {
if (sendATCommand(“AT+QMTCFG=“pdpcid”,0,1”, 1000, “OK”).indexOf(“OK”) == -1) return false;
if (sendATCommand(“AT+QMTCFG=“ssl”,0,1,0”, 1000, “OK”).indexOf(“OK”) == -1) return false;
if (sendATCommand(“AT+QMTCFG=“version”,0,4”, 1000, “OK”).indexOf(“OK”) == -1) return false;
return true;
}
bool activateNetwork() {
sendATCommand(“AT+QIDEACT=1”, 5000, “”);
String apnCmd = “AT+QICSGP=1,1,“” APN “”,“”,“”,0”;
if (sendATCommand(apnCmd, 5000, “OK”).indexOf(“OK”) == -1) return false;
if (sendATCommand(“AT+QIACT=1”, 30000, “OK”).indexOf(“OK”) == -1) return false;
return waitForActivation();
}
bool connectModemAndMQTT() {
if (!initAndCheckNetwork()) return false;
if (!configureSSL()) return false;
if (!configureMQTT()) return false;
if (!activateNetwork()) return false;
String open = “AT+QMTOPEN=0,“” MQTT_SERVER “”,” + String(MQTT_PORT);
if (sendATCommand(open, 15000, “+QMTOPEN: 0,0”).indexOf(“+QMTOPEN: 0,0”) == -1)
return false;
String conn = “AT+QMTCONN=0,“” MQTT_CLIENT_ID “”,“” MQTT_USERNAME “”,“” MQTT_PASSWORD “””;
if (sendATCommand(conn, 15000, “+QMTCONN: 0,0,0”).indexOf(“+QMTCONN: 0,0,0”) == -1)
return false;
return true;
}
bool mqttPublish(const char* payload) {
static int msgId = 1;
String cmd = “AT+QMTPUB=0,” + String(msgId++) + “,0,0,“” MQTT_TOPIC “””;
if (sendATCommand(cmd, 3000, “>”).indexOf(“>”) == -1) return false;
modem.print(payload);
modem.write(0x1A);
String expect = “+QMTPUB: 0,” + String(msgId - 1) + “,0”;
if (sendATCommand(“”, 5000, expect).indexOf(expect) != -1) return true;
return false;
}
void setup() {
Serial.begin(115200);
pinMode(MStat, OUTPUT);
modem.begin(MODEM_BAUD, SERIAL_8N1, MODEM_RX, MODEM_TX);
if (!SPIFFS.begin(true)) while(1);
mqttConnected = connectModemAndMQTT();
}
void loop() {
static unsigned long last = 0;
if (!mqttConnected) mqttConnected = connectModemAndMQTT();
if (mqttConnected && millis() - last > 10000) {
last = millis();
if (!mqttPublish(“hello”)) mqttConnected = false;
}
}
}
OUTPUT-
ESP-ROM:esp32c3-api1-20210207
Build:Feb 7 2021
rst:0x1 (POWERON),boot:0xc (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5810,len:0x438
load:0x403cc710,len:0x90c
load:0x403ce710,len:0x2624
entry 0x403cc710
— EC200U MQTTS Publisher Start (Merged Code) —
[INFO] SPIFFS Mounted.
AT
<<<
OK
[INFO] Modem: OK.
ATE0
<<<
OK>>> AT+CFUN=1
<<<
OK[INFO] Checking SIM and Network…>>> AT+CPIN?
<<<
+CPIN: READY>>> AT+CSQ
<<<
+CSQ:>>> AT+CREG?
<<<
+CREG: 0,1
OK>>> AT+CGATT=1
<<<
OK
[INFO] SIM/Network Checks OK.
[INFO] Forcing deletion of old certificate file(s)…
AT+QFDEL=“UFS:isrgroot.pem”
<<<
OK
AT+QFDEL=“UFS:ca.crt”
<<<
+CME ERROR>>> AT+QFDEL=“UFS:client.crt”
<<<
+CME ERROR>>> AT+QFDEL=“UFS:client.key”
<<<
+CME ERROR>>> AT+QFDEL=“UFS:isrg.pem”
<<<
+CME ERROR>>> AT+QFDEL=“UFS:isrgrootx1.pem”
<<<
+CME ERROR[INFO] Old file cleanup complete.
[INFO] Checking/Uploading Certificate…
[INFO] Checking for file on modem…
AT+QFLST
<<<
+QFLST: “UFS:boot”,15004
+QFLST: “UFS:firm”,243616
+QFLST: “UFS:gnss_data”,4636
+QFLST: “UFS:gnss_loca”,47
+QFLST: “UFS:gnss_time”,21
OK[INFO] File not found in modem file list.
[INFO] Certificate not found on modem, uploading…
[INFO] Uploading file from SPIFFS to modem…
[INFO] File found on SPIFFS. Size: 1939
AT+QFUPL=“isrgroot.pem”,1939,100
<<<
CONNECT[INFO] Modem is ready. Sending file data…
…
[INFO] File data sent.
<<< +QFUPL: 1939,4f64
OK>> Cert Uploaded Successfully: isrgroot.pem
[INFO] Configuring SSL Context…
AT+QSSLCFG=“sslversion”,0,3
<<<
OK>>> AT+QSSLCFG=“ciphersuite”,0,0XC02F
<<<
OK>>> AT+QSSLCFG=“seclevel”,0,1
<<<
OK>>> AT+QSSLCFG=“cacert”,0,“UFS:isrgroot.pem”
<<<
OK>>> AT+QSSLCFG=“ignorelocaltime”,0,1
<<<
OK>>> AT+QSSLCFG=“sni”,0,1
<<<
OK[INFO] SSL Context Configured.
[INFO] Configuring MQTT for SSL…
AT+QMTCFG=“pdpcid”,0,1
<<<
OK>>> AT+QMTCFG=“ssl”,0,1,0
<<<
OK>>> AT+QMTCFG=“version”,0,4
<<<
OK[INFO] MQTT Configured for SSL.
[INFO] Deactivating old PDP context (AT+QIDEACT=1)…>>> AT+QIDEACT=1
<<<
OK
Done.
[INFO] Setting APN…>>> AT+QICSGP=1,1,“www”,“”,“”,0
<<<
OK
[INFO] APN Set.
[INFO] Connecting to GPRS/LTE…>>> AT+QIACT=1
<<<
OK
[INFO] Connected to GPRS/LTE.
[INFO] Waiting for PDP Context Activation (30s timeout)…
AT+QIACT?
<<<
+QIACT: 1,1,1[INFO] PDP Context is active.
[INFO] Connecting to MQTT Broker…>>> AT+QMTOPEN=0,“mqtts.lets.balwaan.com”,8883
<<<
OK
+QMTOPEN: 0,5
[ERROR] Failed to open network connection. Check SSL config.
[FATAL] Initial connection failed. Loop will attempt reconnect.
[WARN] Attempting full modem and MQTT reconnect…
AT
<<<
OK
[INFO] Modem: OK.
ATE0
<<<
OK>>> AT+CFUN=1
repeatative
again and again giving me the +QMTOPEN: 0,5 this error