Esp32 serial monitor not working [SOLVED]

Hi,
I am using the DoIt esp32 dev kit rev1 board.
for some reason the messages that should be printed to the Serial monitor using the Serial.print command are not being dysplayed in the console window.
However, when I reboot the board some info is displayed.
At the end of this data there is a note that seems to indicate that there is some kind of error.
Also, the nRF24L01 begin() function returns an error.
Any hel would be welcome.
The info screen printed is copied below:

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4604
ho 0 tail 12 room 4
load:0x40078000,len:15488
load:0x40080400,len:4
load:0x40080404,len:3180
entry 0x400805b8
[     4][D][esp32-hal-cpu.c:264] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
=========== Before Setup Start ===========
Chip Info:
------------------------------------------
  Model             : ESP32
  Package           : D0WD-Q6
  Revision          : 1.00
  Cores             : 2
  CPU Frequency     : 240 MHz
  XTAL Frequency    : 40 MHz
  Features Bitfield : 0x00000032
  Embedded Flash    : No
  Embedded PSRAM    : No
  2.4GHz WiFi       : Yes
  Classic BT        : Yes
  BT Low Energy     : Yes
  IEEE 802.15.4     : No
------------------------------------------
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   383520 B ( 374.5 KB)
  Free Bytes        :   352956 B ( 344.7 KB)
  Allocated Bytes   :    23384 B (  22.8 KB)
  Minimum Free Bytes:   347444 B ( 339.3 KB)
  Largest Free Block:   114676 B ( 112.0 KB)
------------------------------------------
Flash Info:
------------------------------------------
  Chip Size         :  4194304 B (4 MB)
  Block Size        :    65536 B (  64.0 KB)
  Sector Size       :     4096 B (   4.0 KB)
  Page Size         :      256 B (   0.2 KB)
  Bus Speed         : 80 MHz
  Bus Mode          : DIO
------------------------------------------
Partitions Info:
------------------------------------------
                nvs : addr: 0x00009000, size:    20.0 KB, type: DATA, subtype: NVS
            otadata : addr: 0x0000E000, size:     8.0 KB, type: DATA, subtype: OTA
               app0 : addr: 0x00010000, size:  1280.0 KB, type:  APP, subtype: OTA_0
               app1 : addr: 0x00150000, size:  1280.0 KB, type:  APP, subtype: OTA_1
             spiffs : addr: 0x00290000, size:  1408.0 KB, type: DATA, subtype: SPIFFS
           coredump : addr: 0x003F0000, size:    64.0 KB, type: DATA, subtype: COREDUMP
------------------------------------------
Software Info:
------------------------------------------
  Compile Date/Time : Oct  9 2024 21:13:47
  Compile Host OS   : windows
  ESP-IDF Version   : v5.1.4-828-g33fbade6b8-dirty
  Arduino Version   : 3.0.5
------------------------------------------
Board Info:
------------------------------------------
  Arduino Board     : ESP32_DEV
  Arduino Variant   : doitESP32devkitV1
  Arduino FQBN      : esp32:esp32:esp32doit-devkit-v1:FlashFreq=80,UploadSpeed=921600,DebugLevel=debug,EraseFlash=none
============ Before Setup End ============
[   800][E][esp32-hal-cpu.c:121] addApbChangeCallback(): duplicate func=0x400d9810 arg=0x3ffbdc40
[   809][D][esp32-hal-spi.c:185] spiDetachBus(): Stopping SPI bus
radio hardware is not responding!!
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4604
ho 0 tail 12 room 4
load:0x40078000,len:15488
load:0x40080400,len:4
load:0x40080404,len:3180
entry 0x400805b8
[     4][D][esp32-hal-cpu.c:264] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
=========== Before Setup Start ===========
Chip Info:
------------------------------------------
  Model             : ESP32
  Package           : D0WD-Q6
  Revision          : 1.00
  Cores             : 2
  CPU Frequency     : 240 MHz
  XTAL Frequency    : 40 MHz
  Features Bitfield : 0x00000032
  Embedded Flash    : No
  Embedded PSRAM    : No
  2.4GHz WiFi       : Yes
  Classic BT        : Yes
  BT Low Energy     : Yes
  IEEE 802.15.4     : No
