Skip to content

USB Serial freezes on Arduino Pro Micro / Mac OS #53

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
iafan opened this issue Dec 4, 2018 · 8 comments
Open

USB Serial freezes on Arduino Pro Micro / Mac OS #53

iafan opened this issue Dec 4, 2018 · 8 comments

Comments

@iafan
Copy link

iafan commented Dec 4, 2018

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 arduino/Arduino#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.

@gvarisco gvarisco added the bug label Dec 11, 2018
@algernon
Copy link
Contributor

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).

@aentinger
Copy link
Contributor

@iafan are you still experiencing this issue? Maybe ModemManager contributed on your linux distribution to some of the hangup (see #92 for further information). You may try sudo apt-get purge ModemManager.

@iafan
Copy link
Author

iafan commented Sep 19, 2019

@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.

@aentinger
Copy link
Contributor

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

@sashok1337
Copy link

sashok1337 commented Mar 31, 2020

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.

@svchnik
Copy link

svchnik commented May 23, 2021

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) {
  }
}

@koriwi
Copy link

koriwi commented Dec 22, 2021

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.

@Vinimuller
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants