I am trying to setup a BLE to MQTT gateway that uses a cellular modem. The code will scan for BLE devices, and will publish them via MQTT. But, if there is a problem with publishing one of the messages, the watchdog timer reboots the device.
If I add a small delay between MQTT messages (50ms), then the unit will no longer reboot. BUT, it seems to hang during the BLE scan.
#define TINY_GSM_MODEM_SIM7000
// 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[] = "iot.1nce.net";
const char gprsUser[] = "";
const char gprsPass[] = "";
// MQTT details
const char *broker = "mqtt.lstxsa.com";
const char *topicGps = "g1/869951035779390/gps";
const char *topicInit = "g1/869951035779390/init";
const char *topicBle = "g1/869951035779390/ble";
#include <TinyGsmClient.h>
#include <PubSubClient.h>
#include <Ticker.h>
#include <SPI.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
int scanTime = 5; //In seconds
BLEScan* pBLEScan;
#define BAT_ADC 35
#define SOLAR_ADC 36
#define uS_TO_S_FACTOR 1000000ULL // Conversion factor for micro seconds to seconds
#define TIME_TO_SLEEP 60 // Time ESP32 will go to sleep (in seconds)
#define UART_BAUD 115200
#define PIN_DTR 25
#define PIN_TX 27
#define PIN_RX 26
#define PWR_PIN 4
#define LED_PIN 12
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
TinyGsmClient client(modem);
PubSubClient mqtt(client);
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
String UUID = advertisedDevice.toString().c_str();
int RSSI = abs(advertisedDevice.getRSSI());
String beacon = String(UUID + " RSSI: " + RSSI);
Serial.println(beacon);
mqtt.publish(topicBle, beacon.c_str());
//delay(100);
}
};
void getBattery(){
int vref = 1100;
uint16_t volt = analogRead(35);
float battery_voltage = ((float)volt / 4095.0) * 2.0 * 3.3 * (vref);
Serial.printf("battery : %f\n", battery_voltage);
char tempString[10];
dtostrf(battery_voltage, 8, 2, tempString);
mqtt.publish(topicInit, tempString);
delay(100);
}
boolean mqttConnect()
{
SerialMon.print("Connecting to ");
SerialMon.print(broker);
boolean status = mqtt.connect("GsmClientName", "lst", "lst2021");
if (status == false) {
SerialMon.println(" failed to connect to MQTT broker");
return false;
}
SerialMon.println(" successfully connected to MQTT broker");
//mqtt.publish(topicInit, "GsmClientTest started");
return mqtt.connected();
}
void setup() {
Serial.begin(115200);
Serial.println("Scanning...");
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // less or equal setInterval value
pinMode(PWR_PIN, OUTPUT);
digitalWrite(PWR_PIN, HIGH);
delay(300);
digitalWrite(PWR_PIN, LOW);
SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX);
// Restart takes quite some time
// To skip it, call init() instead of restart()
Serial.println("Initializing modem...");
if (!modem.restart()) {
Serial.println("Failed to restart modem, attempting to continue without restarting");
}
String name = modem.getModemName();
DBG("Modem Name:", name);
String modemInfo = modem.getModemInfo();
DBG("Modem Info:", modemInfo);
// Unlock your SIM card with a PIN if needed
if (GSM_PIN && modem.getSimStatus() != 3) {
modem.simUnlock(GSM_PIN);
}
SerialMon.print(F("Connecting to "));
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println(" fail");
delay(10000);
return;
}
SerialMon.println(" success");
if (modem.isGprsConnected()) {
SerialMon.println("GPRS connected");
}
mqtt.setServer(broker, 1883);
mqttConnect();
}
void loop() {
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
Serial.print("Devices found: ");
Serial.println(foundDevices.getCount());
Serial.println("Scan done!");
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
getBattery();
mqtt.publish(topicInit, "Scan Complete, sleeping for 10 sec");
delay(10000);
}