Nope. Eventually your code reaches the end of SRAM then starts writing at the beginning until the top of the stack is reached at which point your application enters "undefined behaviour mode".
You need to perform bounds checking on serialBatteryIndex.
Once you have your line in char array,
simply use strstr() in order to find first occurence of "keyword" and then atoi() to convert substring to integer
Example:
char str[] = "$ SmartUPS V3.10,Vin NG,BATCAP 57,Vout 5207 $";
char * pch;
int value;
pch = strstr(str, "BATCAP");
value = atoi(pch + strlen("BATCAP"));
Serial.print("Text found at pos: ");
Serial.println(pch - str + 1); // pch - str give the start position
Serial.print("Value: ");
Serial.prinln(value);
// The next value
pch = strstr(str,"Vout");
value = atoi(pch + strlen("Vout"));
Serial.print("Text found at pos: ");
Serial.println(pch - str + 1); // pch - str give the start position
Serial.print("Value: ");
Serial.prinln(value);
wow you are right, that was dumb of me! thanks for pointing that out. I actually figured it out once you reminded me of that. THANKS!
This is the solution for everyone else but I think it might not work for the 2 cases of battery level = 100 or a single digit number. For that I think I'd need to do something like read everything after BATCAP and before a ",".
But for everything else (10-99%):
unsigned long previousMillisD = 0;
int intervalD = 1000;
const byte numChars=45; //counting characters, not number of characters from Serial3.available();
char incomingByte[numChars] ; //size of array
int serialBatteryIndex = 0;
int batCap ;
void serialBatteryRead(){
while (Serial3.available() > 0) {
incomingByte[serialBatteryIndex] = Serial3.read(); //write Serial3 into array
if(serialBatteryIndex==numChars){ //this ensures output only once per intervalD
byte index;
int batcap1 = incomingByte[42]-'0';
int batcap2 = incomingByte[43]-'0';
batCap = batcap1*10+batcap2;
Serial.print(batCap);
Serial.println();
}
serialBatteryIndex++;
if(serialBatteryIndex>numChars){
serialBatteryIndex=0; //reset index
}
}
}
//============
void setup() {
Serial.begin(115200);
Serial3.begin(9600);
}
void loop() {
unsigned long currentMillis = millis();
if(currentMillis - previousMillisD > intervalD) {
previousMillisD = currentMillis;
serialBatteryRead();
}
}
wow thanks, I figured it out a different way that has some limitations, but this is a much more elegant solution that seems to account for cases of BATCAP < 10 and BATCAP = 100.