Indefinite Hanging When Serial Monitor Disconnected

I am having an issue with a simple clock program I am writing for my ArduinoMKRZERO. The entire program runs as expected when connected to the Arduino serial monitor, but I am trying to implement a headless mode so that I can start the Arduino without having it connected to a PC.

I have set a simple timeout for waiting for a serial connection, and a boolean that gets set when the timeout expires so that any serial commands are skipped. Anytime I test the program without the serial monitor connected, it hangs indefinitely as soon as (I assume) the timeout expires. After this hang, the Arduino IDE hangs whenever I attempt to use serial communication. Presumably because of the MKR's Serial port being busy or hung.

I cannot for the life of me figure out what could be causing this, and hope that you can help. Relevant sections of code follow:

bool head = true;

void setup() {
  
  DEBUG_SERIAL.begin(115200); //Start Debug serial
  unsigned long start = millis();
  while(!DEBUG_SERIAL)         //Wait until the serial port is opened with a 5 second timeout
  {
    if (millis() - start > 5000){
    head = false;
      break;
      }
  }

if( head == true ){
  if(!Clock.begin()) {
        DEBUG_SERIAL.println("Couldn't find RTC!");
        DEBUG_SERIAL.flush();
        while (1) delay(10);
    }

  DEBUG_SERIAL.print("RTC Time: "); //Print current RTC time
  DEBUG_SERIAL.print(Clock.now().hour());
  DEBUG_SERIAL.print(":");
  DEBUG_SERIAL.print(Clock.now().minute());
  DEBUG_SERIAL.print(":");
  DEBUG_SERIAL.println(Clock.now().second());

  DEBUG_SERIAL.println("Set RTC Clock, enter invalid times to skip");

  DEBUG_SERIAL.print("Enter Hour (0-23): ");
  while (!DEBUG_SERIAL.available());
    int hour = DEBUG_SERIAL.parseInt();
    Serial.read();
  DEBUG_SERIAL.println(hour);

  DEBUG_SERIAL.print("Enter Minute (0-59): ");
  while (!DEBUG_SERIAL.available());
    int minute = DEBUG_SERIAL.parseInt();
    Serial.read();
  DEBUG_SERIAL.println(minute);

  DEBUG_SERIAL.print("Enter Second (0-59): ");
  while (!DEBUG_SERIAL.available());
    int second = DEBUG_SERIAL.parseInt();
    Serial.read();
  DEBUG_SERIAL.println(second);

  DateTime set = DateTime(2022, 1, 1, hour, minute, second);

  if(set.isValid())
  Clock.adjust(set);

  DEBUG_SERIAL.print("RTC Time Set: "); //Print current RTC time
  DEBUG_SERIAL.print(Clock.now().hour());
  DEBUG_SERIAL.print(":");
  DEBUG_SERIAL.print(Clock.now().minute());
  DEBUG_SERIAL.print(":");
  DEBUG_SERIAL.println(Clock.now().second());
}

What is DEBUG_SERIAL defined as?

I guess I'd have written it like this but I don't see that yours is wrong:

while(!DEBUG_SERIAL && millis() < 5000UL) ; //Wait until the serial port is opened with a 5 second timeout 
if ( !DEBUG_SERIAL ) head = false;

Flash a led at various places in the code to see how far it gets before getting stuck .

For boards with native USB that are externally powered but also at occasion have the data connection, you will need to take the following into account

  1. while(!Serial) will block the start of your sketch; you have solved that with the timeout :+1:
  2. Once a communication channel was detected, it will never be forgotten. So if(Serial) will not affect your code.
  3. Once the communication channel is lost because you disconnected the USB, the microprocessor can't get rid of the data that you print; [edit]that's the root cause of your problem[/edit]. So you should print conditionally.
// check if here is space in the serial output buffer
if(Serial.availableForWrite() > 60)
{
  // you can print
}
else
{
  // do not print
}

The 60(1) is a randomly choosen number. You should actually determine how much is printed (e.g. an uint16_t is max 5 characters, an int16_t will be a max of 6 characters (as it can include the minus sign). You should also take into account possible line endings.

(1)
You can determine the size of the serial output buffer by printing Serial.availableForWrite() in a test sketch.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.