I'm having an issue where the device (esp32) stops receiving a subscription after a few hours. It publishes from a lora node fine, but dows not respond to a message from the broker. Am I missing something? If I reset the board, the messages go to the node, but then quits some time later.
/**
This one is kinda working from Jan 26
**/
#include <WiFi.h>
#include <MQTT.h> // https://github.com/256dpi/arduino-mqtt
#include <SPI.h>
#include <LoRa.h> // https://github.com/sandeepmistry/arduino-LoRa
////
const char ssid[] = "MikesShop";
const char pass[] = "1qazxsw2";
//
#define BROKER_ADDRESS "10.10.7.4"
#define BROKER_PORT 1883
#define BROKER_USER ""
#define BROKER_PASSWORD ""
/////
#define ss 5
#define rst 14
#define dio0 2
#define MONITOR_LED 25
byte msgCount = 0; // count of outgoing messages
byte localAddress = 0xCC; // address of this device
//
WiFiClient net;
MQTTClient mqttClient;
//
bool routeIncomingMessage = false;
String sourceDeviceAddress;
String sourceDeviceProperty;
String sourceValue;
//
bool routeOutgoingMessage = false;
char destinationDeviceAddress[10];
char destinationDevicePropery[10];
char destinationValue[10];
void registerDevice(String address, String device_input_property) {
String topic = "TheShop/" + address + "/" + device_input_property;
mqttClient.subscribe(topic);
}
//############################
void connectToBroker() {
Serial.print("Connecting to MQTT Broker ...");
while (!mqttClient.connect("TheShop", BROKER_USER)) {
Serial.print("MQTT Client Disconnected! ");
Serial.print(mqttClient.lastError()); Serial.println(" Return Code");
Serial.println(mqttClient.returnCode());
delay(1000);
}
Serial.println(" connected!");
// Last Will initialization
mqttClient.publish("Shop", "Ready", true, LWMQTT_QOS1);
mqttClient.subscribe("TheShop/#");
}
void onLoraReceive(int packetSize) {
if (packetSize == 0) return; // if there's no packet, return
// read packet header bytes:
int recipient = LoRa.read(); // recipient address
byte sender = LoRa.read(); // sender address
byte incomingMsgId = LoRa.read(); // incoming msg ID
byte incomingLength = LoRa.read(); // incoming msg length
String incoming = ""; // payload of packet
while (LoRa.available()) {
incoming += (char)LoRa.read();
}
if (incomingLength != incoming.length()) { // check length for error
Serial.println("error: message length does not match length");
return;
}
// if the recipient isn't this gateway
if (recipient != localAddress) {
Serial.println("This message is not for me.");
return;
}
// if message is for this device, or broadcast, print details:
Serial.println("Received from: 0x" + String(sender, HEX));
//Serial.println("Sent to: 0x" + String(recipient, HEX));
//Serial.println("Message ID: " + String(incomingMsgId));
//Serial.println("Message length: " + String(incomingLength));
Serial.println("Message: " + incoming);
Serial.println("RSSI: " + String(LoRa.packetRssi()));
Serial.println();
while (routeIncomingMessage == true);
char buf[sizeof(incoming)];
incoming.toCharArray(buf, sizeof(buf));
sourceDeviceProperty = strtok(buf, "=");
sourceDeviceAddress = String(sender, HEX);
sourceValue = strtok(NULL, "=");
routeIncomingMessage = true;
}
void mqttMessageReceived(String &topic, String &payload) {
Serial.print("Received Topic: ["); Serial.print(topic); Serial.print("] Payload: "); Serial.println(payload);
char buf[topic.length() + 1];
topic.toCharArray(buf, sizeof(buf));
char *p = strtok(buf, "/");
p = strtok(0, "/");
if (p == NULL)
return;
strcpy(&destinationDeviceAddress[0], p);
p = strtok(0, "/");
if (p == NULL)
return;
strcpy(&destinationDevicePropery[0], p);
payload.toCharArray(destinationValue, sizeof(payload));
routeOutgoingMessage = true;
}
void sendLoraMessage(byte device, String outgoing) {
LoRa.beginPacket(); // start packet
LoRa.write(device); // add destination address
LoRa.write(localAddress); // add sender address
LoRa.write(msgCount); // add message ID
LoRa.write(outgoing.length()); // add payload length
LoRa.print(outgoing); // add payload
LoRa.endPacket(); // finish packet and send it
msgCount++; // increment message ID
}
//########################## SETUP #############
void setup() {
Serial.begin(115200);
Serial.println("Start LoRa Gateway");
//
pinMode(MONITOR_LED, OUTPUT);
digitalWrite(MONITOR_LED, HIGH);
// WiFi Initializations
WiFi.begin(ssid, pass);
Serial.print("Connecting to WiFi ...");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.println(" connected!");
// MQTT Initializations
mqttClient.begin(BROKER_ADDRESS, net);
mqttClient.setOptions(15, true, 1500);//keepalive, cleansessiom, timeout
//mqttClient.setWill("LoRa/gateway", "Disconnected", true, LWMQTT_QOS1);
mqttClient.onMessage(mqttMessageReceived);
connectToBroker();
// Lora Initialization
LoRa.setPins( ss, rst, dio0);
if (!LoRa.begin(915E6)) {
Serial.println("LoRa init failed. Check your connections.");
while (true);
}
Serial.println("LoRa init succeeded.");
LoRa.onReceive(onLoraReceive);
LoRa.receive();
}
//##################### LOOP ###############
void loop() {
mqttClient.loop();
delay(180);
if (routeOutgoingMessage) {
routeOutgoingMessage = false;
char buf[30];
strcpy(&buf[0], &destinationDevicePropery[0]);
strcat(&buf[0], "=");
strcat(&buf[0], &destinationValue[0]);
sendLoraMessage(strtol(destinationDeviceAddress, NULL, 16), buf);
LoRa.receive();
}
if (routeIncomingMessage) {
routeIncomingMessage = false;
String topic = "Shop/" + sourceDeviceAddress + "/" + sourceDeviceProperty;
Serial.print("Sending Topic: ["); Serial.print(topic); Serial.print("] Payload: "); Serial.println(sourceValue);
mqttClient.publish(topic, sourceValue, true, LWMQTT_QOS1);
}
delay(100);
digitalWrite(MONITOR_LED, HIGH);
delay(500);
digitalWrite(MONITOR_LED, LOW);
}