Arduino Leonardo port not detected, no serial communication

Hello all,
I am a novice with Arduino, having been thinkering with it for about two weeks only.
I have a (genuine) Arduino Leonardo board, wich i've been working on for a few days, and it worked perfectly fine, but this evening (after about 24-hours of non-usage) i found out that the Leonardo no longer communicates (at all) with the PC.

I have the following "symptoms":

  • The "ON" LED is steadily on when the board is plugged in (as it should).

  • The "L" LED does not blink, except when the reset button is pressed (once for reset, or twice for bootloading).

  • The TX and RX LEDs are steadily off.

  • The board is not detected by Arduino IDE nor the Windows device manager.

  • Arduino IDE sketches cannot be uploaded to the board (the software remains stuck on the "uploading" phase).

  • I have tried all the possible USB ports on my PC, and i've rummaged trough all possible cables, without any change in result.

  • I am not aware of the board having overheated at any point in time, nor it has never been powered by anything besides the USB ports of my PC.

  • I am not aware of the board having ever suffered a short-circuit in it's (brief) service life.

  • The board was working perfectly fine the last time it was used.

  • The code it was running (for about two hours) the last time it was used is the follwing - a keyboard emulator code based on potentiometer positions (specifically, i am using Arduino as a base for a Train Simulator controller).

#include <Keyboard.h>


//Define Ports, button mappings and delays here
#define POWERHANDLE A0
#define BRAKEHANDLE A1

#define POWERINCREASE 'q'
#define POWERDECREASE 'z'

#define BRAKEINCREASE ';'
#define BRAKEDECREASE '.'

#define DELAYPOWER 10
#define DELAYBRAKE 10


int prevPower;
int prevBrake;

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

void loop() {
  
  //-----------------------Power handle code-----------------------
  
  int sensorValuePower = analogRead(POWERHANDLE);
  Serial.println(sensorValuePower);
  
  int mappedPowerVal = map(sensorValuePower, 670, 995, 0, 8);
  Serial.println(mappedPowerVal);
  
  int trendPower = mappedPowerVal - prevPower;

  int runtimePower;
  
  if (trendPower > 0 )
    {
    // increasing
    Serial.println("increasing");
    runtimePower = trendPower * DELAYPOWER;
    
    Serial.println("runtimePower="); Serial.println(runtimePower);
    
    Keyboard.press(POWERINCREASE);
    delay(runtimePower);
    
    Keyboard.releaseAll();
    }
  else if (trendPower < 0)
    {
    // decreasing
    Serial.println("decreasing");
    int posValuePower = -trendPower;
    runtimePower = posValuePower * DELAYPOWER;
    
    Serial.println("runtimePower="); Serial.println(runtimePower);
    
    Keyboard.press(POWERDECREASE);
    delay(runtimePower);
    
    Keyboard.releaseAll();
    }
  else
    {
      Serial.println("No Power Handle change detected");
    }
  prevPower = mappedPowerVal;

  //-----------------------Brake handle code-----------------------
  
  int sensorValueBrake = analogRead(BRAKEHANDLE);
  Serial.println(sensorValueBrake);
  
  int mappedBrakeVal = map(sensorValueBrake, 670, 995, 0, 8);
  Serial.println(mappedBrakeVal);
  
  int trendBrake = mappedBrakeVal - prevBrake;

  int runtimeBrake;
  
  if (trendBrake > 0 )
    {
    // increasing
    Serial.println("increasing");
    runtimeBrake = trendBrake * DELAYBRAKE;
    
    Serial.println("runtimeBrake="); Serial.println(runtimeBrake);
    
    Keyboard.press(BRAKEINCREASE);
    delay(runtimeBrake);
    
    Keyboard.releaseAll();
    }
  else if (trendBrake < 0)
    {
    // decreasing
    Serial.println("decreasing");
    int posValueBrake = -trendBrake;
    runtimeBrake = posValueBrake * DELAYBRAKE;
    
    Serial.println("runtimeBrake="); Serial.println(runtimeBrake);
    
    Keyboard.press(BRAKEDECREASE);
    delay(runtimeBrake);
    
    Keyboard.releaseAll();
    }
  else
    {
      Serial.println("No Brake Handle change detected");
    }
  prevBrake = mappedBrakeVal;

  delay(10);
}

Questions:

  • Is my board fried?

  • If it's not a write-off, is it salvageable? If yes, how?

  • Is the code part of the issue, if it is let to run for extended periods of time?

This is crucial, as i have an upcoming exhibition where i planned to have the simulator playable to the visiting pubblic, thus Arduino would need to stay on with the code running for up to four hours or so.

You have discovered a pain point about Leonardo. When you load a sketch on it that makes the Leonardo a human interface device (HID) and it acts as a keyboard or mouse, it interferes with uploading the next sketch. Go into preferences and turn on verbose output during compiling and during upload. If you tap the reset button, you will notice the L LED pulsating and during that next few seconds, find and set the port in the Arduino IDE. Then try uploading the blink sketch so you can return it to “normal”. You may need to tap the reset button during compiling or right before it starts upload. I have had Leonardos so messed up from programming HID sketches that it is easier to just re-bootload the Leonardo. For that you need another working Arduino onto which you load the Arduino as ISP sketch, or buy a dedicated programmer. .

Your basics are correct and will work; I do have some comments.

In my experience that step is not necessary. It does not hurt though.

