Micro USB port disconnects when certain code loaded

Wasn't sure which category to post this in, so please let me know if I need to do this elsewhere.

Genuine Arduino Micro through Amazon. Has letters "51-20" on the board.

Chip works fine whin I load Blink. If I upload the sketch attached here, the USB port disconnects. Problem persists until I reload the bootloader via upload blink/pressing reset. Chip works fine once bootloader is back, but will start dropping the port once I upload this sketch.

I have tried this with 3 different arduino Micros on two different windows PC's. Plugged into a breadboard with some jumpers and hardware attached, and all by itself with only the USB cable attached. Two different USB cables.

At this point, I can only assume that the Sketch is wack-a-do.

Please don't make fun of my code, I'm still debugging and testing!

Thanks for your help.
Steve

/*

  These displays use I2C to communicate, 2 pins are required to
  interface. There are multiple selectable I2C addresses. For backpacks
  with 2 Address Select pins: 0x70, 0x71, 0x72 or 0x73. For backpacks
  with 3 Address Select pins: 0x70 thru 0x77

 ****************************************************/
/* writeDigitRaw(location,bitmask) SAR
  matrix.writeDigitRaw(0,B00111000);  //L
  matrix.writeDigitRaw(1,B01110111);  //A
  matrix.writeDigitRaw(3,B01110011);  //P
  matrix.writeDigitRaw(4,B01101101);  //S`
*/

#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"

Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4();

int   relayPin       = 4;
int   buttonPin      = 7;
int   voltPin        = A4;
char  curSts         = 'X';
char  displayStat;
volatile bool buttPress      = false;
bool  relayOn        = false;
char  relaySB;
bool  AWait4V        = true;
bool  tooHigh        = false;
float minVolts       = 3.7;
float maxVolts       = 15.0;
bool  waitt          = false;
bool  showTimer      = false;
bool  drawDots       = false;
float input_voltage;
unsigned long   timerCur;
unsigned long   timerEnds;
unsigned long   time2Charge = 120000L;   //= 2 * 1000 * 60; // in millis ( min)
unsigned long   time2Wait   =  60000L; //1 * 1000 * 60; // in millis ( min)
unsigned long   tLeft;
/******************************************************************/
void setup() {
//#ifndef __AVR_ATtiny85__
  Serial.begin(9600);
  Serial.println("7 Segment Backpack Test");
//#endif
  int bright = 2;
  alpha4.begin(0x70);  // pass in the address
  alpha4.setBrightness(bright);

  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(voltPin  , INPUT);
  pinMode(relayPin , OUTPUT);
  attachInterrupt(digitalPinToInterrupt(buttonPin), ButtInterrupt, RISING);

  curSts = 'X';

  pinMode(LED_BUILTIN, OUTPUT);

  Serial.print("exit Setup");
} //end setup

//buttinterrupt IS FIRED OFF BY INTERRUPT FROM PIN falling FROM HIGH TO LOW. (BUTTON HAS BEEN PRESSED THEN RELEASED)
void ButtInterrupt()
{ buttPress = true; //values are backwards
  Serial.println();
  Serial.print("Butt activated");
}

void DisplayStatX()
{ if (waitt) {
    displayStat = 'W';
  }
  else if (tooHigh) {
    displayStat = 'H';
  }
  else if (curSts == 'A') {
    displayStat = 'A';
  }
  else if (curSts == 'O') {
    displayStat = 'O';
  }
  else if (curSts == 'X') {
    displayStat = 'X';
  }
}//end DisplayStatX

void DisplayVolts()
{ bool btrue = true;
  alpha4.clear();
  int d1 = floor(input_voltage / 10);
  int d2 = floor(input_voltage) - (d1 * 10);
  int d3 = 10 * (input_voltage - (d1 * 10) - d2); //
  char dd;
  char ee;
  d1 = 6;
  dd = sprintf(dd, "%i1", d1);
  /*
    if (d1 == 0){dd = '0';}
    if (d1 == 1){dd = '1';}
    if (d1 == 2){dd = '2';}
    if (d1 == 3){dd = '3';}
    if (d1 == 4){dd = '4';}
    if (d1 == 5){dd = '5';}
    if (d1 == 6){dd = '6';}
    if (d1 == 7){dd = '7';}
    if (d1 == 8){dd = '8';}
    if (d1 == 9){dd = '9';}
    --dd = (char)d2;*/
  alpha4.writeDigitAscii(0, 'W');//dd);
  alpha4.writeDigitAscii(1, dd, btrue);
  alpha4.writeDigitAscii(2, char(d3));
  alpha4.writeDigitAscii(3, displayStat);
  Serial.println();
  Serial.print(input_voltage);
  Serial.print(" d1: ");
  Serial.print(d1);
  Serial.print(" d2: ");
  Serial.print(d2);
  Serial.print(" d3: ");
  Serial.print(d3);

  //  matrix.print(input_voltage);
  alpha4.writeDisplay();
} //end DisplayVolts

