Arduino pro micro keeps disconnecting

I'm new to Arduino and I've used Arduino uno before without problems. For a project, I want to use Arduino Pro Micro because it's so compact. I'm using ArduinoJoystickLibrary from MHeironimus, and when I plug it into my pc the connection is solid for a few minutes, but then suddenly it disconnects. Every time I plug it back in it connects for a few seconds and then loses it again. When I try it an hour later, it's again solid for only a few minutes.

Context:
I've tried multiple reboots, even the reboot after compiling and before uploading.
I've two indentical arduino pro micro's, and the problem repeats with both.
I've tried uploading from different pc.
I've tried using Arduino 1.x and Arduino 2.x.
Chip doesn't feel warm under and after use, and is stored in a room of around 15 C°.
I've also tried using a the standard void and loop sketch, no difference.

Try uploading the blink sketch and let it run a while to see if it disconnects. At this point we do not now what code is in it and I want to start from a known.

Arduino pro micro has no LED except power, rx and tx. So blink won't show if it works. And I know that if i upload a sketch (doesn't matter wich one) the first few minutes it works with no problems.

You missed the point :wink: @gilshultz stated "At this point we do not now what code is in it and I want to start from a known." Loading any innocent sketch (blink, blank [which is your standard setup/loop sketch]) will do.

Based on your information, does the problem still happen when nothing (except USB) is connected to your Pro Micro? Do you have a bad USB connection (board to cable); wiggle the connector to check.

Which operating system?

What does your operating system think of the board when it disconnects? Does it go to bootloader (for approx. 8 seconds); or does it just disappear briefly; or disappear completely for a longer period of time?

You can blink the Rx or Tx LEDs; just in case, see the SparkFun's Pro Micro & Fio V3 Hookup Guide - blinkies.

The below sketch might make life a little easier; at least you have a visual indication to see if the board rebooted for whatever reason

int RXLED = 17;  // The RX LED has a defined Arduino pin
void setup()
{
  pinMode(RXLED, OUTPUT);  // Set RX LED as an output

  Serial.begin(115200);
  while (!Serial)
  {
    digitalWrite(RXLED, LOW);  // set the RX LED ON
    delay(500);
    digitalWrite(RXLED, HIGH);  // set the RX LED OFF
    delay(500);
  }
}

void loop()
{
  digitalWrite(RXLED, LOW);  // set the RX LED ON
}

Use an external terminal program (I used Tera Term), not the serial monitor.

The code will blink the RX led till such time that a serial connection is established; connect using Tera Term and the LED will go permanently on. Next disconnect from Tera Term; the LED should stay on. If you come back after brewing the :coffee: and LED blinks you know that the board went through a reset cycle.

Note:
If you use the serial monitor, closing it will result in a reset of the board. That the reason to use an external terminal program.

PS
5V/16MHz or 3.3.V/8MHz?
Clone or genuine SprakFun SparkFun?

1 Like

With the above, my SparkFun Pro Micro (3.3V/8MHz) has been running without issues (LED still on) since the previous post

Thank you so much. It worked!!!

I don't know if I'm allowed to post here, but I've exactly the same problem as the TO.
My OS: Ubuntu 24.04.4 LTS, 64-bit, Arduino IDE 2.3.2, and a SparkFun Clone Pro Micro.

I've tried the blink script @ sterretje provided, and was able, with a very tricky timing, to upload his script. After the the serial connection went dead, the LED on the Pro begins to blink as supposed to, but any attempt to connect to /dev/ttyACM0 via terminal (using putty) results in >nothing< but connection errors, because the /dev/ttyACM0 isn't open, right after 3-4 sec. of reset.

It seems the 3-4 sec after reset are part of the boot process and flash process as well, and in this time period the LED is not blinking until the serial closes, then the LED begins to blink constant as programmed by delay(500)

I'm new to Arduino, but have intense programming experience in application development in C++, Java, and the like, and I'm not completely new to flashing firmware.

May be this is intentional by the clone vendor but I can't see the benefit.

Arduino IDE reports this in red after upload:

Connecting to programmer: .
Found programmer: Id = "CATERIN"; type = S
    Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
    Device code: 0x44

I have no idea what's meant.