------------------------------------------
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   383520 B ( 374.5 KB)
  Free Bytes        :   352956 B ( 344.7 KB)
  Allocated Bytes   :    23384 B (  22.8 KB)
  Minimum Free Bytes:   347444 B ( 339.3 KB)
  Largest Free Block:   114676 B ( 112.0 KB)
------------------------------------------
Flash Info:
------------------------------------------
  Chip Size         :  4194304 B (4 MB)
  Block Size        :    65536 B (  64.0 KB)
  Sector Size       :     4096 B (   4.0 KB)
  Page Size         :      256 B (   0.2 KB)
  Bus Speed         : 80 MHz
  Bus Mode          : DIO
------------------------------------------
Partitions Info:
------------------------------------------
                nvs : addr: 0x00009000, size:    20.0 KB, type: DATA, subtype: NVS
            otadata : addr: 0x0000E000, size:     8.0 KB, type: DATA, subtype: OTA
               app0 : addr: 0x00010000, size:  1280.0 KB, type:  APP, subtype: OTA_0
               app1 : addr: 0x00150000, size:  1280.0 KB, type:  APP, subtype: OTA_1
             spiffs : addr: 0x00290000, size:  1408.0 KB, type: DATA, subtype: SPIFFS
           coredump : addr: 0x003F0000, size:    64.0 KB, type: DATA, subtype: COREDUMP
------------------------------------------
Software Info:
------------------------------------------
  Compile Date/Time : Oct  9 2024 21:13:47
  Compile Host OS   : windows
  ESP-IDF Version   : v5.1.4-828-g33fbade6b8-dirty
  Arduino Version   : 3.0.5
------------------------------------------
Board Info:
------------------------------------------
  Arduino Board     : ESP32_DEV
  Arduino Variant   : doitESP32devkitV1
  Arduino FQBN      : esp32:esp32:esp32doit-devkit-v1:FlashFreq=80,UploadSpeed=921600,DebugLevel=debug,EraseFlash=none
============ Before Setup End ============
[   800][E][esp32-hal-cpu.c:121] addApbChangeCallback(): duplicate func=0x400d9810 arg=0x3ffbdc40
[   809][D][esp32-hal-spi.c:185] spiDetachBus(): Stopping SPI bus
radio hardware is not responding!!

how have you connected the nRF24L01 to the ESP32 - upload a schematic showing wiring?
upload code?

It would be good to see that note.
Is it by any chance
“No DFU”?

If so look at this page:-
No DFU capable USB device avaliable

Continuing the discussion from Esp32 serial monitor not working:

I think is about that last bit.

I think it would be good to see the code and the wiring.

Here is the code

#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_1
//  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
// ========NO NEED FOR THAT ANYMORE, SINCE WE ARE USING PIPES AND VARIABLES WILL BE CHANGED TO uint16_t =========
// 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
};
*/

//====================== NEW ========================================

//The data to be transmitted by lower and upper water tanks modules is:
//         type       cisterna     caixa superior
//        -------    ----------    --------------
//  0      uint32_t    counter         counter  (number of packets transmitted)  
//  1      int16_t     Irms_i          auxVol_i   (last pumping cycle volume)
//  2      int16_t     flow_i          flow_i
//  3      int16_t     Pdisch_i        totalLiters_1_i
//  4      int16_t     DpFilter_i      vazaoPoco_i // changed in July 2023
//  5      int16_t     Pinlet_i        pumpStopTime // format=> 100* now.hour() + now.minute()  March 2024 
//  6      int16_t     lampCurrent_i   dummy4  //added in March 2021
//  7      int16_t     rawDp           rawDp   
//  8      bool      flapstate         dummy3

// Structure of our payload, limited to 32 bytes
struct payload_t      // 32 bytes max,  used= 4+7*2+1= 19 bytes OK! October 2024
{
  uint32_t  counter;    // - 4 bytes number of packets transmitted
  int16_t     val1;     // - 2 bytes
  int16_t     val2;     // - 2 bytes
  int16_t     val3;     // - 2 bytes
  int16_t     val4;     // - 2 bytes
  int16_t     val5;     // - 2 bytes
  int16_t     val6;     // - 2 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_1 = 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; changed to PumpStopTime     Oct 2024
//???float dummy2 = 0.0; changed to dummy4        oct 2024
bool  dummy3 = LOW;
int16_t dummy4 = 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};

//---- define the new int16_t variables used for data transmission
//--caixa-----
   int16_t auxVol_i;
   int16_t totalLiters_1_i;
   int16_t flow_i[3];  // used for cisterna also
   int16_t pumpStopTime;
//--Cisterna
   int16_t Irms_i;
   int16_t Pdisch_i;
   int16_t DpFilter_i;
   int16_t Pinlet_i;
   int16_t lampCurrent_i;
   
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 Serial Port (active HIGH)
bool serialPrintFlag = HIGH;  //   <================================= 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("2 pipes + Integer"));
  tft.println(F(" "));
  tft.println(F("22/09/2024"));
  tft.println(F(" "));
  tft.println(F("rev 0"));
  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);  // <======    Change his to the 1rst time when conn was lost
      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 (ATTENTION!! ALL VALUES ARE INTEGERS NOW!!!
    Irms_i    =     payload.val1;
    flow_i[1] =     payload.val2;
    Pdisch_i =      payload.val3;
    DpFilter_i =    payload.val4;
    Pinlet_i   =    payload.val5;
    lampCurrent_i = payload.val6;
    rawDp[1] =      payload.val7;
    flapState =     payload.val8;

 // Convert integers to float values as in original code
    Irms     = Irms_i/10.0;
    flow[1]  = flow_i[1]/10.0;
    Pdisch   = Pdisch_i/10.0;
    DpFilter = DpFilter_i/10.0;
    Pinlet   = Pinlet_i/10.0;
    lampCurrent = lampCurrent_i/100.0; // this value is<1 so scale factor must be 100
    
// 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 (ATTENTION!! ALL VALUES ARE INTEGERS NOW!!!   
    auxVol_i  =        payload.val1;   // this is the batch volume 
    flow_i[2] =        payload.val2;
    totalLiters_1_i =  payload.val3;
    flow_i[0]=         payload.val4;  // Chaged in July 2023
    pumpStopTime=      payload.val5;
    dummy4=            payload.val6;
    rawDp[2] =         payload.val7;
    dummy3 =           payload.val8;

 // Convert integers to float values as in original code
    auxVol         = auxVol_i/10.0;
    flow[2]        = flow_i[2]/10.0;
    totalLiters_1  = totalLiters_1_i/10.0;
    flow[0]        = flow_i[0]/10.0;
    pumpStopTime   = pumpStopTime/10.0;
    
 
// 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_1 = 0.0;   // Not used for alarms 
    flow[0]=      7.6;   // Added in July 2023 (vazao do poço)
    pumpStopTime= 0.0;   // Not used for alarms
    dummy4=       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_1= " + String(totalLiters_1));
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_1 = 0.0;   
    flow[0]=      0.0;
    pumpStopTime=       0.0;  
    dummy4=       0;   
    rawDp[2] =    0;
    dummy3 =      LOW;    
}

And the wiring.
It must be something very stupid since this code has worked previosly on this same hardware.
I made some changes and lost track of the revisions, so I can't go back to the working code and compare.

