Master Code
`#include <TFT_eSPI.h>
#include <WiFi.h>
#include "thingProperties.h"
#include <esp_now.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "driver/rtc_io.h"
#include <NTPClient.h>
#include <WiFiUdp.h>
#include "time.h"
#include "SPI.h"
//#include <esp_wifi.h>
int Moisture11;
int Moisture12;
int Moisture13;
int Moisture14;
int Moisture15;
int Moisture16;
int Moisture17;
int Moisture18;
int Moisture19;
int Moisture20;
int Moisture21;
int Moisture22;
int Moisture23;
int Moisture24;
const char* ssid = SECRET_SSID;
const char* password = SECRET_OPTIONAL_PASS;
typedef struct struct_message {
int id;
int P1;
int P2;
int P3;
int P4;
int P5;
int P6;
int readingId;
} struct_message;
struct_message incomingReadings;
// Create a structure to hold the readings from each board
struct_message board1;
struct_message board2;
struct_message board3;
struct_message board4;
struct_message boardsStruct[4] = {board1, board2, board3, board4};
void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len) {
// Copies the sender mac address to a string
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(&incomingReadings, incomingData, sizeof(incomingReadings));
Serial.printf("Board ID %u: %u bytes\n", incomingReadings.id, len);
// Update the structures with the new incoming data
boardsStruct[incomingReadings.id-1].P1 = incomingReadings.P1;
boardsStruct[incomingReadings.id-1].P2 = incomingReadings.P2;
boardsStruct[incomingReadings.id-1].P3 = incomingReadings.P3;
boardsStruct[incomingReadings.id-1].P4 = incomingReadings.P4;
boardsStruct[incomingReadings.id-1].P5 = incomingReadings.P5;
boardsStruct[incomingReadings.id-1].P6 = incomingReadings.P6;
//Serial.printf("x value: %d \n", boardsStruct[myData.id-1].P1);
//Serial.printf("y value: %d \n", boardsStruct[myData.id-1].P2);
//Serial.printf("x value: %d \n", boardsStruct[myData.id-1].P3);
//Serial.printf("y value: %d \n", boardsStruct[myData.id-1].P4);
//Serial.printf("x value: %d \n", boardsStruct[myData.id-1].P5);
//Serial.printf("y value: %d \n", boardsStruct[myData.id-1].P6);
Serial.println();
}
uint8_t broadcastAddress4[] = {0x08, 0xA6, 0xF7, 0x24, 0xFD, 0xF0}; //s1 08:a6:f7:24:fd:f0
uint8_t broadcastAddress2[] = {0x08, 0xA6, 0xF7, 0x24, 0xF9, 0xF0}; //08:a6:f7:24:f9:f0
uint8_t broadcastAddress3[] = {0x08, 0xA6, 0xF7, 0x24, 0xC7, 0x24}; //08:a6:f7:24:c7:24
uint8_t broadcastAddress1[] = {0x08, 0xA6, 0xF7, 0xA8, 0x72, 0x10}; //08:a6:f7:a8:72:10
typedef struct test_struct {
int x;
} test_struct;
test_struct test;
esp_now_peer_info_t peerInfo;
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
char macStr[18];
Serial.print("Packet to: ");
// Copies the sender mac address to a string
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3]);
Serial.print(macStr);
Serial.print(" send status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
TFT_eSPI tft = TFT_eSPI();
#define TFTLEDPIN 32
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
// Variables to save date and time
String formattedDate;
String dayStamp;
String timeStamp;
const int buttonPin = 5;
byte oldButtonState = 0;
int screenNumber = 0;
byte buttonState = 0;
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 200;
void connect(){
WiFi.disconnect();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Setting as a Wi-Fi Station..");
tft.setCursor(5, 5);
tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.setTextSize(2);
tft.println("Wifi Off");
delay(500);
}
Serial.print("Station IP Address: ");
Serial.println(WiFi.localIP());
Serial.print("Wi-Fi Channel: ");
Serial.println(WiFi.channel());
ArduinoCloud.begin(ArduinoIoTPreferredConnection, false);
while (ArduinoCloud.connected() == 0)
{
ArduinoCloud.update();//required so things don't crash on us
Serial.println("Waiting for connection to Arduino IoT Cloud");
tft.setCursor(5, 5);
tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.setTextSize(2);
tft.println("Wifi Off");
delay(500);
}
Serial.println("Connected to cloud");
}
void setup() {
Serial.begin(115200);
delay(1500);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(TFTLEDPIN, OUTPUT);
tft.init();
tft.fillScreen(TFT_BLACK);
digitalWrite(TFTLEDPIN, HIGH);
tft.setRotation(1);
tft.setCursor(110, 20);
tft.setTextColor(TFT_GREEN); tft.setTextSize(3);
tft.println("Moisture Levels");
tft.setCursor(100, 160);
tft.setTextColor(TFT_BLUE); tft.setTextSize(3);
tft.println("Loading.........");
// Set the device as a Station and Soft Access Point simultaneously
WiFi.mode(WIFI_AP_STA);
initProperties();
connect();
delay(1000);
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
timeClient.begin();
timeClient.setTimeOffset(14400);
while(!timeClient.update()) {
timeClient.forceUpdate();
}
formattedDate = timeClient.getFormattedDate();
Serial.println(formattedDate);
tft.fillScreen(TFT_BLACK);
esp_now_register_send_cb(OnDataSent);
// register peer
peerInfo.channel = 0;
peerInfo.encrypt = false;
// register first peer
memcpy(peerInfo.peer_addr, broadcastAddress1, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
// register first peer
memcpy(peerInfo.peer_addr, broadcastAddress2, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
// register first peer
memcpy(peerInfo.peer_addr, broadcastAddress3, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
// register first peer
memcpy(peerInfo.peer_addr, broadcastAddress4, 6);
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
delay(3000);
}
void loop() {
test.x = timeClient.getHours();
Serial.println(timeClient.getHours());
//Serial.println(WiFi.status());
if (WiFi.status() != WL_CONNECTED) {
connect();
}
ArduinoCloud.update();
formattedDate = timeClient.getFormattedDate();
buttonState = digitalRead(buttonPin);
if ((millis() - lastDebounceTime) > debounceDelay){
if (buttonState != oldButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if (buttonState == LOW) {
if (buttonState == LOW && screenNumber != 3){
++screenNumber;}
else {
screenNumber = 0;
}
}
}
oldButtonState = buttonState;
if(buttonState == 0){
tft.fillScreen(TFT_BLACK);
}
// Acess the variables for each board
int board1P1 = boardsStruct[0].P1;
int board1P2 = boardsStruct[0].P2;
int board1P3 = boardsStruct[0].P3;
int board1P4 = boardsStruct[0].P4;
int board1P5 = boardsStruct[0].P5;
int board1P6 = boardsStruct[0].P6;
int board2P1 = boardsStruct[1].P1;
int board2P2 = boardsStruct[1].P2;
int board2P3 = boardsStruct[1].P3;
int board2P4 = boardsStruct[1].P4;
int board2P5 = boardsStruct[1].P5;
int board2P6 = boardsStruct[1].P6;
int board3P1 = boardsStruct[2].P1;
int board3P2 = boardsStruct[2].P2;
int board3P3 = boardsStruct[2].P3;
int board3P4 = boardsStruct[2].P4;
int board3P5 = boardsStruct[2].P5;
int board3P6 = boardsStruct[2].P6;
int board4P1 = boardsStruct[3].P1;
int board4P2 = boardsStruct[3].P2;
int board4P3 = boardsStruct[3].P3;
int board4P4 = boardsStruct[3].P4;
int board4P5 = boardsStruct[3].P5;
int board4P6 = boardsStruct[3].P6;
if (screenNumber == 0) {
tft.setRotation(1);
tft.setCursor(5, 5);
tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.setTextSize(2);
tft.print("Wifi Ok ");
tft.setCursor(110, 40);
tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.setTextSize(3);
tft.println("Moisture Levels");
tft.setCursor(200, 90);
tft.setTextColor(TFT_GREEN); tft.setTextSize(2);
tft.println("STATION 1");
tft.setCursor(60, 130);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Flowers: ");
tft.setCursor(190, 130);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board1P1);tft.println(" ");
tft.setCursor(281, 130);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Rosemary: ");
tft.setCursor(415, 130);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board1P2);tft.println(" ");
tft.setCursor(60, 180);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Lavender: ");
tft.setCursor(190, 180);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board1P3);tft.println(" ");
tft.setCursor(281, 180);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Mint: ");
tft.setCursor(415, 180);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board1P4);tft.println(" ");
tft.setCursor(60, 230);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.print("Strawberry: ");tft.println(" ");
tft.setCursor(190, 230);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board1P5);tft.println(" ");
tft.setCursor(281, 230);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Mint: ");
tft.setCursor(415, 230);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board1P6);tft.println(" ");
}
else if (screenNumber == 1) {
tft.setRotation(1);
tft.setCursor(5, 5);
tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.setTextSize(2);
tft.println("Wifi Ok ");
tft.setCursor(110, 40);
tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.setTextSize(3);
tft.println("Moisture Levels");
tft.setCursor(200, 90);
tft.setTextColor(TFT_GREEN); tft.setTextSize(2);
tft.println("STATION 2");
tft.setCursor(60, 130);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Flowers: ");
tft.setCursor(190, 130);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board2P1);tft.println(" ");
tft.setCursor(281, 130);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Rosemary: ");
tft.setCursor(415, 130);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board2P2);tft.println(" ");
tft.setCursor(60, 180);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Lavender: ");
tft.setCursor(190, 180);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board2P3);tft.println(" ");
tft.setCursor(281, 180);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Mint: ");
tft.setCursor(415, 180);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board2P4);tft.println(" ");
tft.setCursor(60, 230);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Strawberry: ");
tft.setCursor(190, 230);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board2P5);tft.println(" ");
tft.setCursor(281, 230);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Mint: ");
tft.setCursor(415, 230);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board2P6);tft.println(" ");
}
else if (screenNumber == 2) {
tft.setRotation(1);
tft.setCursor(5, 5);
tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.setTextSize(2);
tft.println("Wifi Ok ");
tft.setCursor(110, 40);
tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.setTextSize(3);
tft.println("Moisture Levels");
tft.setCursor(200, 90);
tft.setTextColor(TFT_GREEN); tft.setTextSize(2);
tft.println("STATION 3");
tft.setCursor(60, 130);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Flowers: ");
tft.setCursor(190, 130);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board3P1);tft.println(" ");
tft.setCursor(281, 130);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Rosemary: ");
tft.setCursor(415, 130);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board3P2);tft.println(" ");
tft.setCursor(60, 180);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Lavender: ");
tft.setCursor(190, 180);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board3P3);tft.println(" ");
tft.setCursor(281, 180);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Mint: ");
tft.setCursor(415, 180);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board3P4);tft.println(" ");
tft.setCursor(60, 230);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Strawberry: ");
tft.setCursor(190, 230);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board3P5);tft.println(" ");
tft.setCursor(281, 230);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Mint: ");
tft.setCursor(415, 230);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board3P6);tft.println(" ");
}
else if (screenNumber == 3) {
tft.setRotation(1);
tft.setCursor(5, 5);
tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.setTextSize(2);
tft.println("Wifi Ok ");
tft.setCursor(110, 40);
tft.setTextColor(TFT_WHITE, TFT_BLACK); tft.setTextSize(3);
tft.println("Moisture Levels");
tft.setCursor(200, 90);
tft.setTextColor(TFT_GREEN); tft.setTextSize(2);
tft.println("STATION 4");
tft.setCursor(50, 130);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Bell Pepper: ");
tft.setCursor(190, 130);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board4P1);tft.println(" ");
tft.setCursor(281, 130);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Bell Pepper: ");
tft.setCursor(420, 130);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board4P2);tft.println(" ");
tft.setCursor(50, 180);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Lemon Grass: ");
tft.setCursor(190, 180);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board4P3);tft.println(" ");
tft.setCursor(281, 180);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Tomato: ");
tft.setCursor(420, 180);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board4P4);tft.println(" ");
tft.setCursor(50, 230);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Mangrove: ");
tft.setCursor(190, 230);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board4P5);tft.println(" ");
tft.setCursor(281, 230);
tft.setTextColor(TFT_BLUE); tft.setTextSize(2);
tft.println("Tomato: ");
tft.setCursor(420, 230);
tft.setTextColor(TFT_BLUE, TFT_BLACK);
tft.print(board4P6);tft.println(" ");
}
esp_err_t result = esp_now_send(0, (uint8_t *) &test, sizeof(test_struct));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
}
`