Arduino / DigiSpark / ATtiny85 - Receiving and parsing several pieces of data

Hello, i would like to expand on Robin2 example 5 that can be found here:

I am running a digispark / ATtiny 85 for my NeoPixel project and i’m sending my string via bluetooth, i’ve used Robin2 tutorial to do so but i ran into issues when i tired to send longer string, more exactly when i was acctualy trying to parse them into INTs.

i will post my full code then i will go on at explaing what the issues are and how i think i might be able to solve them, if you guys & gals are willing to help me out a bit.

#include <Adafruit_NeoPixel.h> // NeoPixel Lib
#include <SoftSerial.h>  // Serial Lib
#define LED_PIN    2
#define LED_COUNT 30

SoftSerial bluetooth(4, 5); // RX TX
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

const byte numChars = 42;
char receivedChars[numChars];
char tempChars[numChars];
boolean newData = false;

int eFx = 1;
int rC1 = 100;
int gC1 = 100;
int bC1 = 100;
int xS = 20;
int xB = 100;
int rC2 = 5;
int gC2 = 50;
int bC2 = 200;


void setup() {

  bluetooth.begin (9600);
  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP

}


void loop() {
  recvWithStartEndMarkers();
  if (newData == true) {
        strcpy(tempChars, receivedChars);
            // this temporary copy is necessary to protect the original data
            //   because strtok() used in parseData() replaces the commas with \0
  parseData();
  strip.setBrightness(xB);
  controlLed();  
  newData = false;
  }

}


void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
 
    while (bluetooth.available() > 0 && newData == false) {
        rc = bluetooth.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 parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempChars, ",");      // get the first part - the string
    eFx = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, ",");      // get the first part - the string
    rC1 = atoi(strtokIndx);     // convert this part to an integer
 
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    gC1 = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    bC1 = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, ",");
    xS = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, ",");
    xB = atoi(strtokIndx);     // convert this part to an integer




}





void controlLed() {
         colorWipe(strip.Color(rC1, gC1, bC1), xS);
         colorWipe(strip.Color(20, 50, 100), 50);
}

void controlLed2() {

         colorWipe(strip.Color(rC2, gC2, bC2), xS);
} 

void colorWipe(uint32_t color, int wait) {
  
  for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(wait);                           //  Pause for a moment
  }
}

So, what i want to do is store/update all these INTs, and maybe more:

int eFx = 1;
int rC1 = 100;
int gC1 = 100;
int bC1 = 100;
int xS = 20;
int xB = 100;
int rC2 = 5;
int gC2 = 50;
int bC2 = 200;

at this point i can do about

int eFx = 1;
int rC1 = 100;
int gC1 = 100;
int bC1 = 100;
int xS = 20;
int xB = 100;

when i add to parsedata () more things to process then what is here, it stops working:

void parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempChars, ",");      // get the first part - the string
    eFx = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, ",");      // get the first part - the string
    rC1 = atoi(strtokIndx);     // convert this part to an integer
 
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    gC1 = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    bC1 = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, ",");
    xS = atoi(strtokIndx);     // convert this part to an integer

    strtokIndx = strtok(NULL, ",");
    xB = atoi(strtokIndx);     // convert this part to an integer

}

i believe to be an issue of memory, and i think, might be wrong, that the solution is to split the process into 2 parts.

What i want to do is have another string sent that is between and not < > and get another parseData(), like parseData2() to process the info.

now i’m not sure in the first place how the parseData() acctualy knows how to get that string and not something else…

is it because of this call in the void loop?

void loop() {
  recvWithStartEndMarkers();
  if (newData == true) {
        strcpy(tempChars, receivedChars);
  parseData();

Also another thing that is very unclear to me is in the void recvWithStartEndMarkers() {

    while (bluetooth.available() > 0 && newData == false) {
        rc = bluetooth.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;
        }

why is it (rc == startMarker) at the end and not at the beginning ?

well, what i would like to do is rewrite the recvWithStartEndMarkers() to detect first if string starts with [ or < and then to store the values in receivedChars or receivedChars2 and then to run them through parseData(); or parseData2(); so i can get my INTS stored.

Also some behavior i’ve noticed and i call controlLed(); in the void loop

void loop() {
  recvWithStartEndMarkers();
  if (newData == true) {
        strcpy(tempChars, receivedChars);
            // this temporary copy is necessary to protect the original data
            //   because strtok() used in parseData() replaces the commas with \0
  parseData();
  strip.setBrightness(xB);
  controlLed();  
  newData = false;
  }

}

if i run controlLed(); outside the if statement it works but it does not update the colors that i send, any idea why is that?

lots of questions, i’m a total noob :frowning: