Tank level sensor using esp32 Arduino framework using capacitive sensor

Update using a single esp32 capacitive sensor io pin instead of 5

The original design used 5 aluminum tape strips, very complicated to install and also not as reliable as expected. AND this requires the soldering of 4 additional wires on each sensor module. so here is what is happening so far, all current WORKING CODE is included. Now we are just using one esp32 Capacitive sensor io pin

  • Design specs (current)
    • sense liquid from non – metal tank
    • uses esp-now protocol, wifi without the need for a router,
    • up to 3 tanks (more are possible but, just three for now).
    • Esp-now connection between sensor modules and control / display module
    • only needs 12 volts nominal (from about 9 to 16 is okay) reverse polarity protected to each module.
    • Empty, 1/4, 1/2 3/4 and full display by colored LED lights on the master/display module,
    • only one tank level is displayed at a time. 1, 2 or 3 LED indicators indicate which tank is being displayed,
    • selecting tank by pushbutton switch. open open = tank one, open closed, or closed open = tank 2, closed closed = tank 3
    • must be calibrated. Can calibrate just at “empty” but it is best to calibrate at both empty and full. This is done with a push button and a empty-or-full selector switch.
    • All Wi-Fi MAC address discovery is done automatically. If a second or third tank is installed later, the system will find the new sensor module automatically.
    • Sensor units can run off of a separate battery if getting a house battery 12volts to a tank is difficult. It should last a season (still in the research phase)
    • esp-now allows for software update over Wi-Fi, future wishlist, currently needs a USB connection to update code.

Current WORKING CODE below. Not yet totally ready for production. MAC address of only the master has to still be hard-coded, But the master will find the slaves itself.

// Slave / sender / sensor module (many unused obsolete variables exist)
#include <esp_now.h>
#include <WiFi.h>
#include <Preferences.h>  // library to set up write-to-flash function 
#define CHANNEL 1
#define PRINTSCANRESULTS 0
#define DELETEBEFOREPAIR 0
//int slaveNumber = 787878;
int slaveNumber = 949494;
//String slaveNumber = WiFi.macAddress();
byte lockCalibrate;
// *****  INSERT THE MAC ADDRESS OF THE MASTER-DISPLAY UNIT BELOW  use the exact format including curly braces and commas ********
uint8_t broadcastAddress[] = { 0x30, 0xc6, 0xf7, 0x05, 0x9b, 0xb8 }; // mac of master display to send to
// *******************  insert the address of the master card above   ************************************

Preferences preferences;  // Assignment to set up write-to-flash function

/*
  pins used : 04,15, 14, 25,26,32,33:: s1= 04, s5=15, s4=14,, s2=33,  s3=32 switch is on pin 26
  // using touchpins: 0, 3, 6, 7, 8, 9  which are physical pins s1= 04, s5=15, s4=14,, s2=33,  s3=32
  //  MAJOR MILESTONE FOR SLAVE.   UP TO THREE SLAVES WILL SEND AND RECIVE DATA BROADCAST ADDRESS HAS TO BE MANUALLY CHANGED TO THAT OF THE MASTER SO THAT THE SLAVES ARE NOT SENDING TO EACHOTHER. setting the address should BE AUTOMATED AT SOME POINT.
  done
  - wifi / espnow fuctions work
  - the inputs from the slaves is seperated, currently by hard coded values,  NOW DOEN WITH AUTOMATED MAC COLLECTION
  -reestablish good data transfer from slave to master
  - read values from sensor, store reference values (calibration), send to master/display unit
  -reestablish good data transfer from master to slave
   - change hard coded values to automatic mac addresses  THIS IS DONE FOR MASTER.  THE SLAVE CODE STILL NEEDS A MASTER MAC ADDRESS INSERTED.
  - get mac addresses automatically
  - move the calibration button from the slave to the master to reduce component and assembly time and costs
  - clean up code. make vars unique and make as much code into functions as practical
  - suspend wirit functions while setting configuration
  - MAKE IT ALL WORK WITH MORE THAN ONE SENSOR MODULE
  todo
  get slaves to collect the master mac automatically.   this may not be worth the effort. 
 


*/

int numberOfSamples = 1000;     // the number of samples to take for averaging sensor readings
int delayTimeForAverage = 50;  // gap between printout, for troupble shooting

// REPLACE WITH THE MAC Address in slave to the single master board (the master uses 0xFF broadcast address)
//uint8_t broadcastAddress[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
//uint8_t broadcastAddress[] = { 0x30,0xC6,0xF7,0x05,0x9B,0x94 };
//uint8_t broadcastAddress[] = { 0x30, 0xc6, 0xf7, 0x05, 0x9b, 0xb8 }; // mac of master display to send to
//uint8_t broadcastAddress[] = INSERT_MASTER_MAC_HERE; //{ 0x30, 0xc6, 0xf7, 0x05, 0x9b, 0xb8 }; // mac of master //display to send to

// set the capacitive read pin numbers that are used
byte sensorPin1 = 4;
byte sensorPin2 = 14;
byte sensorPin3 = 15;
byte sensorPin4 = 32;
byte sensorPin5 = 33;

int LEDvar1 = 0;  //define varibles to hold sensor status to be sent to master/display
int LEDvar2 = 0;
int LEDvar3 = 0;
int LEDvar4 = 0;
int LEDvar5 = 0;

int  buttonStatus = 1; // initialize button pins and vars
int  pinValue = 1; //  digitalRead(26);

int  currentSensorVal1;  // initialize variables for the latest/current reading of the sensors
int  currentSensorVal2;
int  currentSensorVal3;
int  currentSensorVal4;
int  currentSensorVal5;
int	sendBackToMaster;   // this is to reset the request for calibration flag from the master

int  threshHoldValue1;  // INITIALIZE VARIABLEs TO STORE  drySensorValue used for calibrationr
int  threshHoldValue2;
int  threshHoldValue3;
int  threshHoldValue4;
int  threshHoldValue5;
String MAC1 = "232323";

// Init ESP Now with fallback - by esp no changes by Don
void InitESPNow() {
  WiFi.disconnect();
  if (esp_now_init() == ESP_OK) {
    Serial.println("ESPNow Init Success");
  } else {
    Serial.println("ESPNow Init Failed");
    // Retry InitESPNow, add a counte and then restart?
    // InitESPNow();
    // or Simply Restart
    ESP.restart();
  }
}
String slaveMac ;
String SSID = "not set yet";
// config AP SSID  with indetifying mac -- by esp no changes by don
void configDeviceAP() {
  String Prefix = "Slave_dw:";
  slaveMac = WiFi.macAddress();
  String Mac = WiFi.macAddress();
  String SSID = Prefix + Mac;
  String Password = "123456789";
  bool result = WiFi.softAP(SSID.c_str(), Password.c_str(), CHANNEL, 0);
  if (!result) {
    Serial.println("AP Config failed.");
  } else {
    Serial.println("AP Config Success. Broadcasting with AP: " + String(SSID));
  }
}

// variables used to store level sensor readings and other vars to be sent
int levelSense1;

int levelSense2;
int levelSense3;
int levelSense4;
int levelSense5;
int slaveIdenitier;
char optionalCharVar[32];
//int REsetFlgToOne;

// variables to store incoming values for: padding, button-pushed flag for calibration and master mac value
int incomingDoCalibrate1 = 5;  //1111;
byte incomingPadding;
String incomingDw_s;

String success;  // Variable to store if sending data was successful

//Structure of data that is sent and recived. It must match the structure of paired board
typedef struct struct_message {
  int slaveNumber;
  int sensor1;
  int sensor2;
  int sensor3;
  int sensor4;
  int sensor5;
  char CharFromMstr[32];
  char CharFromSlave1[32];
  char CharFromSlave2[32];
  char CharFromSlave3[32] ;
  byte dw_pad;
  int doCalibrate1;
  int doCalibrate2;
  int doCalibrate3;
} struct_message;

// Create a struct_message called levelSensorReadings to hold sensor readings
struct_message outgoingValues;

// Create a struct_message to hold incoming sensor readings
struct_message incomingValues;

// Callback when data is sent - ALL BY ESP EXCEPT SOME TEXT MESSAGE CHANGES BY
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");
  if (status == 0) {
    success = "Delivery Success :)";
    String Mac = WiFi.macAddress();
    Serial.println("AP Config Success. Broadcasting from SLAVE with AP: " + String(Mac));
  } else {
    success = " OUTGOING DELIVER FAIL FAIL FAIL FAIL FAIL Delivery Fail :(";
  }
} // end of data sent call back
// END Callback when data is SENT

