earlephilhower / arduino-pico

Raspberry Pi Pico Arduino core, for all RP2040 and RP2350 boards
GNU Lesser General Public License v2.1
2.03k stars 422 forks source link

Serial.print not working after delay #1407

Closed GFoxPM closed 1 year ago

GFoxPM commented 1 year ago

The following code does not display anything in third party serial monitor programs until any character has been sent. Tested with: tio, screen, pyserial-miniterm, putty But everything works if you build this code with Arduino Mbed OS RP2040 core In order for the bug to manifest itself, you need to run the serial port monitor in reconnect mode in case of a disconnect.

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);

    Serial.begin(115200);

    // bool ResetAllSettings = false;
    delay(5000);
    // ResetAllSettings = BOOTSEL;
    digitalWrite(LED_BUILTIN, HIGH);

    // while(!Serial);
    // delay(100);
    Serial.println("START");

    // ...
}
SocrateCrypto commented 1 year ago

void setup() { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW);

Serial.begin(115200);

// bool ResetAllSettings = false;
delay(5000);
// ResetAllSettings = BOOTSEL;
digitalWrite(LED_BUILTIN, HIGH);

while(!Serial); // delay(100); Serial.println("START");

// ...

} uncoment while(!Serial);

GFoxPM commented 1 year ago

@SocrateCrypto Presence of while(!Serial); does not affect the existence of the bug. In order for the bug to manifest itself, you need to run the serial port monitor in reconnect mode in case of a disconnect.

GFoxPM commented 1 year ago

изображение

GFoxPM commented 1 year ago

изображение

earlephilhower commented 1 year ago

Sorry, I cannot reproduce this and it seems like something that would kill every user if it was happening since Serial output is the basis for most sketches.

I just ran your sketch (with loop() added) :

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, LOW);

    Serial.begin(115200);

    // bool ResetAllSettings = false;
    delay(5000);
    // ResetAllSettings = BOOTSEL;
    digitalWrite(LED_BUILTIN, HIGH);

    // while(!Serial);
    // delay(100);
    Serial.println("START");

    // ...
}
void loop() {
  static int c = 0;
  Serial.printf("%d\n", c++);
  delay(1000);
}

And in the IDE serial monitor got

START
0
1
2
3
4
5
6
7
8
9
10
....

I suggest you double check which serial port is being connected to in your terminal. The OS can assign a new ID every reboot of the Pico (i.e. COM5: to COM6: or /dev/ttyACM1 to /dev/ttyACM2) and you might be connecting to an older, non-existing port...

GFoxPM commented 1 year ago

@earlephilhower You must: Launch Serial Monitor (Not from Arduino IDE!). Disconnect USB cable and reconnect it After that the output will be missing. The bug manifests itself in any of the listed serial monitors, except for the Arduino IDE.

earlephilhower commented 1 year ago

I just closed the IDE monitor, unplugged the device, replugged it in, and ran minicom -D /dev/ttyACM0 and got...

Welcome to minicom 2.7.1

OPTIONS: I18n 
Compiled on Dec 23 2019, 02:06:26.
Port /dev/ttyACM0, 11:11:54

Press CTRL-A Z for help on special keys

START
0
 1
  2
   3
    4
     5
      6
       7
        8
GFoxPM commented 1 year ago

@earlephilhower A prerequisite for the bug is to start the port monitor before loading the RP2040

GFoxPM commented 1 year ago

изображение

GFoxPM commented 1 year ago

Peek 2023-04-28 21-21

earlephilhower commented 1 year ago

Again, I can't reproduce this on my Ubuntu 22.04 install.

I restarted minicom (the Pico had been running since last message) and then did a USB disconnect/reconnect w/o exiting minicom and all comes back fine:

Compiled on Dec 23 2019, 02:06:26.
Port /dev/ttyACM0, 11:13:28

Press CTRL-A Z for help on special keys                                                               

1266                                                                                                  
    1267                                                                                              
        1268                                                                                          
            START
0
 1
  2
   3
    4
     5
      6
       7
        8
         9
          10
            11

I think you need to check the dmesg when you lose connectivity. Linux might leave /dev/ttytACM0 even though it's disconnected, and reenumerate the Pico as /dev/ttyACM1.

GFoxPM commented 1 year ago

Peek 2023-04-28 21-45

GFoxPM commented 1 year ago

Arduino Core Peek 2023-04-28 21-48

earlephilhower commented 1 year ago

I believe you're seeing what you're showing, but it's not reproducible here and we've not gotten other reports of behaviour like this.

At this point, I think the only way forward is for you to dig into SerialUSB.cpp on your own install while this happens and see exactly what's happening in the Pico. I'd also recommend hooking up a SWD debugger and get a stack trace and see what the core is actually doing in this case (is it sending to TinyUSB where it disappears? is it thinking it's not connected and throwing things away? something else?)

GFoxPM commented 1 year ago

@earlephilhower Just a guess: The kernel is waiting for some information from the port monitor. Because if you press any key, thereby sending a character to the RP2040, then the transmission will resume.

earlephilhower commented 1 year ago

FWIW, my own kernel is Linux amd 5.15.0-69-generic #76~20.04.1-Ubuntu SMP Mon Mar 20 15:54:19 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

If you exit and restart Minicom on the port, does it resume automatically even w/o sending any keypresses?

GFoxPM commented 1 year ago

Linux ... 6.1.0-0.deb11.5-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.12-1~bpo11+1 (2023-03-05) x86_64 GNU/Linux

Yes, if I restart the minicom, the transmission will resume by itself.

GFoxPM commented 1 year ago

TinyUSB CDC also doesn't resume transmission without restarting minicom and prints 2 lines at a time.

earlephilhower commented 1 year ago

Adafruit_TinyUSB is a different version than the Pico-SDK one, so that points more to a specific system problem than a global issue in SerialUSB.cpp, I think.

The 2-line thing is a known normal effect w/the Adafruit version. You need to do a flush() after each line or it will buffer it. The buffering increases potential bandwidth but at the cost of latency in this case.

GFoxPM commented 1 year ago

I will test this bug in Ubuntu 22.04.

earlephilhower commented 1 year ago

@GFoxPM sorry, mybad. I'm running Ubu 20.04.6 LTS, not 22.04

In any case the Adafruit Serial implementation is completely different from my own, and they themselves do all the USB stack (including IRQ handling). So there's no USB shared code between the main core SerialUSB and Adafruit USB.

GFoxPM commented 1 year ago

@earlephilhower On Ubuntu 22.04 the error does not appear.

GFoxPM commented 1 year ago

Well, the problem seems to be really in my system... If I find a reason, I'll post it.

GFoxPM commented 1 year ago

The source of the problem could not be found. Reinstalling the system solved the problem. It is strange that the problem is completely absent on the Arduino core...

Perhaps the topic can be closed.

VitRuzicka commented 1 year ago

Hello, I encountered the very same bug on upgraded ubuntu from 22.04 to 23.04. The serial port "dies" after nothing is being send for ~2s. Might have something to do with the new system because it previously worked flawlessly. The issue can be replicated in both arduino-ide 2.xx and vscode.

Regards, Vít.