Google cloud MQTT with Esp32 Reusing JWT error - google-cloud-platform

I am trying to send fake temperature data from an ESP32 to Google Cloud with Arduino IDE and using this library https://github.com/GoogleCloudPlatform/google-cloud-iot-arduino. I created a registry and a device on google iot core. On my side I manually put the csa certificate on the ESP32 and correctly set all parameters and private key string in 'ciotc_config.h'. When I try to connect I get in the Serial Monitor the following output repeting itself:
ho 0 tail 12 room 4
load:0x40080400,len:6352
entry 0x400806b8
Setup.....
Starting wifi
Connecting to WiFi
Connected
Waiting on time sync...
Esp32-mqtt:
void setupWifi() {
Serial.println("Starting wifi");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(100);
}
Serial.println("Connected");
configTime(0, 0, ntp_primary, ntp_secondary);
Serial.println("Waiting on time sync...");
while (time(nullptr) < 1510644967) {
delay(10);
}
}
void connectWifi() {
Serial.print("checking wifi...");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
}
I made a change in the main.cpp just because I will not be working with those sensors:
unsigned long lastMillis = 0;
void loop() {
mqtt->loop();
delay(10); // <- fixes some issues with WiFi stability
if (!mqttClient->connected()) {
connect();
}
if (millis() - lastMillis > 60000) {
Serial.println("Publishing value");
lastMillis = millis();
float temp = 33;
float hum = 50;
StaticJsonDocument<100> doc;
doc["temp"] = temp;
doc["humidity"] = hum;
serializeJson(doc, buffer);
//publishTelemetry(mqttClient, "/sensors", getDefaultSensor());
publishTelemetry( buffer);
}
}
Image from PUB:

I guess it is just a debug information. It could be in the line where you write the JWT tag information.
I wrote a tutorial about how to connect the ESP32 to Google Cloud IoT with full source code that is very similar to your code but It didn't repeat that info. You can give a look https://www.survivingwithandroid.com/cloud-iot-core-esp32/ and you can reuse the code. Let me know if I can help you somehow.

It doesn't look like you're ever successfully connecting.
In your output, I see connecting... so it's in the mqttConnect() call, but it never outputs connected! so it's stuck in the while loop where it's calling getJwt()
Now, why it's not outputting the mqtt errors may mean your errors are related to something else, and the mqtt client is totally fine, which is why you aren't seeing any other output. As a debugging check, I'd put a Serial.println("fubar") in the mqttConnect() call above the delay(1000) and see if you get other output there, pointing at some other connection error other than an mqtt connection problem.

Related

How to use RTCM data to achieve RTK?

