ricaun / ArduinoUniqueID

Arduino Library to gets the Manufacture Serial Number from the Atmel AVR, SAM, SAMD, STM32, and ESP Microcontroller.
MIT License
220 stars 50 forks source link

ArduinoUniqueID example tries to send data before serial comms established #19

Open ghost opened 2 years ago

ghost commented 2 years ago

Tested on an Arduino Micro the ArduinoUniqueID example tries to send serial data before comms are established and ends up sending nothing! Adding <while (!SerialUSB);> just after serial.begin fixed this issue for me :) This issue also occurred for the ArduinoUniqueID8 example but the ArduinoUniqueIDSerialUSB example already had it and works all good!

GralfR commented 10 months ago

This is the typical behaviour of the native-USB-Arduino. The AVR-Arduino using USB-to-serial are reset as soon as the USB-connection establishes. That's why it seams the Arduino is sending data "at the right time". In fact it just boots up, sends serial data even if nobody is listening and is being reset at the moment the USB-connection is established. If you want this same behaviour on native USB-Arduino, then the while (!Serial); is not a good solution. It will freeze up the Arduino if no USB-connection is available. So, the Arduino depends on a USB-connection to run. You can check this with a simple flashing LED-sketch, which does not blink until a USB-connection is established.

I just wrote a snippet that emulates the oldfashioned way of e.g. UNO R3 (reset on connection) on a modern native-USB-device like UNO R4. Instead of waiting for connection by while (!Serial); the device checks if (Serial) inside loop and as soon as USB connects, you can do what ever you want (like print a welcome-message to serial device or even reboot). Until then the device was working and not asleep. It's also good to remember an established connection to not to get stuck in reboot-loop.

static bool connected=false;
void setup() {
  Serial.begin(9600);
}
void loop() {
  if (Serial && !connected) {
    connected = true;
    Serial.println("Welcome"); //or whatever; UNO R3 did a reset at this stage
  }
  if (!Serial && connected) {
    connected=false; //recognise the lost connection to again print welcome on new connection
  }
}
newCityHunter commented 1 week ago

@GralfR I have tried both solutions many times, and none of them fixed the reboot problem. So, I tried an ‘extreme measure’ by adding a delay of about 1 second before initializing Serial, and it did fix the problem. Of course, I dislike this temporary solution, but for now, it’s the only option I have.

My solution: delay(1000); //Preventing the reboot-loop problem caused by sending data before establishing serial communication. Serial.begin(9600); // Initiate serial communication for printing the results on the Serial monitor

GralfR commented 1 week ago

Hm, @newCityHunter, what did You expect to "fix the reboot problem"? My example does not reboot the device (unless You code into), but recognizes, if the USB is connected and runs with or without USB-connection (needed, if USB is used for debugging on native USB-boards and lateron the device should run without USB). But great You found a solution that works for You. And 1sec delay is like an aeon for microcontrollers but nothing compared to generic PC-based systems.