[Esquema Receptor ESP32 Jan 2024.pdf|attachment](upload://chSIhQW7qBJ5gCA63y40jpkf1pc.pdf) (415.8 KB)



were both the TFP and NEF24 working at the same time without problems?

if not maybe simpler to connect the TFT to VSPI and the NRF24 to HSPI

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!!"));  // this line is being executed 
                                             // and shows in the serial monitor !!
//???   tft.fillScreen(TFT_BLACK); // check if it is required
   tft.println(F("radio not found"));

So hold on, you start Serial, and it actually works !


// 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);

You never tell the TFT library that it should use that pin as a CS pin, and moreover, you never set it LOW, to enable the TFT. Yet you decide to just write to it

 tft.println(F("radio not found"));

If you have 2 devices on the same SPI bus, you should switch the CS pin manually to make sure that only 1 of them is active at the same time.

Anyway i am confident that your issue is with SPI not with Serial, because that works, but you crash the ESP32 because you use SPI incorrectly. There are 2 SPI busses available on an ESP32, but some libraries are not capable of using the alternate bus.

Could you still add the wiring diagram ?

Thank you for the replies.
I though I had include the wiring diagram, but I am not sure if I did it right.
I will try again.
Esquema Receptor ESP32 Jan 2024.pdf (415.8 KB)

The tft display pins are defined in the user setup file of the library

They are ? well can you share where that is done and how and how the CS pin is handled. Maybe the whole init() function. Normally a library like that will use the default SPI port and it's default pins, but will let you choose the CS pin, which is considered GPIO 5 for VSPI default that you are connecting the other SPI pins to.
But you are sharing the SPI bus which is fine, and the CS pins can be any pin, but you should switch them manually.
Before any call to the tft object do

digitalWrite(RF24_CE, HIGH);
digitalWrite(TFT_CS, LOW);

and switch it the other way after.

digitalWrite(TFT_CS, HIGH);
digitalWrite(RF24_CE, LOW);

So keep in mind that a CS pin on almost any SPI device (actually i think it's all but who knows what people come up with) is in fact inverse logic. Setting the pin LOW makes the SPI device active.
You should never have more than 1 SPI device active on the same bus !! You may have damaged the MISO pins of the SPI devices, but maybe you are lucky because the tft will never send a response, and actually i think it may never be enabled.

  tft.init();
  tft.setRotation(0);  
  tft.setTextSize(2);

 // -----Start nRF24L01---------
  SPI.begin();
  radio.begin();

SPI.begin() is redundant is this case, i am fairly sure that tft.init() has already done that, and who knows how the CS pins is identif7ied by the radio library.

Not really, you can upload a picture using the upload tab, but pdf is not a format that will display as a picture, like PNG does, so that means i had to download it. Not the best, but i think my conclusions are valid.

So...
Show us (me) the init() / begin() function and the constructor of both the tft library and the radio library that actually contains the object declaration (or whatchamaycallit)

RF24 radio(RF24_CE,RF24_CSN); 

Are they ? well i don't have that file.

As i said before, the ESP32 has 2 SPI busses available, so if it is possible to pass a pointer to the SPI object to the library used, you may be able to use both of them which can significantly speed things up. As may increasing the SPI speed from it's default speed, but that does depend on the speed of the used devices involved.

Thank you for the replies.
I have no training on C++.
All the codes I have "developed" are based on my previous experince with Fortran IV... they were assembled using snippets and tutorial available from the internet.
So I do not understand your request about object declaration.
Can you provide more "basic level" instructions?

Another point: The display is working , switching the screens as expected, but the ESP32 (wich acts as a receiver) can't get any values.
Also, the Serial.print() instructions which should help me to find the problem does not work also.
is this information useful for narrowing down the problem?
Thanks

I suspected as much, you have gotten quite far, but this is something that we deal with quite a lot, and somehow you did get quite far.

More basic no. Not if you want me to talk about code that is part of the project. I am no pro, and i sometimes get terminology wrong, but let me try and explain.
The libraries you use contain a lot of info, but their basis is that you have a class, and you declare an object of that class. An object is a bit lie a variable type, but with that type you can also call a whole bunch of function and reference variables that are part of that class.

RF24 radio(RF24_CE,RF24_CSN); 

This declares an object of the RF24 class, and calls it 'radio'
Within any class there is a constructor of the class, and a destructor. The constructor contain whatever need to be done to initiate the object, set values for variables sometimes as a consequence of it arguments. In this case to pin numbers are referenced. A constructor can also be empty, as can be the destructor, which in many case it is with arduino. The program is never really terminated, and most classes expect objects to be declared statically as is the case here.
The object is then actually started with a different function which does a few procedures of some kind.
Sometimes within the object declaration or the begin() or init() member functions there are arguments which have been given default values, and that could also be passed along, i am looking for options within the library, but you know it can be quite search, and i want you to do that part of the work.
So more basic, no not really. I mean of course i am looking for conflicts.
edit: i am also looking for ways to use the othe SPI bus with that same library for the hardware you have.

Anyway, i did have a quick look if i could find the TFT_eSPI.h and if this is the same as what you are using, then i don't know if the correct part in User_Setup.h is commented out.
And i don't think that the CS pin is switched on your behalf after the call to init() in which it might be set, but again, there is no guarantee and i don't want to be sifting through those files to verify that.

What i did find in User_Setup.h is

#define SPI_FREQUENCY  27000000

and that may not be overruled later by

SPI.begin();

I am not sure, i know the pin allocations may be overwritten (on an ESP32 you can set the SPI pins to any pin with a MUX) but i don't know about the speed and whether the RF24 is running within range. Most likely though, you need to disable the tft screan by setting the TFT_CS pin HIGH before you make calls to the RF24. Those libraries rarely do switch the CS pins HIGH after use themselves. And you can't have 2 SPI devices enabled on the same bus ! You can make them share a bus, but you have to enable and disable them yourself. Try that !

Thank you very much for your detailed explanation Deva_Rishi
I am still intrigued by the fact that I have this setup (two arduinos Promicro sending data to the ESP32) working in my country house 24/7 for a long time...
As it happens, from time to time, I decide to make improvements in the code.
I have been doing this for more than 4 years (no changes in the ESP32 hardware)
Maybe some of the libraries have changed and the problem appeared after I updated them.
But let's stay objective... there is a message informing that the spi bus is crashing, but how come the display is working?
I might try to change the nRFL01 to the HSPI bus as you suggested, but I will have to stop working on this until next wednesday.
I will post the results when I come back.
Thanks

T

Or more likely you have upgraded the core and some of the libraries do not work with the newer core. What core are you using now (there have been quite a few reports from core 3.x.x not working with older code)

The display is working until then. The SPI bus gets shut down and pretty much straight away the ESP reboots.
Possibly as a consequence of the attempt to start the RF24, while the TFT is still enabled and on the bus.

Did i miss this information somewhere earlier in the thread or are you only now informing us ?

Have you tried my suggestion from post #11 switching the CS pins manually ? I suspect that the RF24 will actually initiate properly once the TFT has been disabled.

It may be tricky or complex to modify the library to accept a pointer to the SPI object. You may also not want to modify it at all so unless it has the option included (like for instance the SD library has) that may not be the way to go.

I have not tried it, mostly because I am not sure how to do it.

1 - Does it mean that I have to turn CSN pin LOW at the beginning of the functions that use the radio, turning it HIGH at the exit
and turning display CS HIGH at the beginning of each display function call turning it LOW at the function end.
And do this at EVERY radio and display function calls?
Is this understanding correct?

2 - I am suspecting the problem is related to another issue
Look at this message "[ 800][E][esp32-hal-cpu.c:121] addApbChangeCallback(): duplicate func=0x400d9810 arg=0x3ffbdc40

Can you explain what it means?
Is it possible the the code is no longer capable to override some default pin assignment due to revisions on it?

PS I google it and found that tft-eSPI can generate the error addApbChangeCallback(): duplicate func when using with TFT_eSPI #462 (using SDFat library)
see( addApbChangeCallback(): duplicate func when using with TFT_eSPI · Issue #462 · greiman/SdFat · GitHub)
It seems to be related to pin assignment, but I will have to spend some (a lot of) time trying to understand it

Not quite. Both CS pins are active LOW, which means that setting the pin LOW enables the device and setting it HIGH disables it. So you got it right for the radio, but inverted for the TFT.
The CS pin usually just gets set LOW on init() or begin() by the library and left alone after that. There seems to be the option of defining it as a 'Shared SPI bus' in at least the TFT library, but i tend to just do it myself. If you don't trust others to do it properly, better do it yourself.

Not quite. The ESP somehow has 2 callback functions for same event ? hmm strange, It is a run-time error though, so i don't know exactly. The ESP32 core has quite a lot of pre-compiled parts and some of the SPI parts are.

Well something similar is probably happening here.
so anyway, just try this for me for the moment in this section of code

//-----Start Serial Communication-------
  Serial.begin(115200); // start serial communication
 

//-----Start TFT, set rotation and background color------
  tft.init();
  tft.setRotation(0);  
  tft.setTextSize(2);
  digitalWrite(TFT_CS, HIGH);  // add this line
 // -----Start nRF24L01---------
  // SPI.begin();     // comment this out, SPI has been initiated already by the TFT library
  digitalWrite(RF24_CE, LOW);   // add this line
  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!!"));  // this line is being executed 
                                             // and shows in the serial monitor !!
      digitalWrite(RF24_CE,HIGH);   // add this line
     digitalWrite(TFT_CS, LOW);  // add this line 
//???   tft.fillScreen(TFT_BLACK); // check if it is required
   
   tft.println(F("radio not found"));
   delay(2000);
    digitalWrite(TFT_CS, HIGH);  // add this line
    digitalWrite(RF24_CE, LOW);   // add this line
   }
  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();    
    digitalWrite(RF24_CE,HIGH);   // add this line
     digitalWrite(TFT_CS, LOW);  // add this line 

tft.setCursor(0, 0);
  tft.setTextColor(ILI9341_YELLOW);  
  tft.setTextSize(3);
  tft.println(F("2 pipes + Integer"));
  tft.println(F(" "));
  tft.println(F("22/09/2024"));
  tft.println(F(" "));
  tft.println(F("rev 0"));
  tft.println(F(" "));
  delay(2000);

And see if there is a clear difference. I am fairly confident the radio now should start, but i am of course not sure.
Could you provide me with a link to the RF24.h library ? Because it seems it may want to be connected to the SPI bus permanently, and in that case the use of both busses is the better way.

within the TFT library there seems to be a way to use HSPI, but i have no idea how to initiate it

// ESP32 specific SPI port selection
#ifdef USE_HSPI_PORT
  #ifdef CONFIG_IDF_TARGET_ESP32
    #define SPI_PORT HSPI  //HSPI is port 2 on ESP32
  #else
    #define SPI_PORT 3     //HSPI is port 3 on ESP32 S2
  #endif

if you #define USE_HSPI_PORT somewhere (maybe in User_Setup.h) it should start using that, but i had problems with the default pins (12, 13 & 14) for using it, though you may not have. I think there is a pulldown on GPIO12 or something, since it's a strapping pin.

The rf24 library is from thmr20.
It can be found on github and downloaded from the ide.
I will try this change of code this weekend but I have some domestic repairs to do also.
I read in a post from a sd card library forum that the spi parameters used by rf24 library are “locked” by the library.
They proposed a solution using the spi.begintransaction with the required parameyers and spi.endtransaction each time the radio and the display functions are called.
( I am not sure the names ate correct).
I will have to sped time to find out what are the correct parameters for the rf24 and TFT_eSPI libraries.
Do you have any idea of where I can find them?

i would start by looking at the .h file, i found a hardware specific file for the TFT library (i think i linked that already) you should be looking for the functions. Easiest is to use notepad++, just load a bunch of files to sift through and use the find function of notepad++ you can look for any keyword through all open files if you have to.

Hi,
I have been out for a while, but now I had the time to try Deva_Rishi's suggestion .
Unfortunately I am still getting the "RADIO NOT FOUND" message.
Any ideas?