Working with a T-Sim7600H and have most of what I want working (well the basics).
My issue is around getting MQTT working over 8883, works on 1883 ok. Does any one have experience or guidance on how to send a message over 4g to a cloud hosted MQTT provided such as HiveMQ?
#define TINY_GSM_MODEM_SIM7600
// Set serial for debug console (to the Serial Monitor, default speed 115200)
#define SerialMon Serial
// Set serial for AT commands (to the module)
// Use Hardware Serial on Mega, Leonardo, Micro
#define SerialAT Serial1
// See all AT commands, if wanted
#define DUMP_AT_COMMANDS
// Define the serial console for debug prints, if needed
#define TINY_GSM_DEBUG SerialMon
// set GSM PIN, if any
#define GSM_PIN ""
// Your GPRS credentials, if any
//const char apn[] = "";
const char apn[] = "";
const char gprsUser[] = "";
const char gprsPass[] = "";
// MQTT details Private 8883
//const char* broker = "**********f7c4.s1.eu.hivemq.cloud"; // hivemq.cloud
//const char* mqttUsername = "*******"; // MQTT username
//const char* mqttPassword = "*******"; // MQTT password
// MQTT details Public 1883
const char* broker = "broker.hivemq.com"; // hivemq.cloud
const char* mqttUsername = ""; // MQTT username
const char* mqttPassword = ""; // MQTT password
const char* topicOutput1 = "esp/output1";
const char* topicOutput2 = "esp/output2";
const char* topicTemperature = "esp/temperature";
const char* topicHumidity = "esp/humidity";
//All Functions libraries
#include <TinyGsmClient.h>
#include <time.h>
//Debug
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
//MQTT
#include <PubSubClient.h>
TinyGsmClient client(modem);
PubSubClient mqtt(client);
/*
//“openssl s_client -showcerts -verify 5 -connect your_id.s1.eu.hivemq.cloud:8883” and the last cert from the chain
// Define the root CA PEM cert (this is the new ISRG Root X1)
static const char *root_ca PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC
ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL
wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D
LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK
4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5
bHbvO5BieebbpJovJsXQEOEO3tk**********iN5YNNnWe+w5y
sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ
Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4
FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc
SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql
PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND
TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1
c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx
+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB
ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu
b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E
U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu
MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC
5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW
9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG
WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O
he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----
)EOF";
// Remove this:
//client.setFingerprint(fingerprint);
//X509List cert(root_ca);
//client.setTrustAnchors(&cert);
*/
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 30 /* Time ESP32 will go to sleep (in seconds) */
#define UART_BAUD 115200
#define MODEM_TX 27
#define MODEM_RX 26
#define MODEM_PWRKEY 4
#define MODEM_DTR 32
#define MODEM_RI 33
#define MODEM_FLIGHT 25
#define MODEM_STATUS 34
#define SD_MISO 2
#define SD_MOSI 15
#define SD_SCLK 14
#define SD_CS 13
#define LED_PIN 12
#define OUTPUT_1 2
#define OUTPUT_2 15
uint32_t lastReconnectAttempt = 0;
float temperature = 0;
float humidity = 0;
//long lastMsg = 0;
//MQTT Setup
void mqttCallback(char* topic, byte* message, unsigned int len) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < len; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
// Feel free to add more if statements to control more GPIOs with MQTT
// If a message is received on the topic esp/output1, you check if the message is either "true" or "false".
// Changes the output state according to the message
if (String(topic) == "esp/output1") {
Serial.print("Changing output to ");
if (messageTemp == "true") {
Serial.println("true");
digitalWrite(OUTPUT_1, HIGH);
}
else if (messageTemp == "false") {
Serial.println("false");
digitalWrite(OUTPUT_1, LOW);
}
}
else if (String(topic) == "esp/output2") {
Serial.print("Changing output to ");
if (messageTemp == "true") {
Serial.println("true");
digitalWrite(OUTPUT_2, HIGH);
}
else if (messageTemp == "false") {
Serial.println("false");
digitalWrite(OUTPUT_2, LOW);
}
}
}
//boolean mqttConnect() {
//SerialMon.print("Connecting to ");
// Connect to MQTT Broker without username and password
//boolean status = mqtt.connect("user1");
// Or, if you want to authenticate MQTT:
//boolean status = mqtt.connect("user1", mqttUsername, mqttPassword);
//SerialMon.print(status);
// This is the sha-1 fingerprint of the current certificate for <your-id>.s1.eu.hivemq.cloud (It's a wildcard certificate, so should be the same for all deployments) I'm not sure at this point if this will change once the letsencrypt certificate is updated
//static const char *fingerprint PROGMEM = "EA 59 CA BD 80 01 01 E8 12 58 B6 4E A3 59 2B 5A 6E 60 BC F5";
/*
if (status == false) {
SerialMon.println(" fail");
//ESP.restart();
return false;
}
SerialMon.println(" success");
mqtt.subscribe(topicOutput1);
mqtt.subscribe(topicOutput2);
*/
//return mqtt.connected();
//SerialMon.print("MQTT Connected ");
//}
void setup()
{
SerialMon.begin(115200);
delay(10);
Serial.println("Booting");
delay(1000);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
pinMode(MODEM_PWRKEY, OUTPUT);
digitalWrite(MODEM_PWRKEY, HIGH);
delay(300); //Need delay
digitalWrite(MODEM_PWRKEY, LOW);
//MQTT
pinMode(OUTPUT_1, OUTPUT);
pinMode(OUTPUT_2, OUTPUT);
pinMode(MODEM_FLIGHT, OUTPUT);
digitalWrite(MODEM_FLIGHT, HIGH);
SerialMon.println("Wait...");
// Set GSM module baud rate
SerialAT.begin(UART_BAUD, SERIAL_8N1, MODEM_RX, MODEM_TX);
//delay(6000);
bool res ;
DBG("Initializing modem...");
Serial.println("Initializing modem..");
delay(1000);
if (!modem.init()) {
DBG("Failed to restart modem, delaying 10s and retrying");
return;
}
SerialMon.print("Connecting to APN: ");
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println(" fail");
ESP.restart();
}
else {
SerialMon.println(" OK");
}
if (modem.isGprsConnected()) {
SerialMon.println("GPRS connected");
}
// MQTT Broker setup
mqtt.setServer(broker, 1883); //use TLS 8883 not Web Sockets not supported 8884
//mqtt.setCallback(mqttCallback);
DBG("Connecting to APN");
Serial.println("Connecting to APN");
delay(1000);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
light_sleep(10);
return;
}
res = modem.isGprsConnected();
DBG("GPRS status: ", res ? "connected" : "not connected");
String ccid = modem.getSimCCID();
DBG("CCID: ", ccid);
Serial.println(ccid);
String imei = modem.getIMEI();
DBG("IMEI: ", imei);
Serial.println(imei);
String imsi = modem.getIMSI();
DBG("IMSI: ", imsi);
Serial.println(imsi);
String cop = modem.getOperator();
DBG("Operator: ", cop);
Serial.println(cop);
IPAddress local = modem.localIP();
DBG("Local IP: ", local);
Serial.println(local);
int csq = modem.getSignalQuality();
DBG("Signal quality: ", csq);
Serial.println(csq);
//mqttConnect();
//mqtt.connect("user1", mqttUsername, mqttPassword);
mqtt.connect("user1");
SerialMon.print("MQTT Connected ");
mqtt.publish("esp32/temperature", "122");
SerialMon.print("MQTT publish esp32/temperature value ");
}
//Sleep Timer
void light_sleep(uint32_t sec )
{
esp_sleep_enable_timer_wakeup(sec * 1000000ULL);
esp_light_sleep_start();
}
void loop() {
/*
// Make sure we're still registered on the network
if (!modem.isNetworkConnected()) {
SerialMon.println("Network disconnected");
if (!modem.waitForNetwork(180000L, true)) {
SerialMon.println(" fail");
delay(10000);
return;
}
if (modem.isNetworkConnected()) {
SerialMon.println("Network re-connected");
}
}
//MQTT Check and reconnect
if (!mqtt.connected()) {
SerialMon.println("=== MQTT NOT CONNECTED ===");
// Reconnect every 10 seconds
uint32_t t = millis();
if (t - lastReconnectAttempt > 60000L) {
lastReconnectAttempt = t;
if (mqttConnect()) { lastReconnectAttempt = 0; }
}
delay(100);
return;
}
mqtt.loop();
*/
}
AT response is good on 1883 but cant figure out how to do this on 8883 TLS. Following other threads Arduino example with server signed certificate - #5 by Chris - HiveMQ
+COPS: 0,0,"Skinny",7
OK
[3854] Operator: Skinny
Skinny
AT+IPADDR
+IPADDR: 100.x.x.x
OK
[3872] Local IP: 100.x.x.x
100.94.54.109
AT+CSQ
+CSQ: 21,99
OK
[3886] Signal quality: 21
21
AT+CIPRXGET=4,0
+CIPRXGET: 4,0,0
OK
AT+CIPCLOSE?
+CIPCLOSE: 0,0,0,0,0,0,0,0,0,0
OK
AT+CIPCLOSE=0
+CIPCLOSE: 0,4
ERROR
AT+CIPRXGET=1
OK
AT+CIPOPEN=0,"TCP","broker.hivemq.com",1883
OK
+CIPOPEN: 0,0
AT+CIPSEND=0,26
>
So in summary I want to publish over MQTT 8883 from a TSIM 7600
Note the TSIM7600 has built in MQTT commands but very little examples to work from.
Tried to break the code into smaller chunks to see where/what is my issue but it seems to be 8883/Certs.