I'm using this example from the Sparkfun Arduino Library
/*
Use ESP32 WiFi to get RTCM data from RTK2Go (caster) as a Client
By: SparkFun Electronics / Nathan Seidle
Date: November 18th, 2021
License: MIT. See license file for more information but you can
basically do whatever you want with this code.
This example shows how to obtain RTCM data from a NTRIP Caster over WiFi
and push it over I2C to a ZED-F9x.
It's confusing, but the Arduino is acting as a 'client' to a 'caster'. In this case we will
use RTK2Go.com as our caster because it is free. See the NTRIPServer example to see how
to push RTCM data to the caster.
You will need to have a valid mountpoint available. To see available mountpoints go here: http://rtk2go.com:2101/
This is a proof of concept to show how to connect to a caster via HTTP. Using WiFi for a rover
is generally a bad idea because of limited WiFi range in the field.
For more information about NTRIP Clients and the differences between Rev1 and Rev2 of the protocol
please see: https://www.use-snip.com/kb/knowledge-base/ntrip-rev1-versus-rev2-formats/
Feel like supporting open source hardware?
Buy a board from SparkFun!
ZED-F9P RTK2: https://www.sparkfun.com/products/16481
RTK Surveyor: https://www.sparkfun.com/products/18443
RTK Express: https://www.sparkfun.com/products/18442
Hardware Connections:
Plug a Qwiic cable into the GNSS and a ESP32 Thing Plus
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
Open the serial monitor at 115200 baud to see the output
*/
#include <WiFi.h>
#include "secrets.h"
#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
SFE_UBLOX_GNSS myGNSS;
//The ESP32 core has a built in base64 library but not every platform does
//We'll use an external lib if necessary.
#if defined(ARDUINO_ARCH_ESP32)
#include "base64.h" //Built-in ESP32 library
#else
#include <Base64.h> //nfriendly library from https://github.com/adamvr/arduino-base64, will work with any platform
#endif
//Global variables
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
long lastReceivedRTCM_ms = 0; //5 RTCM messages take approximately ~300ms to arrive at 115200bps
int maxTimeBeforeHangup_ms = 10000; //If we fail to get a complete RTCM frame after 10s, then disconnect from caster
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void setup()
{
Serial.begin(115200);
Serial.println(F("NTRIP testing"));
Wire.begin(); //Start I2C
if (myGNSS.begin() == false) //Connect to the Ublox module using Wire port
{
Serial.println(F("u-blox GPS not detected at default I2C address. Please check wiring. Freezing."));
while (1);
}
Serial.println(F("u-blox module connected"));
myGNSS.setI2COutput(COM_TYPE_UBX); //Turn off NMEA noise
myGNSS.setPortInput(COM_PORT_I2C, COM_TYPE_UBX | COM_TYPE_NMEA | COM_TYPE_RTCM3); //Be sure RTCM3 input is enabled. UBX + RTCM3 is not a valid state.
myGNSS.setNavigationFrequency(1); //Set output in Hz.
Serial.print(F("Connecting to local WiFi"));
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(F("."));
}
Serial.println();
Serial.print(F("WiFi connected with IP: "));
Serial.println(WiFi.localIP());
while (Serial.available()) Serial.read();
}
void loop()
{
if (Serial.available())
{
beginClient();
while (Serial.available()) Serial.read(); //Empty buffer of any newline chars
}
Serial.println(F("Press any key to start NTRIP Client."));
delay(1000);
}
//Connect to NTRIP Caster, receive RTCM, and push to ZED module over I2C
void beginClient()
{
WiFiClient ntripClient;
long rtcmCount = 0;
Serial.println(F("Subscribing to Caster. Press key to stop"));
delay(10); //Wait for any serial to arrive
while (Serial.available()) Serial.read(); //Flush
while (Serial.available() == 0)
{
//Connect if we are not already. Limit to 5s between attempts.
if (ntripClient.connected() == false)
{
Serial.print(F("Opening socket to "));
Serial.println(casterHost);
if (ntripClient.connect(casterHost, casterPort) == false) //Attempt connection
{
Serial.println(F("Connection to caster failed"));
return;
}
else
{
Serial.print(F("Connected to "));
Serial.print(casterHost);
Serial.print(F(": "));
Serial.println(casterPort);
Serial.print(F("Requesting NTRIP Data from mount point "));
Serial.println(mountPoint);
const int SERVER_BUFFER_SIZE = 512;
char serverRequest[SERVER_BUFFER_SIZE];
snprintf(serverRequest, SERVER_BUFFER_SIZE, "GET /%s HTTP/1.0\r\nUser-Agent: NTRIP SparkFun u-blox Client v1.0\r\n",
mountPoint);
char credentials[512];
if (strlen(casterUser) == 0)
{
strncpy(credentials, "Accept: */*\r\nConnection: close\r\n", sizeof(credentials));
}
else
{
//Pass base64 encoded user:pw
char userCredentials[sizeof(casterUser) + sizeof(casterUserPW) + 1]; //The ':' takes up a spot
snprintf(userCredentials, sizeof(userCredentials), "%s:%s", casterUser, casterUserPW);
Serial.print(F("Sending credentials: "));
Serial.println(userCredentials);
#if defined(ARDUINO_ARCH_ESP32)
//Encode with ESP32 built-in library
base64 b;
String strEncodedCredentials = b.encode(userCredentials);
char encodedCredentials[strEncodedCredentials.length() + 1];
strEncodedCredentials.toCharArray(encodedCredentials, sizeof(encodedCredentials)); //Convert String to char array
snprintf(credentials, sizeof(credentials), "Authorization: Basic %s\r\n", encodedCredentials);
#else
//Encode with nfriendly library
int encodedLen = base64_enc_len(strlen(userCredentials));
char encodedCredentials[encodedLen]; //Create array large enough to house encoded data
base64_encode(encodedCredentials, userCredentials, strlen(userCredentials)); //Note: Input array is consumed
#endif
}
strncat(serverRequest, credentials, SERVER_BUFFER_SIZE);
strncat(serverRequest, "\r\n", SERVER_BUFFER_SIZE);
Serial.print(F("serverRequest size: "));
Serial.print(strlen(serverRequest));
Serial.print(F(" of "));
Serial.print(sizeof(serverRequest));
Serial.println(F(" bytes available"));
Serial.println(F("Sending server request:"));
Serial.println(serverRequest);
ntripClient.write(serverRequest, strlen(serverRequest));
//Wait for response
unsigned long timeout = millis();
while (ntripClient.available() == 0)
{
if (millis() - timeout > 5000)
{
Serial.println(F("Caster timed out!"));
ntripClient.stop();
return;
}
delay(10);
}
//Check reply
bool connectionSuccess = false;
char response[512];
int responseSpot = 0;
while (ntripClient.available())
{
if (responseSpot == sizeof(response) - 1) break;
response[responseSpot++] = ntripClient.read();
if (strstr(response, "200") > 0) //Look for 'ICY 200 OK'
connectionSuccess = true;
if (strstr(response, "401") > 0) //Look for '401 Unauthorized'
{
Serial.println(F("Hey - your credentials look bad! Check you caster username and password."));
connectionSuccess = false;
}
}
response[responseSpot] = '\0';
Serial.print(F("Caster responded with: "));
Serial.println(response);
if (connectionSuccess == false)
{
Serial.print(F("Failed to connect to "));
Serial.print(casterHost);
Serial.print(F(": "));
Serial.println(response);
return;
}
else
{
Serial.print(F("Connected to "));
Serial.println(casterHost);
lastReceivedRTCM_ms = millis(); //Reset timeout
}
} //End attempt to connect
} //End connected == false
if (ntripClient.connected() == true)
{
uint8_t rtcmData[512 * 4]; //Most incoming data is around 500 bytes but may be larger
rtcmCount = 0;
//Print any available RTCM data
while (ntripClient.available())
{
//Serial.write(ntripClient.read()); //Pipe to serial port is fine but beware, it's a lot of binary data
rtcmData[rtcmCount++] = ntripClient.read();
if (rtcmCount == sizeof(rtcmData)) break;
}
if (rtcmCount > 0)
{
lastReceivedRTCM_ms = millis();
//Push RTCM to GNSS module over I2C
myGNSS.pushRawData(rtcmData, rtcmCount, false);
Serial.print(F("RTCM pushed to ZED: "));
Serial.println(rtcmCount);
}
}
//Close socket if we don't have new data for 10s
if (millis() - lastReceivedRTCM_ms > maxTimeBeforeHangup_ms)
{
Serial.println(F("RTCM timeout. Disconnecting..."));
if (ntripClient.connected() == true)
ntripClient.stop();
return;
}
delay(10);
}
Serial.println(F("User pressed a key"));
Serial.println(F("Disconnecting..."));
ntripClient.stop();
}
on an ESP32 Thing Plus C with a ZED-F9P and it's working fine, but it only outputs RTCM data. How do I apply the RTCM data to the GPS data and achieve RTK? My goal is to have the ESP32 Thing Plus C output RTK Latitude and Longitude to the serial monitor.
Example output:
RTCM pushed to ZED: 163
RTCM pushed to ZED: 311
RTCM pushed to ZED: 1694
RTCM pushed to ZED: 1332
Any ideas would be appeciated! Thanks
Answered by PaulZC on Sparkfun Forum
Hi Jacob,
It sounds like everything is working OK. But, correct, there is
nothing in that example to actually print out the position.
Please try Example17. It is better-structured and uses callbacks to:
display your position; and push NMEA GGA data to the server. Some
NTRIP servers require the GGA data, others don't. If the GGA data
causes problems, you can comment this line to disable the push:
https://github.com/sparkfun/SparkFun_u- ... ck.ino#L81
Have fun! Paul

