I have a Hubitat C8 and three ESP32 Boards that I'd like to link together.
At the moment, the three boards talk to each other and I do see the ESP32 boards on my router.
The 3SP32 boards only talk to each other at the moment
One ESP32 device monitors the outside temperature
One ESP32 device monitors the temperature on an interior pipe.
The third ESP32 device askes the other two for temperatures and will close a contact when the pipe temperature gets too low, or periodically close the contact if the temperature is too low.
I'd like to monitor the temp from each device through hubitat and also log when the contact opens and closes so I can make sure they are all doing their jobs correctly. I do want the actual operation to stay inside the Arduinos for reliability.
Here's my code for the main unit
#include "arduino_secrets.h"
#include <esp_now.h>
#include <WiFi.h>
// Structure example to receive data
// Must match the sender structure
int startup;
int pipeon;
int timedelay_on;
int timer;
int timer_2;
int relay_time;
int Relaypin = 32; //can be modified.
int Relaypin2 = 33; //can be modified.
typedef struct struct_message {
int id;
float x;
float y;
float z;
} struct_message;
// Create a struct_message called myData
struct_message myData;
// Create a structure to hold the readings from each board
struct_message board1;
struct_message board2;
// Create an array with all the structures
struct_message boardsStruct[2] = {board1, board2};
// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac_addr, const uint8_t incomingData, int len) {
char macStr[18];
Serial.print("Packet received from: ");
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
Serial.println(macStr);
memcpy(&myData, incomingData, sizeof(myData));
Serial.printf("Board ID %u: %u bytes\n", myData.id, len);
// Update the structures with the new incoming data
boardsStruct[myData.id - 1].x = myData.x;
boardsStruct[myData.id - 1].y = myData.y;
boardsStruct[myData.id - 1].z = myData.z;
/
Serial.printf("x value: %d \n", boardsStruct[myData.id-1].x);
Serial.printf("y value: %d \n", boardsStruct[myData.id-1].y);
Serial.printf("z value: %d \n", boardsStruct[myData.id-1].z);
Serial.println();
*/
}
void setup() {
pinMode(Relaypin, OUTPUT);
pinMode(Relaypin2, OUTPUT);
//Initialize Serial Monitor
Serial.begin(115200);
//Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
//Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
float pipe_temp = boardsStruct[0].x;
float envir_temp = boardsStruct[1].x;
Serial.println(""); Serial.println(""); Serial.println(""); Serial.println("");
Serial.print("Lowest copper pipe temperature: "); Serial.println(pipe_temp);
Serial.println(""); Serial.println("");
Serial.print("Environmental Temperature: "); Serial.println(envir_temp);
Serial.println(""); Serial.println("");
Serial.print("Delay is On?: "); Serial.println(timedelay_on);
Serial.println(""); Serial.println("");
Serial.print("Pipe is On: "); Serial.println(pipeon);
Serial.println(""); Serial.println("");
Serial.print("Timer: "); Serial.println(timer_2);
Serial.println(""); Serial.println(""); Serial.println(""); Serial.println("");
if (pipe_temp < 2)
{
Serial.println(""); Serial.println("");
Serial.println("Pipe Temp <2");
Serial.println(""); Serial.println("");
digitalWrite(Relaypin2, HIGH);
digitalWrite(Relaypin, HIGH);
delay(300000);
timedelay_on = 1;
pipeon = 1;
timer_2 = 0;
}
if (pipeon == 1) {
if (pipe_temp > 5) {
Serial.println(""); Serial.println("");
Serial.println("Pipe Temp > 5");
Serial.println(""); Serial.println("");
digitalWrite(Relaypin2, LOW);
digitalWrite(Relaypin, LOW);
pipeon = 0;
}
}
if (envir_temp < -2.0)
{
Serial.println(""); Serial.println("");
Serial.println("Enviromment Temp < -2.0");
Serial.println(""); Serial.println("");
if (timedelay_on == 0)
{
Serial.println(""); Serial.println("");
Serial.println("Enviromment Temp < -2.0 & Time Delay = 0");
Serial.println(""); Serial.println("");
digitalWrite(Relaypin, HIGH);
digitalWrite(Relaypin2, HIGH);
delay(300000);
digitalWrite(Relaypin2, LOW);
digitalWrite(Relaypin, LOW);
timedelay_on = 1;
timer_2 = 0;
}
}
if (timer_2 > 300000)
{
/Serial.println(""); Serial.println(""); Serial.println("Timer >90"); Serial.println(""); Serial.println("");/
timedelay_on = 0;
/*
Serial.println(""); Serial.println("");
Serial.println(""); Serial.println(""); Serial.print("Time Delay On is supposed to be 0, it is: "); Serial.println(timedelay_on); Serial.println(""); Serial.println("");
*/
timer_2 = 0;
/Serial.println(""); Serial.println(""); Serial.print("Timer is supposed to be 0, it is: "); Serial.println(timer_2); Serial.println(""); Serial.println("");/
}
delay(10000);
if (timedelay_on == 1)
{
timer_2 = timer_2 + 10000;
}
}
Sender 1 code #include "arduino_secrets.h"
#include <esp_now.h>
#include <WiFi.h>
// REPLACE WITH THE RECEIVER'S MAC Address
uint8_t broadcastAddress = {0x30, 0xc6, 0xf7, 0x2f, 0x68, 0x3c};
// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
int id; // must be unique for each sender board
float x;
float y;
float z;
} struct_message;
// Create a struct_message called myData
struct_message myData;
// Create peer interface
esp_now_peer_info_t peerInfo;
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
#define RT_0 10000 // Ω
#define B 3950 // K
#define VCC 3.29 //Supply voltage
#define R 10000 //R=10KΩ
#define SCALE 0.2 //Scaling Factor for bad measurements
//Variables
float RT, VR, ln, TX1, T_0, VRT, VRTC, VRT_2, VRT_2C, RT_2, VR_2, ln_2, TX2, low_temp;
void setup() {
// Init Serial Monitor
Serial.begin(115200);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_register_send_cb(OnDataSent);
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("Failed to add peer");
return;
}
}
void loop() {
T_0 = 25 + 273.15; //Temperature T_0 from datasheet, conversion from Celsius to kelvin
VRT = analogRead(32); //Acquisition analog value of VRT
VRTC = SCALE + (((VRT / 4095)) * VCC); //Conversion to voltage
VR = VCC - VRTC;
RT = (VRTC * R / VCC) / (1 - (VRTC / VCC)); //Resistance of RT
ln = log(RT / RT_0);
TX1 = (1 / ((ln / B) + (1 / T_0))); //Temperature from thermistor
TX1 = TX1 - 273.15; //Conversion to Celsius
// sensor_2 of copper wire temperature.
VRT_2 = analogRead(34); //Acquisition analog value of VRT_2
VRT_2C = SCALE + (((VRT_2 / 4095)) * VCC); //Conversion to voltage
VR_2 = VCC - VRT_2C;
RT_2 = (VRT_2C * R / VCC) / (1 - (VRT_2C / VCC)); //Resistance of RT_2
ln_2 = log(RT_2 / RT_0);
TX2 = (1 / ((ln_2 / B) + (1 / T_0))); //Temperature from thermistor
TX2 = TX2 - 273.15; //Conversion to Celsius
Serial.println(""); Serial.println(""); Serial.println(""); Serial.println("");
Serial.print("Temperature of Sensor 1: "); Serial.print("\t"); Serial.print(TX1); Serial.println("C\t\t");
Serial.println(""); Serial.println("");
Serial.print("Raw Measurement: "); Serial.println(VRT);
Serial.println(""); Serial.println("");
Serial.print("Calculated Voltage: "); Serial.println(VRTC);
Serial.println(""); Serial.println("");
Serial.print("Calculated Resistance: "); Serial.println(RT);
Serial.println(""); Serial.println("");
Serial.println(""); Serial.println("");
Serial.print("Temperature of Sensor 2: "); Serial.print("\t"); Serial.print(TX2); Serial.println("C\t\t");
Serial.println(""); Serial.println("");
Serial.print("Raw Measurement: "); Serial.println(VRT_2);
Serial.println(""); Serial.println("");
Serial.println(""); Serial.println("");
Serial.print("Calculated Voltage: "); Serial.println(VRT_2C);
Serial.println(""); Serial.println("");
Serial.print("Calculated Resistance: "); Serial.println(RT_2);
Serial.println(""); Serial.println(""); Serial.println(""); Serial.println("");
if (TX1 < TX2) {
low_temp = TX1;
}
else {
low_temp = TX2;
}
// Set values to send
myData.id = 1;
myData.x = low_temp;
myData.y = TX1;
myData.z = TX2;
Serial.println(""); Serial.println(""); Serial.println(""); Serial.println("");
Serial.print("Lowest Temp: "); Serial.print("\t"); Serial.println(myData.x);
Serial.println(""); Serial.println("");
Serial.print("Pipe 1 Temp: "); Serial.print("\t"); Serial.println(myData.y);
Serial.println(""); Serial.println("");
Serial.print("Pipe 2 Temp: "); Serial.print("\t"); Serial.println(myData.z);
Serial.println(""); Serial.println(""); Serial.println(""); Serial.println("");
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
delay(10000);
}
Sender 3 code
#include "arduino_secrets.h"
#include <esp_now.h>
#include <WiFi.h>
#include <DHT.h>
// REPLACE WITH THE RECEIVER'S MAC Address( that you found form mac finder code only receiver is needed)
uint8_t broadcastAddress = {0x30, 0xc6, 0xf7, 0x2f, 0x68, 0x3c};
// Structure for sending temp to send data
// Must match the receiver structure
typedef struct struct_message {
int id; // must be unique for each sender board can be ignored this but good to have.
float env_temp;
} struct_message;
// Create a struct_message called myData_2
struct_message myData_2;
// Create peer interface
esp_now_peer_info_t peerInfo;
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
// temperature sensor variables and pin
#define DHTPIN 32 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for Arduino
int chk;
//float hum; //Stores humidity value
float temp; //Stores temperature value
void setup() {
// Init Serial Monitor
Serial.begin(115200);
dht.begin();
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_register_send_cb(OnDataSent);
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
}
void loop() {
//hum = dht.readHumidity();
temp= dht.readTemperature(); //read in celcius
// Set values to send
myData_2.id = 2;
myData_2.env_temp = temp;
Serial.print(temp);
Serial.println(" C");
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData_2, sizeof(myData_2));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
delay(5000);
}
What would be the best way to do this? I'm pretty familiar with Hubitat, but a complete beginner with arduino. I'm thinking of playing around with Home Automation, would that be a better solution?
Here's the Arduino code I'm currently using