// on data RECEIVE callback function  --- THIS IS WHERE THE DATA IS RECEIVED
void OnDataRecv(const uint8_t* mac, const uint8_t* incomingData, int len) {
  memcpy(&incomingValues, incomingData, sizeof(incomingValues));
  char macStr[18];
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  Serial.print("////////////// Last Packet Recv FROM  >>>>>>>>>: "); Serial.println(macStr);
  Serial.print("Bytes received: ");
  Serial.println(len);
  Serial.print("Last Packet Recv Data: "); Serial.println(*incomingData);
  // Data being captured and stored to local variables
  incomingPadding = incomingValues.dw_pad;
  incomingDoCalibrate1 = incomingValues.doCalibrate1;
  lockCalibrate = incomingDoCalibrate1;
  Serial.println(" JUST RECEIVED  incomingDoCalibrate1 from incomingValues.doCalibrate1 value is >>> : ");
  Serial.println(incomingDoCalibrate1);
} // end of RECEIVE call back function

void setup() {
  // Init Serial Monitor
  Serial.begin(115200);
  preferences.begin("calibration", false);//for nonvolitile memory process  NO ERROR REPORTED IF MISSING!

  pinMode(25, OUTPUT); // this is for LED that indicates button has been pressed long enough
  pinMode(26, INPUT_PULLUP);  // enable internal pull-up	for calibration pushbutton
  int pinValue = 1;

  WiFi.mode(WIFI_AP_STA); 	// configure device AP mode
  configDeviceAP();

  // Init ESP-NOW
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  //  register for Send CB to get the status of Trasnmitted packet
  esp_now_register_send_cb(OnDataSent);
  esp_now_peer_info_t peerInfo; // Register peer
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;
  peerInfo.encrypt = false;
  if (esp_now_add_peer(&peerInfo) != ESP_OK) {  // Add peer
    Serial.println("Failed to add peer");
    return;
  }
  // Register for a callback function that will be called when data is received
  esp_now_register_recv_cb(OnDataRecv);
} //  END OF SETUP()

unsigned long startMillis = 0;
void loop() { // *********  *    this is the start of looop ****************

  Serial.print("a Mac address from master  CHAR CHAR CHAR 32 >>>>>>>>>>>>>>>: ");
  Serial.println(incomingValues.CharFromMstr);

 // delay(7000);
  Serial.println(" end of incomingValues.dw_char" );
  displayStatusOfSlave(); // various troubleshooting information to display no variables set, can be removed.

  checkCalibrationRequestSW(); // looks for calibration request from switch on the module
  checkCalibrationRequestWIFI(); // looks for calibration request from switch on the module


  readAndReport();  // get the sensor readings, store the values and display them

  valuesToSend();  // collect the sensor values and any other values to send
  sendSensorValues(); // send the sensor values from this slave to the master using it's MAC address

}  //   *********************************** end of loop() *********************************

void displayStatusOfSlave() {// various informatina about slave to display for troublshooting.
  Serial.println("// *******  *    this is the start of looop ***********");
  Serial.print("This is second  count  millis() / 1000               >>> "); Serial.println(millis() / 1000);
  Serial.println(" incomingDoCalibrate1   var to request calibration >>>>>>> : ");
  Serial.println(incomingDoCalibrate1);
  Serial.print(" incomingPad  var to set padding              >>>>>>>>>>>>>>> : ");
  Serial.println(incomingPadding);
 // delay(2000);
  Serial.println("  CHECK FOR CALIBRATION FUNCTION IS NEXT - CHECKS FOR BUTTON PRESS OR nine nine nine nine");
//  delay(2000);
}

void sendSensorValues() {// Send the data over esp-now
  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t*)&outgoingValues, sizeof(outgoingValues));
  if (result == ESP_OK) {
    Serial.println("FEB 11TH Sent with success");
  } else {
    Serial.println("FEB 11TH Error sending the data");
  }
  delay(500);
}

void checkCalibrationRequestSW() {
  //  ************************************ GET BUTTON VALUE  ****************************************
  pinValue = digitalRead(26); // this works from the pushbutton on the slave board.
  delay(10); // quick and dirty debounce filter
  if (pinValue == 0) {
    // END OF SECTION THAT GETS INPUT FROM THE BUTTON ON THE SLAVE BOARD.
    Serial.println("***INSIDE button FUCTION JUST BEFORE CALIBRATE FUNCTION >>>incomingDoCalibrate = :  ");
    Serial.println(incomingDoCalibrate1);
   // delay(2000);
    Serial.println("*********************************GOING TO RUN THE CALIBRATE FUNCTION **************************");
    Serial.println("*********************************GOING TO RUN THE CALIBRATE FUNCTION **************************");
    Serial.println("*********************************GOING TO RUN THE CALIBRATE FUNCTION **************************");
    digitalWrite(4, HIGH); // blink an LED to show request has be registered
    digitalWrite(4, HIGH);  delay(500); digitalWrite(4, LOW);   delay(300); digitalWrite(4, HIGH);  delay(300);
    digitalWrite(4, LOW); delay(300); digitalWrite(4, HIGH); delay(300); digitalWrite(4, LOW);  delay(300);
    digitalWrite(4, HIGH);  delay(300); digitalWrite(4, LOW);
    threshHoldValue1 = runCalibrationFunction(); // RUN FUNCTION // fuction to Capture and store 'dry' value
  }
}

void checkCalibrationRequestWIFI() {
  //	WiFi.disconnect(true);
  delay(100);
  //  ************************************ Get Calibration trigger from master ***************************

  Serial.println("CHECKING FOR calibration request from master.  Value of doCalibrate is >>> :  ");
  Serial.println(incomingDoCalibrate1);
 // delay(2000);
  if (incomingDoCalibrate1 == 9999) {
    //	if (lockCalibrate == 9999) {
    Serial.print("EXICUTING  CALIBRATE FUNCTION >>>incomingDoCalibrate = :  ");
    Serial.println("*********************************GOING TO RUN THE CALIBRATE FUNCTION **************************");
    Serial.println("*********************************GOING TO RUN THE CALIBRATE FUNCTION **************************");
    digitalWrite(4, HIGH); // blink an LED to show request has be registered
    digitalWrite(4, HIGH);  delay(500); digitalWrite(4, LOW);   delay(300); digitalWrite(4, HIGH);  delay(300);
    digitalWrite(4, LOW); delay(300); digitalWrite(4, HIGH); delay(300); digitalWrite(4, LOW);  delay(300);
    digitalWrite(4, HIGH);  delay(300); digitalWrite(4, LOW);

    threshHoldValue1 = runCalibrationFunction(); // RUN FUNCTION // fuction to Capture and store 'dry' value

    lockCalibrate = 1111; //   incomingDoCalibrate1 = 1111;
    Serial.println("***JUST  >>> AFTER <<< CALIBRATE FUNCTION ********incomingDoCalibrate = :  ");
    Serial.println(incomingDoCalibrate1);
  }
}


