recvWithEndMarker Use it more than once for the same data received?

Hello,
in a project I am being working on I have noticed that "recvWithEndMarker" from the Serial Basics post -which is very helpful by the way- that using it twice doesn't work for me.

Basically what I am doing is upon a simple input like "1", goes to a switch and calls:

recvWithEndMarker();
showNewData();
parseData();
showParsedData();

which parses the data from an array structured like this "int1,int2,int3,int4" into this a = int1, b = int2 and so on. Using it once works fine, but if I go back to the same mode in the switch, the values goes crazy and stop working.

Maybe is something simple that I am missing. Looking forward to your comments.

Thank you!

Post the code, in code tags, please.

OK, right now is a little bit messy, full of mashups, I am currently working on it. I added more data to parse, but anyways, here it is.

#include "SPI.h"
#include <Wire.h>
#include <SoftwareSerial.h>
SoftwareSerial BTserial(2, 3); // RX | TX
// Connect the HC-05 TX to Arduino pin 2 RX. 
// Connect the HC-05 RX to Arduino pin 3 TX through a voltage divider.

// simple parse demo

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

char recvChar;
char endMarker = '>';
boolean newData = false;

int activities, totalAct, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, x, y;
int sum = 0;
int far, medium, near;
int act1, act2, act3, act4, act5, act6, act7, act8, act9, act10; // types of activities
int mode = 0;

bool clear = true;

char bt = ' '; // the data given from Computer

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

    strip.begin();
    strip2.begin();
    strip3.begin();

    strip.setBrightness(BRIGHTNESS); // set brightness
    strip2.setBrightness(BRIGHTNESS); // set brightness
    strip3.setBrightness(BRIGHTNESS); // set brightness

    // startup sequence
    delay(500);
    colorWipe(strip.Color(255, 0, 0), 20); // Red
    colorWipe(strip2.Color(255, 0, 0), 20); // Red
    colorWipe(strip3.Color(255, 0, 0), 20); // Red
    delay(500);

    BTserial.begin(9600);
    Serial.println("<BT is ready>");
    BTserial.print(1);
}
  
void loop() {
  

  delay(1000);

   // Keep reading from HC-05 and send to Arduino Serial Monitor
  if (BTserial.available() > 0)
  {  
      bt = BTserial.read();
      Serial.write(bt);
      
  }

  bluetoothProximity();
 
   
  // get activities time

  int activities[10] = { act1, act2, act3, act4, act5, act6, act7, act8, act9, act10 };
  int totalAct = 0;

  for (i = 0; i < 10; i++) {
    if (activities[i] > 0) {
        totalAct += activities[i];
        delay(10);
    }         
  }

  act1 = (act1 * TOP)/totalAct;
  delay(10);

  // Serial.print(act1); // 0

  act2 = (act2 * TOP)/totalAct;
  delay(10);

  // Serial.print(act2); // 0.42

  act3 = (act3 * TOP)/totalAct;
  delay(10);

  // Serial.print(act3); // 0.63934426

  act4 = (act4 * TOP)/totalAct;
  delay(10);

  // Serial.print(act4); // 0.63934426

  act5 = (act5 * TOP)/totalAct;
  delay(10);

  // Serial.print(act5); // 1.27868852

  act6 = (act6 * TOP)/totalAct;
  delay(10);

  // Serial.print(act6); // 7.67213115

  act7 = (act7 * TOP)/totalAct;
  delay(10);

  // Serial.print(act7); // 1.27868852

  act8 = (act8 * TOP)/totalAct;
  delay(10);

  // Serial.print(act8); // 0.85245902

  act9 = (act9 * TOP)/totalAct;
  delay(10);

  // Serial.print(act9); // 0.85245902

  act10 = (act10 * TOP)/totalAct;
  delay(10);

  // Serial.print(act10); // 0

  if (totalAct < 0L) totalAct = 0;  // Clip output
  else if(totalAct > TOP) totalAct = TOP;
  totalAct = TOP;

  pixelArrange();

  //display
  strip.show();
  //display
  strip2.show();
  //display
  strip3.show();

  // wait
  delay(100);
  
  if (!BTserial.available())
    {  
//something
  return;
    }

   // Keep reading from Arduino Serial Monitor and send to HC-05
  if (Serial.available())
  {
      bt =  Serial.read();
      BTserial.write(bt);

  }

}

