Serial flush - seems I can't get it to clear data

I'm using Arduino uno to control addressable leds, if uses bluetooth an app I made for my phone and sends serial data. For some reason I can't get serial data to clear.

Here's some code, so you can see

void colours(){
  fill_solid(leds, NUM_LEDS, CRGB(varR1, varG1, varB1)); //put this here so when we start or break out of fx, colour is populated 
  
  if (Serial.available() > 0) {
    dataIn = Serial.readString();
    delay(100);//give the data time to be read before we can read info from it.
    
    if (dataIn.startsWith("A")) {
      String stringR = dataIn.substring(dataIn.indexOf("R") + 1, dataIn.indexOf("G"));
      varR1 = stringR.toInt();
      String stringG = dataIn.substring(dataIn.indexOf("G") + 1, dataIn.indexOf("B"));
      varG1 = stringG.toInt();
      String stringB = dataIn.substring(dataIn.indexOf("B") + 1, dataIn.indexOf("E"));
      varB1 = stringB.toInt();
      if ((stringR.length() > 0) && (stringG.length() > 0)&& (stringB.length() > 0)){
        fill_solid(leds, NUM_LEDS, CRGB(varR1, varG1, varB1));
        }
      /*
      //debug - to check incoming remote commands work.
      char buf [100]; // must be large enough for the whole string
      sprintf (buf, "Red: %d, Green: %d, Blue: %d", varR1, varG1, varB1);
      String sum = (buf);
      Serial.println(sum);
      */
      }
    
    else if (dataIn.startsWith("B")) {
      String stringBright = dataIn.substring(dataIn.indexOf("E") + 1, dataIn.indexOf("F"));
      BRIGHTNESS = stringBright.toInt();
      FastLED.setBrightness(BRIGHTNESS);
      
      //debug - to check incoming remote commands work.
      char buf [100]; // must be large enough for the whole string
      sprintf (buf, "Brightness: %d", BRIGHTNESS);
      String sum = (buf);
      Serial.println(sum);
      
      }
    else if (dataIn.startsWith("FX")) {
      FastLED.clear();
      ledMode = 1;
      }
  }
  
  if (dataIn.length() >=4){
    delay(300); //this seems to be the best time to allow fastled code to run and give enough time for data to be sent to the leds.
    Serial.flush();
    Serial.println(dataIn.length());
  }
}

I need to put a delay in so that the data gets enough time to read before the routine loops again and ends up sending the wrong data. However when I check the data length - it's not been cleared by Serial.flush() when the loop resets, what an I doing wrong?

Serial.flush() waits for the transmission of outgoing serial data to complete. Is that what you are trying to do ?

I am trying to get rid of a delay if there's no serial data being sent for example:

void colours(){
  fill_solid(leds, NUM_LEDS, CRGB(varR1, varG1, varB1)); //put this here so when we start or break out of fx, colour is populated 
  
  if (Serial.available() > 0) {
    dataIn = Serial.readString();
    delay(100);//give the data time to be read before we can read info from it.
    
    if (dataIn.startsWith("A")) {
      String stringR = dataIn.substring(dataIn.indexOf("R") + 1, dataIn.indexOf("G"));
      varR1 = stringR.toInt();
      String stringG = dataIn.substring(dataIn.indexOf("G") + 1, dataIn.indexOf("B"));
      varG1 = stringG.toInt();
      String stringB = dataIn.substring(dataIn.indexOf("B") + 1, dataIn.indexOf("E"));
      varB1 = stringB.toInt();
      if ((stringR.length() > 0) && (stringG.length() > 0)&& (stringB.length() > 0)){
        fill_solid(leds, NUM_LEDS, CRGB(varR1, varG1, varB1));
        }
      /*
      //debug - to check incoming remote commands work.
      char buf [100]; // must be large enough for the whole string
      sprintf (buf, "Red: %d, Green: %d, Blue: %d", varR1, varG1, varB1);
      String sum = (buf);
      Serial.println(sum);
      */
      }
    
    else if (dataIn.startsWith("B")) {
      String stringBright = dataIn.substring(dataIn.indexOf("E") + 1, dataIn.indexOf("F"));
      BRIGHTNESS = stringBright.toInt();
      FastLED.setBrightness(BRIGHTNESS);

      /*
      //debug - to check incoming remote commands work.
      char buf [100]; // must be large enough for the whole string
      sprintf (buf, "Brightness: %d", BRIGHTNESS);
      String sum = (buf);
      Serial.println(sum);
      */
      
      }
    else if (dataIn.startsWith("FX")) {
      FastLED.clear();
      ledMode = 1;
      }
  }
  
  if (dataIn.length() > 0){
    Serial.print(dataIn);
    dataIn = ""; 
  }
  delay(250); //this seems to be the best time to allow fastled code to run and give enough time for data to be sent to the leds.
}

If I change the code and put the delay here:

 if (dataIn.length() > 0){
    Serial.print(dataIn);
    delay(250); //this seems to be the best time to allow fastled code to run and give enough time for data to be sent to the leds.
    dataIn = ""; 
  }

The delay doesn't seem to work properly and only the first 2 string characters are read. I realised after posting it wasn't the serial buffer I needed to flush, I just needed to clear the dataIn string. Now I just have this delay issue.

Is the incoming data terminated in some way, perhaps with a Carriage Return ?

If so, then why not read characters if they are available and add them to the String until you get the end of message marker, then use the message that you have accumulated ?

See Serial input basics - updated

I'm not sure what you mean, most of the time the data received is fine - by if I am in a delay when the data is sent, it doesn't fully get read:

example:

AR255G255B255
AR255G255B255
AR255G255B255
AR255G255B255
AR255G255B255
AR
AR255G255B255
AR255G255B255
AR255G255B255
AR255G255B255
AR255G255B255
AR255G255B255
AR255G255B255
AR255G255B255

I wanted to get rid of the delay near the bottom of the code, so the delay in the void only gets run when dataIn string is not empty.

Did you look at the examples in the link I posted ?

1 Like

I'll have a look, thanks for replying. I'll figure it out- maybe I am having a blonde moment.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.