void readAndReport() {   // code by dw to get values, compare them and turn on LEDs as needed.
    WiFi.disconnect();
    delay(1000);

  Serial.println("------------------- IN LOOP ");
  int  savedThreshHoldValue1;  // intialize the variables used for calibration *************
  int  savedThreshHoldValue2;
  int  savedThreshHoldValue3;
  int  savedThreshHoldValue4;
  int  savedThreshHoldValue5;

  // READ SENSOR THREASHOLD VALUES STORED AT LAST CALIBRATION. USED TO COMPARE TO CURRENT SENSOR READINGS
  savedThreshHoldValue1 = preferences.getInt("sensor1", savedThreshHoldValue1);
  savedThreshHoldValue2 = preferences.getInt("sensor2", savedThreshHoldValue2);
  savedThreshHoldValue3 = preferences.getInt("sensor3", savedThreshHoldValue3);
  savedThreshHoldValue4 = preferences.getInt("sensor4", savedThreshHoldValue4);
  savedThreshHoldValue5 = preferences.getInt("sensor5", savedThreshHoldValue5);
  Serial.print("====================saved value one   ");
  Serial.println(savedThreshHoldValue1);
  delay(100);

  // get the AVERAGE value of sensor at the current time and store it to currentSensor Val watch for them to go below the stored threashold value
  currentSensorVal1 = touchread1();  delay(5000);
  currentSensorVal2 = touchread2();   delay(50);  // 32
  currentSensorVal3 = touchread3();  delay(50); //15
  currentSensorVal4 = touchread4(); delay(50); //12
  currentSensorVal5 = touchread5(); delay(50); //33

  Serial.println("||||||||||||||||||||||||||||||||||||||||||||||||||||");
  Serial.println("       SAVED	 CURRENT	    DIFFERENCE =================");
  Serial.print(" value of padding : ");
  Serial.print(incomingValues.dw_pad);
  Serial.print("     value of pinvalue         >>>>> : "); Serial.println(pinValue);
  Serial.println("THIS IS THE CURRENT VALUE OF incomingDoCalibrate1  >>>>>>>>>>>>>>>>> : ");
  Serial.println(incomingDoCalibrate1);
  Serial.print("Value 1 > ");
  Serial.print(savedThreshHoldValue1);
  Serial.print("\t");
  Serial.print(currentSensorVal1);
  Serial.print("\t"); Serial.print("\t");
  Serial.println(savedThreshHoldValue1 - currentSensorVal1);
  Serial.print("Value 2 > ");
  Serial.print(savedThreshHoldValue2);
  Serial.print("\t");
  Serial.print(currentSensorVal2);
  Serial.print("\t"); Serial.print("\t");
  Serial.println(savedThreshHoldValue2 - currentSensorVal2);
  Serial.print("Value 3 > ");
  Serial.print(savedThreshHoldValue3);
  Serial.print("\t");
  Serial.print(currentSensorVal3);
  Serial.print("\t"); Serial.print("\t");
  Serial.println(savedThreshHoldValue3 - currentSensorVal3);
  Serial.print("Value 4 > ");
  Serial.print(savedThreshHoldValue4);
  Serial.print("\t");
  Serial.print(currentSensorVal4);
  Serial.print("\t"); Serial.print("\t");
  Serial.println(savedThreshHoldValue4 - currentSensorVal4);
  Serial.print("Value 5 > ");
  Serial.print(savedThreshHoldValue5);
  Serial.print("\t");
  Serial.print(currentSensorVal5);
  Serial.print("\t"); Serial.print("\t");
  Serial.println(savedThreshHoldValue5 - currentSensorVal5);
  delay(2000);

  if (currentSensorVal1 <= savedThreshHoldValue1) {
    Serial.println("HIGH  HIGH                     HIGH   HIGH");
    LEDvar1 = 1;
  } else {
    Serial.println("LOW   LOW LOW                   LOW    LOW");
    LEDvar1 = 0;
  }
  if (currentSensorVal2 <= savedThreshHoldValue2) {
    Serial.println("HIGH  HIGH                     HIGH   HIGH");
    LEDvar2 = 1;
  } else {
    Serial.println("LOW   LOW LOW                   LOW    LOW");
    LEDvar2 = 0;
  }
  if (currentSensorVal3 <= savedThreshHoldValue3) {
    Serial.println("HIGH  HIGH                     HIGH   HIGH");
    LEDvar3 = 1;
  } else {
    Serial.println("LOW   LOW LOW                   LOW    LOW");
    LEDvar3 = 0;
  }
  if (currentSensorVal4 <= savedThreshHoldValue4) {
    Serial.println("HIGH   HIGH                    HIGH   HIGH");
    LEDvar4 = 1;
  } else {
    Serial.println("LOW   LOW LOW                   LOW    LOW");
    LEDvar4 = 0;
  }
  if (currentSensorVal5 <= savedThreshHoldValue5) {
    Serial.println("HIGH  HIGH                     HIGH   HIGH");
    LEDvar5 = 1;
  } else {
    Serial.println("LOW   LOW LOW                   LOW    LOW");
    LEDvar5 = 0;
  }
  //	delay(100);

  WiFi.reconnect();
  delay(1000);
}  // end of readAndReport()
// end of readAndReport()

int  runCalibrationFunction() { // PUSH BUTTON TO COLLECT CURRENT SENSOR VALUES AND SAVE
  Serial.println("NOW INSIDE   PushButtonToSetDrySensor1()");

  threshHoldValue1 = currentSensorVal1 - incomingPadding; //sensor on analog in 0
  threshHoldValue2 = currentSensorVal2 - incomingPadding;
  threshHoldValue3 = currentSensorVal3 - incomingPadding;
  threshHoldValue4 = currentSensorVal4 - incomingPadding;
  threshHoldValue5 = currentSensorVal5 - incomingPadding;

  Serial.println(" BUTTON IS PUSHED ================     ");
  Serial.print("    VALUE OF   threshHoldValue1 ======   ");
  Serial.println(threshHoldValue1);
  Serial.print("    VALUE OF   threshHoldValueTWO == ===  ");
  Serial.println(threshHoldValue2);
  delay(1500); // this is just here to give time to read value
  // save the threshHoldvalue in eeprom
  dwEeprommRoutine(threshHoldValue1, threshHoldValue2, threshHoldValue3, threshHoldValue4, threshHoldValue5);
} //  end of this function  PushButtonToSetDrySensor1()
// end of PushButtonToSetDrySensor1()

//  DEFINE FUNCTION  *************** READ WRITE TO EEPROM  FUCTION **************************
void dwEeprommRoutine(int  threshHoldValue1, int  threshHoldValue2, int savedThreshHoldValue3, int  savedThreshHoldValue4, int  savedThreshHoldValue5) {
  digitalWrite(25, HIGH); // this section just blinks the LED to know it is in calibrate mode
  delay(700); digitalWrite(25, LOW); delay(500);
  digitalWrite(25, HIGH); delay(800); digitalWrite(25, LOW); 	delay(500);
  digitalWrite(25, HIGH); // end blink mode ,  now show the stored data

  Serial.println("**************IN EEPROM FUNCTION === IN EEPROM FUNCTION **********************=== -");
  Serial.println("************IN EEPROM FUNCTION === IN EEPROM FUNCTION ************************=== --");
  delay(500);
  Serial.print(" this is threshHoldValue1    >>>>>>>#########>> ");
  Serial.println(threshHoldValue1);
  delay(1000);

  preferences.putInt("sensor1", threshHoldValue1); // WRITE TO FLASH MEMOREY USING PREFERENCES FUCTION
  delay(50);
  preferences.putInt("sensor2", threshHoldValue2);
  delay(50);
  preferences.putInt("sensor3", threshHoldValue3);
  delay(50);
  preferences.putInt("sensor4", threshHoldValue4);
  delay(50);
  preferences.putInt("sensor5", threshHoldValue5);
  delay(50);

  Serial.print("       SAVED in Prefereces threshHoldValue1 >>> ");
  Serial.println(threshHoldValue1);
  //delay(3100);
  digitalWrite(25, LOW);//  turn off "button presssed"  signel LED
  //  REsetFlgToOne = 1;  // send back via levelSensorReadings.doCalibrate1
  // REsetFlgToOne = 1; // set flag back to normal to send back to master
  //  REsetFlgToOne = 1;
  //  buttonStatus = 1;
  //  pinValue = 1;
  delay(10);
  // incomingDoCalibrate1 = 1111;
  lockCalibrate = 1111;
}
// end dwEeprommRoutine  >> flash memory routine ============================================
// String slaveMac = "THIS IS TEST VALUE 14700";

void valuesToSend() {   // this is where the values to send get collected and ququed for sending
  char StingToChar[32]; // ; // " test one in TO SEND";
  slaveMac.toCharArray(StingToChar, sizeof(StingToChar));
  strcpy(outgoingValues.CharFromSlave1 , StingToChar);
  outgoingValues.CharFromSlave1[32];
  outgoingValues.slaveNumber = slaveNumber;
  outgoingValues.sensor1 = LEDvar1;
  outgoingValues.sensor2 = LEDvar2;
  outgoingValues.sensor3 = LEDvar3;
  outgoingValues.sensor4 = LEDvar4;
  outgoingValues.sensor5 = LEDvar5;
  //  outgoingValues.reSetCalFlag = sendBackToMaster;
  // outgoingValues.reSetCalFlag = REsetFlgToOne;
}

void displayInformation() {
  // Display Readings in Serial Monitor
  Serial.println("INCOMING READINGS");
  Serial.print("dw_pad buffer/padding between stored and current values: ");
  Serial.print(incomingValues.dw_pad);
  Serial.println("boolian to hold flag var to request calibration : ");
  Serial.print(incomingValues.doCalibrate1);
  Serial.print("a variable that holds a string or char[32] value: ");
  Serial.println(incomingValues.CharFromMstr);
  Serial.print(" dw_a and int to hold some flag value: ");
  Serial.println(incomingValues.slaveNumber);
  Serial.println("END OF PRINT DISPLAY ");
}