void bluetoothProximity() {

  switch (bt) {

  case 'w':
  mode = 0;
  return;

  case 'x':
  mode = 1;
  
  if (clear) {
  clearStrip();
  clear = false;
  Serial.println("waiting...");
  delay(3000);
  recvWithEndMarker();
  showNewData();
  parseData();
  showParsedData();
  Serial.println("Far");
  }

  delay(200);

  act1 = a;
  delay(100);
  act2 = b;
  delay(100);
  act3 = c;
  delay(100);
  act4 = d;
  delay(100);
  act5 = e;
  delay(100);

  Serial.println(act1);
  Serial.println(act2);
  Serial.println(act3);
  Serial.println(act4);
  Serial.println(act5);
  return;

  case 'y':
  mode = 2;

  if (clear) {
  clearStrip();
  clear = false;
  }

  act1 = f;
  delay(100);
  act2 = g;
  delay(100);
  act3 = h;
  delay(100);
  act4 = i;
  delay(100);
  act5 = j;
  delay(100);

  Serial.println(act1);
  Serial.println(act2);
  Serial.println(act3);
  Serial.println(act4);
  Serial.println(act5);
  return;

  case 'z':
  mode = 3;

  if (clear) {
    clearStrip();
    clear = false;
  }

  Serial.println("near");
  
  act1 = k;
  delay(100);
  act2 = l;
  delay(100);
  act3 = m;
  delay(100);
  act4 = n;
  delay(100);
  act5 = o;
  delay(100);

  Serial.println(act1);
  Serial.println(act2);
  Serial.println(act3);
  Serial.println(act4);
  Serial.println(act5);
  return;

  }
  
  }

// Turn off all pixels
void clearStrip() {
  for( int i = 0; i<8; i++){
    strip.setPixelColor(i, 0x000000); strip.show();
  }
  for( int i = 0; i<8; i++){
    strip2.setPixelColor(i, 0x000000); strip2.show();
  }
  for( int i = 0; i<8; i++){
    strip3.setPixelColor(i, 0x000000); strip3.show();
  }
}


void parseData() {

    // split the data into its parts
    
  char * strtokIndx; // this is used by strtok() as an index
  
  strtokIndx = strtok(receivedChars,",");      // get the first part - the string
  a = atoi(strtokIndx); // copy it to messageFromPC
  
  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  b = atoi(strtokIndx); // copy it to messageFromPC
  
  strtokIndx = strtok(NULL, ","); 
  c = atoi(strtokIndx); // copy it to messageFromPC

  strtokIndx = strtok(NULL, ","); 
  d = atoi(strtokIndx); // copy it to messageFromPC

    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  e = atoi(strtokIndx); // copy it to messageFromPC
  
  strtokIndx = strtok(NULL, ","); 
  f = atoi(strtokIndx); // copy it to messageFromPC

  strtokIndx = strtok(NULL, ","); 
  g = atoi(strtokIndx); // copy it to messageFromPC

  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  h = atoi(strtokIndx); // copy it to messageFromPC

  strtokIndx = strtok(NULL, ","); 
  i = atoi(strtokIndx); // copy it to messageFromPC

  strtokIndx = strtok(NULL, ","); 
  j = atoi(strtokIndx); // copy it to messageFromPC

    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  l = atoi(strtokIndx); // copy it to messageFromPC

    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  m = atoi(strtokIndx); // copy it to messageFromPC

    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  n = atoi(strtokIndx); // copy it to messageFromPC

    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  o = atoi(strtokIndx); // copy it to messageFromPC

}

