adafruit / Adafruit_TinyUSB_Arduino

Arduino library for TinyUSB
MIT License
449 stars 120 forks source link

Serial.print not working with TinyUSB #51

Closed cyborg5 closed 4 years ago

cyborg5 commented 4 years ago

Describe the bug I've been working with Tiny USB on a Feather M0 Express, Feather M4 Express, and Feather nRF52840 Express and could not get serial monitor output to work. Specifically on the nRF serial output only works if you use a Tools-> Debug:-> Debug 1 level or higher. However on the M0 and M4 when selecting Tools -> USB Stack ->TinyUSB I could not get any serial output from Serial.print("Hello"); regardless of Debug setting or baud rate.

Set up (please complete the following information)

To Reproduce Run any example sketch that has serial output or the following sketch…

void setup() {
  //Serial.begin(9600); 
  Serial.begin(115200);
  //while (! Serial) {};
  Serial.println("Attempting to detect Tiny USB"); 
  #ifdef USE_TINYUSB
    Serial.println("Tiny USB detected");
  #else
    Serial.println("Tiny USB NOT detected");
  #endif  
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

That is a modified version of Blink. The LED does blink however there is no serial output except on the nRF52840 with Debug level greater than zero. Adding or removing "while (! Serial) {};" has no effect.

Expected behavior Should see serial output

Screenshots None

Additional context

hathach commented 4 years ago

You must give up CPU control by calling yield() or delay while waiting for USB event. TinyUSB handles all events in non-ISR context.

while (! Serial) yield();

or

while (! Serial) delay(1);
cyborg5 commented 4 years ago

I verified that this solves my problems. None of the example sketches in the library have that while (! Serial) delay(1); statement and without it none of those sketches will work on a Feather M0 or Feather M4. I didn't try Circuit Playground but my guess is it would not work either. I would be willing to fix all of those examples and submit a pull request if you would like me to. As I said in a previous message anything I can do to help document this code and/or write an Adafruit Learning Guide for some of it I would be willing to do.

todbot commented 4 years ago

Hi @cyborg5, are doing any prints in loop() or just in setup() as your above sketch? I've found with USB on Arduino, the setup() exits before your terminal program can connect (or even before the OS fully sets up the CDC stack for applications to see a serial port present). The while (! Serial) {}; should block setup() until CDC is configured, but I wonder if it's being optimized out by the compiler?

TLDR: try inserting a Serial.print('hello'); in your loop() and see if that works, regardless of what while() you have in setup()

hathach commented 4 years ago

thanks @todbot for anwsering, @cyborg5 as todbot said, TinyUSB doesn't need that while(!Serial) to work with. The setup() just complete before usb is enumerated, per-design, TinyUSB dropped all characters if it is not connected/enumerated. After connected e.g in loop() it should work as usual.