int Min1;    // initialize the varibles that are used in the averaging/smoothing functions
int Max1;
int sampleSensor1;
unsigned long Sum1;
unsigned long Average1;
int Min2;  // Global Variables 2
int Max2;
int Analog2;
unsigned long Sum2;
unsigned long Average2;
int Min3;     // Global Variables 3
int Max3;
int Analog3;
unsigned long Sum3;
unsigned long Average3;
int Min4;                     // Global Variables  4
int Max4;
int Analog4;
unsigned long Sum4;
unsigned long Average4;
int Min5;                 // Global Variables 5
int Max5;
int Analog5;
unsigned long Sum5;
unsigned long Average5;

int  touchread1() {   // FUNCTION  to average pin values
  Min1 = 1023;     //Initilize/reset to limit
  Max1 = 0;        //Initilize/reset to limit
  Sum1 = 0;        //Initialize/reset
  //Take numberOfSamples readings, find min, max, and average.  This loop takes about 100ms.
  for (int i = 0; i < numberOfSamples; i++) {
   // sampleSensor1 = touchRead(04);
    sampleSensor1 = touchRead(sensorPin1);
    Sum1 = Sum1 + sampleSensor1;   //Sum for averaging
    if (sampleSensor1 < Min1)
      Min1 = sampleSensor1;
    if (sampleSensor1 > Max1)
      Max1 = sampleSensor1;
  }
  Average1 = (Sum1 / numberOfSamples);
  // print results
  Serial.print(" Min1 = ");
  Serial.print(Min1);
  Serial.print(" Max1 = ");
  Serial.print(Max1);
  Serial.print(" Average1 = ");
  Serial.println(Average1);
  delay(delayTimeForAverage);
  return  Average1;
}  //End

int  touchread2() {   // FUNCTION  to average pin values
  Min2 = 1023;     //Initilize/reset to limit
  Max2 = 0;        //Initilize/reset to limit
  Sum2 = 0;        //Initialize/reset
  //Take numberOfSamples readings, find min, max, and average.  This loop takes about 100ms.
  for (int i = 0; i < numberOfSamples; i++) {
    Analog2 = touchRead(sensorPin2);
    Sum2 = Sum2 + Analog2;   //Sum for averaging
    if (Analog2 < Min2)
      Min2 = Analog2;
    if (Analog2 > Max2)
      Max2 = Analog2;
  }
  Average2 = (Sum2 / numberOfSamples);
  // print results
  Serial.print(" Min2 = ");
  Serial.print(Min2);
  Serial.print(" Max2 = ");
  Serial.print(Max2);
  Serial.print(" Average2 = ");
  Serial.println(Average2);
  delay(delayTimeForAverage);
  return  Average2;
}  //End

int  touchread3() {   // FUNCTION  to average pin values
  Min3 = 1023;     //Initilize/reset to limit
  Max3 = 0;        //Initilize/reset to limit
  Sum3 = 0;        //Initialize/reset
  //Take numberOfSamples readings, find min, max, and average.  This loop takes about 100ms.
  for (int i = 0; i < numberOfSamples; i++) {
    Analog3 = touchRead(sensorPin3);
    Sum3 = Sum3 + Analog3;   //Sum for averaging
    if (Analog3 < Min3)
      Min3 = Analog3;
    if (Analog3 > Max3)
      Max3 = Analog3;
  }
  Average3 = (Sum3 / numberOfSamples);
  // print results
  Serial.print(" Min3 = ");
  Serial.print(Min3);
  Serial.print(" Max3 = ");
  Serial.print(Max3);
  Serial.print(" Average3 = ");
  Serial.println(Average3);
  delay(delayTimeForAverage);
  return  Average3;
}  //End

int  touchread4() {   // FUNCTION  to average pin values
  Min4 = 1023;     //Initilize/reset to limit
  Max4 = 0;        //Initilize/reset to limit
  Sum4 = 0;        //Initialize/reset
  //Take numberOfSamples readings, find min, max, and average.  This loop takes about 100ms.
  for (int i = 0; i < numberOfSamples; i++) {
    Analog4 = touchRead(sensorPin4);
    Sum4 = Sum4 + Analog4;   //Sum for averaging
    if (Analog4 < Min4)
      Min4 = Analog4;
    if (Analog4 > Max4)
      Max4 = Analog4;
  }
  Average4 = (Sum4 / numberOfSamples);
  // print results
  Serial.print(" Min4 = ");
  Serial.print(Min4);
  Serial.print(" Max4 = ");
  Serial.print(Max4);
  Serial.print(" Average4 = ");
  Serial.println(Average4);
  delay(delayTimeForAverage);
  return  Average4;

}  //End

int  touchread5() {   // FUNCTION  to average pin values
  Min5 = 1023;     //Initilize/reset to limit
  Max5 = 0;        //Initilize/reset to limit
  Sum5 = 0;        //Initialize/reset

  //Take numberOfSamples readings, find min, max, and average.  This loop takes about 100ms.
  for (int i = 0; i < numberOfSamples; i++) {
    //  Analog = analogRead(A0);

    Analog5 = touchRead(sensorPin5);

    Sum5 = Sum5 + Analog5;   //Sum for averaging
    if (Analog5 < Min5)
      Min5 = Analog5;

    if (Analog5 > Max5)
      Max5 = Analog5;
  }
  Average5 = (Sum5 / numberOfSamples);
  // print results
  Serial.print(" Min5 = ");
  Serial.print(Min5);
  Serial.print(" Max5 = ");
  Serial.print(Max5);
  Serial.print(" Average5 = ");
  Serial.println(Average5);
  delay(delayTimeForAverage);
  return  Average5;
}  //End
fuel guage

A high percentage of this code probably came from someone else. I do not know how to write code, but I can sometimes paste things together that work. Even if the code shown here did not come from one of the sources below, I most likely learned how to make it work with help from them. My apologies to anyone I missed. Please make use of anything you see here, but do not count on good coding practice as I have just done what was needed to make it work. But it does work, unless otherwise noted. Thanks to everyone who has shared their knowledge and good luck to those who are learning. https://www.jarutex.com/index.php/2021/12/19/8868/ https://www.arduino.cc/ https://www.sparkfun.com/ https://randomnerdtutorials.com/ https://youtu.be/3BWSSpcn95A https://stackoverflow.com/ https://youtu.be/684KSAvYbw4 https://exploreembedded.com/ https://www.youtube.com/watch?v=JmvMvIphMnY&t https://prosperityconsulting.com

// master / display / contol module 
#include <esp_now.h>
#include <WiFi.h>
#include <Preferences.h>  // library to set up write-to-flash function 

Preferences prefString;  // Assignment to set up write-to-flash function
Preferences prefInteger;
String savedThreshHoldValue1;
String savedThreshHoldValue2;
String savedThreshHoldValue3;

#define CHANNEL 1
byte paddingValue = 10;
int doCalibrate1 = 5;
int doCalibrate2 = 5;
int doCalibrate3 = 5;
byte chooseTank = 2;
String dw_M_SSID; // these vars are to capture the mac addresses of the slaves
String macCapture = "00";
String slaveOneMac = "00";
String slaveTwoMac = "00";
String slaveThreeMac = "00";
unsigned int slaveCountNumber;
bool stopFindingMacs = 0;
int gotMacs = 0;
int saved_DoneWithMacs = 0;

String myMac = WiFi.macAddress() + "AB";

// Pins used 
// 18, 19, 21, 22, 23 for level LEDs  26 for Calibrate switch 04 for calibrate indiscator 
// pins 32 33 inupt_pullup used for setting display to tank 1, 2, or 3/
// tank indicator LED 04 16, 17, 

int macLock1 = 1111; // 1111 is UNlocked 9999 is LOCKED 
int macLock2 = 1111;
int macLock3 = 1111;