You are; although it might have been better to start your own topic because this one is marked as "solved" :wink: But just leave it here for now (it can always be moved to it's own topic if needed).

You should have those 3-4 seconds that you mention; it should actually be 8 seconds as the below dmesg output (for a real Pro Micro) shows; I've added some comments for clarity. I did not actually use the IDE for this but just a reset button (I know there is no reset button on the Pro Micro).

# normal usage immediately after connecting the board
[13732.476662] usb 1-5.4.2: new full-speed USB device number 20 using ehci-pci
[13732.562223] usb 1-5.4.2: New USB device found, idVendor=1b4f, idProduct=9204, bcdDevice= 1.00
[13732.562232] usb 1-5.4.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[13732.562238] usb 1-5.4.2: Product: SparkFun Pro Micro
[13732.562243] usb 1-5.4.2: Manufacturer: SparkFun
[13732.563564] cdc_acm 1-5.4.2:1.0: ttyACM1: USB ACM device

# board reset (simulated with button, IDE will perform this in a different way)
[13736.144661] usb 1-5.4.2: USB disconnect, device number 20

# bootloader activated
[13736.834668] usb 1-5.4.2: new full-speed USB device number 21 using ehci-pci
[13736.917061] usb 1-5.4.2: New USB device found, idVendor=1b4f, idProduct=9203, bcdDevice= 0.01
[13736.917069] usb 1-5.4.2: New USB device strings: Mfr=2, Product=1, SerialNumber=0
[13736.917075] usb 1-5.4.2: Product: Pro Micro 3.3V
[13736.917079] usb 1-5.4.2: Manufacturer: SparkFun Electronics
[13736.917987] cdc_acm 1-5.4.2:1.0: ttyACM1: USB ACM device

# normal usage after (timed-out) upload
[13744.685669] usb 1-5.4.2: reset full-speed USB device number 21 using ehci-pci
[13744.686125] usb 1-5.4.2: device reset changed ep0 maxpacket size!
[13744.687310] usb 1-5.4.2: USB disconnect, device number 21
[13744.864667] usb 1-5.4.2: new full-speed USB device number 22 using ehci-pci
[13744.950138] usb 1-5.4.2: New USB device found, idVendor=1b4f, idProduct=9204, bcdDevice= 1.00
[13744.950147] usb 1-5.4.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[13744.950152] usb 1-5.4.2: Product: SparkFun Pro Micro
[13744.950157] usb 1-5.4.2: Manufacturer: SparkFun
[13744.950944] cdc_acm 1-5.4.2:1.0: ttyACM1: USB ACM device

Please note the change in idProduct from 9204 (normal use) to 9203 (bootloader) and back; these numbers are for the real 3.3V/8MHz Pro Micro. The time in dmesg shows the 8 seconds (13736/13744).

Below is the same for a Leonardo (as I suspect that your board actually has the Leonardo bootloader).

[14243.500658] usb 1-5.4.2: new full-speed USB device number 23 using ehci-pci
[14243.585781] usb 1-5.4.2: New USB device found, idVendor=2341, idProduct=8036, bcdDevice= 1.00
[14243.585790] usb 1-5.4.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[14243.585795] usb 1-5.4.2: Product: Arduino Leonardo
[14243.585800] usb 1-5.4.2: Manufacturer: Arduino LLC
[14243.587120] cdc_acm 1-5.4.2:1.0: ttyACM1: USB ACM device


[14248.451140] usb 1-5.4.2: USB disconnect, device number 23
[14248.683667] usb 1-5.4.2: new full-speed USB device number 24 using ehci-pci
[14248.764436] usb 1-5.4.2: New USB device found, idVendor=2341, idProduct=0036, bcdDevice= 0.01
[14248.764445] usb 1-5.4.2: New USB device strings: Mfr=2, Product=1, SerialNumber=0
[14248.764450] usb 1-5.4.2: Product: Arduino Leonardo
[14248.764455] usb 1-5.4.2: Manufacturer: Arduino LLC
[14248.765173] cdc_acm 1-5.4.2:1.0: ttyACM1: USB ACM device


[14256.738669] usb 1-5.4.2: reset full-speed USB device number 24 using ehci-pci


[14256.739076] usb 1-5.4.2: device reset changed ep0 maxpacket size!
[14256.740261] usb 1-5.4.2: USB disconnect, device number 24
[14256.918663] usb 1-5.4.2: new full-speed USB device number 25 using ehci-pci
[14257.002674] usb 1-5.4.2: New USB device found, idVendor=2341, idProduct=8036, bcdDevice= 1.00
[14257.002683] usb 1-5.4.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[14257.002688] usb 1-5.4.2: Product: Arduino Leonardo
[14257.002693] usb 1-5.4.2: Manufacturer: Arduino LLC
[14257.003335] cdc_acm 1-5.4.2:1.0: ttyACM1: USB ACM device

As can be seen, the duration of the bootloader is approx. 8 seconds (14248/14256). The idProduct is different from that of the real Promicro; now 8036 (normal use) and 0036 (bootloader). The idVendor differs from Pro Micro one because of different manufacturers.

If your timing is indeed 3-4 seconds, something is wrong. Can you provide de idVendor/idProducts based on the above dmesg output? Can you also let me know if you bought a 3.3V/8MHz or a 5V/16MHz board?

If that is all you see, it's the normal output for a successful upload when using IDE 2.x. It's annoying that it's in red but it is as it is; IDE 1.x does not show it (but that is not a reason to use IDE 1.x).

@sterretje Thank you for taking your time and extensive elaboration of the possible issue, appreciate that.

If your timing is indeed 3-4 seconds, something is wrong. Can you provide de idVendor/idProducts based on the above dmesg output? Can you also let me know if you bought a 3.3V/8MHz or a 5V/16MHz board?

As requested the board is a 5V/16Mhz clone.

Board Info:
BN: Arduino Leonardo
VID: 0x2341
PID: 0x8036
SN: (null)

Performing the same procedure using dmesg yields:

[13588.986854] usb 1-5.3: new full-speed USB device number 90 using xhci_hcd
[13589.114381] usb 1-5.3: New USB device found, idVendor=2341, idProduct=8036, bcdDevice= 1.00
[13589.114404] usb 1-5.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[13589.114416] usb 1-5.3: Product: Arduino Leonardo
[13589.114426] usb 1-5.3: Manufacturer: Arduino LLC
[13589.124770] cdc_acm 1-5.3:1.0: ttyACM0: USB ACM device

After reset:

[13991.930974] usb 1-5.3: USB disconnect, device number 90
[13992.186650] usb 1-5.3: new full-speed USB device number 91 using xhci_hcd
[13992.320881] usb 1-5.3: New USB device found, idVendor=2341, idProduct=0036, bcdDevice= 0.01
[13992.320894] usb 1-5.3: New USB device strings: Mfr=2, Product=1, SerialNumber=0
[13992.320899] usb 1-5.3: Product: Arduino Leonardo
[13992.320903] usb 1-5.3: Manufacturer: Arduino LLC
[13992.331192] cdc_acm 1-5.3:1.0: ttyACM0: USB ACM device

And suddenly (out of the blue) I have my 8 seconds, and a stable serial port, after graceful bootloader exit.

[14000.122996] usb 1-5.3: USB disconnect, device number 91
[14000.378675] usb 1-5.3: new full-speed USB device number 92 using xhci_hcd
[14000.514653] usb 1-5.3: New USB device found, idVendor=2341, idProduct=8036, bcdDevice= 1.00
[14000.514661] usb 1-5.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[14000.514664] usb 1-5.3: Product: Arduino Leonardo
[14000.514667] usb 1-5.3: Manufacturer: Arduino LLC
[14000.524681] cdc_acm 1-5.3:1.0: ttyACM0: USB ACM device

But I rather doubt this issue has been solved by it self quasi "over night", there is a reason why the Pro Micro yesterday did not play well, and this problem surely will reemerge shortly after I've posted this reply.

But maybe there is more to it, if you check my log, something that I did not see. Thanks in advance.

I can not explain why you suddenly got your 8 seconds. I have some doubts that your issue will come back but only time will tell :wink:

The dmesg output is OK (same as mine as far as I can see). Here is a little background how those boards work.

From your output I can see that the bootloader is the Leonardo bootloader (idProduct=0036 after reset) and the last time a sketch was uploaded it was uploaded with the Leonardo selected as the board (idProduct=8036 when you connected your board).

When a sketch is compiled, the compiler adds some code that you don't see (it's part of the so-called core). This code is, amongst other things, responsible for the identification of the board to the operating system (vid/pid for normal use, name) and the reaction on a software reset issued by the IDE. A bug in your sketch (or libraries that you use) can overwrite variables used by the above functionalities. As a result board identification might fail or the board might not react on the software reset.