void showParsedData() {
 Serial.print("a:");
 Serial.println(a);
 Serial.print("b: ");
 Serial.println(b);
 Serial.print("c: ");
 Serial.println(c);
 Serial.print("d: ");
 Serial.println(d);
  Serial.print("e:");
 Serial.println(e);
 Serial.print("f: ");
 Serial.println(f);
 Serial.print("g: ");
 Serial.println(g);
 Serial.print("h: ");
 Serial.println(h);
 Serial.print("i: ");
 Serial.println(i);
 Serial.print("j: ");
 Serial.println(j);
 Serial.print("k: ");
 Serial.println(k);
 Serial.print("l: ");
 Serial.println(l);
 Serial.print("m: ");
 Serial.println(m);
 Serial.print("n: ");
 Serial.println(n);
 Serial.print("o: ");
 Serial.println(o);
}

void recvWithEndMarker() {
 static byte ndx = 0;
 char endMarker = '\n';
 char rc;
 
 // if (Serial.available() > 0) {
 while (BTserial.available() > 0 && newData == false) {
 rc = BTserial.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;
    }
}

delay(1000);

There's your problem. More than 64 serial characters might arrive while you are stuck in the delay, so you will never get a proper data packet.

And all those little delay(10)s? Get rid of them too.

Why are you using if (BTserial.available() > 0) when you know how to use the examples in Serial Input Basics. You can have another copy of the relevant example to receive the Bluetooth data.

And take all the delay()s out of your program. You should ensure that receiveWithEndMarker() is called as often as possible. You can use millis() to manage timing without blocking. See Several Things at a Time

Personally I would call it directly from loop() and use my other functions (for example your bluetoothProximity() to process the data it receives.

I don't understand this

which parses the data from an array structured like this "int1,int2,int3,int4" into this a = int1, b = int2 and so on. Using it once works fine, but if I go back to the same mode in the switch, the values goes crazy and stop working.

You need to post the code so I can see exactly what you mean by "go back to the same mode in the switch"

You cannot read the same data twice. After a Serial.read() the data has been taken from the Serial input buffer. However it will remain in the array receivedChars[] until your code sets newData to false.

...R

Hi, thanks! I updated it a little bit taking your advices, I am posting the code again.

#include "SPI.h"
#include <Wire.h>
#include <Adafruit_NeoPixel.h> // include the library code:
#include <SoftwareSerial.h>
SoftwareSerial BTserial(2, 3); // RX | TX
// Connect the HC-05 TX to Arduino pin 2 RX. 
// Connect the HC-05 RX to Arduino pin 3 TX through a voltage divider.

// simple parse demo

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

char recvChar;
char endMarker = '>';
boolean newData = false;

int activities, totalAct, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, x, y;
int sum = 0;
int far, medium, near;
int act1, act2, act3, act4, act5, act6, act7, act8, act9, act10; // types of activities
int mode = 0;

bool clear = true;

char bt = ' '; // the data given from Computer

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

    strip.begin();
    strip2.begin();
    strip3.begin();

    strip.setBrightness(BRIGHTNESS); // set brightness
    strip2.setBrightness(BRIGHTNESS); // set brightness
    strip3.setBrightness(BRIGHTNESS); // set brightness

    // startup sequence
    delay(500);
    colorWipe(strip.Color(255, 0, 0), 20); // Red
    colorWipe(strip2.Color(255, 0, 0), 20); // Red
    colorWipe(strip3.Color(255, 0, 0), 20); // Red
    delay(500);

    BTserial.begin(9600);
    Serial.println("<BT is ready>");
    BTserial.print(1);
}
  