Trying to carry out HTTP request to device connected to ESP8266 in access point configuration

Edit:
I apologize for the lack of information and quality of the previous version of this question, I will try to rephrase and give more information about my issue.
I am currently running a web server using XAMPP in my laptop. The webserver contains several php files that make a website, and a database.
Inside the database I created a table for testing purposes called 'test'. This table consists on 2 columns: a timestamp and a value column which accepts integers.
One of the php files in the web server is called update.php, and uses GET to write information into the 'test' table in the database, like this:
<?php
require_once "db.php";
$value = $_GET['value'];
$query = "
INSERT INTO test(value)
VALUES ('".$value."')
";
mysqli_query($conn, $query);
?>
This works properly, if I go into my browser and type 'http://localhost/swater/update.php?value=2', a new row is successfully added to the table with value 2.
This is great, but I need this to be carried out from an ESP8266, which is connected to a button. The goal is that every X seconds the ESP checks if the button is pressed or not. If it is pressed it should add value 1 to the table, and if it is not it should add value 0.
I first carried this out connecting the ESP to my house Wi-Fi network, using this code:
void loop() {
if ((millis() - lastTime) > timerDelay) {
if(WiFi.status()== WL_CONNECTED){
WiFiClient client;
HTTPClient http;
value = digitalRead(4);
String serverPath = serverName + "?value=" + value;
http.begin(client, serverPath.c_str());
int httpResponseCode = http.GET();
if (httpResponseCode>0) {
Serial.print("Response code: ");
Serial.println(httpResponseCode);
String payload = http.getString();
Serial.println(payload);
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
http.end();
}
else {
Serial.println("Disconnected");
}
lastTime = millis();
}
}
This worked perfectly fine, and my table started periodically getting values added. However this is not my final goal, as I want the ESP to act as an access point, to which my laptop is connected.
I managed to write this code:
void setup() {
Serial.begin(115200);
WiFi.softAP(ssid, pwd);
pinMode(4, INPUT);
}
void loop() {
WiFiClient client;
HTTPClient http;
http.begin(client, "http://192.168.4.2:80/swater/update.php?value=1");
Serial.print("Request sent.\n");
delay(5000);
}
Note that I am not using the values that the ESP reads, I am just testing so I am skipping that part of the code and just using value=1 all the time.
When I run this code in the ESP, I can connect my laptop and my phone to the Wi-Fi that it creates, and I can successfully visit the website from any device connected to it, however no values are added to the 'test' table.
I apologize if I now made my explanation too long, but it is my first time working with this kind of systems and it is the first time I ask a question in this platform, I appreciate the help.
You forget to send your GET request int httpResponseCode = http.GET();
void loop() {
WiFiClient client;
HTTPClient http;
http.begin(client, "http://192.168.4.2:80/swater/update.php?value=1");
int httpResponseCode = http.GET();
if (httpResponseCode>0) {
Serial.print("Request sent.\n");
}
delay(5000);
}

ESP8266 WiFi Manager and Modem Sleep

Noob question, I'm very knew here, I'm trying tu use wifi manager and modem sleep, but once I turn off the wifi I can't reconnect again. I know what I'm missing is the configuration to connect to the wifi after it has been turned off but I don't know how to do it if I'm using WiFi Manager.
These are the steps:
Power on ESP8266
Call WiFi Manager and set the credential. Save them for the next time
Turn the WiFi Off (In order to collect data from a sensor without power consumption)
Collected my 5 data I need to power on the WiFi and connect to it
I made two functions, one to turn off wifi and one to turn it on
void active_mode(){
//se spento accendiamo il wifi
if(WiFi.status() != WL_CONNECTED){
WiFi.forceSleepWake();
//here I should connect to the wifi but how
//if I'm using wifi manager?
//normally I would use this:
//WiFi.mode(WIFI_STA);
//WiFi.begin(ssid, password);
//but what if I already saved my credential the first time I powered on the esp
//how to retrieve them in order to connect to wifi?
delay(1);
}
}
void sleep_mode(){
//spegniamo il wifi
WiFi.disconnect();
WiFi.forceSleepBegin();
if(WiFi.status() != WL_CONNECTED){
Serial.print(WiFi.status());
Serial.println(" :WiFi spento");
}
delay(1);
}
in the void setup I've got this. This way when I first power on my esp I can save my WiFi credential and connect to it everytime I power on my esp.
void setup(){
// WiFiManager
// Local intialization.
WiFiManager wifiManager;
//wifiManager.autoConnect("AutoConnectAP");
// if you get here you have connected to the WiFi
Serial.println("Connected.");
delay(5000);
//I call sleep_mode here because I need to collect data from a sensor without the WiFi
powered on
sleep_mode();
}
Here's the loop
void loop() {
//Reading data every 3 seconds and save them in file.txt
now = millis();
if (now - start_time >= timer_save){
//if (count < 3){
read_data();
saveHistory();
start_time = now;
count++;
//}
}
//saved 5 data turn on wifi, read them and clear the content of file.txt
if (count == 5){
active_mode();
// checking connection
if (!client.connected()) {
reconnect();
}
client.loop();
readHistory();
//mqtt_publish();
LittleFS.remove("/file.txt");
count = 0;
start_time = 0;
sleep_mode();
//delay(5000);
}
}//end of void loop();
if I've understood the question right. This could be of great help:
https://github.com/tzapu/WiFiManager/issues/272
If not, my bad.

How can I include a body while sending a POST request using HTTP AT commands with a SIM7000A module and an Arduino?

I'm crossposting this from where I posted it on the Arduino forum in hopes that maybe someone here has an answer. I am working on a project that involves sending POST requests to a Twilio function using an Arduino Uno and a SIMCOM SIM7000A breakout board using AT commands. So far with the Uno, I can only POST an empty request that contains headers but no body. The following code is a test sketch where I am POSTing to a RequestBin repository.
#include <AltSoftSerial.h>
unsigned char data = 0;
AltSoftSerial SIM7000;
char incomingChar;
void setup() {
Serial.begin(9600);
SIM7000.begin(19200);
// put your setup code here, to run once:
SIM7000.print("AT+CMGF=1\r"); //put in text mode
delay(100);
SIM7000.print("AT+CGDCONT=1\"IP\",\"super\"\r"); //create profile. "super" is APN for twilio super sim
delay(1000);
SIM7000.print("AT+COPS=1,2,\"310410\"\r"); //log on to AT&T network
delay(5000);
SIM7000.print("AT+SAPBR=3,1,\"APN\",\"super\"\r"); //create SAPBR profile. same APN.
delay(300);
SIM7000.print("AT+SAPBR=1,1\r");
delay(2000);
Serial.println("Setup complete. Module should be online and fast-blinking\n from successful SAPBR profile setup.\n Entering loop. Send \"CHECK\" to test POST");
}
void loop() {
SIM7000.print("AT+CMGL\r");
if (SIM7000.available() > 0) {
incomingChar = SIM7000.read();
if (incomingChar == 'C') {
delay(10);
Serial.print(incomingChar);
incomingChar = SIM7000.read();
if (incomingChar == 'H') {
delay(10);
Serial.print(incomingChar);
incomingChar = SIM7000.read();
if (incomingChar == 'E') {
delay(10);
Serial.print(incomingChar);
incomingChar = SIM7000.read();
if (incomingChar == 'C') {
delay(10);
Serial.print(incomingChar);
incomingChar = SIM7000.read();
if (incomingChar == 'K') {
delay(10);
Serial.print(incomingChar);
incomingChar = "";
Serial.println(F("\nGOOD CHECK"));
Serial.println(F("SENDING POST REQUEST NOW")) ;
sendText();
Serial.println("POST SENT");
return;
}
}
}
}
}
}
incomingChar = "";
return;
}
void sendText()
{
SIM7000.print("AT+HTTPINIT\r");
delay(1000);
getResponse();
SIM7000.print("AT+HTTPPARA=\"CID\",1\r");
delay(1000);
getResponse();
SIM7000.print("AT+HTTPPARA=\"URL\",\"http://engt62k9mgbgo.x.pipedream.net\"\r");
delay(1000);
getResponse();
SIM7000.print("AT+HTTPPARA=\"CONTENT\",\"text/plain\"\r");
delay(1000);
getResponse();
SIM7000.print("AT+HTTPDATA=100,5000\r\n");
delay(100);
getResponse();
SIM7000.print("\"TEST MESSAGE\"\r\n");
SIM7000.print("\r\n");
delay(5000);
getResponse();
SIM7000.print("AT+HTTPACTION=1\r");
delay(1000);
getResponse();
SIM7000.print("AT+HTTPTERM\r");
getResponse();
}
void getResponse()
{
if (SIM7000.available())
{
while (SIM7000.available())
{
data = SIM7000.read();
Serial.write(data);
}
data = 0;
}
}
//NOV 3 2020, note: need to include AT command AT+CMGD=0,4 for routinely deleting messages
//message storage limited and not automatically overwritten
I've included the output on the Serial monitor below.
Output on Serial Monitor
I'm thinking that the problem lies between
SIM7000.print("AT+HTTPDATA=100,5000\r\n");
and
SIM7000.print("AT+HTTPACTION=1\r");
You can see on the output where it prompts for DOWNLOAD, but the "TEST MESSAGE" that I try to insert here doesn't go. I've also attached a screenshot of the RequestBin output to show that it's showing up as an empty POST with nothing but headers and a content length of 0. Output in RequestBin
When I've done similar POST requests using the same SIM7000A module with the same AT commands on PuTTY via USB, all I have to do is enter my text during the time specified in the AT+HTTPDATA command and hit enter. Whatever I enter during that time as it says "DOWNLOAD" shows up as the body of my POST. But I have as of yet been unable to do the same using the Uno.
Any help you can offer is much appreciated.
First of all, you must to send CR NL char after all AT commands...
SIM7000.print("AT+HTTPDATA=100,5000\r\n");
Note: \r and \n = CR and NL respectively.
Second, try the steps below:
// SEND HTTP PROCESS
SIM7000.println("AT+HTTPINIT\r\n");
delay(1500);
Serial.println(SIM7000.readString());
SIM7000.println("AT+HTTPPARA=\"CID\",1\r\n");
delay(1500);
Serial.println(SIM7000.readString());
char httpSend[105] = "[URL]";
SIM7000.println(httpSend + String("\r\n"));
delay(1500);
Serial.println(SIM7000.readString());
SIM7000.println("AT+HTTPSSL=1\r\n"); // THIS LINE FOR SSL URL
delay(1500);
Serial.println(SIM7000.readString());
SIM7000.println("AT+HTTPACTION=0\r\n"); //GET REQUEST = 0 | POST REQUEST = 1
delay(7000);
Serial.println(SIM7000.readString());
SIM7000.println("AT+HTTPREAD\r\n");
delay(1500);
Serial.println(SIM7000.readString());
SIM7000.println("AT+HTTPTERM\r\n");
delay(1500);
Serial.println(SIM7000.readString());
Try adding ctrl-z Character (decimal 26) to the end of the data buffer you are sending after seeing DOWNLOAD.

Google iot MQTT - ESP32 Connects the first time and only reconnects after 30m

I'm working with google Iot cloud with ESP32, I am sending fake values just to make a test with the MQTT data PUB/SUB, Apparently I'm succeeding in publishing the values, sometimes, I can't reconnect to google iot.
I don't know why it keeps checking wifi...publising and doest check for the JWT key.
I have noticed that if I connect once to the google iot and then I unplug the esp32 from my pc (disconnect no power), and plug it back again and try to connect, I will enter in this "checking wifi" for about 30m, until I can connect back to google iot. How can fix this? I beleived there was something to deal with this:
// Time (seconds) to expire token += 20 minutes for drift
const int jwt_exp_secs = 3600; // Maximum 24H (3600*24)
When I manage to get a good response that send info to the servers, i get this+:
entry 0x400806b8
Setup.....
Starting wifi
Connecting to WiFi
Connected
Waiting on time sync...
checking wifi...
connecting...Refreshing JWT
connected
Library connected!
incoming: /devices/esp32-device/config -
incoming: /devices/esp32-device/config -
Publishing value
Publishing value
Publishing value
Publishing value
Publishing value
There is times that I get a bad response for about 30m, using the same code, it seems to be sending constant data, which shouldn't be constant.(wasn't suppose to happen):
ho 0 tail 12 room 4
load:0x40080400,len:6352
entry 0x400806b8
Setup.....
Starting wifi
Connecting to WiFi
Connected
Waiting on time sync...
checking wifi...Publishing value
checking wifi...checking wifi...checking wifi...Publishing value
(Just keeps repeating)
This is the main connection to MQTT code, with the attempts to fix problems, but didn't work:
// This file contains static methods for API requests using Wifi / MQTT
#ifndef __ESP32_MQTT_H__
#define __ESP32_MQTT_H__
#include <Client.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <MQTT.h>
#include <CloudIoTCore.h>
#include <CloudIoTCoreMqtt.h>
#include "ciotc_config.h" // Update this file with your configuration
void messageReceived(String &topic, String &payload) {
Serial.println("incoming: " + topic + " - " + payload);
}
// Initialize WiFi and MQTT for this board
Client *netClient;
CloudIoTCoreDevice *device;
CloudIoTCoreMqtt *mqtt;
MQTTClient *mqttClient;
unsigned long iat = 0;
String jwt;
String getDefaultSensor() {
return "Wifi: " + String(WiFi.RSSI()) + "db";
}
String getJwt() {
Serial.println("Entered JWT");
delay(5000);
iat = time(nullptr);
Serial.println("Refreshing JWT");
jwt = device->createJWT(iat, jwt_exp_secs);
return jwt;
}
void setupWifi() {
Serial.println("Starting wifi");
Serial.print("WIFI status = ");
Serial.println(WiFi.getMode());
WiFi.disconnect(true);
delay(3000);
WiFi.mode(WIFI_STA);
delay(3000);
Serial.print("WIFI status = ");
Serial.println(WiFi.getMode());
WiFi.begin(ssid, password);
Serial.println("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(100);
}
Serial.println("Connected");
delay(5000);
configTime(0, 0, ntp_primary, ntp_secondary);
Serial.println("Waiting on time sync...");
while (time(nullptr) < 1510644967) {
delay(10);
}
}
void connectWifi() {
Serial.print("checking wifi...");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
}
delay(5000);
}
bool publishTelemetry(String data) {
return mqtt->publishTelemetry(data);
}
bool publishTelemetry(const char* data, int length) {
return mqtt->publishTelemetry(data, length);
}
bool publishTelemetry(String subfolder, String data) {
return mqtt->publishTelemetry(subfolder, data);
}
bool publishTelemetry(String subfolder, const char* data, int length) {
return mqtt->publishTelemetry(subfolder, data, length);
}
void connect() {
connectWifi();
mqtt->mqttConnect();
delay(5000);
}
void setupCloudIoT() {
device = new CloudIoTCoreDevice(
project_id, location, registry_id, device_id,
private_key_str);
setupWifi();
netClient = new WiFiClientSecure();
mqttClient = new MQTTClient(512);
mqttClient->setOptions(180, true, 1000); // keepAlive, cleanSession, timeout
mqtt = new CloudIoTCoreMqtt(mqttClient, netClient, device);
mqtt->setUseLts(true);
mqtt->startMQTT();
delay(5000);
}
#endif //__ESP32_MQTT_H__
This is the main.cpp:
#include <Arduino.h>
#include <WiFiClientSecure.h>
#include "esp32-mqtt.h"
#include <ArduinoJson.h>
#define led 14
char buffer[100];
float counter = 0;
float counter1 = 0;
void setup() {
Serial.begin(115200);
Serial.println("Setup.....");
pinMode(led, OUTPUT);
setupCloudIoT();
}
unsigned long lastMillis = 0;
void loop() {
mqtt->loop();
delay(10); // <- fixes some issues with WiFi stability
if (!mqttClient->connected()) {
connect();
}
counter++;
counter1++;
if (millis() - lastMillis > 1000) {
Serial.println("Publishing value");
lastMillis = millis();
float temp = counter;
float hum = counter1;
StaticJsonDocument<100> doc;
doc["temp"] = temp;
doc["humidity"] = hum;
serializeJson(doc, buffer);
publishTelemetry(buffer);
}
}
Does someone know if there is any other module that doesn't have this same issue?
The issue you face is IMHO not a problem of your code or the MQTT-lib you use. There seems to be a problem in the ESP32 core package (1.04 has it still). See this collection of issues from github and some proposed work around, which in the end delay the problem but do not solve it.
Issue with MQTT collection of problems from 2018 till today
These are open issues regarding WiFi re/connection problems
A test case for provoking an error is linked from one of the post.I use for identifying ESP32 specific problems the identical programm on an esp8266 with MQTT connection and there it runs for months.The ESP32 people have the bad habit to leave issues uncommented open for month hopeing the stale bot closes them. So I just cited the open issues, if you search for closed issues you'll find some more) closed by stale bot and not by solution!