Different time behavior for Serial1 with USB-cable connected and without?

I want to combine two Arduino Micro (due to lack of space I can't use the Mega). One Micro has all the communication modules (switches, Infrared, Bluetooth, capacitive sensors) and sends the values via Serial1 (Pin 0 and 1) to the main Micro which gets it via Serial1 (Pin 0 and 1).

As I had huge time lags, I have created a very, very simple test sketch. The idea is, that my main Micro sends all 200ms the code "color_1" to the communication Micro. At the end of the string I attach a "&" as a stopper sign. The communication Micro gets the String and answer "OK". Also a "&" as a stopper sign. This "OK" is not read by the main Micro, as it has no impact on the issue.

Issue: The main Micro works well, sends all 200ms the String. The communication Micro works well as long as I have the communication Micro connected via USB to Arduino IDE and have the SerialMonitor open. As soon as I remove the USB-cable, I get a way longer time (I see this on the LED on the communication Micro). If I disconnect the common power and power up again, then both Micros works well. Until I upload a new sketch to the communication Micro.

I have a common source with common Ground.

Sketch main Micro:

void setup() {
  pinMode(13, OUTPUT);
  Serial1.begin(57600);
}

void loop() {
  Serial1.write("color_1&");  //  Farbe 1, sprich für den Kopf der Schlang    
  digitalWrite(13,HIGH); delay(50);     digitalWrite(13,LOW); // visual check whats going on
  delay(150);
}

Code of the communication Micro:

void setup() {
  Serial1.begin(57600);
  pinMode(13,OUTPUT);
}

void loop() {
  if (Serial1.available()){
    Serial.println(Serial1.readStringUntil(38));  //38 is ASCII for "&" as stopper sign
    digitalWrite(13,HIGH); delay(30);     digitalWrite(13,LOW);  //visual check whats going on
    Serial1.write("OK&");
  }
   

}

The code you are using to receive the data is not robust and readStringUntil() is a blocking function. Have a look at the second and third examples in Serial Input Basics

...R

Thanks Robin

I tried example 3 but I had unfortunately the same issue as with my code... (Example 2 is the same but without start marker).

Is the issue, that I use "Serial1" instead of "Serial"? But with Micro I need Serial1 for the pins 0 and 1. With SoftwareSerial I could use also other pins, but I have timing issues on the communication Micro, as there is an Bluetooth module (HC-06) on the pins 11 and 12 (integrated with SoftwareSerial library).

Any other ideas?

chaterrony: I tried example 3 but I had unfortunately the same issue as with my code...

Please post that program so I can see exactly what you have tried.

...R

communication Micro:

// Example 3 - Receive with start- and end-markers
// http://forum.arduino.cc/index.php?topic=396450.0
// works until the USB-calbe is pluged off. Then the reset button needs to be pushed
// works, but not stable!

const byte numChars = 32;
char receivedChars[numChars];

boolean newData = false;

void setup() {
    Serial.begin(9600);
    Serial1.begin(57600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvWithStartEndMarkers();
    showNewData();
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
 
    while (Serial1.available() > 0 && newData == false) {
        rc = Serial1.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
        Serial1.write("<OK>");
    }
}

main Micro:

// Example 3 - Receive with start- and end-markers
// http://forum.arduino.cc/index.php?topic=396450.0
// works until the USB-calbe is pluged off. Then the reset button needs to be pushed
// works, but not stable!


// Example 2 - Receive with an end-marker

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

void setup() {
    Serial.begin(9600);
    Serial1.begin(57600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvWithEndMarker();
    showNewData();
}

void recvWithEndMarker() {
    static byte ndx = 0;
    char endMarker = '\n';
    char rc;
    
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            ndx = 0;
            newData = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
    }
}

You have not explained the roles of the two programs in Reply #4. I'm sorry, but I can't know what is in your head unless you tell me.

Also I don't know what your comment means where it says "works until the USB-calbe is pluged off". If an Arduino was being powered by the USB cable, of course it won't work when you disconnect the cable.

...R

Sorry, you’re right. It was no correct response.

My intention is to send from the main Micro to the communication Micro a request for datas. This should be read by the communication Micro and then be answered. The test sketch has only a “” (with start and end marker) as an answer. In the real programm there are the inputs from my code.

However, I have updated the code with an LED (13) blinking every time when the communication Micro is answering. If everything goes well, i have 100ms HIGH and 100ms LOW on the LED.

The setup is, that I have an USB cable as power source (common 5V and ground for both Arduinos) and a seccond USB cable for communication. Both USB cables are connected to my external monitor (so same voltage level).
When I have connected the communication Micro to the computer and upload the code, the LED works fine. This means, I get the request from the main Micro. After I unplug the usb cable, the LED is firing for 1s in this interval and changes then to an interval of 300ms HIGH, 300ms LOW. If I then push reset on the communication Micro, it works well again…
Same goes with the main Micro.
It looks like they don’t like if I unplug the USB Data cable? Is this possible? Does the Micro need some time to switch the internal power supply channel and interrupts the code during this?

Here us the updated code for the communication Micro (with LED 13 for visual check):

// Example 3 - Receive with start- and end-markers
// http://forum.arduino.cc/index.php?topic=396450.0
// works until the USB-Data-cable is pluged off. Then the reset button needs to be pushed
// Power source is stable
// Code works, but not stable

const byte numChars = 32;
char receivedChars[numChars];

boolean newData = false;

void setup() {
    pinMode(13,OUTPUT);
    digitalWrite(13,LOW);
    Serial.begin(9600);
    Serial1.begin(57600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvWithStartEndMarkers();
    showNewData();
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
 
    while (Serial1.available() > 0 && newData == false) {
        rc = Serial1.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        digitalWrite(13,HIGH); delay(100);digitalWrite(13,LOW);delay(100);
        newData = false;
        Serial1.write("<OK>");
    }
}

Am I correct in thinking you are using the MAIN program from Reply #4 with the COMMUNICATION program from Reply #6?

How are the two Micros connected to each other?

In the MAIN program you initialize Serial1 but you don't use it - so how can data get to the other Micro?

In the MAIN program you use recvWithEndMarker() but in the COMMUNICATION program you use recvWithStartEndMarkers(). Why aren't they both the same?

Please post an example of the output from both programs while they are communicating with each other.

...R

I don’t get it. I did the “main” Arduino code again and now it works…
I need to sleep more to get a better view about the code. Sorry for this and thanks a lot for your help!

Below the working code for the Serial1 communication between 2 Arduino Micro.

main Arduino:
```
**// Example 3 - Receive with start- and end-markers
// http://forum.arduino.cc/index.php?topic=396450.0
// works until the USB-calbe is pluged off. Then the reset button needs to be pushed
// works, but not stable!

// Example 2 - Receive with an end-marker

const byte numChars = 32;
char receivedChars[numChars];  // an array to store the received data
long timer=0; // time stamp to send a command to “control” Arduino
boolean newData = false;

void setup() {   
    pinMode(13,OUTPUT);
    digitalWrite(13,LOW);
    Serial.begin(9600);
    Serial1.begin(57600);
    Serial.println("");
    Serial1.write("<color_1>");  // 11 ist der Code für die Farbe 1, sprich für den Kopf der Schlang   
}

void loop() {
    if((millis()-timer)>1000){ // alle 1000ms wird der Befehl geschickt.
      Serial1.write("<color_1>");  // 11 ist der Code für die Farbe 1, sprich für den Kopf der Schlang   
      timer=millis(); // set back timer   
    }
    recvWithEndMarker();
    showNewData();
    delay(3); // Simulation delay of NeoPixel command (132Pixels = 2-3ms)
}

void recvWithEndMarker() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = ‘<’;
    char endMarker = ‘>’;
    char rc;
   
    while (Serial1.available() > 0 && newData == false) {
        rc = Serial1.read();

if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = ‘\0’; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("Confirmation by communication Arduino ");
        Serial.println(receivedChars);
        digitalWrite(13,HIGH); delay(100);digitalWrite(13,LOW);delay(100);
        newData = false;
    }
}[/b]**
** __**communication Arduino:**__ **
**// Example 3 - Receive with start- and end-markers
// http://forum.arduino.cc/index.php?topic=396450.0
// works until the USB-calbe is pluged off. Then the reset button needs to be pushed
// works, but not stable!

const byte numChars = 32;
char receivedChars[numChars];

boolean newData = false;

void setup() {
    pinMode(13,OUTPUT);
    digitalWrite(13,LOW);
    Serial.begin(9600);
    Serial1.begin(57600);
    Serial.println("");
}

void loop() {
    recvWithStartEndMarkers();
    showNewData();
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = ‘<’;
    char endMarker = ‘>’;
    char rc;

while (Serial1.available() > 0 && newData == false) {
        rc = Serial1.read();

if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = ‘\0’; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print(“This just in … “);
        Serial.println(receivedChars);
        digitalWrite(13,HIGH); delay(100);digitalWrite(13,LOW);delay(100);
        newData = false;
        Serial1.write(””);
    }
}**
```