void loop() {

   // Keep reading from HC-05 and send to Arduino Serial Monitor
  if (BTserial.available() > 0)
  {  
      bt = BTserial.read();
      Serial.write(bt);
      
  }

  bluetoothProximity();
 
   
  // get activities time

  int activities[10] = { act1, act2, act3, act4, act5, act6, act7, act8, act9, act10 };
  int totalAct = 0;

  for (i = 0; i < 10; i++) {
    if (activities[i] > 0) {
        totalAct += activities[i];
    }         
  }

  act1 = (act1 * TOP)/totalAct;

  // Serial.print(act1); // 0

  act2 = (act2 * TOP)/totalAct;

  // Serial.print(act2); // 0.42

  act3 = (act3 * TOP)/totalAct;

  // Serial.print(act3); // 0.63934426

  act4 = (act4 * TOP)/totalAct;

  // Serial.print(act4); // 0.63934426

  act5 = (act5 * TOP)/totalAct;

  // Serial.print(act5); // 1.27868852

  act6 = (act6 * TOP)/totalAct;

  // Serial.print(act6); // 7.67213115

  act7 = (act7 * TOP)/totalAct;

  // Serial.print(act7); // 1.27868852

  act8 = (act8 * TOP)/totalAct;
  
  // Serial.print(act8); // 0.85245902

  act9 = (act9 * TOP)/totalAct;
  
  // Serial.print(act9); // 0.85245902

  act10 = (act10 * TOP)/totalAct;
  
  // Serial.print(act10); // 0

  if (totalAct < 0L) totalAct = 0;  // Clip output
  else if(totalAct > TOP) totalAct = TOP;
  totalAct = TOP;

  pixelArrange();

  //display
  strip.show();
  //display
  strip2.show();
  //display
  strip3.show();

  if (!BTserial.available())
    {  
//something
  return;
    }

   // Keep reading from Arduino Serial Monitor and send to HC-05
  if (Serial.available())
  {
      bt =  Serial.read();
      BTserial.write(bt);
  }

}

void bluetoothProximity() {

  switch (bt) {

  case '0':
  mode = 0;
  return;

  case '1':
  mode = 1;
  
  if (clear) {
  clearStrip();
  clear = false;
  Serial.println("waiting...");
  recvWithEndMarker();
  showNewData();
  parseData();
  showParsedData();
  Serial.println("Far");
  }

  act1 = a;
  act2 = b;
  act3 = c;
  act4 = d;
  act5 = e;

  Serial.println(act1);
  Serial.println(act2);
  Serial.println(act3);
  Serial.println(act4);
  Serial.println(act5);
  return;

  case '2':
  mode = 2;

  if (clear) {
  clearStrip();
  clear = false;
  }

  act1 = f;
  act2 = g;
  act3 = h;
  act4 = i;
  act5 = j;
  

  Serial.println(act1);
  Serial.println(act2);
  Serial.println(act3);
  Serial.println(act4);
  Serial.println(act5);
  return;

  case '3':
  mode = 3;

  if (clear) {
    clearStrip();
    clear = false;
  }

  Serial.println("near");
  
  act1 = k;
  act2 = l;
  act3 = m;
  act4 = n;
  act5 = o;

  Serial.println(act1);
  Serial.println(act2);
  Serial.println(act3);
  Serial.println(act4);
  Serial.println(act5);
  return;

  }
  
  }

void parseData() {

    // split the data into its parts
    
  char * strtokIndx; // this is used by strtok() as an index
  
  strtokIndx = strtok(receivedChars,",");      // get the first part - the string
  a = atoi(strtokIndx); // copy it to messageFromPC
  
  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  b = atoi(strtokIndx); // copy it to messageFromPC
  
  strtokIndx = strtok(NULL, ","); 
  c = atoi(strtokIndx); // copy it to messageFromPC

  strtokIndx = strtok(NULL, ","); 
  d = atoi(strtokIndx); // copy it to messageFromPC

    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  e = atoi(strtokIndx); // copy it to messageFromPC

}

void showParsedData() {
 Serial.print("a:");
 Serial.println(a);
 Serial.print("b: ");
 Serial.println(b);
 Serial.print("c: ");
 Serial.println(c);
 Serial.print("d: ");
 Serial.println(d);
  Serial.print("e:");
 Serial.println(e);

}

void recvWithEndMarker() {
 static byte ndx = 0;
 char endMarker = '\n';
 char rc;
 
 // if (Serial.available() > 0) {
 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;
    }
}

Guys, thank you for your help and advice, indeed I removed the delays that were scattered around the code and it worked. Although I only put a delay(2000); before receiving the data upon bluetooth.

Thank you very much.

jordicasanueva:
Hi, thanks! I updated it a little bit taking your advices,

Which ones?

You did not clarify the part I said I do not understand!

How does your revised program perform?

...R