Nano won't process until after a USB data connection

I can post sketches but to get your head around the situation please let me fully describe this craziness first.

I have a Nano and a Pro Micro (clones) that talk to each other.
On the Pro Micro (let's call it PM), Serial1 is used, pins "TX0" and "RX1".
SoftwareSerial is used on the Nano pins D2 and D3.
The PM is connected to some momentary switches.
When a switch press is detected it sends a TTL serial message to the Nano.
The Nano gets the message, does stuff then sends a TTL serial message back to the PM, then the PM does stuff.
This is actually working. Except when it doesn't.

So I load the sketches, test and everything is fine.
I disconnect the USB connections from the laptop, cycle power on the Nano and PM, press a switch and the "stuff" doesn't happen.
(The power being cycled is external, regulated 12V DC feeding VIN on the Nano and RAW on the PM.)
BUT...
if I then simply connect a DATA ONLY USB cable (modified, Red 5V lead cut on the USB A end) to the Nano, everything starts working immediately.
Now, I disconnect the USB from the Nano and the "stuff" continues to work.
BUT if I cycle the power again it stops working.

Tried substitute power supplies, Nanos, cables, etc.

What the hey? Is the USB port having to "Wake up" to enable some functioning on the Nano?

Thoughts? Doubts?

I think you didn't read the forum guide. No code, no schematics...

How far apart will the Nano and Pro Micro be in the deployed project?

Before posting your code and schematic, please review the forum guidelines and use code tags to ensure clarity. Additionally, include links to the technical information for your hardware and provide a preliminary schematic that shows all power, ground, and power sources.

For more guidance, please refer to this link:

Important Notes:

  • Breadboard diagrams (often referred to as "frizzes") are not considered proper schematics in this context.

  • Wiring diagrams are helpful for assembly but are not effective for debugging.

  • Screenshots are discouraged because they are often hard to read. Please provide text-based code and clear, high-quality images of schematics.

Providing the correct information will help others understand your setup and offer better assistance.

Since all the hardware works, the problem must be in the software!

No code shown, but let me guess. You are waiting on Serial.available() or doing a Serial.read() that never happens when the USB-Serial interface is disconnected.

Well the code is waiting on mySerial.available(), I thought that had nothing to do with the USB connection Serial().

Anyway here’s all the code. The Nano Code:

#include <SoftwareSerial.h> 

// Relay pins A1 to A4
int relayPON = A1;
int relayPOFF = A2;
int relayLATCH = A3;
int relay12V = A4;

// Set up a new SoftwareSerial object
SoftwareSerial mySerial = SoftwareSerial(2, 3);  // pin 2 is RX, 3 is TX, communication to Pro Micros
String msg = "";                                 // Initialize an empty string for messages
bool msgGood = false;                            // Initialize bool value for if message is good                          

//Assign starting LED states
char statesSw1 = 'J';
char statesSw2 = 'J';
//continue for more switches

int swNum = 0;

// ------------------RS232 commands---------------//
byte necPOFF[6] = {0x02, 0x01, 0x00, 0x00, 0x00, 0x03}; // NEC projector power off
byte necPON[6] = {0x02, 0x00, 0x00, 0x00, 0x00, 0x02};  // NEC projector power on
byte necHDBT[8] = {0x02, 0x03, 0x00, 0x00, 0x02, 0x01, 0xBF, 0xC7};  // NEC projector select HDBT input  (Last value is checksum)


void setup() {

  // Set the baud rate for the SoftwareSerial object
  mySerial.begin(9600);
  Serial.begin(9600);  // debug with local serial monitor

// output pins for relays
  pinMode(relayPON, OUTPUT);
  pinMode(relayPOFF, OUTPUT);
  pinMode(relayLATCH, OUTPUT);
  pinMode(relay12V, OUTPUT);
}


void loop() {

  //=================== START GET MESSAGE ======================//

  char rc;
  // the start marker is W, end marker is \n
  while (mySerial.available() > 0 && mySerial.available() < 7) {
    rc = mySerial.read();
    if (rc != '\n') {  // message has started but not reached the end
       msg += rc;
       delay(2);
    } else {  // endMarker reached
       msg += '\n';
       if (msg.charAt(0) == 'W' && msg.length() == 6) {  // verify message
          msgGood = true;  // not sure if really needed or there is a simpler method, but it worked so it stays for now.
  //     Serial.print("Message: "); //use for debug test, can interfere with serial receiving devices parsing commands
  //     Serial.print(msg);  //use for debug test
      }   // end verify message
    }   // end else for when rc reaches end marker (\n)
  }   // end while mySerial.available

  //=================== END GET MESSAGE ======================//


  //=================== START EVALUATE COMMANDS ======================//

if(msgGood == true){
   swNum = msg.charAt(3);
   //Code section for each switch.
   // Manually lookup switch state on external document and construct as below
   
   if(swNum == 49){  // 1 sent from Pro Micro is decimal 49

    if(statesSw1 == 'J'){
        statesSw1 = 'N';  
        // do switch 1 state 2 stuff (For state 2 action, typically "On" stuff)

        mySerial.write("NS1"); // send message to PMs
        mySerial.write("1");
        mySerial.write(statesSw1);
        mySerial.write("\n");
        delay(50);
        //  relayOn();

        Serial.write(necPON, 6);  // power on
        delay(10);

       delay(20000);  // projector took about 20 seconds to be ready to accept source select commands.  Pro Micro blink routine "N" happens during delay.
       Serial.write(necHDBT, 8);  // select HDBT Input
    }  // end if statesSw1 == 'J'
	
    else if(statesSw1 == 'N'){
        statesSw1 = 'J';
        // do switch 1 state 1 stuff  (For 2 state action, typically "Off" stuff)

        mySerial.write("NS1");
        mySerial.write("1");
        mySerial.write(statesSw1);
        mySerial.write("\n");
        delay(50);
        // relayOff();

        Serial.write(necPOFF, 6);  // power off 

        delay(10);
        delay(20000);  // projector took about 20 seconds to be ready to reset and be ready for power on
     } // end if statesSw1 == 'N'

  }  // end if swNum == 49 (switch 1)

    //-------------------------------------//

if(swNum == 50){  // 2 sent from Pro Micro is decimal 50

    if(statesSw2 == 'J'){
       statesSw2 = 'G';
       // do switch 2 state 2 stuff (For 2 state action, typically "On" stuff)
       relayOn();

       mySerial.write("NS1");
       mySerial.write("2");
       mySerial.write(statesSw2);
       mySerial.write("\n");
       delay(20000);
       } // end if statesSw2 == 'J'
	   
    else if(statesSw2 == 'G'){
      statesSw2 = 'J';
      // do switch 2 state 1 stuff (For 2 state action, typically "Off" stuff)
      relayOff();

      mySerial.write("NS1");
      mySerial.write("2");
      mySerial.write(statesSw2);
      mySerial.write("\n");
      delay(20000);

    } //end if statesSw2 == 'G'

}  // end if swNum == 50 (switch 1)

    //----Expand for more switched, if swNum == 51, etc. -------//

// reset message and msgGood, empty serial buffer
    msg = "";
    msgGood = false;
    while (mySerial.available()) { mySerial.read();}

  }  // end if msgGood == true


  //=================== END EVALUATE COMMANDS ======================//


}  // END main program

void relayOn() {
  digitalWrite(relayLATCH, HIGH);
  digitalWrite(relay12V, HIGH);
  digitalWrite(relayPON, HIGH);
  delay(600);
  digitalWrite(relayPON, LOW);
}

void relayOff() {
  digitalWrite(relayLATCH, LOW);
  digitalWrite(relay12V, LOW);
  digitalWrite(relayPOFF, HIGH);
  delay(600);
  digitalWrite(relayPOFF, LOW);
}

Pro Micro Code:

// Pro Micro code
String msg = "";  // Initialize an empty string

int Btn1 = 2;
int Btn2 = 3;
int Btn3 = 4;
int Btn4 = 5;

int LEDG1 = 6;
int LEDR1 = 7;
int LEDG2 = 8;
int LEDR2 = 9;
int LEDG3 = 18;
int LEDR3 = 19;
int LEDG4 = 20;
int LEDR4 = 21;
int SuppRX = 14; //Socket pin 15
int SuppTX = 16; // socket pin 14
int IDPin = 10; // socket pin 13


void setup() {
 //  digitalWrite(13, HIGH); //test
  pinMode(Btn1, INPUT_PULLUP);
  pinMode(Btn2, INPUT_PULLUP);
  pinMode(Btn3, INPUT_PULLUP);
  pinMode(Btn4, INPUT_PULLUP);
  pinMode(SuppRX, INPUT);   //  need external pulll down resistor, other Pro Micro SuppTx pin drives this pin HIGH when it sends Serial data first.
  pinMode(IDPin, INPUT_PULLUP);  // Pro Micro is #2 when Jumper is in place to drive this pin LOW

  pinMode(LEDG1, OUTPUT);
  pinMode(LEDR1, OUTPUT);
  pinMode(LEDG2, OUTPUT);
  pinMode(LEDR2, OUTPUT);
  pinMode(LEDG3, OUTPUT);
  pinMode(LEDR3, OUTPUT);
  pinMode(LEDG4, OUTPUT);
  pinMode(LEDR4, OUTPUT);
  pinMode(SuppTX, OUTPUT);

// output pins use reverse logic, LOW turns on the LED
  digitalWrite(LEDG1, HIGH);
  digitalWrite(LEDR1, HIGH);
  digitalWrite(LEDG2, HIGH);
  digitalWrite(LEDR2, HIGH); 
  digitalWrite(LEDG3, HIGH);
  digitalWrite(LEDR3, HIGH);
  digitalWrite(LEDG4, HIGH);
  digitalWrite(LEDR4, HIGH);  

  Serial1.begin(9600);  // Serial port to Nano.
  Serial.begin(9600);   // if we want to print out to serial monitor for debug.


  // reboot LED display
  
        digitalWrite(LEDG1, HIGH);  
        digitalWrite(LEDR1, LOW);  
        delay(500);
        digitalWrite(LEDG1, LOW);  
        digitalWrite(LEDR1, LOW); 
        delay(500);        
        digitalWrite(LEDG1, LOW);  
        digitalWrite(LEDR1, HIGH); 
        delay(1000);
        digitalWrite(LEDG1, HIGH); 

}

void loop() {

  // =========== START GET MESSAGE ========================= //
  char rc;

  // the start marker is N, end marker is \n
  while (Serial1.available() > 0 && Serial1.available() < 7) {
    rc = Serial1.read();
    if (rc != '\n') {  // message has started but not reached the end
      msg += rc;
      delay(2);
    } else {  // endMarker reached
      msg += '\n';

      if (msg.charAt(0) == 'N' && msg.length() == 6) {  // message verify
        // Serial.print("Message: "); //test
        // Serial.print(msg); //test  
                  } // end verify message
    }  // end else for when rc reaches end marker
  }    // end while Serial1.available

  // =========== end GET MESSAGE ========================= //

  // =========== START SWITCH PRESS DETECTION ========================= //

    if (digitalRead(Btn1) == LOW) {  // Inputs LOW ACTIVE mode
      delay(10);  // software debounce
      if (digitalRead(Btn1) == LOW) {
        if(digitalRead(SuppRX) == LOW){
          digitalWrite(SuppTX, HIGH);
           if(digitalRead(IDPin) == HIGH) {Serial1.write("W1S1P\n"); 
             Serial.println("I sent a message"); //test
           } // tell Nano Pro Micro 1 button 1 was pressed
        if(digitalRead(IDPin) == LOW){Serial1.write("W2S1P\n"); } // tell Nano Pro Micro 2 button 1 was pressed
           delay(300);
           digitalWrite(SuppTX, LOW);
        } //end if suppRx is low
      } 
    } // end if digitalRead(Btn1) == LOW

    if (digitalRead(Btn2) == LOW) {  // Inputs LOW ACTIVE mode
       delay(10);  // software debounce
       if (digitalRead(Btn2) == LOW) {
           if(digitalRead(SuppRX) == LOW){
              digitalWrite(SuppTX, HIGH);
              if(digitalRead(IDPin) == HIGH) {Serial1.write("W1S2P\n"); 
                 Serial.println("I sent a message"); //test
              } // tell Nano Pro Micro 1 button 2 was pressed
           if(digitalRead(IDPin) == LOW){Serial1.write("W2S2P\n"); } // tell Nano Pro Micro 2 button 1 was pressed
              delay(300);
             digitalWrite(SuppTX, LOW);
           } //end if suppRx is low
       } 
    }  // end if digitalRead(Btn2) == LOW

  // =========== END SWITCH PRESS DETECTION ========================= //

  // =========== START EVALUATE COMMANDS ========================= //

  if (msg == "NS11N\n") {
        msg = "";
        while(Serial1.available()){Serial.read();}
        Serial.println("NS11N received"); //test
        digitalWrite(LEDR1, HIGH);

        for (int i = 0; i < 21; i++){
           digitalWrite(LEDG1, HIGH);  
           delay(500);
           digitalWrite(LEDG1, LOW);  
           delay(500);
        }
  }
  
    if (msg == "NS11J\n") {
         msg = "";
        while(Serial1.available()){Serial.read();}
        Serial.println("NS11J received"); //test
        digitalWrite(LEDG1, HIGH);  

        for (int j = 0; j < 21; j++){
           digitalWrite(LEDR1, LOW);  
           delay(500);
           digitalWrite(LEDR1, HIGH);  
           delay(500);
        }
  }

 if (msg == "NS12G\n") {
        msg = "";
        while(Serial1.available()){Serial.read();}
        Serial.println("NS12G received"); //test
        digitalWrite(LEDR2, HIGH);

        for (int k = 0; k <21; k++){
           digitalWrite(LEDG2, HIGH);  
           delay(500);
           digitalWrite(LEDG2, LOW);  
           delay(500);
        }
  }
  
    if (msg == "NS12J\n") {
         msg = "";
        while(Serial1.available()){Serial.read();}
        Serial.println("NS12J received"); //test
        digitalWrite(LEDG2, HIGH); 

        for (int l = 0; l < 21; l++){
           digitalWrite(LEDR2, LOW);  
           delay(500);
           digitalWrite(LEDR2, HIGH);  
           delay(500);
        }
  }

  // =========== END EVALUATE COMMANDS ========================= //

}  // end main program


Pro Micro and Nano will be about 125 ft apart communicating over shielded cat6.

That is a really long distance for 9600 BPS and a really lot of capacitance when trying to communicate using TTL signals. 0-5 volts. This is why RS-232 and other electrical specifications were developed so many years ago. Try RS-485 or R_422 communications.

We tested the system at our shop with a 200’ spool of Cat6 (EDIT: spool was labelled 200’ but was measure to be about 95’) and didn't experience any glitches, but as a better design we still may go with a different protocol like you mentioned. (EDIT: yes, we went with RS-485, much better!) We are using RS232 to control a video projector but that cable distance is only a few feet.

Found it!

The Pro Micro and Nano power up at the same time when the system is reset.

Some kind of noise from the Pro Micro was getting read by mySerial() on the Nano.

In setup on the Nano I added a 1 second delay.

Been testing about 30 minutes, no glitches.

Also, redacted the schematics at employer’s request.