// REPLACE WITH THE MAC Address of your receiver - as this is the master it is using the broadcast-to-all 0xFF address
uint8_t broadcastAddress[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
//uint8_t broadcastAddress[] = { 0x30,0xC6,0xF7,0x05,0x9B,0x94 };   

//  MASTER - RECIVES DATA FROM THREE SLAVES AND SORTS THE DATA INTO THREE SERIAL OUTPUT DISPLAYS.
// This recives and labels them ONE  TWO AND THREE
// IT IS DEPENDENT ON PUTTING THE RIGHT IDENTIFIER INTO the right var SUCH AS 949494 OR 707070 OR 787878

//unsigned long previousMillis = 0;        // will store last time LED was updated
//const long interval = 10000;
//const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
String saved_MacValue1;
String saved_MacValue2;
String saved_MacValue3;
unsigned int  count_lookForMacAddr = 0;
char CharFromMstr[32]; // = "123456789 123456789 1234567893";

// Define variables to hold incoming incoming LED status readings
int incomingSlaveNumber;
int incomingSensorVarA1;
int incomingSensorVarA2;
int incomingSensorVarA3;
int incomingSensorVarA4;
int incomingSensorVarA5;
char incomingSlaveMacA;

int incomingSensorVarB1;
int incomingSensorVarB2;
int incomingSensorVarB3;
int incomingSensorVarB4;
int incomingSensorVarB5;

int incomingSensorVarC1;
int incomingSensorVarC2;
int incomingSensorVarC3;
int incomingSensorVarC4;
int incomingSensorVarC5;
String success;  // Variable to store if sending data was successful

void InitESPNow() {  // Init ESP Now with fallback
	WiFi.disconnect();
	if (esp_now_init() == ESP_OK) {
		Serial.println("ESPNow Init Success");
	} else {
		Serial.println("ESPNow Init Failed");
		// Retry InitESPNow, add a counte and then restart?
		// InitESPNow();
		// or Simply Restart
		ESP.restart();
	}
}

// config AP SSID  with indetifying mac
void configDeviceAP() {
	String Prefix = "Master_dw:";
	String Mac = WiFi.macAddress();
	String SSID = Prefix + Mac;
	String Password = "123456789";
	bool result = WiFi.softAP(SSID.c_str(), Password.c_str(), CHANNEL, 0);
	if (!result) {
		Serial.println("AP Config failed.");
	} else {
		Serial.println("AP Config Success. Broadcasting with AP: " + String(SSID));
		dw_M_SSID = String(SSID);
	}
}


//Structure example to send data
//Must match the receiver structure
typedef struct struct_message {
	int slaveNumber;
	int sensor1;
	int sensor2;
	int sensor3;
	int sensor4;
	int sensor5;
	char CharFromMstr[32];
	char CharFromSlave1[32];
	char CharFromSlave2[32];
	char CharFromSlave3[32];
	byte dw_pad;
	int doCalibrate1;
	int doCalibrate2;
	int doCalibrate3;
} struct_message;

// Create a struct_message called BME280Readings to hold VARIABLES TO SEND TO SLAVES
struct_message outgoingMasterToSlave;

// Create a struct_message to hold incoming sensor readings
struct_message incomingFromSlaves;

// 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");
	String macAddress1 = WiFi.macAddress();
	if (status == 0) {
		success = "Delivery Success :)";
		String Mac = WiFi.macAddress();
		Serial.println("AP Config Success. Broadcasting from MASTER with AP: " + String(Mac));
	} else {
		success = " OUTGOING DELIVER FAIL FAIL FAIL FAIL FAIL Delivery Fail :(";
	}
}

// Callback when data is received
void OnDataRecv(const uint8_t* mac, const uint8_t* incomingData, int len) {
	memcpy(&incomingFromSlaves, incomingData, sizeof(incomingFromSlaves));
	char macStr[18];
	snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
			 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
	Serial.print("Bytes received: ");
	Serial.println(len);
	Serial.print("////////////// LAST PACKET RECV FROM  ///////////: "); Serial.println(macStr);
	Serial.print("Last Packet Recv Data: "); Serial.println(*incomingData);
	Serial.print("Bytes received: ");
	Serial.println(len);
	Serial.print(" Mac address from SLAVE as CHAR  >>>>>>>>>>>>>>>: ");
	Serial.println(incomingFromSlaves.CharFromSlave1);
	delay(2000);
	macCapture = macStr; // capture the MAC id of the current slave being read
	findSave_SlaveMacAddr();// collect slave addresses, assign to a tank and then save to flash memory
	// save_SlaveMacAddr();  // we probably don't need this and it should be eliminated.

	save_FoundAllMacs();

	captureAndDisplaySlave1(); // capture incoming sensor values based on the slave slected 
	captureAndDisplaySlave2();
	captureAndDisplaySlave3();

}

void setup() {
	Serial.begin(115200);
	prefString.begin("macAssign", false);//for nonvolitile memory process  NO ERROR REPORTED IF MISSING!
	prefInteger.begin("allMacsSaved", false);//for nonvolitile memory process  NO ERROR REPORTED IF MISSING!

	pinMode(26, INPUT_PULLUP);  // enable internal pull-up  for calibration pushbutton	

	factoryReset();  // Check if -factory reset- button is pressed during startup
	displaySlaveMacAddr(); // This is for testing 

	pinMode(32, INPUT_PULLUP);  // for chooseTank switch 
	pinMode(33, INPUT_PULLUP); // for chooseTank switch 

	pinMode(4, OUTPUT); // this is for LED that indicates button has been pressed long enough
	pinMode(16, OUTPUT);
	pinMode(17, OUTPUT);
	pinMode(18, OUTPUT);
	pinMode(19, OUTPUT);
	pinMode(21, OUTPUT);
	pinMode(22, OUTPUT);
	pinMode(23, OUTPUT);

	WiFi.mode(WIFI_AP_STA);  // configure device AP mode	
	configDeviceAP();
	if (esp_now_init() != ESP_OK) {  // Init ESP-NOW  Set device as a Wi-Fi Station
		Serial.println("Error initializing ESP-NOW");
		return;
	}
	esp_now_register_send_cb(OnDataSent); // register for Send CB to get the status of Trasnmitted packet
	esp_now_peer_info_t peerInfo;  // Register peer
	memcpy(peerInfo.peer_addr, broadcastAddress, 6);
	peerInfo.channel = 0;
	peerInfo.encrypt = false;
	if (esp_now_add_peer(&peerInfo) != ESP_OK) {  // Add peer
		Serial.println("Failed to add peer");
		return;
	}
	esp_now_register_recv_cb(OnDataRecv);// Register callback function that is called when data is received
}

void loop() { // *************************** start loop *******************************

	Serial.println("*************************** start loop *******************************");
	Serial.println("*************************** start loop *******************************");
	Serial.println("*************************** start loop *******************************");
	Serial.print("VALUE OF  >>var<< DONE - WITH - MACS done collecting mac addresses  : ");
	Serial.println(saved_DoneWithMacs);
	Serial.print("VALUE OF  >>GET<<  DONE - WITH - MACS done collecting mac addresses  : ");
	Serial.println(prefInteger.getUInt("GetStatus", gotMacs));
	delay(2000);

	

	int	saved_GetMacsIsDone = prefInteger.getUInt("GetStatus", gotMacs);
	Serial.print("*******       THIS IS THE  VALUE   >>>>>>>>>>>  saved_GetMacsDone <<< >>>>>>> ");
	Serial.println(saved_GetMacsIsDone);
	Serial.print("         THIS IS  prefInteger.getUInt( 'tempValue2', gotMacs) >>>>>> ");
	Serial.println(prefInteger.getUInt("GetStatus", gotMacs));
	Serial.println("  ");

	//	delay(5000);
	displaySlaveMacAddr(); // this is just for testing 

	chooseTank = selectTank(); 	// part of set mac of slave function 

	pressForCalibrate(); //  read pushbutton to send calibrate request to slave

	valuesToSend();  // collect the values that will be sent to slaves
	//delay(5000);
	sendMessageToSlaves(); // send the message to the slave with esp-now

} // **********************************   end loop  **************************************************