void DisplayTimer()
{ alpha4.clear();
  DisplayStatX();
  if (curSts != '9')
  { tLeft = timerEnds - timerCur;
    //int hr    = tLeft / 3600;      /////////// Watch it here if timer is set > 1 hour!
    unsigned long mins  = tLeft / 60000L;
    unsigned long sec   = tLeft / 1000L;
    unsigned long min1  = mins / 10L;
    unsigned long min2  = mins - (min1 * 10L);
    int mini = round(sec / 60);

    Serial.println();
    Serial.print("Left : ");
    Serial.print(tLeft);
    Serial.print(" minutes: ");
    Serial.print(mins);
    Serial.print(" mini: ");
    Serial.print(mini);
    Serial.print(" sec: ");
    Serial.print(sec);
    Serial.print(" min1: ");
    Serial.print(min1);
    Serial.print(" min2: ");
    Serial.print(min2);
    Serial.print(" timerEnds: ");
    Serial.print(timerEnds);
    Serial.print(" timerCur: ");
    Serial.print(timerCur);
    alpha4.writeDigitAscii(0, min1);
    alpha4.writeDigitAscii(1, min2);
    alpha4.writeDigitAscii(2, ' ');
    alpha4.writeDigitAscii(3, displayStat);
    alpha4.writeDisplay();
  }

} // End DisplayTimer

void loop() {
  Serial.println(); Serial.println(); Serial.print("Start Loop");

  digitalWrite(LED_BUILTIN, HIGH); // turn the LED on -- proof of life..
  delay(500); // wait for a second
  digitalWrite(LED_BUILTIN, LOW); // turn the LED off
  delay(500); // wait for a second

  input_voltage = analogRead(voltPin);
  input_voltage = 4.8 * ((input_voltage * 5.0) / 1024.0);
  //input_voltage = roundf(input_voltage * 10);
  //input_voltage = round(input_voltage / 10);
  input_voltage   = round(10 * input_voltage) / 10;

  timerCur = millis(); //millis since sketch started

  //Check Button
  //ButtPress is set in ButtInterrupt
  // Sts goes X => A => O with button presses
  if (buttPress == true)
  { buttPress = false; //reset
    waitt     = false; // button pressed / turn off wait
    if (curSts == 'X') {
      curSts    = 'O';
      timerEnds = timerCur + time2Charge;
    }
    else if (curSts == 'O') {
      curSts    = 'A';
      AWait4V   = true;
    }
    else if (curSts == 'A') {
      curSts    = 'X';
    }
  } //Butt Pressed

  if (curSts == 'A' && !waitt && timerEnds < timerCur /*&& !AWait4V*/) // Start Wait
  { waitt     = true;
    timerEnds = timerCur + time2Wait;
  }
  else if (curSts == 'A' && waitt && timerEnds < timerCur) // EndWait
  { waitt   = false;
    AWait4V = true;
  }

  if (curSts  == 'O' && timerEnds < timerCur) //Stop Override after timer ends
  { waitt   = false;
    curSts  = 'X';
  }

  if (AWait4V && curSts == 'A' && input_voltage > minVolts)
  { AWait4V   = false;
    timerEnds = timerCur + time2Charge;
    waitt     = false;
  }

  if (input_voltage > maxVolts) {
    tooHigh = true;
  }
  else {
    tooHigh = false;
  }

  if (curSts == 'O' && !tooHigh)
  {
    relaySB = true;
  }
  else if (curSts == 'A' && !AWait4V && !waitt && !tooHigh)
  {
    relaySB = true;
  }
  else {
    relaySB = false;
  }

  if (relaySB && !relayOn)
  {
    digitalWrite(relayPin, HIGH);
    relayOn = true;
  }

  if (!relaySB && relayOn)
  {
    digitalWrite(relayPin, LOW);
    relayOn = false;
  }
  Serial.println();
  Serial.print ("CurSts :");
  Serial.print (curSts);
  Serial.print (" Waitt: ");
  Serial.print (waitt);
  Serial.print (" Wait4V: ");
  Serial.print (AWait4V);

  /*
    Serial.println();
    Serial.print(" Time2Charge: ");
    Serial.print(time2Charge);
    Serial.print(" Time2Wait: ");
    Serial.print(time2Wait);
  */
  DisplayStatX();
  DisplayVolts();

  if (curSts != 'X')
  {
    delay (1000);
    DisplayTimer();
  }

  delay(3000);
} //End Loop

Hello @rauscs, your topic has been moved to a more suitable location on the forum.

Serial.print inside an ISR is bad, or worse, practise.

If I upload the sketch attached here, the USB port disconnects.

Does it disconnect on upload, or does the code run for a bit and then disconnect? Do you see "Exit Setup" and "Start loop"? Do your other serial prints give any indication of where things go wrong?

char dd;
char ee;
d1 = 6;
dd = sprintf(dd, "%i1", d1);

I see two things wrong here.

First, with your use of sprintf() you are writing into memory you don't "own" and the result is unpredictable. dd needs to be a character buffer large enough for what you are writing there, and a single char is certainly not enough given that sprintf() appends a null terminator.

Second, return from sprintf is the number of characters written not including the null terminator. You can't assign the return value to the string you are creating.

Thanks all. I removed the Serial.print in the ISR, and the sprintf per your suggestions, and it is working now.

Great! Thanks for telling!

Also, for the Arduino Micro or Leonardo, you should have an extra statement in setup (), that is:

while (!Serial) ;

The explanation is below:

“ Unlike the Arduino Uno, the Leonardo and Micro won't restart your sketch when you open a serial port on the computer. That means you won't see serial data that's already been sent to the computer by the board, including, for example, most data sent in the setup() function.

This change means that if you're using any Serial print(), println() or write() statements in your setup, they won't show up when you open the serial monitor. To work around this, you can check to see if the serial port is open after calling Serial.begin() like so:

Serial.begin(9600);

// while the serial stream is not open, do nothing:

while (!Serial) ;

Hey thanks, 6v6gt. I was wondering why I wasn't getting all of the output.