Void loop() stops for a few minutes, when Serial Monitor closed

I've an ESP32-S3 Zero using it's 'native' serial port pins, connected to a GY-GPS6MV2 gps module. IE. UART0 Tx and UART0 Rx.

A nRF23L01 module (on SPI) transmits the gps data, once a second.

The ESP32 USB port is connected to a laptop for programming/monitoring as normal, with Arduino IDE. (V2.3.8)

The data is received on another nRF24L01 - Arduino PRO Mini, connected to another laptop some feet away, which just displays what it receives in a PuTTY terminal screen.

The Tx program was being tested and 'all working fine', until I closed the Serial Monitor. I just happened to notice, the data was no longer being received.
At this stage, I had removed all the print statements as they were only in for testing purposes. So although Serial Monitor was still running, IE. showing what happens during the boot process (debug level in the IDE), it wasn't actually printing anything from the program.

So I re-opened the Serial Monitor again, and it immediately started Txing data again. Close it and it stops sending the data. Huh?

If the IDE is shut down. It stops Txing.

I then stumbled upon it starting up again on its own after around 4 to 5 minutes.??
Then carries on 'working perfectly'.

I put a test bit in the free running loop to flash the onboard led once a second using the millis() timer. The led stops flashing (stays on or off, whichever state it is in when the Serial Monitor is closed. So it looks like the main loop is just not being processed.

The led also starts to flash again, when the Txing re-starts after a few minutes.

There are no error messages.
Any ideas?

PS. Altimately this is not a problem, as it won't be connected to a laptop normally. I just wondered WTF is going on?

I've included the program here FWIW.

// nRF_S3_Collar02 has original print routine removed [displayGPSData();]
// nRF_S3_Collar01  Has gps working and pushing data into nRF registers.


// GY-GPS is modified from 9600 to 38400 baud
// XIAO_ESP32-C3 need to declare Tx,Rx pins, -S3 Zero has native pins for UART0.

String sketchName ="nRF_S3_Collar01";

#include <TinyGPSPlus.h>
#include <HardwareSerial.h>

HardwareSerial GPSserial(0);  // S3 has native pins for Tx,Rx

const byte address[6] = "00069";  // Address of this nRF24L01   "00001"; was BogBot

TinyGPSPlus gps;       // GPS data decoder

#include <SPI.h>
#define SCK  13  
#define MISO 12  
#define MOSI 11  
#define SS   10  // (CSN)  

#include <RF24.h>
RF24 radio(9, 10); // CE, CSN  (9,10)  CE=Mode Tx or Rx , CSN = SS

///+++++++++++++++++++++++
// #define RGB_BUILTIN 21  // It doesn't like this and calls it a re-definition
//+++++++++++++++++++++++

int counter02,toggleLED;
unsigned long timer00,timer01;
int GPSsecondMem,toggle,oneShot;
byte txGPSData[32];
//  Copy GPS data into Long Ints to manipulate for nRF. It can only send 32 bytes (max) at a time.
long dayLong,monthLong,yearLong,hourLong,minuteLong, secondLong,latLong,longLong;  // use for structure 



void setup() 
{
   Serial.begin(115200);  //USB port - serial monitor
   
   GPSserial.begin(38400,SERIAL_8N1); // Use default pins on S3
// GPSserial.begin(38400,SERIAL_8N1,RX_PIN,TX_PIN );  // GPS serial port specific TxRx pins

  delay(2000);
  Serial.println(); Serial.println(sketchName); Serial.println();

  SPI.begin(SCK,MISO,MOSI,SS);    // Specific pin declare / enable
  radio.begin();                  // Starting the Wireless communication

  radio.openWritingPipe(address); // Address to send the data to
  radio.setPALevel(RF24_PA_MAX);  //You can set it as MIN,LOW,HIGH or MAX
  //                                LOW  3.55 V  @ 2hrs
  //                                HIGH 3.50 V  @ 2hrs
  //                                MAX
  radio.setDataRate(RF24_250KBPS);  //Need to check this out!!! (also 1MBPS or 2MBPS)
  radio.stopListening();            //This sets the module as transmitter
  
 // rgbLedWrite(RGB_BUILTIN, 1, 1, 1);  // seems to get rid of an error issue

}

void loop()
{
    // Get GPS data and send to TinyGPS to decode
    while (GPSserial.available() > 0) {
    char c = GPSserial.read();
    gps.encode(c);

  }


//++++++++++++++++++++++++++++++++++++++++++ LED added for testing ++++++++++++++++++++++++
  if (millis() > timer01) 
  {
      timer01 = millis() + 1000;

    toggleLED = !toggleLED;
  if (toggleLED == 0)
  {
    rgbLedWrite(RGB_BUILTIN, 0, 0, 150);   // Blue    (G,R,B)
  }
  else
  {
     rgbLedWrite(RGB_BUILTIN, 0, 0, 0);   // Blue    (G,R,B)  Off
  }

  } // endof if (millis() > timer01) 
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


  if (gps.time.isValid()) { // When time data valid, start 1 second updates

    if (GPSsecondMem != gps.time.second()){   // Do it once a second
        GPSsecondMem = gps.time.second();
        // 
        assignGPSData();  // Copy TinyGPSPlus derived values into Long Int format variables
        groupGPSData();   // Fill Tx array
        radio.write(&txGPSData, sizeof(txGPSData));  //Array is written to the radio module to send





    }
  }
   
}  // endof void loop()



// Subroutines
void assignGPSData()
{
secondLong =  gps.time.second();
minuteLong = gps.time.minute();
hourLong =  gps.time.hour();
dayLong = gps.date.day();
monthLong = gps.date.month();
yearLong = gps.date.year();
latLong = gps.location.lat() * 100000;  // Retain 5 decimals
longLong = gps.location.lng() * 100000; // Retain 5 decimals
// gps.satellites.value()
// gps.altitude.meters()
// gps.hdop.value()
// gps.speed.kmph()
// gps.course.deg()

} // endof void assignGPSData()



//++++++++++++++++++
void groupGPSData () {


// if (gps.date.isValid()) {

long tmp,tmp2,startValue;
int startGPSDat,digitPlaces;
byte tmp3;          // force value to a byte
int digitPrint = 0; // count number of array digits to print
txGPSData[0] = 0;   // Keep this for possible future paging of data
//                     txGPSData[30] is used for a sign value for lat and long values.
//                     bit 0 is latitude -ve, bit 1 is longitude -ve

// Set signDigit for lat and long values
byte signDigit = 0;
if (latLong < 0){
  bitSet (signDigit,0);  // set bit 0 = 1 if latitude -ve
  latLong = latLong * -1;
}

if (longLong < 0){
  bitSet (signDigit,1);  // set bit 1 = 1 if longitude -ve
  longLong = longLong * -1;
}

txGPSData[30] = signDigit; // sign status data


// ++ fill nRF data array ++

// +++  hour   +++
startGPSDat = 1;  // txGPSData[x] start value ( Start at 1, possibly use [0] for data paging)
digitPlaces = 2;  // number of digits in value eg year 2026 will be 4
startValue = hourLong; // set the starting value

digitPlaces = digitPlaces - 1;          // Setup values for handling routine
digitPrint = digitPrint + digitPlaces;  // Setup values for handling routine

do { //                                 // Start of handling routine
  float b =  digitPlaces ;
  float a = 1 * pow(10, b);
tmp = a ; // back to a long
tmp3 = startValue /  tmp;   
txGPSData[startGPSDat] = tmp3;

startValue =  startValue - (tmp3 * tmp); 
digitPlaces = digitPlaces - 1;
startGPSDat = startGPSDat + 1;

} while (digitPlaces >= 0);




// +++  minutes   +++
//startGPSDat = 4;  // txGPSData[x] start value
digitPlaces = 2; // number of digits in value eg year 2026 will be 4
startValue = minuteLong; // set the starting value
digitPlaces = digitPlaces - 1;
digitPrint = digitPrint + digitPlaces;

do {
  float b =  digitPlaces ;
  float a = 1 * pow(10, b);
tmp = a ; // back to a long
tmp3 = startValue /  tmp;   
txGPSData[startGPSDat] = tmp3;

startValue =  startValue - (tmp3 * tmp); 
digitPlaces = digitPlaces - 1;
startGPSDat = startGPSDat + 1;

} while (digitPlaces >= 0);

// ++++++++++++++++++++++++++++++++++++++++++++++


// +++  seconds   +++
//startGPSDat = 4;  // txGPSData[x] start value
digitPlaces = 2; // number of digits in value eg year 2026 will be 4
startValue = secondLong; // set the starting value
digitPlaces = digitPlaces - 1;
digitPrint = digitPrint + digitPlaces;

do {
  float b =  digitPlaces ;
  float a = 1 * pow(10, b);
tmp = a ; // back to a long
tmp3 = startValue /  tmp;   
txGPSData[startGPSDat] = tmp3;

startValue =  startValue - (tmp3 * tmp); 
digitPlaces = digitPlaces - 1;
startGPSDat = startGPSDat + 1;

} while (digitPlaces >= 0);




// +++  day   +++
//startGPSDat = 6;  // txGPSData[x] start value
digitPlaces = 2; // number of digits in value eg year 2026 will be 4
startValue = dayLong; // set the starting value
digitPlaces = digitPlaces - 1;
digitPrint = digitPrint + digitPlaces;

do {
  float b =  digitPlaces ;
  float a = 1 * pow(10, b);
tmp = a ; // back to a long
tmp3 = startValue /  tmp;   
txGPSData[startGPSDat] = tmp3;

startValue =  startValue - (tmp3 * tmp); 
digitPlaces = digitPlaces - 1;
startGPSDat = startGPSDat + 1;

} while (digitPlaces >= 0);



// +++  month   +++
//startGPSDat = 8;  // txGPSData[x] start value
digitPlaces = 2; // number of digits in value eg year 2026 will be 4
startValue = monthLong; // set the starting value
digitPlaces = digitPlaces - 1;
digitPrint = digitPrint + digitPlaces;

do {
  float b =  digitPlaces ;
  float a = 1 * pow(10, b);
tmp = a ; // back to a long
tmp3 = startValue /  tmp;   
txGPSData[startGPSDat] = tmp3;

startValue =  startValue - (tmp3 * tmp); 
digitPlaces = digitPlaces - 1;
startGPSDat = startGPSDat + 1;

} while (digitPlaces >= 0);



//  ++++  year   +++++
//startGPSDat = 10;                  // txGPSData[x] start value
digitPlaces = 4;                  // number of digits in value eg year 2026 will be 4
startValue = yearLong;            // set the starting value
digitPlaces = digitPlaces - 1;    // Preset digits
digitPrint = digitPrint + digitPlaces;

do {
  float b =  digitPlaces ;
  float a = 1 * pow(10, b);
tmp = a ; // back to a long
tmp3 = startValue /  tmp;   
txGPSData[startGPSDat] = tmp3;

startValue =  startValue - (tmp3 * tmp); 
digitPlaces = digitPlaces - 1;
startGPSDat = startGPSDat + 1;

} while (digitPlaces >= 0);



//  ++++  latitude   +++++
//startGPSDat = 14;                  // txGPSData[x] start value
digitPlaces = 7;                  // number of digits in value eg year 2026 will be 4
startValue = latLong;            // set the starting value
digitPlaces = digitPlaces - 1;    // Preset digits
digitPrint = digitPrint + digitPlaces;

do {
  float b =  digitPlaces ;
  float a = 1 * pow(10, b);
tmp = a ; // back to a long
tmp3 = startValue /  tmp;   
txGPSData[startGPSDat] = tmp3;

startValue =  startValue - (tmp3 * tmp); 
digitPlaces = digitPlaces - 1;
startGPSDat = startGPSDat + 1;

} while (digitPlaces >= 0);



//  ++++  longitude   +++++
//startGPSDat = 22;                  // txGPSData[x] start value
digitPlaces = 7;                  // number of digits in value eg year 2026 will be 4
startValue = longLong;            // set the starting value
digitPlaces = digitPlaces - 1;    // Preset digits
digitPrint = digitPrint + digitPlaces;

do {
  float b =  digitPlaces ;
  float a = 1 * pow(10, b);
tmp = a ; // back to a long
tmp3 = startValue /  tmp;   
txGPSData[startGPSDat] = tmp3;

startValue =  startValue - (tmp3 * tmp); 
digitPlaces = digitPlaces - 1;
startGPSDat = startGPSDat + 1;

} while (digitPlaces >= 0);






// ++++++   print results   ++++++
/*

for (int x=1 ; x< (sizeof(txGPSData)); x++)  // was for (int x=1 ; x< (startGPSDat); x++)
{
  Serial.print(txGPSData[x]);
}

 Serial.println();  //Serial.println(txGPSData[30]);
*/


// } // endof if (gps.date.isValid() && gps.time.isValid()) {

  

} // endof void groupGPDData () {




any reason not to use Serial1 for the GY-GPS6MV2 and use Serial for debugging messages?

e.g. test of Serial1 ob the ESP32S3 zero

// ESP32-S3 ZERO  Serial1 test - for loopback test connect pin GPIO8 U1TXD to pin GPIO7 U1RXD"
// note on the Zero Serial is on the TX and RX pins
// NOTE: does not work with USB enable "USB CDC on Boot

#define RXD1 7
#define TXD1 8

void setup() {
  // initialize both serial ports:
  Serial.begin(115200);   // note Serial is on the TX and RX pins NOT the USB
  Serial1.begin(9600, SERIAL_8N1, RXD1, TXD1);
  Serial.println();
  Serial.println("\n\nESP32-S3 ZERO serial1  test pin GPIO8 U1TXD pin GPIO7 U1RXD");
  Serial.write("   for loopback test connect pin GPIO8 U1TXD to pin GPIO7 U1RXD\n");
}

void loop() {
  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
   // Serial.print("\nSerial1 = ");
    Serial.write(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    //Serial.write(inByte);
    Serial1.write(inByte);
  }
}

loopback test serial monitor output

ESP32-S3 ZERO serial1  test pin GPIO8 U1TXD pin GPIO7 U1RXD
   for loopback test connect pin GPIO8 U1TXD to pin GPIO7 U1RXD
ioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii1234567890

I thought the USB on an S3 was separate to U0TXD / U0RXD.

Having just googled it for this board, it looks like I was wrong. That would also go a long way in explaining what is happening.

So your suggestion to use Serial(1) and defining some other pins is an option.
Although, I can just leave it as it is. At least 'we know' now.

Thanks.