Leonardo while(!Serial) problem

Hello !

For a project I need to emulate a USB keyboard and so I'm using an Arduino Leonardo.
For different reasons, I need to use the serial port through the USB port at the same time.
I've read a lot of posts on the internet that encourage me to be wary of this type of configuration: they're right! :wink:

Here are two sources that should do more or less the same thing:

  • the first waits 10 seconds, continues, ... and everything works!
  • the second waits for the port to open, ... and loops ad infinitum! :frowning:
    I must have missed something!
void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  bool serialIsOpen = Serial;
  delay(10000);
  Serial.println(serialIsOpen);
  Serial.println(Serial);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop() {
  // nothing
}

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  bool serialIsOpen = Serial;
  while (!Serial) {
    ;
  }
  Serial.println(serialIsOpen);
  Serial.println(Serial);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop() {
  // nothing
}

An idea ?

Thanks a lot !

PS : To complete, the second source is unlocked if you open the serial monitor ...

1 Like

Arduino - MouseKeyboard

That answers a problem in another (unknown) thread. The

while (!Serial) ;

should be used only if connection to the Serial Monitor is crucial. Otherwise it only blocks the program start for no good reason.

you can try

void setup() {
    while (!Serial) ;
   Serial.begin(115200);

No, it loops until the serial connection gets available (as you also write in the next post).

As you didn't write yet, what intention you had to use these two types of initialization we don't know what hints to give to you.

If you need the serial connection in your sketch to work for it's functionality, the second option should be used. If you just want to avoid printing anything to the serial interface if nobody is listening you can use a

if (Serial) Serial.println("message");

OK: what do I want to do?

When I use an Arduino (or other board) in a project, I try as much as possible to implement this behavior:

  • the normal start, as planned in the project specifications
  • start in development mode, so anyone can continue/troubleshoot/improve the project

For this project, normal mode just needs to send characters emulating a standard USB keyboard.

In development mode, I plug in the card which I may not know what program it has, and in the serial console, I show a magic number and some other version or other information. These informations are stored for example in EEPROM.

I hope I'm clear enough ... :wink:

Thanks a lot for your kind attention !

Do you thinks it's acceptable to wait a few seconds on every startup just for the case you might want to be in debug mode? If not, you should add a pin that puts the board into debug mode if connected to ground at startup. If you don't see this connection at startup, immediately start over and don't print anything to serial.

It WILL be acceptable, at least for this project! :wink:

Thanks a lot for your kind attention !

And here is the template of this type of project ...

// debug
#define DEBUG
#ifdef DEBUG
#define DEBUG_PRINTLN(x) Serial.println(x)
#define DEBUG_PRINTLN2(x,y) Serial.println(x,y)
#define DEBUG_PRINT(x) Serial.print(x)
#define DEBUG_PRINT2(x,y) Serial.print(x,y)
#else
#define DEBUG_PRINTLN(x)
#define DEBUG_PRINTLN2(x,y)
#define DEBUG_PRINT(x)
#define DEBUG_PRINT2(x,y)
#endif

// Librairies
#include <EEPROM.h>
#include <...>
#include "..."

// Params -> EEPROM
const uint32_t MAGIC_NUMBER = 1234567890;
const uint8_t VERSION_NUMBER = 10; // v1.0 - 2022-03
const char PROJECT_NAME[80] = "Xxxxxxxxxx";
const char GIT_LINK[80] = "https://github.com/yyyyy/zzzzz";

struct prefsStruct {
  uint32_t magicNb;
  uint8_t versionNum;
  char projectName[80];
  char gitLink[80];
};
prefsStruct prefsValues;

// Globals

// SETUP
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.begin(115200);
  delay(10000);
  digitalWrite(LED_BUILTIN, LOW);

  EEPROM.get(0, prefsValues);
  if (!((prefsValues.magicNb == MAGIC_NUMBER) && (prefsValues.versionNum == VERSION_NUMBER))) {
    Serial.println ("NO PREFS -> SETUP PREFS");
    prefsValues.magicNb = MAGIC_NUMBER;
    prefsValues.versionNum = VERSION_NUMBER;
    strcpy(prefsValues.projectName, PROJECT_NAME);
    strcpy(prefsValues.gitLink, GIT_LINK);
    EEPROM.put(0, prefsValues);
    Serial.println ("PREFS NOW OK");
  }
  else {
    Serial.println ("PREFS OK");
  }
  Serial.print("Magic number: ");
  Serial.println(prefsValues.magicNb);
  Serial.print("Project name: ");
  Serial.println(prefsValues.projectName);
  Serial.print("Version: ");
  Serial.println(prefsValues.versionNum);
  Serial.print("Git link: ");
  Serial.println(prefsValues.gitLink);
  Serial.println("END SETUP");
}

// LOOP
void loop() {
...

Voilà !!!

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