Morning Guys,
I have an ESP32 Wroom 32 with 2 x Dallas Temp sensors and a JemRF radio module connected.
Data is sent via MQTT to HA.
It took me a while and a lot of searching to get where I am now. No experience in coding!
The script runs for a few days then crashes and I have to power cycle the ESP32 to get it going again!
Any pointers in what's wrong in my code?
/************ External Libraries*****************************/
#include <stdlib.h>
#include <WiFi.h>
#include <ArduinoMqttClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is connected to GPIO15
#define ONE_WIRE_BUS 23
// Setup a oneWire instance to communicate with a OneWire device
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
DeviceAddress hot_water_out = { 0x28, 0xAA, 0xDC, 0x76, 0xE0, 0x1, 0x3C, 0x4D };
DeviceAddress hot_water_in = { 0x28, 0xF5, 0xBA, 0x76, 0xE0, 0x1, 0x3C, 0xCA };
// ****** Serial Data Read***********
// Variables for the serial data read
char inByte; // incoming serial char
String str_buffer = ""; // This is the holder for the string which we will display
//**********STRINGS TO USE****************************
String dataID; // This holds the actual data
String dataTEMP; // This holds the actual data
//****************WiFi*******************************
const char* ssid = "*****";
const char* password = "******";
//****************MQTT*******************************
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const char broker[] = "192.168.0.201";
int port = 1883;
const char topic[] = "myhome/RF_Device";
const char topic2[] = "myhome/Hot_In";
const char topic3[] = "myhome/Hot_Out";
//set interval for sending messages (milliseconds)
const long interval = 8000;
unsigned long previousMillis = 0;
int count = 0;
#define MAX_STRING 80 // Sets the maximum length of string probably could be lower
char stringBuffer[MAX_STRING]; // A buffer to hold the string when pulled from program memory
//****************INITIALISE ROUTINE******************************
void setup()
{
Serial.begin(9600); // Set up a serial output for data display
Serial2.begin(9600, SERIAL_8N1, 16, 17); // Set up a hardwareserial input for Gateway
sensors.begin();
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
// failed, retry
Serial.print(".");
delay(1000);
}
Serial.println();
Serial.print("You're connected to the network");
Serial.println();
Serial.println(WiFi.localIP());
Serial.println();
mqttClient.setUsernamePassword("homeassistant", "oph3doo9Iej7eh2iev7okee0Eiwu6feequoo3einaex2quoo4eeyuwoo9oogeiph");
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(broker);
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
while (1);
}
Serial.println("You're connected to the MQTT broker!");
Serial.println();
String discoveryTopic = "homeassistant/myhome/RFDevices";
}
void loop()
{
//*********Here we check to see if any serial data has been seen***********
getData(); // Check the serial port for data
sortData(); // Sort the data for useful information
getDallas();
mqttClient.poll();
delay(50);
}
void getDallas()
{
Serial.print("Requesting temperatures...");
sensors.requestTemperatures(); // Send the command to get temperatures
Serial.println("DONE");
Serial.print("Hot Water In Temp(*C): ");
Serial.println(sensors.getTempC(hot_water_in));
Serial.print("Hot Water Out(*C): ");
Serial.println(sensors.getTempC(hot_water_out));
MQTTPublishTank();
delay(60000);
}
// **********************GET DATA SUBROUTINE*****************************************
// This sub-routine picks up and serial string sent to the device and sorts out a power string if there is one
// All values are global, hence nothing is sent/returned
void getData()
{
// **********GET DATA*******************************************
// We want to find the bit of interesting data in the serial data stream
// As mentioned above, we are using LLAP for the data.
// All the data arrives as serial commands via the serial interface.
// All data is in format aXXDDDDDDDDD where XX is the device ID
if (Serial2.available() > 0)
{
inByte = Serial2.read(); // Read whatever is happening on the serial port
if(inByte=='a') // If we see an 'a' then read in the next 11 chars into a buffer.
{
str_buffer+=inByte;
for(int i = 0; i<11;i++) // Read in the next 11 chars - this is the data
{
inByte = Serial2.read();
str_buffer+=inByte;
}
Serial.println(str_buffer); // TEST - print the str_buffer data (if it has arrived)
sortData();
str_buffer=""; // Reset the buffer to be filled again
Serial.flush();
}
}
}
// **********************SORT DATA SUBROUTINE*****************************************
// This sub-routine takes the read-in data string (12 char, starting with a) and does what is required with it
// The str-buffer is global so we do not need to send it to the routine
void sortData()
{
// Receive Data in format “aXXTMPA??.??“
// Where XX is the Device ID and ??.?? is the temperature data
//Check String has temperature data
if(str_buffer.substring(3,7) == "TMPA")
{
//Print Device ID
Serial.print("ID:");
Serial.println(str_buffer.substring(1,3));
//Store Device ID
dataID = str_buffer.substring(1,3);
//Print Device Temerature
Serial.print("TEMP:");
Serial.println(str_buffer.substring(7,12));
//Store Device Temperature
dataTEMP = str_buffer.substring(7,9);
dataTEMP += str_buffer.substring(9,12);
MQTTPublishJemRF();
}
}
void MQTTPublishJemRF()
{
Serial.print("Sending message to topic: ");
Serial.println(topic + dataID);
Serial.print(dataTEMP);
// send message, the Print interface can be used to set the message contents
mqttClient.beginMessage(topic + dataID);
mqttClient.println(dataTEMP);
mqttClient.endMessage();
Serial.println();
}
void MQTTPublishTank()
{
Serial.print("Sending message to topic: ");
Serial.println(topic2);
Serial.println(sensors.getTempC(hot_water_in));
// send message, the Print interface can be used to set the message contents
mqttClient.beginMessage(topic2);
mqttClient.println(sensors.getTempC(hot_water_in));
mqttClient.endMessage();
Serial.print("Sending message to topic: ");
Serial.println(topic3);
Serial.println(sensors.getTempC(hot_water_out));
// send message, the Print interface can be used to set the message contents
mqttClient.beginMessage(topic3);
mqttClient.println(sensors.getTempC(hot_water_out));
mqttClient.endMessage();
Serial.println();
}