void findSave_SlaveMacAddr() {
	Serial.println(" ***************   ARE LOOKING FOR MAC ADDRESSES ?????   ****************");
	Serial.print("   *********  VALUE OF >  ||| STOP FINDING MACS |||           >>>>>> : ");
	Serial.println(prefInteger.getUInt("GetStatus", gotMacs));
	if (stopFindingMacs == 0 && gotMacs == 0 && prefInteger.getUInt("GetStatus", gotMacs) == 0) {
		Serial.println(" *********  WE >>> ARE <<<< LOOKING FOR MAC ADDRESSES * LOOKING * LOOKING *LOOKING **");
		//	delay(5000);
		if (gotMacs == 0) {
			count_lookForMacAddr++;
		} // increment the counter if we got this far
		if (slaveOneMac == "00") {
			slaveOneMac = macCapture;
			prefString.putString("slaveNum1", slaveOneMac); // SAVE VALUE TO PERMANENT FLASH STORAGE
			saved_MacValue1 = prefString.getString("slaveNum1", slaveOneMac);
			macLock1 = 9999;
		}	// set one 
		if (slaveTwoMac == "00" && macLock1 == 9999 && macCapture != slaveOneMac) {
			slaveTwoMac = macCapture; // set two 
			prefString.putString("slaveNum2", slaveTwoMac); // SAVE VALUE TO PERMANENT FLASH STORAGE
			saved_MacValue2 = prefString.getString("slaveNum2", slaveTwoMac);
			macLock2 = 9999;
		}
		if (slaveTwoMac != "00" && macLock2 == 9999 && macLock1 == 9999 && macCapture != slaveOneMac && macCapture != slaveTwoMac) {
			slaveThreeMac = macCapture; // set three
			prefString.putString("slaveNum3", slaveThreeMac); // SAVE VALUE TO PERMANENT FLASH STORAGE
			saved_MacValue3 = prefString.getString("slaveNum3", slaveThreeMac);
			macLock3 = 9999;
		}
		Serial.println("");
		Serial.print("    value of dw_ssid >>>> ");
		Serial.println(dw_M_SSID);
		Serial.println("     ");
		Serial.print("      Value of XXX  >>>> ");
		Serial.println(macCapture);
		Serial.print("                                  Value of slaveOneMac >>>> ");
		Serial.println(slaveOneMac);
		Serial.print("                                  Value of slaveTwoMac >>>> ");
		Serial.println(slaveTwoMac);
		Serial.print("                                Value of slaveThreeMac >>>> ");
		Serial.println(slaveThreeMac);
		Serial.print("                                         value of counter : ");
		Serial.println(count_lookForMacAddr);

		if (slaveOneMac != "00" && slaveTwoMac != "00" && slaveThreeMac != "00") {
			Serial.println("               ");
			Serial.println("**********************  WE CAN SAVE THIS *******************************");
			Serial.println(" ***************  WE HAVE FOUND ALL THE SLAVES - STOP LOOKING !!!! ************");

			stopFindingMacs = 1; //if we got to here in find_SlaveMacAddr, set flag and stop looking for slaves
			 //if we got to here in find_SlaveMacAddr, set flag and stop looking for slaves
			if (stopFindingMacs == 1); {
				gotMacs = 1;  // this will go to nonvolitle stoage 
				Serial.println("stopFindingMacs = 1  && gotMacs = 1 **** NO LONGER LOOKING FOR MACS !!!!  *****");
				Serial.println("stopFindingMacs = 1  && gotMacs = 1 **** NO LONGER LOOKING FOR MACS !!!!  *****");
				displaySlaveMacAddr();
				//	delay(5000);
				Serial.print("                                                                gotMacs = :  ");
				Serial.println(gotMacs);
				//	delay(9000);
			}
		}
	}  //  stop finding if macs == 0
	if (count_lookForMacAddr >= 7) { gotMacs = 1; }
	// save_SlaveMacAddr();
} // end fuction 

void save_FoundAllMacs() { // Just save the flag that says all macs are found and stored
	Serial.println(" SEE IF WE ARE GOING TO SAVE THE DONE-WITH-MACS FLAG  ");
	saved_DoneWithMacs = prefInteger.getUInt("GetStatus", gotMacs);
	//	saved_DoneWithMacs = 0; // THIS IS FOR TESTING, >> TO RESET <<  SHOULD BE REMOVED FOR PRODUCTION
	if (saved_DoneWithMacs == 0) {
		prefInteger.putUInt("GetStatus", gotMacs);
	}
	saved_DoneWithMacs = prefInteger.getUInt("GetStatus", gotMacs);
}

void save_SlaveMacAddr() {  // this may not be needed as it was included in other function
	Serial.println("  BEFORE saving the macs TO FLASH STORAGE   ");

	Serial.print(" STOP FINDING MACS  =  :   ");
	Serial.println(stopFindingMacs);
	Serial.print("          GOT MACS  =  :   ");
	Serial.println(gotMacs);
	Serial.print("  GET U INIT GOT MACS  :   ");
	Serial.println(prefInteger.getUInt("GetStatus", gotMacs));
	delay(7000);
	if (stopFindingMacs == 0 && gotMacs == 0 && prefInteger.getUInt("GetStatus", gotMacs) == 0) {
		Serial.print("    WE NOW SAVING MAC  ADDRESSES ********************** ");
		delay(5000);
		if (slaveOneMac != "00" && slaveTwoMac != "00" && slaveThreeMac != "00") { // if all have macs, skip
			if (slaveOneMac != "00" && gotMacs == 0) {
				prefString.putString("slaveNum1", slaveOneMac); // if slot one is empty SAVE MAC TO FLASH 
				Serial.print(" SAVING * SAVING * SAVING  KEY SlaveNum1 TO FLASH display   saved_MacValue1   : ");
				saved_MacValue1 = prefString.getString("slaveNum1", slaveOneMac);
				Serial.println(saved_MacValue1);
				delay(9000);
			}
			if (slaveTwoMac != "00" && gotMacs == 0) {
				prefString.putString("slaveNum2", slaveTwoMac); // if slot two is empty SAVE MAC TO FLASH
				Serial.print(" SAVING * SAVING * SAVING  KEY SlaveNum2 TO FLASH display   saved_MacValue2   : ");
				saved_MacValue2 = prefString.getString("slaveNum2", slaveTwoMac);
				Serial.println(saved_MacValue2);
				delay(9000);
			}
			if (slaveThreeMac != "00" && gotMacs == 0) {
				prefString.putString("slaveNum3", slaveThreeMac); // if slot three is empty SAVE MAC TO FLASH
				Serial.print(" SAVING * SAVING * SAVING  KEY SlaveNum3 TO FLASH display   saved_MacValue3   : ");
				saved_MacValue3 = prefString.getString("slaveNum3", slaveThreeMac);
				Serial.println(saved_MacValue3);
				delay(9000);
			}
		} //end     of if to see if the slots are already filled.
	} //end    if stop finding macs  == 0 AND all macs have not been found

	/*
	saved_MacValue1 = prefString.getString("slaveNum1", slaveOneMac);
	delay(20);
	saved_MacValue2 = prefString.getString("slaveNum2", slaveTwoMac);
	delay(20);
	saved_MacValue3 = prefString.getString("slaveNum3", slaveThreeMac);
	*/
	//  prefString.end(); //  I don' know what this does
} // end if

void displaySlaveMacAddr() {
	Serial.println("// *********    this is the start of display  *****************************");
	Serial.println("");
	Serial.print(" saved_MacValue1: ");
	Serial.print(saved_MacValue1 + "  slaveOneMac: ");
	Serial.print(slaveOneMac + "  getString(slaveNum1:   ");
	Serial.println(prefString.getString("slaveNum1", slaveOneMac));

	Serial.print(" saved_MacValue2: ");
	Serial.print(saved_MacValue2 + "  slaveTwoMac: ");
	Serial.print(slaveTwoMac +   "  getString(slaveNum2:   ");
	Serial.println(prefString.getString("slaveNum2", slaveTwoMac));

	Serial.print(" saved_MacValue3: ");
	Serial.print(saved_MacValue3 + "slaveThreeMac: ");
	Serial.print(slaveThreeMac + " getString(slaveNum3:    ");
	Serial.println(prefString.getString("slaveNum3", slaveThreeMac));
	Serial.print(" FLASH SAVED VALUE OF |||| saved_DoneWithMacs ||| >>>: ");
	Serial.println(prefInteger.getUInt("GetStatus", gotMacs));
	Serial.print(" VARIABLE       Value of count_lookForMacAddr : ");
	Serial.println(count_lookForMacAddr);
	delay(5000);

	Serial.println("");
	//	prefInt.putUInt("slaveCounter1", count_lookForMacAddr);
	//	storedLookForMacCounter = prefInt.getUInt("slaveCounter1", count_lookForMacAddr);
	delay(20);
	Serial.print(">>>>>> value of saved_DoneWithMacs >>>>> : ");
	Serial.println(saved_DoneWithMacs);
	Serial.println(prefInteger.getUInt("GetStatus", gotMacs));

}

