drmpf:
@dragynn
Question 1, let me look into that. SafeStringReader has alot of extra code to handle input buffer overflows, skip to next delimiter and timeout, but I would not have expected it to take an extra 11mS. but...
Question 2.
Check out the GPS parsing example which splits via ",*" and change the
char delims[] = ",*"; // fields delimited by , or *
to
char delims[] = "-"; // fields delimited by -
OK, Question 2 follow up... I have it almost figured out but I am getting some weird results.
What is supposed to happen:
Input a line into the serial monitor like ArdString-21-21-20-27-1-3-150-1 and it will return PiStr-21-21-20-27-1-3-150-1. Change any of the numbers in the original string and it will return the numbers preceded by PiStr. if all numbers are the same nothing is returned.
#include <millisDelay.h>
#include <SafeString.h>
#include <BufferedOutput.h>
#include <loopTimer.h>
#include <SafeStringReader.h>
millisDelay printDelay;
createBufferedOutput(output, 66, DROP_UNTIL_EMPTY); // modes are DROP_UNTIL_EMPTY, DROP_IF_FULL or BLOCK_IF_FULL
// set up SafeString environment
// args are (ReaderInstanceName, expectedMaxCmdLength, delimiters)
createSafeStringReader(sfReader, 50, " ,\r\n");
createSafeString(msgStr, 30);
createSafeString(field, 10); // for the field strings. Should have capacity > largest field length
createSafeString(PiString, 50, " ,\r\n");
createSafeString(ArdString, 50, " ,\r\n");
createSafeString(PiStringOld, 50, " ,\r\n");
int8_t print2serial = 0; //set to zero to diable serial printing of debug lines ,
const char delimiters[] = "-"; // just dash for delimiter, could also use ",;" if comma or semi-colon seperated fields
int nextIdx = 0; // index into inputLine
size_t fieldNumber = 0;
bool returnEmptyFields = true; // ,, returns an empty field
int8_t Drivers_tempC_var = 0; //Drivers Area Temp
int8_t Passenger_tempC_var = 0; //Passenger Area Temp
int8_t CabAve_var = 20; //Current Cabin Average
int8_t CabinSet_var = 27; //Desired Temperature
int8_t SystemState_var = 1; //System State Selection (Off/On/Auto) Value 1-3
int8_t DamperSel_var = 3; //Damper Selection (Cabin/Defrost/Both)Value 1-3
int FanActual_var = 0; //Fan Speed actual
int8_t Units_var = 0; // Units of measure for system 0 = Celcius, 1 = Fereinheit
int8_t flag = 0;
void setup() {
// put your setup code here, to run once:
// SafeString::setOutput(Serial);
output.connect(Serial); // <<<<< connect the buffered output to Serial
// sfReader.connect(Serial); // where SafeStringReader will read from
sfReader.connect(output); // where SafeStringReader will read from
sfReader.echoOn(); // echo goes out via bufferedOut
sfReader.setTimeout(100); // set 100mS == 0.1sec non-blocking timeout
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
output.nextByteOut();
ListenToPI();
}
void ListenToPI() {
if (sfReader.read()) {
if (sfReader.startsWith("ArdString-")) {
DecodeArdString();
}
} // else no delimited command yet
}
void DecodeArdString() {
flag = 0;
while (nextIdx >= 0) { // still finding tokens
nextIdx = sfReader.stoken(field, nextIdx, delimiters, returnEmptyFields); // steps over previous delimiter // returns -1 if none found
field.debug(F(" sfReader.stoken => "));
fieldNumber++;
float f;
if (field.toFloat(f)) {
if ( print2serial == 1 ) { //print first type of debug line
output.print(F("Field ")); output.print(fieldNumber); output.print(F(" : ")); output.println(f);
}
if ( fieldNumber == 2) {
if (Drivers_tempC_var == f) {
} else {
Drivers_tempC_var = f;
flag = 1;
}
}
//String Pi2Str = String(Passenger_tempC_var);
if ( fieldNumber == 3) {
if (Passenger_tempC_var == f) {
} else {
Passenger_tempC_var = f;
flag = 1;
}
}
//String Pi3Str = String(CabAve_var);
if ( fieldNumber == 4) {
if (CabAve_var == f) {
} else {
CabAve_var = f;
flag = 1;
}
}
//String Pi4Str = String(CabinSet_var);
if ( fieldNumber == 5) {
if (CabinSet_var == f) {
} else {
CabinSet_var = f;
flag = 1;
}
}
//String Pi5Str = String(SystemState_var);
if ( fieldNumber == 6) {
if (SystemState_var == f) {
} else {
SystemState_var = f;
flag = 1;
}
}
//String Pi6Str = String(DamperSel_var);
if ( fieldNumber == 7) {
if (DamperSel_var == f) {
} else {
DamperSel_var = f;
flag = 1;
}
}
//String Pi7Str = String(FanActual_var);
if ( fieldNumber == 8) {
if (FanActual_var == f) {
} else {
FanActual_var = f;
flag = 1;
}
}
//String Pi8Str = String(Units_var);
if ( fieldNumber == 9) {
if (Units_var == f) {
} else {
Units_var = f;
flag = 1;
}
}
} else {
SafeString::Output.print(F("TR- ,")); SafeString::Output.print(field); SafeString::Output.println(F(", is not a number"));
}
}
nextIdx = 0;
fieldNumber = 0;
if (flag == 1) {
// flag = 0;
TalkToPI();
}
}
void TalkToPI() {
PiString.concat("PiStr-").concat(Drivers_tempC_var).concat("-").concat(Passenger_tempC_var).concat("-").concat(CabAve_var).concat("-").concat(CabinSet_var).concat("-").concat(SystemState_var).concat("-").concat(DamperSel_var).concat("-").concat(FanActual_var).concat("-").concat(Units_var).concat("\n");
output.println(PiString);
}
The results:
ArdString-22-21-20-27-1-3-150-1
10:33:15.736 -> ,
10:33:15.736 -> PiStr-22-21-20-27-1-3-150-1
10:33:15.736 ->
10:33:19.983 -> ArdString-21-21-20-27-1-3-150-1
10:33:19.983 -> ,
10:33:19.983 -> PiStr-22-21-20-27-1-3-150-1
10:33:19.983 -> PiStr-21-21-20-27-
10:34:06.308 -> ArdString-21-21-20-27-1-3-150-1
10:34:12.947 -> ArdString-21-21-20-27-1-3-150-0
10:34:12.947 -> ,
10:34:12.947 -> PiStr-22-21-20-27-1-3-150-1
10:34:12.947 -> PiStr-21-21-20-27-
I don't know where the "," in the second and fifth (etc) line is coming from... it seems to be interrupting my PiStr which then never recovers. I also get an extra PiStr before my modified PiStr (so I am assuming it is in the buffer already?)
set print2serial = 1 and I get:
10:37:57.111 -> ArdString-21-21-20-27-1-3-150-1
10:37:57.111 -> Field 2 : 21.00
10:37:57.111 -> Field 3 : 21.00
10:37:57.111 -> Field 4 : 20.00
10:37:57.111 -> Field 5 : 27.00
10:37:57.111 -> Field 6 : 1.00
10:37:57.111 -> Field 7 : 3.00
10:37:57.111 -> Field 8 : 150.00
10:37:57.111 -> Field 9 : 1.00
10:37:57.111 -> ,
10:37:57.111 -> PiStr-21-21-20-27-1-3-150-1
10:37:57.111 ->
10:38:05.319 -> ArdString-22-21-20-27-1-3-150-1
10:38:05.319 -> Field 2 : 22.00
10:38:05.319 -> Field 3 : 21.00
10:38:05.319 -> Field 4 : 20.00
10:38:05.319 -> Field 5 : 27.00
10:38:05.319 -> Field 6 : 1.00
10:38:05.319 -> Field 7 : 3.00
10:38:05.319 -> Field 8 : 150.00
10:38:05.319 -> Field 9 : 1.00
10:38:05.319 -> ,
10:38:05.319 -> PiStr-21-21-20-27-1-3-150-1
10:38:05.319 -> PiStr-22-21-20-27-
So the changed line is being received and parsed but the previous PiStr is returned first.
I'm stumped,
Thanks
Dragynn