Again, in my experience setting the port is not necessary, at least not in IDE 2.x; I can't remember if it's necessary in IDE 1.x. I mostly use IDE 2.x, uploaded OP's sketch and could upload again without doing that step; I had to keep the Leonardo in reset as the code (without potentiometers connected) was spamming the IDE and release the reset button when the IDE reported the memory usage.

That point would be when the IDE reports the memory usage and starts the upload.

The basic solution is given in post #2.

Here are some tips for boards with native USB.

HID usage

It's advisable to reserve one pin (below I use A3 but it can be any free pin) as a safety pin that can prevent that the board spams the PC or is no longer detected.

#define SAFETYPIN A2
#define SAFETYINDICATOR LED_BUILTIN

And modify setup()

void setup()
{
  pinMode(SAFETYPIN, INPUT_PULLUP);
  pinMode(SAFETYINDICATOR, OUTPUT);

  // while the safety pin is not connected, wait
  while (digitalRead(SAFETYPIN) == HIGH)
  {
    digitalWrite(SAFETYINDICATOR, HIGH);
    delay(200);
    digitalWrite(SAFETYINDICATOR, LOW);
    delay(800);
  }
  
  // other setup code here
  ...
  ...
}

If the safety pin is not connected to GND, the program will wait after a reset of the board till the safety pin is connected to GND.

So if your board enters a state where it spams the PC or is not correctly detected you can disconnect the safety pin from GND and reset the board and it should be detected again and stop spamming so you can e.g. edit your code.

You can also embed all your Keyboard.press() functions (as well as mouse functions if applicable) in an if statement like below

    if (digitalRead(SAFETYPIN) == LOW)
    {
      Keyboard.press(POWERINCREASE);
    }

This prevents (obviously) that the board can send keypresses which can interfere with e.g. editing code. You can use the same approach for mouse clicks.

It's your call if you want to implement the first one only or both.

Serial

When a board with native USB (like your Leonardo) is externally powered and you e.g. connect a serial monitor for debugging and later disconnect it you can bring your board to a near grinding halt if you use Serial.print. This is because the board can no longer get rid of the characters that are being printed.

You can use Serial.availableForWrite() to check if there is still space in the print buffer.
E.g.

  if (Serial.availableForWrite() > 6)
  {
    Serial.println(sensorValuePower);
  }

In this example I did choose 6 (4 for the analog value plus the <CR><LF>).
Personally I usually use something like 60 so it can cater for longer text messages.

Thanks for the answer!
Unfortunately IDE still does not recognizes the port even after pressing the reset button, and thus, i was unable to upload anything.

I have a spare non-genuine UNO board, so i technically might be able to re-bootload my Leonardo.

Hi @socimi.

Does the LED pulse when you do that, or does it only do a basic off/on blink?

It pulses for a few seconds.

What does device manager say during those few seconds?

Normal use

While the L-LED fades

Note the change in the entry for the Leonardo.

There is no change at all when i plug or unplug the "faulty" Leonardo, nor when i hit the reset button. The Windows device manager does not refresh itself either.
I have both arduino boards plugged to my PC right now - both the genuine Leonardo and the non-genuine spare UNO, but only the UNO shows up on the device manager (on COM13).

It doesn't show up as an entry in the Human-Interface Device list either.

The fact tha the L-LED fades indicates that the bootloader is present and can be activated.
If your screenshot reflects the status after tapping (or double tapping) the reset button the first thing to check is the cable.

The screenshot was taken after tapping once, and while the L LED pulsed.
I have just checked five different cables, all with the same routine - tap for reset, check device manager while L LED pulses - board still doesn't show up on the windows device manager. I doubt it's a cable problem.

If you're sure that the cables are data / sync cables and not just power cables (like sold with powerbanks and bluetooth speakers) I do not know what is wrong.

The only solution I see in that case is to burn the bootloader as mentioned by dmjlambert in post #2 and see if that solves the detection issue.

Tapping the reset button twice should cause the board to stay in bootloader mode.

I'm pretty sure they all are data-sync-capable cables, and a couple of those i've tried i'm sure they are, i've used both previously with the board and it connected to the PC just fine...

I'll try burning the bootloader if i can, but it seems can't find specific guides for the Leonardo board... There are a few guides for the UNO however - can i follow the same steps (and most importantly, use the same pins)?

As i mentioned, i have a spare (non-genuine) UNO board - can it be used to burn the bootloader on the Leonardo, or do i need another Leonardo to burn mine?

That's the odd thing, at closer observation it seems there is no difference betwen resetting with one tap or double-tapping (or atleast the L LED exhibits the same behaviour of 14 pulses and that's it.) - the board doesn't show up on the device manager in either case.

You will need to connect to the ICSP pins on the Leonardo, most tutorials show connections to pins 11/12/13 for the SPI bus, but the SPI bus for a Leonardo is only connected to the ICSP header.

So, Pins 11, 12 and 13 from the UNO to the ICSP pins on the Leonardo? And of the ICSP pins, wich ones of the six?

I take the other connections (5V-to-5V, Ground-to-Ground and Pin 10-to-Reset) still stand?

On official Leonardos (not clones) it should not make a difference.

I've never seen that on an official Leonardo.

5V, GND, and RESET would stay the same.
The pinout for the ICSP header is on the 3rd page of the pdf https://content.arduino.cc/assets/Pinout-Leonardo_latest.pdf

So, i take the connections would be as follows:

UNO -> Leonardo
Ground - Ground
5V - 5V
Pin 10 - Reset
Pin 11 - ICSP Pin 1
Pin 12 - ICSP Pin 3
Pin 13 - ICSP Pin 5

?