void captureAndDisplaySlave1() {  // capture incoming sensor values based on the slave slected 
	// if (incomingFromSlaves.slaveNumber == 949494 && chooseTank == 1) {
	if (prefString.getString("slaveNum1", slaveOneMac) == macCapture && chooseTank == 1) {
		incomingSlaveNumber = incomingFromSlaves.slaveNumber;
		incomingSensorVarA1 = incomingFromSlaves.sensor1;
		incomingSensorVarA2 = incomingFromSlaves.sensor2;
		incomingSensorVarA3 = incomingFromSlaves.sensor3;
		incomingSensorVarA4 = incomingFromSlaves.sensor4;
		incomingSensorVarA5 = incomingFromSlaves.sensor5;
		incomingSlaveMacA = incomingFromSlaves.CharFromSlave1[32];
				if (incomingSensorVarA1 == 1) { digitalWrite(18, HIGH); }
		if (incomingSensorVarA1 == 0) { digitalWrite(18, LOW); }
		if (incomingSensorVarA2 == 1) { digitalWrite(19, HIGH); }
		if (incomingSensorVarA2 == 0) { digitalWrite(19, LOW); }
		if (incomingSensorVarA3 == 1) { digitalWrite(21, HIGH); }
		if (incomingSensorVarA3 == 0) { digitalWrite(21, LOW); }
		if (incomingSensorVarA4 == 1) { digitalWrite(22, HIGH); }
		if (incomingSensorVarA4 == 0) { digitalWrite(22, LOW); }
		if (incomingSensorVarA5 == 1) { digitalWrite(23, HIGH); }
		if (incomingSensorVarA5 == 0) { digitalWrite(23, LOW); }
		updateDisplay1();
	}
} // end of read the incoming sensor values 

void captureAndDisplaySlave2() {
	if (prefString.getString("slaveNum2", slaveTwoMac) == macCapture && chooseTank == 2) {
		incomingSlaveNumber = incomingFromSlaves.slaveNumber;
		incomingSensorVarB1 = incomingFromSlaves.sensor1;
		incomingSensorVarB2 = incomingFromSlaves.sensor2;
		incomingSensorVarB3 = incomingFromSlaves.sensor3;
		incomingSensorVarB4 = incomingFromSlaves.sensor4;
		incomingSensorVarB5 = incomingFromSlaves.sensor5;
		if (incomingSensorVarB1 == 1) {
			digitalWrite(18, HIGH);
		}
		if (incomingSensorVarB1 == 0) {
			digitalWrite(18, LOW);
		}
		if (incomingSensorVarB2 == 1) {
			digitalWrite(19, HIGH);
		}
		if (incomingSensorVarB2 == 0) {
			digitalWrite(19, LOW);
		}
		if (incomingSensorVarB3 == 1) {
			digitalWrite(21, HIGH);
		}
		if (incomingSensorVarB3 == 0) {
			digitalWrite(21, LOW);
		}
		if (incomingSensorVarB4 == 1) {
			digitalWrite(22, HIGH);
		}
		if (incomingSensorVarB4 == 0) {
			digitalWrite(22, LOW);
		}
		if (incomingSensorVarB5 == 1) {
			digitalWrite(23, HIGH);
		}
		if (incomingSensorVarB5 == 0) {
			digitalWrite(23, LOW);
		}
		updateDisplay2();
	}
}

void captureAndDisplaySlave3() {
	if (prefString.getString("slaveNum3", slaveThreeMac) == macCapture && chooseTank == 3) {
		incomingSlaveNumber = incomingFromSlaves.slaveNumber;
		incomingSensorVarC1 = incomingFromSlaves.sensor1;
		incomingSensorVarC2 = incomingFromSlaves.sensor2;
		incomingSensorVarC3 = incomingFromSlaves.sensor3;
		incomingSensorVarC4 = incomingFromSlaves.sensor4;
		incomingSensorVarC5 = incomingFromSlaves.sensor5;
		if (incomingSensorVarC1 == 1) {
			digitalWrite(18, HIGH);
		}
		if (incomingSensorVarC1 == 0) {
			digitalWrite(18, LOW);
		}
		if (incomingSensorVarC2 == 1) {
			digitalWrite(19, HIGH);
		}
		if (incomingSensorVarC2 == 0) {
			digitalWrite(19, LOW);
		}
		if (incomingSensorVarC3 == 1) {
			digitalWrite(21, HIGH);
		}
		if (incomingSensorVarC3 == 0) {
			digitalWrite(21, LOW);
		}
		if (incomingSensorVarC4 == 1) {
			digitalWrite(22, HIGH);
		}
		if (incomingSensorVarC4 == 0) {
			digitalWrite(22, LOW);
		}
		if (incomingSensorVarC5 == 1) {
			digitalWrite(23, HIGH);
		}
		if (incomingSensorVarC5 == 0) {
			digitalWrite(23, LOW);
		}
		updateDisplay3();
	}
}

byte selectTank() {// function to choose the active tank (tank being displayed) 
	if (digitalRead(32) == 0 && (digitalRead(33) == 0)) { chooseTank = 1; }
	if (digitalRead(32) == 1 && (digitalRead(33) == 1)) { chooseTank = 3; }
	if (digitalRead(32) == 0 && (digitalRead(33) == 1)) { chooseTank = 2; }
	if (digitalRead(32) == 1 && (digitalRead(33) == 0)) { chooseTank = 2; }
	Serial.print(" chooseTank  value  >>>> :  ");
	Serial.println(chooseTank);
	delay(1000);
	if (chooseTank == 1) {
		digitalWrite(16, LOW);
		digitalWrite(17, LOW);
		digitalWrite(4, HIGH);
	}
	if (chooseTank == 2) {
		digitalWrite(4, LOW);
		digitalWrite(17, LOW);
		digitalWrite(16, HIGH);
	}
	if (chooseTank == 3) {
		digitalWrite(16, LOW);
		digitalWrite(4, LOW);
		digitalWrite(17, HIGH);
	}
	return chooseTank;
}

void blinkLED1() { 	 // blink an LED to show request has be registered
	digitalWrite(4, HIGH); 	delay(300); digitalWrite(4, LOW); 	delay(900);
	digitalWrite(4, HIGH); 	delay(300);
	digitalWrite(4, LOW); delay(300); digitalWrite(4, HIGH); delay(300); digitalWrite(4, LOW); 	delay(300);
	digitalWrite(4, HIGH); 	delay(300);	digitalWrite(4, LOW); digitalWrite(4, HIGH); 	delay(500);
	digitalWrite(4, LOW); 	delay(300);	digitalWrite(4, HIGH); 	delay(300);
	digitalWrite(4, LOW); delay(300); digitalWrite(4, HIGH); delay(300); digitalWrite(4, LOW); 	delay(300);
	digitalWrite(4, HIGH); 	delay(300);	digitalWrite(4, LOW);
}
void blinkLED2() { 	 // blink an LED to show request has be registered
	digitalWrite(16, HIGH); 	delay(300); digitalWrite(16, LOW); 	delay(900);
	digitalWrite(16, HIGH); 	delay(300);
	digitalWrite(16, LOW); delay(300); digitalWrite(16, HIGH); delay(300); digitalWrite(16, LOW); 	delay(300);
	digitalWrite(16, HIGH); 	delay(300);	digitalWrite(16, LOW); digitalWrite(16, HIGH); 	delay(500);
	digitalWrite(16, LOW); 	delay(300);	digitalWrite(16, HIGH); 	delay(300);
	digitalWrite(16, LOW); delay(300); digitalWrite(16, HIGH); delay(300); digitalWrite(16, LOW); 	delay(300);
	digitalWrite(16, HIGH); 	delay(300);	digitalWrite(16, LOW);
}
void blinkLED3() { 	 // blink an LED to show request has be registered
	digitalWrite(17, HIGH); 	delay(300); digitalWrite(17, LOW); 	delay(900);
	digitalWrite(17, HIGH); 	delay(300);
	digitalWrite(17, LOW); delay(300); digitalWrite(17, HIGH); delay(300); digitalWrite(17, LOW); 	delay(300);
	digitalWrite(17, HIGH); 	delay(300);	digitalWrite(17, LOW); digitalWrite(17, HIGH); 	delay(500);
	digitalWrite(17, LOW); 	delay(300);	digitalWrite(17, HIGH); 	delay(300);
	digitalWrite(17, LOW); delay(300); digitalWrite(17, HIGH); delay(300); digitalWrite(17, LOW); 	delay(300);
	digitalWrite(17, HIGH); 	delay(300);	digitalWrite(17, LOW);
}

























