Serial.print slow down the main loop - but only while is Serial Monitor closed!

Dear community,

I have standard 4digit 7segment display and fast Serial.print loop (sending ADC value to my computer via USB). Everything work well while I have Serial Monitor opened. But when is closed, the 7segment display starts to flickering (up to several seconds) BUT only before I open Serial Monitor. Than all speeds up like normally. If I close Serial Monitor again, after a while all start to slow down.

I have block of code for reading from Serial. I am storing incoming data into one String and than parsing it (have special first and last char to recognize a command from computer). I tested that all variables are cleaned so no “memory leaks” can happen. I belive problem is somewhere in internal MCU buffer. Does anyone know what to do with this problem?

Thank you.

Please post your code. Please use code tags.

I have block of code for reading from Serial.

I look forward to seeing it

Or ... here is code. Because it is huge, I will show only parts which use serial.

    Serial.print(SENSOR);
    Serial.print("=");
    Serial.print(VALUE, 0);
    Serial.print(";");

... this code sends ADC value to the computer every 10 milliseconds. Next code is for parsing incoming string from computer. Command allways start with char "#" and ends with char ";". My application can succesfully send command to my custom board.

  if (Serial.available() > 0) {
    INCOMING_DATA.concat(Serial.readString());
    String MESSAGE = "";
    while (INCOMING_DATA.length() > 0) {
      if (INCOMING_DATA.startsWith("#")) {
        if (INCOMING_DATA.indexOf(';') != -1) {
          MESSAGE = INCOMING_DATA.substring(0, INCOMING_DATA.indexOf(';') + 1); 
          INCOMING_DATA.remove(0, MESSAGE.length());
          break; 
        }
      } else {
        INCOMING_DATA.remove(0, 1);
      }
    }        
    if (MESSAGE != "") {
      int POS_DELIMETER = ZPRAVA.indexOf('=');
      if (POS_DELIMETER != -1) {    
        String COMMAND = MESSAGE.substring(0, POS_DELIMETER );
        String VALUE = MESSAGE.substring(POS_DELIMETER + 1, MESSAGE.length() - 1);
      if (COMMAND == "#SET_VALUE") {
         ...
         ...

Code is simple. It will concat all the data into one string, find first and last char, cut it out and separate command from value (if it has value).

So. How is it possible that if I not have Serial Monitor opened, Arduino start to slowing down? And when I open Serial Monitor than Arduino go normally?!

Any idea?

Well it would help if you at least posted all the code using Serial, told us which board you are using, which OS on the host and what other programs on the host might be accessing the serial port.

Post full code !

Using a board with native USB support like Leonardo? In that case, check with availableForWrite() if there is still space to write.

OK … I spend over one hour with code analysis and found weir behaviour. I thought it is a problem of reading on serial but I was wrong. I try to describe it:

  1. Turn ON an Arduino with 4 digit 7 segment display. It will show 9999 on 7segment display. All looks good at this moment.
  2. Open Arduino Serial Monitor to see if data is sending correctly. BUT from this moment, when I close Serial Montor, 7segment display start to flickering (switching digits with slow frequency).
  3. Re-open Serial Monitor remove flickering to normal.

… so, after Arduino start is all in normal. First open of Serial Monitor will “crash” something in Arduino and it starts to behave weirdly!

Please take a look on AKTUALNI_DIGIT. This variable will rotate from 4 to 1 and represent which 7segment digit will be ON at one loop cycle. If I place line “AKTUALNI_DIGIT = 1” before “switch (AKTUALNI_DIGIT) {”, flickering never happen…

Maybe I have a mistake in a code but I not see where. Any idea?

Thanks!

Code:

int SENZOR = 1;
int AKTUALNI_DIGIT = 4;
int HODNOTA = 9999;

const byte SEG_D1 = A4;
const byte SEG_C  = A3;
const byte SEG_D2 = A2;
const byte SEG_B  = A1;
const byte SEG_D  = A0;
const byte SEG_DP = 13;
const byte SEG_E  = 5; 
const byte SEG_F  = 10;
const byte SEG_G  = 9; 
const byte SEG_D3 = 8; 
const byte SEG_A  = 6; 
const byte SEG_D4 = 12;

void setup() {
  Serial.begin(115200);
  delay(1000);

  pinMode(SEG_D1, OUTPUT);
  pinMode(SEG_C,  OUTPUT);
  pinMode(SEG_D2, OUTPUT);
  pinMode(SEG_B,  OUTPUT);
  pinMode(SEG_D,  OUTPUT);
  pinMode(SEG_DP, OUTPUT);
  pinMode(SEG_E,  OUTPUT);
  pinMode(SEG_F,  OUTPUT);
  pinMode(SEG_G,  OUTPUT);
  pinMode(SEG_D3, OUTPUT);
  pinMode(SEG_A,  OUTPUT);
  pinMode(SEG_D4, OUTPUT);  
}

void loop() {
  Nastav_7segment(HODNOTA);
    
  Serial.print(SENZOR);
  Serial.print("R=");
  Serial.print(HODNOTA);
  Serial.print(";");

  delay(1);
}

void Nastav_7segment(int HODNOTA) {  
  // zobrazení hodnot 7segmentu
  if (HODNOTA < 0) {
    HODNOTA = 0;
  } else if (HODNOTA > 9999) {
    HODNOTA = 9999;
  }

  // separace jednotlivých znaků 
  int DIGIT   = 0;
  int DIGIT_1 = HODNOTA / 1000;
  int DIGIT_2 = (HODNOTA - (DIGIT_1 * 1000)) / 100;
  int DIGIT_3 = (HODNOTA - (DIGIT_1 * 1000 + DIGIT_2 * 100)) / 10;
  int DIGIT_4 = HODNOTA % 10;
    
  // zhasnutí všech segmentů
  digitalWrite(SEG_D1, HIGH);
  digitalWrite(SEG_D2, HIGH);
  digitalWrite(SEG_D3, HIGH);
  digitalWrite(SEG_D4, HIGH); 

  // cyklování znaků 7segmentu            
  switch (AKTUALNI_DIGIT) {
    case 1:      
      if (HODNOTA > 999) {
        DIGIT = DIGIT_1;       
        digitalWrite(SEG_D1, LOW);
      }
      AKTUALNI_DIGIT = 4;
      break;
    case 2:    
      if (HODNOTA > 99) {
        DIGIT = DIGIT_2;
        digitalWrite(SEG_D2, LOW);
      }
      AKTUALNI_DIGIT = 1;
      break;
    case 3: 
      if (HODNOTA > 9) {
        DIGIT = DIGIT_3;   
        digitalWrite(SEG_D3, LOW);
      }
      AKTUALNI_DIGIT = 2;
      break;
    case 4:      
      if (HODNOTA >= 0) {
        DIGIT = DIGIT_4;
        digitalWrite(SEG_D4, LOW);
      }
      AKTUALNI_DIGIT = 3;
      break;
  }

  // rozsvícení daného znaku
  switch (DIGIT) {
    case 0:
      digitalWrite(SEG_A,  HIGH);
      digitalWrite(SEG_B,  HIGH);
      digitalWrite(SEG_C,  HIGH);
      digitalWrite(SEG_D,  HIGH);
      digitalWrite(SEG_E,  HIGH);
      digitalWrite(SEG_F,  HIGH);
      digitalWrite(SEG_G,  LOW);
      digitalWrite(SEG_DP, LOW);
      break;
    case 1:
      digitalWrite(SEG_A,  LOW);
      digitalWrite(SEG_B,  HIGH);
      digitalWrite(SEG_C,  HIGH);
      digitalWrite(SEG_D,  LOW);
      digitalWrite(SEG_E,  LOW);
      digitalWrite(SEG_F,  LOW);
      digitalWrite(SEG_G,  LOW);
      digitalWrite(SEG_DP, LOW);
      break;
    case 2:
      digitalWrite(SEG_A,  HIGH);
      digitalWrite(SEG_B,  HIGH);
      digitalWrite(SEG_C,  LOW);
      digitalWrite(SEG_D,  HIGH);
      digitalWrite(SEG_E,  HIGH);
      digitalWrite(SEG_F,  LOW);
      digitalWrite(SEG_G,  HIGH);
      digitalWrite(SEG_DP, LOW);
      break;
    case 3:
      digitalWrite(SEG_A,  HIGH);
      digitalWrite(SEG_B,  HIGH);
      digitalWrite(SEG_C,  HIGH);
      digitalWrite(SEG_D,  HIGH);
      digitalWrite(SEG_E,  LOW);
      digitalWrite(SEG_F,  LOW);
      digitalWrite(SEG_G,  HIGH);
      digitalWrite(SEG_DP, LOW);
      break;
    case 4:
      digitalWrite(SEG_A,  LOW);
      digitalWrite(SEG_B,  HIGH);
      digitalWrite(SEG_C,  HIGH);
      digitalWrite(SEG_D,  LOW);
      digitalWrite(SEG_E,  LOW);
      digitalWrite(SEG_F,  HIGH);
      digitalWrite(SEG_G,  HIGH);
      digitalWrite(SEG_DP, LOW);
      break;
    case 5:
      digitalWrite(SEG_A,  HIGH);
      digitalWrite(SEG_B,  LOW);
      digitalWrite(SEG_C,  HIGH);
      digitalWrite(SEG_D,  HIGH);
      digitalWrite(SEG_E,  LOW);
      digitalWrite(SEG_F,  HIGH);
      digitalWrite(SEG_G,  HIGH);
      digitalWrite(SEG_DP, LOW);
      break;
    case 6:
      digitalWrite(SEG_A,  HIGH);
      digitalWrite(SEG_B,  LOW);
      digitalWrite(SEG_C,  HIGH);
      digitalWrite(SEG_D,  HIGH);
      digitalWrite(SEG_E,  HIGH);
      digitalWrite(SEG_F,  HIGH);
      digitalWrite(SEG_G,  HIGH);
      digitalWrite(SEG_DP, LOW);
      break;
    case 7:
      digitalWrite(SEG_A,  HIGH);
      digitalWrite(SEG_B,  HIGH);
      digitalWrite(SEG_C,  HIGH);
      digitalWrite(SEG_D,  LOW);
      digitalWrite(SEG_E,  LOW);
      digitalWrite(SEG_F,  LOW);
      digitalWrite(SEG_G,  LOW);
      digitalWrite(SEG_DP, LOW);
      break;
    case 8:
      digitalWrite(SEG_A,  HIGH);
      digitalWrite(SEG_B,  HIGH);
      digitalWrite(SEG_C,  HIGH);
      digitalWrite(SEG_D,  HIGH);
      digitalWrite(SEG_E,  HIGH);
      digitalWrite(SEG_F,  HIGH);
      digitalWrite(SEG_G,  HIGH);
      digitalWrite(SEG_DP, LOW);
      break;
    case 9:
      digitalWrite(SEG_A,  HIGH);
      digitalWrite(SEG_B,  HIGH);
      digitalWrite(SEG_C,  HIGH);
      digitalWrite(SEG_D,  HIGH);
      digitalWrite(SEG_E,  LOW);
      digitalWrite(SEG_F,  HIGH);
      digitalWrite(SEG_G,  HIGH);
      digitalWrite(SEG_DP, LOW);
      break;   
    default:
      digitalWrite(SEG_A,  LOW);
      digitalWrite(SEG_B,  LOW);
      digitalWrite(SEG_C,  LOW);
      digitalWrite(SEG_D,  LOW);
      digitalWrite(SEG_E,  LOW);
      digitalWrite(SEG_F,  LOW);
      digitalWrite(SEG_G,  LOW);
      digitalWrite(SEG_DP, LOW);
      break;
    }
}

unknow001:
… so, after Arduino start is all in normal. First open of Serial Monitor will “crash” something in Arduino and it starts to behave weirdly!

When you open the Serial Monitor the Arduino will reset, the same as if you pressed the reset button.

Among other things that will cause all your SEG pins to revert to INPUT until they are changed to OUTPUT in your setup() function after the 1 second delay.

It might be wise to initialize all the segments in setup().

…R

From timj37

The flickering issue with the 7 segment display relating to viewing through serial port..... You have to increase the baud rate both in your code and then changing it on the serial setting... Hope that helps!