ArduinoCore-avr icon indicating copy to clipboard operation
ArduinoCore-avr copied to clipboard

USB Serial freezes on Arduino Pro Micro / Mac OS

Open iafan opened this issue 7 years ago • 8 comments

I have Arduino Pro Micro connected via USB to my Mac (Mac OS Sierra 10.12.6). Arduino IDE is 1.8.7, and the board is identified there as "Board: SparkFun Pro Micro / Processor: ATmega32U4 5V/16 Mhz". Board info gives: "BN: Unknown board / VID: 1B4F / PID: 9206".

If I send to it more than 384 bytes of data at once, only 384 bytes will be displayed, and the board will freeze, freezing Arduino Serial Monitor as well (or screen) until I unplug the board from USB. While frozen, I can't upload new sketch to it either.

Here's the simplest code that I use:

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    if (Serial.available())
    {
        Serial.write(Serial.read());
    }
}

So it reads the data at the fastest speed possible and just echoes it back. If I don't echo the data back, but just read it to empty the serial buffer, the problem still persists.

Once I upload this sketch to Arduino, I can either open the Serial Monitor, or use screen /dev/cu.usbmodem14121 9600 from the console. As I type on the keyboard in screen, or send entire strings via the Serial Monitor, the input will be echoed back. But If I copy a large block of text (more than 384 symbols) and paste that into the screen session or paste and send via Serial Monitor, only the first 384 symbols will be echoed back, and Arduino will freeze.

Rebooting the Mac doesn't help.

I noticed that if I force the serial speed to 1200bps (for example, by using screen /dev/cu.usbmodem14121 1200), then I will see no freezing. 2400bps and above results in the same freezing issue. I tested this on 3 different Arduino Pro Micro boards from different vendors, and all have the same issue. I used bare boards, with no external components attached to pins.

I understand that these boards connect USB directly to ATmega32U4 chip, so the problem seems to be either in the chip itself (less likely) or the USB drivers / USB Serial implementation in Arduino (more likely).

I originally submitted this issue at https://github.com/arduino/Arduino/issues/8260 and @facchinm suggested to move the issue here and provided the following additional information:

the Serial object exposed by boards based on 32u4 is USB based, so HardwareSerial is not involved. The code is here. Changing baud rate should not affect the CDC subsystem EXCEPT for 1200bps, which triggers a reboot to bootloader every time the port is opened with that baud. So the problem is always reproducible.

iafan avatar Dec 04 '18 09:12 iafan

I have seen similar-ish issue, not sure if it is related: I noticed that if my device writes too fast, OSX will end up missing some of the data. This in turn makes a whole lot of things super confused. I didn't see the device locking up, mind you.

My workaround so far has been adding a small delay to Serial_::write (like this). This seems to have helped. Windows and Linux hosts do not seem to exhibit the same issue.

(My board is an atmega32u4, problem was noticed with a Keyboardio Model01 keyboard, haven't tried with my other 32u4 devices [some teensies, some not] yet).

algernon avatar Dec 11 '18 09:12 algernon

@iafan are you still experiencing this issue? Maybe ModemManager contributed on your linux distribution to some of the hangup (see https://github.com/arduino/ArduinoCore-avr/pull/92 for further information). You may try sudo apt-get purge ModemManager.

aentinger avatar Sep 18 '19 06:09 aentinger

@lxrobotics I didn't check this for quite a while, but this issue was happening for me on my Mac (macOS), not Linux. So definitely not a ModemManager. I see that @algernon also reported issue specifically with macOS.

iafan avatar Sep 19 '19 06:09 iafan

@iafan Unfortunately I've got no Mac available for testing this - could you please try again and see if the issue still affects you?

aentinger avatar Sep 19 '19 06:09 aentinger

Hello everyone! I ran into this problem today :( MacOS Catalina 10.15.4. I'm sending binary data from c++ program (around 20kb/sec) through serial port to my arduino pro micro. In my case death-block sizes are 64 OR 128 OR 256 OR >=384 bytes. My workaround for now:

#define SERIAL_PACKAGE_SIZE 382    // 62, 70, 124, 132, 262, 382 works well

void sendWithDelay(SerialWrapper *serial, uint8_t *data, int lenght){
    while(lenght > 0){
        int size = lenght > SERIAL_PACKAGE_SIZE ? SERIAL_PACKAGE_SIZE : lenght;

        if(!serial->send(data, size)){
            exit(1);
        }

        data += size;
        lenght -= size;
        usleep(10);
    }
}

int main()
{
    SerialWrapper serial;
    if(!serial.open("/dev/cu.usbmodem1431301", B230400)){
        return -1;
    }
    ...........
}

If I change SERIAL_PACKAGE_SIZE to 64 | 128 | 256 | 384, I get the error:

Error 35: Resource temporarily unavailable

If I change usleep(10) to usleep(5) I also get error 35 after 10-40 transmissions.

If I change usleep(10) to usleep(1), error 35 occurs immediately.

On Windows system all works fine on full speed.

sashok1337 avatar Mar 31 '20 00:03 sashok1337

I had such a problem the Arduino port monitor (Mega 2560) in Arduino IDE displays the result of a loop iteration only 15 values (in a loop of 20) and there is no line labeled END, then it freezes. If I change the value in the loop, the result changes, but the same value. I'm guessing this is a problem in the Serial.

#include <avr/io.h>

int main(void) {
  Serial.begin(19200);

  unsigned short z = 0;

  while (z < 20) {
    Serial.println("Value - " + String(z));
    //Serial.println(z, DEC);
    _delay_ms(100);
    z++;
  }

  Serial.println("END");

  while (1) {
  }
}

svchnik avatar May 23 '21 10:05 svchnik

our webserial app is also having this problem with a 32u4 on macos. i'm using sashok1337's approach with 62 chunk size. right now i'm just happy that there is at least one hacky workaround.

koriwi avatar Dec 22 '21 23:12 koriwi

Any updates on how to write more than 384 bytes via serial port at once on macOS? I'm using macOS Bigsur(11.6.5) and just ran into the same problem. Serial port hangs after trying to write more than 384 bytes, the only way to get it back to work is by unplugging the usb-serial device.

Sorry that it's not an arduino related issue, but this is the only place I could find some material on this macOS issue.

Vinimuller avatar Sep 09 '22 20:09 Vinimuller