void factoryReset() {
	Serial.print("   inside    factory reset  BEFORE BUTTON CHECK  ");
	delay(50);
	if (digitalRead(26) == 0) {
		delay(50);
		blinkLED1();
		gotMacs = 0;
		slaveOneMac = "00";
		saved_MacValue1 = "00";
		saved_MacValue2 = "00";
		slaveThreeMac = "00";
		saved_MacValue3 = "00";
		prefInteger.putUInt("GetStatus", gotMacs);
		prefString.putString("slaveNum1", slaveOneMac);
		prefString.putString("slaveNum2", slaveTwoMac);
		prefString.putString("slaveNum3", slaveThreeMac);
		Serial.print("            inside >>> AFTER <<<  BUTTON IS PUSHEED   factory reset  gotMacs  =  >>>> ");
		displaySlaveMacAddr();
		Serial.println(gotMacs);

		Serial.print("                      the get saved value >  value >>>> ");
		Serial.println(prefInteger.getUInt("GetStatus", gotMacs));
		//	delay(6000); // to be able to read the message
	}
}


void pressForCalibrate() {
	if (digitalRead(26) == 0 && chooseTank == 1) {
		blinkLED1();
		doCalibrate1 = 9999;
		Serial.print("            inside    readPushButton() function  Value of doCalibrate1 >>>> ");
		Serial.println(doCalibrate1);
		delay(500); // to be able to read the message
		Serial.print("                                                  alue of doCalibrate1 >>>> ");
		Serial.println(doCalibrate1);
		delay(2000); // to be able to read the message
	}
	if (digitalRead(26) == 0 && chooseTank == 2) {
		blinkLED2();
		doCalibrate2 = 9999;
		Serial.print("            inside    readPushButton() function  Value of doCalibrate1 >>>> ");
		Serial.println(doCalibrate2);
		delay(500); // to be able to read the message
		Serial.print("                                                 Value of doCalibrate1 >>>> ");
		Serial.println(doCalibrate2);
	}
	if (digitalRead(26) == 0 && chooseTank == 3) {
		blinkLED3();
		doCalibrate3 = 9999;
		Serial.print("            inside    readPushButton() function  Value of doCalibrate1 >>>> ");
		Serial.println(doCalibrate3);
		delay(500); // to be able to read the message
		Serial.print("                                                  Value of doCalibrate1 >>>> ");
		Serial.println(doCalibrate3);
	}

} // end of read pushbutton

void valuesToSend() {    // values TO SEND TO SLAVE
	char StingToChar[32]; // ; // " test one in TO SEND";
	myMac.toCharArray(StingToChar, sizeof(StingToChar));
	strcpy(outgoingMasterToSlave.CharFromMstr, StingToChar);

	outgoingMasterToSlave.CharFromMstr[32]; // = "assign var in To Send";

	outgoingMasterToSlave.dw_pad = paddingValue;
	outgoingMasterToSlave.doCalibrate1 = doCalibrate1;
}

void sendMessageToSlaves() {  // Send the message from Master to Slave via ESP-NOW

	Serial.print("sending padding and doCalibrate >>>>>> : ");
	Serial.print(outgoingMasterToSlave.dw_pad);
	Serial.print("  <<<<<<  >>> ");
	Serial.print(outgoingMasterToSlave.doCalibrate1);
	Serial.println("  <<<<<<  sending char from master 32  ");
	Serial.print(outgoingMasterToSlave.CharFromMstr[32]);
	Serial.println("  <<<<<<   ");


	//delay(5000); // to be able to read the message
	esp_err_t result = esp_now_send(broadcastAddress, (uint8_t*)&outgoingMasterToSlave, sizeof(outgoingMasterToSlave));
	if (result == ESP_OK) { // If the message was recived by the slave, do the following
		Serial.println("***************MESSEGE RECEIVED BY A SLAVE with success  ********************");
		if (outgoingMasterToSlave.doCalibrate1 == 9999) { // if 9999 was recieved SUCCESFULLY, reset the value to 1111 
			doCalibrate1 = 1111;
		}
	} else {
		Serial.println("ERROR SENDING DATA TO THE SLAVE ");
		delay(1000); // allow time to read the message
	}
	delay(150); // allow time to read the message
}

void updateDisplay1() { // create function Display Readings in Serial Monitor
	String Mac = WiFi.macAddress();
	//  Serial.print("MAC OF THE MASTER CARD =====================   :  ");
	// Serial.println(Mac);
	Serial.println("======== THIS IS THE MASTER AND LED DISPLAY   >>111  ONE  111<<  ====== (14)");
	Serial.print("SAVED mac value");
	Serial.println(prefString.getString("slaveNum1", slaveOneMac));
	Serial.print("CURRENT  mac value");
	Serial.println(macCapture);
	Serial.print("TANK 1  TANK 1      TANK 1");


	Serial.print("incomingSensorVarA1:   ");
	Serial.println(incomingSensorVarA1);
	Serial.print("incomingSensorVarA2:   ");

	Serial.println(incomingSensorVarA2);
	Serial.print("incomingSensorVarA3:   ");
	Serial.println(incomingSensorVarA3);
	Serial.print("incomingSensorVarA4  : ");
	Serial.println(incomingSensorVarA4);
	Serial.print("incomingSensorVarA5  : ");
	Serial.println(incomingSensorVarA5);
	Serial.print(" Mac address from SLAVE as CHAR  >>>>>>>>>>>>>>>: ");
	Serial.println(incomingFromSlaves.CharFromSlave1);
	Serial.println(incomingSlaveMacA);

	Serial.print("   //////////            Start of loop -- doCalibrate1 =  : "); Serial.println(doCalibrate1);
	Serial.print(" digitalRead(26) ====  : "); Serial.println(digitalRead(26));

	//Serial.print("                             BUTTON STATUS  IS  >>>>>   : ");  Serial.println(pinValue);
//	Serial.print("    outgoing From Master To Slave.reSetCalFlag IS >>>   : ");
//	Serial.println(outgoingMasterToSlave.requestToCalibrateSensors);
	delay(3000);
}

void updateDisplay2() { // create function to Display Readings in Serial Monitor
	String Mac = WiFi.macAddress();
	Serial.print("MAC OF THE MASTER CARD =====================  :  ");
	Serial.println(Mac);
	Serial.println("== THIS IS THE MASTER AND LED DISPLAY     >>TWO<< ");
	Serial.print("SAVED mac value");
	Serial.println(prefString.getString("slaveNum2", slaveTwoMac));
	Serial.print("CURRENT  mac value");
	Serial.println(macCapture);
	Serial.print("TANK 2  TANK 2      TANK 2");
	Serial.print("incomingSensorVarB1:  ");
	Serial.println(incomingSensorVarB1);
	Serial.print("incomingSensorVarB2:  ");
	Serial.println(incomingSensorVarB2);
	Serial.print("incomingSensorVarB3:  ");
	Serial.println(incomingSensorVarB3);
	Serial.print("incomingSensorVarB4 : ");
	Serial.println(incomingSensorVarB4);
	Serial.print("incomingSensorVarB5 : ");
	Serial.println(incomingSensorVarB5);
}

void updateDisplay3() { // create function  Display Readings in Serial Monitor
	String Mac = WiFi.macAddress();
	Serial.print("MAC OF THE MASTER CARD ===================== :  ");
	Serial.println(Mac);
	Serial.println("== THIS IS THE MASTER AND LED DISPLAY     >>333 THREE  333<< ");
	Serial.print("SAVED mac value");
	Serial.println(prefString.getString("slaveNum3", slaveThreeMac));
	Serial.print("CURRENT  mac value");
	Serial.println(macCapture);
	Serial.print("TANK 3  TANK 3      TANK 3");
	Serial.print("incomingSensorVarC1: ");
	Serial.println(incomingSensorVarC1);
	Serial.print("incomingSensorVarC2: ");
	Serial.println(incomingSensorVarC2);
	Serial.print("incomingSensorVarC3: ");
	Serial.println(incomingSensorVarC3);
	Serial.print("incomingSensorVarC4  ");
	Serial.println(incomingSensorVarC4);
	Serial.print("incomingSensorVarC5: ");
	Serial.println(incomingSensorVarC5);
	delay(5000);
}

Loading

Please share it. Thanks!