The objective is to receive sensor data for remote units via radio and display these values.
The sketch has been working for more than two years without problems, but from time to time I decide to correct minor bugs and/or add more fetures to it.
Last revision was on January 2024 and no problems were found.
Recently I updated the libraries and board files and made some cosmetic changes to the code.
To my suprise, only two lines are printed in the Serial monitor of a total of more than 100 lines of debug information which the code is generating.
I have contacted the autors of the two libraries used in the code (thmr20 for RF24 and Bodmer for TFT_eSPI for the TFT) and it seems there are no known issues with the libraries, but I found on some forums that you made revision to the board files that are causing some issues.
Can anyone here help?
The code is below;
Code: Select all
//------End of Comments-------------
#include <TFT_eSPI.h> // Hardware-specific library
// In the TFT_ESPI user_setup.h file //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
// be sure to comment OUT the line for TFT_CS // <======== BE SURE TO DO THIS EVERYTIME A NEW COMPUTER IS USED
// //#define TFT_CS 21 // Chip select control pin // OR the library is Re-installed
// ###!!!!Jan 2024 see notes on ...D:\Eletronica\Arduino\SketchBook\libraries\TFT_eSPI_Setups
// load RF related libraries
#include "printf.h" // Added Jan 2024
#include "SPI.h"
#include "nRF24L01.h" // Added Jan 2024
#include "RF24.h"
//???? #include "RF24Network.h" //Commented Jan 2024
//----- Using faster Graphic Library
TFT_eSPI tft = TFT_eSPI(); // Invoke TFT custom library
// *************My setup for Harware SPI for ILI9341***************
// The pins used by the TFT display are defined in the user_setup.h file
// ####### DO NOT ERASE THIS #######
// TFT_MISO 19
// TFT_MOSI 23
// TFT_SCLK 18
// TFT_CS 15
// TFT_DC 2 // Data Command control pin
// TFT_RST 4 // Reset pin (could connect to RST pin)
//----- define RF24L01 variables ###### CHANGED IN JAN 2024######################## nRF24L01 pin definitions changed#####################
#define RF24_CSN 16 // ####### New Radio pinout#######
#define RF24_CE 17 // ####### New Radio pinout#######
//======= in old layout board the pins are:=======
//???#define RF24_CSN 3
//???#define RF24_CE 1
//???uint8_t address[][6] = {"Prime", "1Node", "2Node" }; // using tmhr20 example
long long unsigned addresses[5] = { 0x00D00FAFFA, 0x00D00FAFFB, 0x00D00FAFFC, 0x00D00FAFFD, 0x00D00FAFFE }; // cisterna = pipe0 caixa = pipe1
uint8_t pipeNum; // used in checkPipe() Jan 2024
RF24 radio(RF24_CE,RF24_CSN); // NRF24L01 used SPI pins radio (CE, CSN)
const uint16_t channel = 108; //changed on Marco2021
// Structure of our payload
// ESP32 group data in 4 bytes chunks, so data structure has to be rearranged
//The data to be transmitted by lower and upper water tanks modules is:
// type cisterna caixa superior
// ------- ---------- --------------
// 1 float Irms auxVol (last pumping cycle volume)
// 2 float flow flow
// 3 float Pdisch totalLiters
// 4 float DpFilter flowPoco (added July 2023)
// 5 float Pinlet dummy2
// 6 float lampCurrent dummy4 //added in March 2021
// 7 int rawDp rawDp
// 8 bool flapstate dummy3
// In Jan 2024 rev 0 on, dummy variables on Cx Superior will be assigned a value 0f -100, which will
// be used by the receiver to identify the data belongs to Caixa Superior
// Structure of our payload
struct payload_t // 32 bytes max, used=7*4+2+1 = 31 bytes OK! corrected March 2023
{
uint32_t counter; // - 4 bytes number of packets transmitted
float val1; // - 4 bytes
float val2; // - 4 bytes
float val3; // - 4 bytes
float val4; // - 4 bytes
float val5; // - 4 bytes
float val6; // - 4 bytes
int16_t val7; // - 2 bytes
bool val8; // - 1 byte
};
payload_t payload; // create a variable with the above structure
//******** Initialize and define variables ***************
unsigned long startTime; //timer used to ckeck if data has been received
unsigned long clearTime = 90000; // in milliseconds
unsigned long waitTime = 60000; // in milliseconds
unsigned long pumpOnMillis =0; // time when pump has been turned ON
unsigned long pumpOnDelay = 10000; // wait 10 s to check if the flow has been established normally
unsigned long lastCisternaTime;
unsigned long lastCaixaTime;
unsigned long dataLossTime = 60000; // changed to 60 sec. Data is transmitted every second (Txtime in Cx & Cisterna) Jan 2024
unsigned long dataUpdateTime = 900; //Fev 2024 // each Tx is sending data every 1sec
const int LCDinterval = 5000; //added in rev noDelays (03/2021)
unsigned long buzzer_millis_new;
unsigned long buzzer_millis_old;
unsigned long fault_ID_mil[7];
unsigned long fault_ID_mil_Old[7] = { 0, 0, 0, 0, 0, 0, 0 };
bool flapState = LOW;
float Pdisch = 0.0;
float PdischLow = 0.5; // Check value !!!! ***** added in June 2021
float flow[3] = {0.0, 0.0 , 0.0};
float totalLiters = 0.0;
float auxVol = 0.0;
float pumpFlowLow = 2.0; // ***Check Value info added June 2021
int rawDp[3] = {0, 0 , 0};
int rawDpMin = 32;
int rawDpMax[3] = {0, 243 , 187}; // values changed in rev 2_A
int levelDp[3] = {0, 0 , 0};
int levelDpLow = 30; // critical level in %
int levelDpMin = 20; // minimal level in %
int levelDpWarning = 50; // warning leval in %
int cisternaRxLossTime; // current time (in sec) when Cisterna RX loss happened
int caixaRxLossTime; // current time (in sec) when caixa RX loss happenend
int currentTime; // current time (in sec) of internal clock
float Irms = 0.0;
float current = 0.0;
float DpFilter = 0.0; // filter Dp in mmca
float DpFilter_max = 700.0; // was 600.0 changed in July 2023 (better display in Bar Graph)
float kFilter;
float Pinlet = 0.0;
float PinletLow = 1.0; // Changed in rev 3A- this variable has no useful purpose
float lampCurrent = 0.0;
float lampCurrentLow = 0.1;
float dummy1 = 0.0;
float dummy2 = 0.0;
bool dummy3 = LOW;
float dummy4 = 0.0;
uint32_t packetReceived[3] = {0,0,0}; // 1= cisterna, 2= caixa Jan 2024
uint32_t packetReceivedOld[3] = {0,0,0};
uint32_t nPacketsLost[3] = {0,0,0};
bool faultStatus = LOW;
bool warningStatus = LOW;
bool ackAlarmStatus = LOW;
bool delayRunning = LOW;
bool pump_State = LOW;
bool last_Pump_State = LOW;
bool flowDelay = LOW;
bool clearDataFlag = true; // Feb 2024 check if we will decide to clear the current values of buffers
bool cisternaRxLoss = false; // this is used to change text colour to yellow
bool caixaRxLoss = false;
bool buzzer_ON_OFF_Toggle = LOW; //is buzzer ON or OFF
bool buzzer_Status = LOW;
bool levelWarningStatus = LOW;
int x = 1;
unsigned long t1;
unsigned long t2;
//----FlowMin[]--------CHECK ACTUAL VALUES MEASURED BY THE FLOW SENSORS!!!-----------------
// average flowrate to reservoir 1 is 4.0 l/min --- let's set the alarm @ 50% of normal flowrate, so flowMin[1] = 2.0
// Calculated flowrate for the installed pump is 20 l/min --- let's set the alarm @ 50% of normal flowrate, so flowMin[2] = 10.0
float flowMin[3] = { 0.0 , 1.3 , 10.0 }; // minimum flow values used to trigger alarm condition // <=======Min flow changed to 1.3
//----Toggle button & Misc stuff----
int buzzerState=0;
int alarm_Button_New;
int alarm_Button_Old=1;
//???int ack_Button_New;
//???int ack_Button_Old=1;
int dt=100;
bool fault_ID[12] = {0,0,0,0,0,0,0,0,0,0,0,0 }; // revised March 2024
bool fault_ID_Old[12] = {0,0,0,0,0,0,0,0,0,0,0,0}; // revised March 2024
unsigned long fault_ID_millis[6] = {0,0,0,0,0,0};
unsigned long time_between_failures = 3600000;
int i= 1;
//------ Set s flag to define if Debug messages should be sent to Seria Port (active HIGH)
bool serialPrintFlag = true; // <================================= Set DEBUG flag here
// Set a Flag to simulate that data is being received (active HIGH)
bool simulateInputData = LOW; // <================================ Use this to input data to the sketch
//------Define Pin numbers for buttons & LEDs
const int pump_On_Pin = 26;
const int alarm_On_Pin = 12;
const int alarm_Toggle_Button_Pin = 13;
const int ack_Alarm_Button_Pin = 33;
const int buzzerPin = 25;
const int fault_Led_Pin = 27;
const int warning_Led_Pin = 14;
//------Display without delay variables and definitions-------------------
unsigned long previousLCDMillis = 0; // for LCD screen update
unsigned long lcdInterval = 10000;
int screen = 0;
int screenMax = 2; //was 1 changed in July 2023
bool screenChanged = true; // initially we have a new screen, by definition
// defines of the screens to show
#define PROCESS_VARIABLES 0
#define DISPLAY_FAULTS 1
#define DRAW_GRAPH 2
// Define RCT variables added DEc 2022
float dummyTime;
int hVal;
int minVal;
// ------BarGraph variables and initial calculations--------
int valueBlock[4];
int posBlock[4];
int prevPosBlock[4];
uint16_t blockColor;
// Editable Variables
bool displayValues = true; // EDIT - Display Value of Blocks?
uint16_t graphColor = TFT_BLUE; // EDIT - Prefered Colour of Graph
//??? uint16_t blockColor = TFT_GREEN; // EDIT - Prefered Colour of Blocks <===== Bars can be green, yellow or red depending on value
String graphBlock[] = {"Cst", "Cx", "l/m", "DP" }; // EDIT - Names of Blocks
int graphRange = 100; // EDIT - Max possible number of block, eg Potentiometer = from 0 to 1024, so 1024 <==Changed to 100 (graphs in %)=======
int numberOfBlocks = 4; // EDIT - Number of Blocks to display
int dx= 52; // move x axis information to the right to correct display error
//-- calculate graph parameters-----
const int numberOfMarks = (numberOfBlocks * 2); // calculates amount of lines that mark x axis
const int originX = 52; // the origin of the graph on the x axis // Chosen value
const int originY = 280; // the origin of the graph on the y axis // ==> 320 (Height) -50 (for the Graph title) = 270
const int sizeX = 180; // the size of the chart on the x axis (lenght) // ==> 240 (width) - 60 (for the y axis value) = 180
const int sizeY = 230; // the size of the chart on the y axis (height) // ==> 320 (height) - 40 (for the Graph title) - 50 (for the Graph title) = 230
int boxSize = (sizeX / numberOfMarks); // calculates the size between the marks
int mark[] = {(dx+boxSize), (dx+boxSize * 2), (dx+boxSize * 3), (dx+boxSize * 4), (dx+boxSize * 5), (dx+boxSize * 6), (dx+boxSize * 7), (dx+boxSize * 8)}; // calculates the position of the marks
const int minorSizeY = (originY + 10); // calculates the y origin of the marks
const int minorSizeX = (originX - 10); // calculates the x origin of the numbers
//??? int numberSize = (sizeY / 6); // calculates the size between the numbers
//??? int number[] = {numberSize, (numberSize * 2), (numberSize * 3), (numberSize * 4), (numberSize * 5), (numberSize * 6)}; // calculates the position of the numbers
//??? int numberValue = (graphRange / 6); // calculates the value per number
//??? int val[] = {graphRange, (numberValue * 5), (numberValue * 4), (numberValue * 3), (numberValue * 2), numberValue}; // calculates the value of each number
// change y marks from 6 to 5
int numberSize = (sizeY / 5); // calculates the distance between each Y axis div
int number[] = {numberSize, (numberSize * 2), (numberSize * 3), (numberSize * 4),(numberSize * 5)}; // calculates the position of Y axis divisions
int numberValue = (graphRange / 5); // calculates the value of one Y axis div
int val[] = {graphRange, (numberValue * 4), (numberValue * 3), (numberValue * 2), numberValue}; // Y axis values
void setup() //-------------SETUP-------------------------------
{
// ----define Led pins as outputs
pinMode(alarm_On_Pin, OUTPUT);
pinMode(pump_On_Pin, OUTPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(alarm_Toggle_Button_Pin, INPUT_PULLUP);
pinMode(ack_Alarm_Button_Pin, INPUT_PULLUP);
pinMode(warning_Led_Pin, OUTPUT);
pinMode(fault_Led_Pin, OUTPUT);
// it seems that Arduino IDE does not define the pins as outputs so we do it manuallly here
pinMode(TFT_CS, OUTPUT);
digitalWrite(TFT_CS, HIGH);
pinMode(RF24_CSN, OUTPUT); // check if it is required
pinMode(RF24_CE, OUTPUT); // check if it is required
digitalWrite(RF24_CSN, HIGH); // check if it is required
//-----Start Serial Communication-------
Serial.begin(115200); // start serial communication
//-----Start TFT, set rotation and background color------
tft.init();
tft.setRotation(0);
tft.setTextSize(2);
// -----Start nRF24L01---------
SPI.begin();
radio.begin();
// check if nRF24L01 was initialized on SPI bus (ADDED Jan 2024)
if (!radio.begin()) {
if (serialPrintFlag == true) Serial.println(F("radio hardware is not responding!!"));
//??? tft.fillScreen(TFT_BLACK); // check if it is required
tft.println(F("radio not found"));
delay(2000);
}
//??? network.begin(channel, this_node); //Commented Jan 2024
radio.setPALevel(RF24_PA_HIGH); // Added Jan 2924 ??? Is it valid for an Rx?
radio.setDataRate( RF24_250KBPS ); //added on rev 3C
//########## we will open all pipes to see if we can find two that works #############
radio.openReadingPipe(1,addresses[0]); // All added on Feb 2024
radio.openReadingPipe(2,addresses[1]);
radio.openReadingPipe(3,addresses[2]);
radio.openReadingPipe(4,addresses[3]);
radio.openReadingPipe(5,addresses[4]);
radio.startListening(); //added on rev 3C
//------- Initialize display------------------ Welcome Message----------------------------------------
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_YELLOW);
tft.setTextSize(3);
tft.println(F("Rev4 BarGraph"));
tft.println(F(" "));
tft.println(F("23/03/2024"));
tft.println(F(" "));
tft.println(F("Two Pipes"));
tft.println(F(" "));
delay(2000);
/*
// Check if data input is simulated and print warning message
if (simulateInputData == HIGH)
{ tft.setTextColor(ILI9341_RED);
tft.println(F("DATA READ SIMULATED"));
input_Data();
}
delay(2000);
*/
// Set value for the timers monitoring Cisterna & Caixa data packets were received
startTime = millis(); // start the timer
lastCisternaTime = millis(); // start Cisterna RX timer
lastCaixaTime = millis(); // start Caixa RX timer
/*
// For debugging radio info
if(serialPrintFlag == true){
printf_begin(); // needed only once for printing details
radio.printDetails(); // (smaller) function that prints raw register values
//???? radio.printPrettyDetails(); // (larger) function that prints human readable data // error compiling in laptop
}
*/
} //------ this is the end of Setup
void loop() //-----------------LOOP------------------------------------
{
getRadioData();
// -------Calculate output variables from raw data ---------
levelDp[1] = map(rawDp[1], rawDpMin, rawDpMax[1], 0, 100);
levelDp[2] = map(rawDp[2], rawDpMin, rawDpMax[2], 0, 100);
kFilter = DpFilter / sq(flow[1]) ;
//------Light warning LEDs and Sound Buzzer--------------
Buzzer_and_Leds();
// -----Check if there are abnormal conditions in the system
check_faults();
//---Display data------
display_Data();
// sound buzzer if FAULT 7 had occured ---- Added REv 3A Dez 2021
if (buzzer_ON_OFF_Toggle ==HIGH && levelWarningStatus == HIGH)
{
beep_Buzzer();
}
} //-----------this is the end of the loop
//////////////////////////////////////////////////////////////////////////////////
// getRadioData // get data from transmitters
//////////////////////////////////////////////////////////////////////////////////
void getRadioData(){
if(radio.available(&pipeNum)){
radio.read(&payload,sizeof(payload));
if (pipeNum == 1){ // Changed Jan 2024 check pipe 1 => Cisterna
getCisternaData(); // Changed Jan 2024
}
if (pipeNum == 2){ // Changed Jan 2024 check pipe 2 => Caixa
getCaixaData(); // Changed Jan 2024
}
//--------node connection check----------------
// if the conn with one of the Txs is lost, lastCisternaTime and/or lastCisternaTime
// will NOT BE UPDATED so we can check this to detect a problem
//----Cisterna-----
if ( (millis() - lastCisternaTime) > dataLossTime){
cisternaRxLoss = true;
cisternaRxLossTime = millis()/1000;
if (serialPrintFlag == true){
Serial.print("******Cisterna Conn Failure***** ");
Serial.print(" time= ");
Serial.println(cisternaRxLossTime);
Serial.println("=== Clearing Cisterna Data ===");
clearCisternaData();
}
}
else { cisternaRxLoss = false;}
//----Caixa-----
if ( (millis() - lastCaixaTime) > dataLossTime){
caixaRxLoss = true;
caixaRxLossTime = millis()/1000 ;
if (serialPrintFlag == true){
Serial.print("******Caixa Conn Failure***** ");
Serial.print(" time= ");
Serial.println(caixaRxLossTime);
Serial.println("=== Clearing Caixa Data ===");
clearCaixaData();
}
}
else { caixaRxLoss = false;}
if (serialPrintFlag == true)
{
printSerial_1();
}
}
} // end getRadioData
//////////////////////////////////////////////////////////////////////////////////
// getCisternaData() // get data from Cisterna
//////////////////////////////////////////////////////////////////////////////////
void getCisternaData(){ //####MAJOR CHANGE IN 01/02/2024 ########
// tft.setTextColor(ILI9341_RED); // Commented Jan 2024
//------Read Cisterna Data-------
if(serialPrintFlag == true) Serial.println("------Reading Cisterna Data-----"); // <==================Reading Cisterna Data Message
packetReceived[1] = payload.counter;
//???? if( packetReceived[1] > packetReceivedOld[1] ){
// Check if connection is lost: Caixa data should be updated at last every 60 seconds
if ( (millis() - lastCisternaTime) > dataUpdateTime){
// this is new data
if(serialPrintFlag == true){
Serial.print("-- This is new Data---");
Serial.print(" Time= ");
Serial.println(millis());
}
// update Cisterna Data
Irms = payload.val1;
flow[1] = payload.val2;
Pdisch = payload.val3;
DpFilter = payload.val4;
Pinlet = payload.val5;
lampCurrent = payload.val6;
rawDp[1] = payload.val7;
flapState = payload.val8;
// check how many packets were lost
nPacketsLost[1] = packetReceived[1]- packetReceivedOld[1] ;
lastCisternaTime = millis(); // restart the Cisterna RX timer
packetReceivedOld[1] = packetReceived[1];
clearDataFlag = false;
cisternaRxLoss = false;
} // end of new data based on packet #
else { // some packages were lost!!!
nPacketsLost[2] = packetReceived[2]- packetReceivedOld[2] ;
cisternaRxLoss = true;
if(serialPrintFlag == true){
Serial.print("-- WARNING NUMBER OF PACKETS LOST = ");
Serial.println(nPacketsLost[2]);
}
}
if (serialPrintFlag == true)
{
printCisternaData();
}
} // end getCisternaData
//////////////////////////////////////////////////////////////////////////////////
// getCaixaData() // get data from Caixa
//////////////////////////////////////////////////////////////////////////////////
void getCaixaData(){ //####MAJOR CHANGE IN 01/02/2024 ########
if (serialPrintFlag == true) { Serial.println("---------Reading Caixa Data--------");} //<==================Reading caixa Data Message
packetReceived[2] = payload.counter;
// Check if connection is lost: Caixa data should be updated at last every second
if ( (millis() - lastCaixaTime) > dataUpdateTime){
// this is new data
if(serialPrintFlag == true){
Serial.print("-- This is new Data---");
Serial.print(" Time= ");
Serial.println(millis());
}
// update Caixa Data
auxVol = payload.val1; // this is the batch volume
flow[2] = payload.val2;
totalLiters = payload.val3;
flow[0]= payload.val4; // Chaged in July 2023
dummy1= payload.val5;
dummy2= payload.val6;
rawDp[2] = payload.val7;
dummy3 = payload.val8;
// check how many packets were lost
nPacketsLost[2] = packetReceived[2]- packetReceivedOld[2] ;
packetReceivedOld[2] = packetReceived[2];
lastCaixaTime = millis(); // restart the Caixa RX timer
clearDataFlag = false;
caixaRxLoss = false;
} // end of new data based on packet #
else { // some packages were lost!!!
nPacketsLost[2] = packetReceived[2]- packetReceivedOld[2] ;
caixaRxLoss = true;
if(serialPrintFlag == true){
Serial.print("-- WARNING NUMBER OF PACKETS LOST = ");
Serial.println(nPacketsLost[2]);
}
}
//-------- for Debugging
if (serialPrintFlag == true)
{
printCaixaData();
}
} //--- end of getCaixaData
////////////////////////////////////////////////////////////////////////////
// Display Function
////////////////////////////////////////////////////////////////////////////
// MUST WE SWITCH SCREEN?
void display_Data()
{
unsigned long currentLCDMillis = millis();
if(currentLCDMillis - previousLCDMillis > lcdInterval) // save the last time you changed the display
{
previousLCDMillis = currentLCDMillis;
screen++;
if (screen > screenMax) screen = 0; // all screens done? => start over
screenChanged = true;
}
// DISPLAY CURRENT SCREEN
if (screenChanged) // -- only update the screen if the screen is changed.
{
screenChanged = false; // reset for next iteration
switch(screen)
{
case PROCESS_VARIABLES:
display_variables();
break;
case DISPLAY_FAULTS: // this screen should be displayed only if there are abnormal conditions
if (faultStatus == HIGH || warningStatus == HIGH) display_faults(); // changed March 2024
break;
case DRAW_GRAPH:
drawGraph();
break;
default:
// cannot happen -> showError() ?
break;
}
}
} //--- end of display_data
//////////////////////////////////////////////////////////////////////////////////
// display Variables
//////////////////////////////////////////////////////////////////////////////////
void display_variables()
{
// return background to black (needed after displaying the bargraph) and set cursor
tft.fillScreen(TFT_BLACK); // moved from Cistena March 2024
tft.setCursor(0, 0);
tft.setTextSize(3);
tft.setTextColor(ILI9341_WHITE);
// customize output printing using node id for certain variables
// index 1 2
// place cisterna caixa
dummyTime = Pinlet;
hVal=floor(dummyTime/100.0);
minVal = dummyTime - 100.0*hVal;
if(serialPrintFlag == true) Serial.println("hVal= " + String(hVal) + " minVal= " + String(minVal) );
//***********CISTERNA***********
if (cisternaRxLoss == true) tft.setTextColor(ILI9341_YELLOW);
tft.println("* CISTERNA *");
tft.setTextSize(2);
tft.print("NIVEL= ");
tft.print(levelDp[1]);
tft.println(" %");
tft.print("l/min= ");
tft.println(flow[1]);
if (Irms !=0) // Pump is ON
{
tft.print ("CURR.= ");
tft.print (Irms, 1);
tft.println (" A");
digitalWrite(pump_On_Pin, HIGH);
}
else // Pimp is OFF
{
tft.println("Pump is OFF");
digitalWrite(pump_On_Pin, LOW);
}
tft.print("Flap ");
if (flapState == LOW) tft.println ("CLOSED");
else tft.println("OPEN");
tft.print("Pdisch= ");
tft.println(Pdisch);
tft.println (" ");
tft.print("P_Inlet= ");
tft.println(Pinlet);
tft.print("Dp Filter= ");
tft.println(DpFilter);
kFilter = DpFilter / sq(flow[1]) ; //-------Calculate Filter k ---------
tft.print("K Filter= ");
tft.println(kFilter);
tft.print("UV Lamp (A)= ");
tft.println(lampCurrent);
//********CAIXA**********************
tft.println (" ");
tft.setTextSize(3);
tft.setTextColor(ILI9341_WHITE);
if (caixaRxLoss == true) tft.setTextColor(ILI9341_YELLOW);
tft.println("** CX. SUP **");
tft.setTextSize(2);
tft.print("NIVEL= ");
tft.print(levelDp[2]);
tft.println(" %");
tft.print("l/min= ");
tft.println(flow[2]);
tft.print("ult bomb(l)= ");
tft.println(auxVol);
tft.print("vaz Poço= ");
tft.println(flow[0]);
tft.print("Time= "); // <====== End of pumping cycle Dez 2022
tft.print(hVal);
tft.print(":");
if (minVal <10) tft.print("0");
tft.print(minVal);
tft.setTextColor(ILI9341_WHITE);
} //---- end of display_variables
//////////////////////////////////////////////////////////////////////////////////
// Check Faults -- Identify possible faults in the system and turn alarm ON
//////////////////////////////////////////////////////////////////////////////////
void check_faults(){
faultStatus = LOW;
warningStatus = LOW; //-------------Added in Rev1 01/09/2019
// Start the pump cavitation/low flow check
pump_State = LOW;
// check if PUMP has been turned on and start flow delay timer
if (Irms > 0.0)
{
pump_State = HIGH;
if (pump_State == HIGH && last_Pump_State == LOW)
{
pumpOnMillis = millis();
last_Pump_State = HIGH;
flowDelay = HIGH;
}
if ((millis() - pumpOnMillis) > pumpOnDelay) flowDelay = LOW; // this is HIGH while waiting to purge air from pump discharge pipe
} // do this if pump is ON ONLY
else last_Pump_State = LOW;
//++++++++++++++++++++++++++++++++++Should be used for debug only+++++++++++++++++++++++++++
/*
Serial.println ("---------------------------------Faults---------------------------------------");
Serial.println("checking pump State & Delay ");
Serial.println("FAULT 1 & 2----- Nivel Baixo nivel cisterna= " + String(levelDp[1]) + " nivel caixa= " + String(levelDp[2]));
Serial.println("FAULT 3----- vaz mininha vaz minima= " + String(flow[1]));
Serial.println("FAULT 4----- UV Failure Lamp Current= " + String(lampCurrent));
Serial.println("FAULT 5------Pump Protection Failure Irms " + String(Irms) + " Nivel Cisterna= " + String(levelDp[1]));
Serial.println("FAULT 6----- RF LINK LOSS Cisterna " +String(cisternaRxLoss) + " Caixa " + String(caixaRxLoss));
Serial.println("-----------------------------------Warnings-----------------------------------");
Serial.println("fault 7------Check Level nivel cisterna= " + String(levelDp[1]) + " nivel caixa= " + String(levelDp[2]));
Serial.println("fault 8------High Filter DP Filter DP= " + String(DpFilter));
Serial.println("fault 9------No Flow with Pump ON Irms= " + String(Irms) + " pumpOnMills= " + String(pumpOnMillis) + " flowDelay= "+ String(flowDelay));
Serial.println("flaut 10-----Flap closed & pump ON Irms= " + String(Irms) + " flapState= " + String(flapState));
*/
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// FAULT 1 --- low level in reservoir 1 (Cisterna)
if ( levelDp[1] < levelDpLow) {
faultStatus = HIGH;
fault_ID[1] = HIGH;
}
else {
faultStatus = LOW;
fault_ID[1] = LOW;
}
// FAULT 2 --- Low level in reservoir 2 (Caixa)
if (levelDp[2] < levelDpLow ) {
faultStatus = HIGH;
fault_ID[2] = HIGH;
}
else {
faultStatus = LOW;
fault_ID[2] = LOW;
}
// FAULT 3 --- Low flow to reservoir 1 (Cisterna)
if ( flow[1] <= flowMin[1] ){
faultStatus = HIGH;
fault_ID[3] = HIGH;
}
else {
faultStatus = LOW;
fault_ID[3] = LOW;
}
// FAULT 4--- UV Lamp Current too low
if ( lampCurrent < lampCurrentLow ){
faultStatus = HIGH;
fault_ID[4] = HIGH;
}
else {
faultStatus = LOW;
fault_ID[4] = LOW;
}
// FAULT 5 -- Pump on with low level in reservoir 1
if ( Irms > 0.0 && levelDp[1] <= levelDpMin) {
faultStatus = HIGH;
fault_ID[5] = HIGH;
}
else {
faultStatus = LOW;
fault_ID[5] = LOW;
}
// FAULT 6 ---RF Link Loss //Added in June 2021
if ( caixaRxLoss == HIGH || cisternaRxLoss == HIGH )
{
faultStatus = HIGH;
fault_ID[6] = HIGH;
}
else {
faultStatus = LOW;
fault_ID[6] = LOW;
}
// -----This is the beginning of the warnings section-------------------------------
// FAULT 7 -- Level in Reservoirs 1 or 2 below normal
if ( levelDp[1] <= levelDpWarning || levelDp[2] <= levelDpWarning)
{
if ( fault_ID[1] == LOW && fault_ID[2] == LOW ) // check if the levels are NOT in the VERY LOW condition to set Warning
{
warningStatus = HIGH;
levelWarningStatus = HIGH;
fault_ID[7] = HIGH;
}
}
else {
levelWarningStatus = LOW;
fault_ID[7] = LOW;
}
//FAULT 8 -- Pressure drop very high in Filter
if ( DpFilter > DpFilter_max ){
warningStatus = HIGH;
fault_ID[8] = HIGH;
}
else {
levelWarningStatus = LOW;
fault_ID[8] = LOW;
}
// FAULT 9 -- low or no flow (after 60 sec) with pump on
if (Irms > 0.0 && flowDelay == LOW && flow[2] <= flowMin[2]){
warningStatus = HIGH;
fault_ID[9] = HIGH;
}
else {
levelWarningStatus = LOW;
fault_ID[9] = LOW;
}
// FAULT 10 -- Flap closed with pump ON
if ( Irms > 0.0 && flapState == LOW){
warningStatus = HIGH;
fault_ID[10] = HIGH;
}
else {
levelWarningStatus = LOW;
fault_ID[10] = LOW;
}
// FAULT 11 (old definition) --- Filter Inlet Pressure too low (air in pipe)
// ----This Warning was delete since it makes no sense
// FAULT 11 (New definition) -- Pump Cavitation ( Pump ON AND (low Pdisch OR low flow to reservoir 2 )
//--- first implementation in JUNE 2021--- check if works before adding to critical faults
if ( Irms > 0.5 && ( Pdisch <= PdischLow || flow[2] <= pumpFlowLow )) {
warningStatus = HIGH;
fault_ID[11] = HIGH;
}
else {
levelWarningStatus = LOW;
fault_ID[11] = LOW;
}
// --- Check if there are faults and/or warnings and turn ON the corresponding LEDs
if( warningStatus == HIGH ) digitalWrite(warning_Led_Pin, HIGH);
else digitalWrite(warning_Led_Pin, LOW);
if( faultStatus == HIGH) digitalWrite(fault_Led_Pin, HIGH);
else digitalWrite(fault_Led_Pin, LOW);
if (serialPrintFlag == true)
{
Serial.println ("---------------------------Fault Status Indicators-------------------------");
Serial.println ("faultStatus= " +String(faultStatus));
Serial.println ("warningStatus= " +String(warningStatus));
}
} // ----- end of check faults
//////////////////////////////////////////////////////////////////////////////////
// Display Faults -- Display the faults in the system
//////////////////////////////////////////////////////////////////////////////////
void display_faults(){
// Prepare display to show faults
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(0 ,0);
tft.setTextColor(ILI9341_RED); tft.setTextSize(2);
//RF link loss is the most critical fault so other faults related to zero value variables makes no sense
// So this will be the first fault to be checked
// FAULT 6 ---RF Link Loss //Added in June 2021
if (fault_ID[6] == HIGH){
if ( caixaRxLoss == HIGH ){
tft.println("**CAIXA LINK LOSS**");
tft.print(" time= ");
tft.println(caixaRxLossTime);
tft.print(" currentTime= ");
currentTime=millis()/1000;
tft.println(currentTime);
tft.println(" ");
}
if ( cisternaRxLoss ==HIGH ){
tft.println("***CIST LINK LOSS***");
tft.print(" time= ");
tft.println(cisternaRxLossTime);
tft.print(" currentTime= ");
currentTime=millis()/1000;
tft.println(currentTime);
tft.println(" ");
}
}
// FAULT 1 --- low level in reservoir 1 (Cisterna)
if (fault_ID[1] == HIGH){
tft.println("VERY LOW LEVEL IN");
tft.print("Cisterna = ");
tft.print(levelDp[1]);
tft.println(" %");
tft.println(" ");
}
// FAULT 2 --- Low level in reservoir 2 (Caixa)
if (fault_ID[2] == HIGH){
tft.println("VERY LOW LEVEL IN");
tft.print("Caixa Sup = ");
tft.println(levelDp[2]);
tft.println(" %");
tft.println(" ");
}
// FAULT 3 --- Low flow to reservoir 1 (Cisterna)
if (fault_ID[3] == HIGH){
tft.println("LOW FLOW TO CISTERNA");
tft.print("Flow(l/m) = ");
tft.println (flow[1]);
tft.println(" ");
}
// FAULT 4--- UV Lamp Current too low
if (fault_ID[4] == HIGH){
tft.println("LOW UV LAMP CURRENT");
tft.print("lampCurrent = ");
tft.print (lampCurrent);
tft.println(" A");
tft.println(" ");
}
// FAULT 5 -- Pump on with low level in reservoir 1
if (fault_ID[5] == HIGH){
tft.println("PUMP PROTECTION FAILURE");
tft.print("level = ");
tft.print(levelDp[1]);
tft.println(" %");
tft.println(" ");
}
// -----This is the beginning of the warnings section-------------------------------
// Change Text colour to yellow
tft.setTextColor(ILI9341_YELLOW);
// FAULT 7 -- Level in Reservoirs 1 or 2 below normal
if (fault_ID[7] == HIGH){
tft.println("CHECK LEVEL");
if (levelDp[1] <= levelDpWarning)
{
tft.print("Cisterna= ");
tft.print(levelDp[1]);
tft.println(" %");
}
if (levelDp[2] <= levelDpWarning)
{
tft.print("Caixa= ");
tft.print(levelDp[2]);
tft.println(" %");
tft.println(" ");
}
}
//FAULT 8 -- Pressure drop very high in Filter
if (fault_ID[8] == HIGH){
tft.println("HIGH FILTER DP");
tft.print("DpFilter = ");
tft.println (DpFilter);
tft.println(" ");
}
// FAULT 9 -- low or no flow (after 60 sec) with pump on
if (fault_ID[9] == HIGH){
tft.println("PUMP LOW FLOW FAIL");
tft.print("Flow(l/min) = ");
tft.println(flow[2]);
tft.println(" ");
}
// FAULT 10 -- Flap closed with pump ON
if (fault_ID[10] == HIGH){
tft.println("FLAP CLOSED FAILURE");
tft.print("Flow(l/m) = ");
tft.println(flow[2]);
tft.print("Current= ");
tft.print(Irms, 1);
tft.println(" A");
tft.println(" ");
}
// FAULT 11 (New definition) -- Pump Cavitation ( Pump ON AND (low Pdisch OR low flow to reservoir 2 )
//--- first implementation in JUNE 2021--- check if works before adding to critical faults
if (fault_ID[11] == HIGH){
tft.println("PUMP CAVITATION");
tft.print("Pdisch = ");
tft.println (Pdisch);
tft.print("Vazao(l/m) = ");
tft.println (flow[2]);
tft.println(" ");
}
/* // NO NEED TO PRINT THIS MESSAGE AFTER THE BARGRAPH IMPLEMENTATION
// Changed in the July 2023 Rev - no need to Clear screen, just display the "no faults detected" message
//If no faults were detected, print message
if (faultStatus == LOW && warningStatus == LOW) {
//??? tft.fillScreen(ILI9341_BLACK); //commented out in July 2023
tft.setCursor(4, 0); // changed July 2023
tft.setTextColor(ILI9341_GREEN); tft.setTextSize(3);
tft.println("NO FAULTS");
tft.println("DETECTED");
delay(1000); // Added in Rev 3C ***Check if it is required
}
*/
} //--- end of display_faults()
////////////////////////////////////////////////////////
// beep_Buzzer
///////////////////////////////////////////////////////
void beep_Buzzer(){
t2=millis();
if (t2-t1 >=2000)
{
x=1-x;
t1=millis();
digitalWrite(buzzerPin,x);
if (serialPrintFlag == true)Serial.println ("millis= " +String(millis())+ " x= " + String(x));
}
}
//////////////////////////////////////////////////////////////////////////////////
// input_Data()
//////////////////////////////////////////////////////////////////////////////////
// &&&&& USE FOR DEBUGGING ONLY &&&&&&&&&&
// Use this fuction to input data to the receiver to test code
void input_Data(){
/*
Serial.println(" Simulating Operation ");
tft.setTextColor(ILI9341_RED);
tft.setTextSize(3);
tft.print("Simulating Operation");
delay (1000);
*/
// Values that will be used as received
//------Cisterna------------
Serial.println(" Cisterna Data ");
Irms = 0.0; // Pump OFF
flow[1] = 2.0; // Normal Contition
Pdisch = 2.6; // Pump OFF
DpFilter = 100.0; // Norm =100, max= 600
Pinlet = 856.0; // This variable is used for time. Value = 100*hour + minutes
lampCurrent = 0.17; // Lamp ON
rawDp[1] = 200; // Normal Operation (Max=243 , warrning=50%, Low=30%, min= 20%)
flapState = HIGH; // Pump OFF
cisternaRxLoss = LOW; // Cisterna RF Link OK
//-------Caixa-------------
Serial.println(" Caixa Data");
auxVol = 0.0; // Not used for alarms ==>his is the batch volume
flow[2] = 2.1; // min= 2.0
totalLiters = 0.0; // Not used for alarms
flow[0]= 7.6; // Added in July 2023 (vazao do poço)
dummy1= 0.0; // Not used for alarms
dummy4= 0.0; // Not used for alarms
rawDp[2] = 170; // Normal Operation (Max=187 , warrning=50%, Low=30%, min= 20%)
dummy3 = LOW;
caixaRxLoss = LOW; // Caixa RF Link OK
//??? clearDataFlag = false; // check if required
// Print values used in this simulation
Serial.println ("clearDataFlag= " + String(clearDataFlag));
Serial.println ("levelDp[1]= " + String(levelDp[1]));
Serial.println ("levelDp[2]= " + String(Irms));
Serial.println ("Irms= " + String(Irms));
Serial.println ("rawDp[1]= " + String(rawDp[1]));
Serial.println ("Pdisch= " + String(Pdisch));
Serial.println ("DpFilter= " + String(DpFilter));
Serial.println ("Pinlet= " + String(Pinlet));
Serial.println ("kFilter= " + String(kFilter));
Serial.println ("auxVol= " + String(auxVol));
Serial.println ("flow[2]= " + String(flow[2]));
Serial.println ("totalLiters= " + String(totalLiters));
Serial.println ("lampCurrent= " + String(lampCurrent));
} // This is the end of input_Data
////////////////////////////////////////////////////////////////////////////
// Buzzer_and_Leds()
////////////////////////////////////////////////////////////////////////////
//-----------Check buttons, Light Led's & sound buzzer when required
void Buzzer_and_Leds(){
// Toggle BUZZER ON/OFF and display LED status accordingly
alarm_Button_New = digitalRead(alarm_Toggle_Button_Pin);
if(alarm_Button_Old == 0 && alarm_Button_New == 1)
{
if (buzzer_ON_OFF_Toggle == LOW)
{
digitalWrite(alarm_On_Pin,HIGH);
buzzer_ON_OFF_Toggle = HIGH;
tft.fillScreen(ILI9341_BLACK); // used in test alarm
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_RED); tft.setTextSize(3);
tft.println("BUZZER IS ON");
}
else
{
digitalWrite(alarm_On_Pin, LOW);
buzzer_ON_OFF_Toggle = LOW;
tft.fillScreen(ILI9341_BLACK); // used in test alarm
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_RED); tft.setTextSize(3);
tft.println("BUZZER IS OFF");
}
}
alarm_Button_Old=alarm_Button_New;
delay(dt);
} // this is the end of buzzer & LEDs function
///////////////////////////////////////////////////////////////
// drawGraph()
/////////////////////////////////////////////////////////////
void drawGraph()
{
// initial definitions
tft.init();
tft.setRotation(0);
tft.fillScreen(TFT_WHITE);
// draw title
tft.setCursor(10, 10);
tft.setTextColor(TFT_BLUE);
tft.setTextSize(2);
tft.println(F("Lvls,Flow & DP (%)"));
tft.print(F("l/m= "));
tft.print(flow[1]);
tft.print(F(" DP= "));
tft.println(DpFilter);
// draw outline
tft.drawLine(originX, originY, (originX + sizeX), originY, graphColor);
tft.drawLine(originX, originY, originX, (originY - sizeY), graphColor);
// draw lables
for(int i = 0; i < numberOfMarks; i++)
{
tft.drawLine(mark[i], originY, mark[i], minorSizeY, graphColor);
}
// draw label names
for(int i = 0; i < numberOfMarks; i += 2)
{
tft.setCursor((mark[i] + 6), (originY + 10));
tft.setTextColor(graphColor);
tft.setTextSize(2);
tft.println(graphBlock[i / 2]);
}
// draw numbers
for(int i = 0; i < 5; i++) // was 6
{
tft.drawLine(originX, (originY - number[i]), minorSizeX, (originY - number[i]), graphColor);
}
// draw values of Y axis marks
// for some reason numbers are in the wrong position
//let's add a "correction offset" as was done in the X axis
int dy =-46; // worked!
for(int i = 0; i < 5; i++) // was 6
{
tft.setCursor((minorSizeX - 30), (number[i] + numberSize +dy));
tft.setTextColor(graphColor);
tft.setTextSize(1);
tft.println(val[i]);
}
/*
// get the values of the sensors <========== COMMENT THIS SECTION AFTER TESTING=================================
valueBlock[0] = map(analogRead(A14),0,1024,0,100);
valueBlock[1] = map(analogRead(A15),0,1024,0,100);
valueBlock[2] = map(analogRead(A14),0,1024,0,100);
valueBlock[3] = map(analogRead(A15),0,1024,0,100);
*/
// get the value of the variables to be displayed
valueBlock[0] = levelDp[1];
valueBlock[1] = levelDp[2];
valueBlock[2] = map(flow[1],0,6,0,100); // Assumed max lowrate = 6.0 l/min
valueBlock[3] = map(DpFilter,0,700,0,100); // Assumed Dp_max= 700 mmH2O
// map the sensor values to the graph size
for(int i = 0; i < numberOfBlocks; i++)
{
posBlock[i] = map(valueBlock[i], 0, graphRange, originY, (originY - sizeY));
}
// draw the blocks - draw only if value differs and select colour <===== This was changed
for(int i = 0; i < numberOfBlocks; i++)
{
// The blocks need to be drawn ALWAYS
//??? if(posBlock[i] > (prevPosBlock[i] + 2) || posBlock[i] < (prevPosBlock[i] - 2))
//??? {
prevPosBlock[i] = posBlock[i];
tft.fillRect((mark[i * 2] + 1), (originY - sizeY), (boxSize - 1), sizeY, TFT_WHITE);
// for levels and flow, low values should be RED for Filter DP high values are RED and low values are GREEN
if (i<=2)
{
if ( valueBlock[i] >= 50 ) blockColor = TFT_GREEN;
if ( valueBlock[i] < 50 && posBlock[i] >= 30) blockColor = TFT_YELLOW;
if (valueBlock[i] < 30 ) blockColor = TFT_RED;
}
else
{
if ( valueBlock[i] >= 50 ) blockColor = TFT_RED;
if (valueBlock[i] < 30 ) blockColor = TFT_GREEN;
}
tft.fillRect((mark[i * 2] + 1), posBlock[i], (boxSize - 1), (originY - posBlock[i]), blockColor);
//??? }
}
// display values of sensors if mode selected
if(displayValues)
{
for(int i = 0; i < numberOfMarks; i += 2)
{
tft.setCursor((mark[i] + 5), (originY - 20));
tft.setTextColor(TFT_BLACK, TFT_WHITE); // changed
tft.setTextSize(2);
tft.println(valueBlock[i / 2]);
}
}
} // --- end of drawGraph
/*
// THIS FUNCTION WAS USED DURING THE DEVELOPMENT OF THE CODE AND NO LONGER IS REQUIRED
///////////////////////////////////////////////////////////////
// checkPipe -------- check if there is data available in a pipe and read it
/////////////////////////////////////////////////////////////
// source: https://raspberrypi.stackexchange.com/questions/37033/nrf24l01-multiple-transmitters-one-receiver
void checkPipe()
{
//??? uint8_t pipeNum; //<-------- moved to global variable
if(radio.available(&pipeNum)){
radio.read(&payload,sizeof(payload));
Serial.print("Got data on pipe= ");
Serial.println(pipeNum);
}
}
*/
///////////////////////////////////////////////////////////////
// printSerial_1 -------- check if there is data available in a pipe and read it
/////////////////////////////////////////////////////////////
void printSerial_1()
{
Serial.print("---------getting radio data from pipe= ");
Serial.print(pipeNum);
Serial.println(" -----------------------");
Serial.print("----time = ");
Serial.println(millis());
Serial.print("val0= ");
Serial.println(payload.counter);
Serial.print("val1= ");
Serial.println(payload.val1);
Serial.print(" val2= ");
Serial.println(payload.val2);
Serial.print(" val3= ");
Serial.println(payload.val3);
Serial.print(" val4= ");
Serial.println(payload.val4);
Serial.print(" val5= ");
Serial.println(payload.val5);
Serial.print(" val6= ");
Serial.println(payload.val6);
Serial.print(" val7= ");
Serial.println(payload.val7);
Serial.print(" val8= ");
Serial.println(payload.val8);
}
///////////////////////////////////////////////////////////////
// printCisternaData -------- check if there is data available in a pipe and read it
/////////////////////////////////////////////////////////////
void printCisternaData()
{
Serial.println("----------Cisterna Data----------- ");
Serial.print("packetReceivedOld[1]= ");
Serial.println(packetReceivedOld[1]);
Serial.print("packetReceived[1]= ");
Serial.println(packetReceived[1]);
Serial.print("nPacketsLost[1]= ");
Serial.println(nPacketsLost[1]);
Serial.print("val0= ");
Serial.println(payload.counter);
Serial.print("val1= ");
Serial.println(payload.val1);
Serial.print(" val2= ");
Serial.println(payload.val2);
Serial.print(" val3= ");
Serial.println(payload.val3);
Serial.print(" val4= ");
Serial.println(payload.val4);
Serial.print(" val5= ");
Serial.println(payload.val5);
Serial.print(" val6= ");
Serial.println(payload.val6);
Serial.print(" val7= ");
Serial.println(payload.val7);
Serial.print(" val8= ");
Serial.println(payload.val8);
Serial.print("cisternaRxLoss ");
Serial.println(cisternaRxLoss);
Serial.print(" millis= ");
Serial.println(millis());
Serial.print(" lastCisternaTime= ");
Serial.println(lastCisternaTime);
}
///////////////////////////////////////////////////////////////
// printCisternaData -------- check if there is data available in a pipe and read it
/////////////////////////////////////////////////////////////
void printCaixaData()
{
Serial.println("-------Caixa Data------- ");
Serial.print("packetReceivedOld[2]= ");
Serial.println(packetReceivedOld[2]);
Serial.print("packetReceived[2]= ");
Serial.println(packetReceived[2]);
Serial.print("nPacketsLost[2]= ");
Serial.println(nPacketsLost[2]);
Serial.print("val0= ");
Serial.println(payload.counter);
Serial.print("val1= ");
Serial.println(payload.val1);
Serial.print(" val2= ");
Serial.println(payload.val2);
Serial.print(" val3= ");
Serial.println(payload.val3);
Serial.print(" val4= ");
Serial.println(payload.val4);
Serial.print(" val5= ");
Serial.println(payload.val5);
Serial.print(" val6= ");
Serial.println(payload.val6);
Serial.print(" val7= ");
Serial.println(payload.val7);
Serial.print(" val8= ");
Serial.println(payload.val8);
Serial.print("caixaRxLoss ");
Serial.println(caixaRxLoss);
Serial.print(" millis= ");
Serial.println(millis());
Serial.print(" lastCaixaTime= ");
Serial.println(lastCaixaTime);
}
//////////////////////////////////////////////////////////////////////
// clearCisternaData() used to clear data in case of communication failure with Cistena node
////////////////////////////////////////////////////////////////////
void clearCisternaData()
{
Irms = 0.0;
flow[1] = 0.0;
Pdisch = 0.0;
DpFilter = 0.0;
Pinlet = 0.0;
lampCurrent = 0.0;
rawDp[1] = 0;
flapState = LOW;
hVal = 0;
minVal = 0;
}
//////////////////////////////////////////////////////////////////////
// clearCaixaData() used to clear data in case of communication failure with caixa node
////////////////////////////////////////////////////////////////////
void clearCaixaData()
{
auxVol = 0.0;
flow[2] = 0.0;
totalLiters = 0.0;
flow[0]= 0.0;
dummy1= 0.0;
dummy4= 0.0;
rawDp[2] = 0;
dummy3 = LOW;
}