You can follow what the IDE does if you enable verbose output during upload in file/preferences in the IDE.

Forcing reset using 1200bps open/close on port /dev/ttyACM1
PORTS {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } / {/dev/ttyACM0, /dev/ttyUSB0, } => {}
PORTS {/dev/ttyACM0, /dev/ttyUSB0, } / {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } => {/dev/ttyACM1, }
Found upload port: /dev/ttyACM1

This is the output when using IDE 1.x; the first line will be slightly different for IDE 2.x and in IDE 2.x your will not see the lines starting with PORTS.

You can see in the second line that /dev/ttyACM1 disappears (it does not show in the second pair of {} and next comes back (it shows again in the second pair of {} of the third line) and the IDE recognises it as the correct device (the third pair of {} on the third line).

The number of lines can slightly vary if the correct port was selected; the IDE will try to find the port with the bootloader for quite a long time.

You can match the above output against dmesg (use dmesg -w).

In the below IDE output, I choose the wrong port (ttyUSB0 which in my setup was an Uno clone). The Uno clone will not react on the software reset issued by the IDE hence the number of lines did increase. Selection of the wrong port can happen by user mistake, here it was used to demonstrate a bug in the previously uploaded code where the board does not react on the software reset.

When I realised that I had the wrong port selected, I issued a manual reset with the reset button (double tap the button) after which the board was detected and the upload started.

Forcing reset using 1200bps open/close on port /dev/ttyUSB0
PORTS {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } / {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } => {}
PORTS {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } / {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } => {}
PORTS {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } / {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } => {}
PORTS {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } / {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } => {}
PORTS {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } / {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } => {}
PORTS {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } / {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } => {}
PORTS {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } / {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } => {}

# manual reset; note that /dev/ttyACM1 disappeared from the second pair of {}

PORTS {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } / {/dev/ttyACM0, /dev/ttyUSB0, } => {}
PORTS {/dev/ttyACM0, /dev/ttyUSB0, } / {/dev/ttyACM0, /dev/ttyUSB0, } => {}
PORTS {/dev/ttyACM0, /dev/ttyUSB0, } / {/dev/ttyACM0, /dev/ttyUSB0, } => {}
PORTS {/dev/ttyACM0, /dev/ttyUSB0, } / {/dev/ttyACM0, /dev/ttyACM1, /dev/ttyUSB0, } => {/dev/ttyACM1, }
Found upload port: /dev/ttyACM1

Note:
The bootloader is fully independent of the uploaded code; you can see it as a BIOS that is independent of the installed operating system (your sketch).

Question
How do you intend to use the board? As a HID? If so, I will provide some additional information.

According to your explanation, I might get the idea as to why my Pro Micro was acting frenzy. I far as I can remember tried to use different bootloader target in Arduino IDE like Pro Micro, even downloaded the sparkfun Pro Micro, thinking at that time this this would be more appropriate than Arduino Leonardo, because I have a Pro Micro after all.

You helped my quite a lot in understanding as to how things might work in background, and as I stated earlier I'm new to Arduino and it's mechanics, thanks a lot.

This board should act partly as an HID indeed. It's supposed to read Weigand protocol from a reader and switch a relay, if the correct chip was provided. Some OLE display for stats and maintenance, buttons for menu selection and chip programming (like add or remove chip). Nothing fancy, at least that's what I'm thinking. Optional a Wifi-Module to connect an Android smartphone, dropping the OLE display and doing maintenance from there, but this is a different, more complex, story I guess.

Any information is always appreciated, thanks in advance.

Here are a few issues that you can encounter.

HID

The below uses Keyboard.h to send data to the PC; the spamming below is equally applicable to Mouse.h to control the mouse pointer and mouse clicks.

Keyboard spamming

Consider the below code that you might have loaded by accident. It will, at high speed, print Hello world to the application that currently has the focus.

#include <Keyboard.h>

void setup()
{
  Keyboard.begin();
}

void loop()
{
  Keyboard.println("//Hello world");
}

If you now want to fix it in the IDE, the IDE will get spammed with Hello world messages. So you have to disconnect the board or keep it in reset while editing which is inconvenient.

If you have an IO pin available, you can use that and only conditionally print. In the below I used A10 but you're free to use any pin that is available.

#include <Keyboard.h>

const uint8_t safetyPin = A10;

void setup()
{
  Keyboard.begin();

  pinMode(safetyPin, INPUT_PULLUP);
}

void loop()
{
  if (digitalRead(safetyPin) == LOW)
  {
    Keyboard.println("//Hello world");
  }
}

Only if the safety pin is connected to ground the code will send the Hello world message; disconnecting from ground will stop the spamming.

Keypress stuck

When you press keys, they will be remembered in the PC. So you should never forget to release them. The below code demonstrates that a single press is remembered; I've taken the left control key as it's one of the worst scenarios.

#include <Keyboard.h>

const uint8_t safetyPin = A10;

void setup()
{
  Keyboard.begin();
  delay(2000);

  Keyboard.press(KEY_LEFT_CTRL);
  delay(1000);

  pinMode(safetyPin, INPUT_PULLUP);
}

void loop()
{
}

This will activate the left control key on your PC. With the IDE as the foreground application, pressing 'u' on the PC's keyboard will start an upload, pressing 'a' will select all text in the active window and on my system the scroll wheel of the mouse will zoom and the ESC key will invoke the start menu.

The only way to get out of it is to disconnect the board (or keep it in reset) and reboot your PC.

Using the safety pin as described above can solve the problem of the key that is stuck.

#include <Keyboard.h>

const uint8_t safetyPin = A10;

void setup()
{
  Keyboard.begin();
  delay(2000);

  Keyboard.press(KEY_LEFT_CTRL);
  delay(1000);

  pinMode(safetyPin, INPUT_PULLUP);
}

void loop()
{
  if (digitalRead(safetyPin) == LOW)
  {
	// do your keyboard actions here
  }
  else
  {
    Keyboard.releaseAll();
  }
}

To demonstrate, upload the sketch with the safety pin connected to ground; the control key will be stuck. To release the control key (and any other key that might not be released), disconnect the safety pin from ground at a later stage and your PC will behave normal again.

Serial

This is not related to HID use.

while(!Serial)

You will nearly always see examples like below.

void setup()
{
  Serial.begin(115200);
  while(!Serial);
  Serial.println("Hello world");
}

The only reason for the while(!Serial) is to wait for a communication channel to be opened so you don't miss the first data when printing. If you don't care about that, you can leave it out. You can also expand it with a timeout; the sloppy way is below which waits till either the communication channel is open or till the sketch has been running for 3 seconds.

void setup()
{
  Serial.begin(115200);
  while(!Serial && millis() < 3000);
}

print

If your Pro Micro is externally powered and is printing over USB, you can bring your Pro Micro to a (near) grinding halt if you disconnect the USB. The below code demonstrates

uint8_t ledState = LOW;

void setup()
{
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, ledState);
}

void loop()
{
  static uint32_t cnt = 0;
  Serial.println(cnt++);

  ledState = !ledState;
  digitalWrite(LED_BUILTIN, ledState);
  delay(100);
}

Arduino externally powered and connected via USB.
Above sketch uploaded.
Open serial monitor.
Observe L-LED.
Remove USB (serial monitor still open).
Note the slowdown of the blinking of the L-LED

The solution is to use Serial.availableForWrite() and check if there is enough space in the buffer to print. E.g. a 16-bit integer takes a maximum of 6 characters (including sign).

void loop()
{
  static int cnt;
  // print an int plus <cr><lf>
  if(Serial.availableForWrite() >=8)
  {
    Serial.println(cnt++);
  }
}

And now you know about as much as me :smiley:

Thank you very much for your "effective Arduino" programming tips. You might consider writing a blog or paper book compiling all your knowledge into it. I personally found them useful for a startup, gaining a quick understanding of the inner mechanics different from PC or Smartphone programming.

It tested some of your code to hone my education, and found some interesting issues with different bootloaders like slightly different behavior handling the serial port so on and so forth.

Thank you again for your quick preps. I'm going back to work know.
Happy Coding