When I run this test program, it crashes just before leaving the decipherReceived function. Sometimes It will crash in the middle of printing the last Serial.print line in decipherReceived. But the crash is initiated in the jsonParseValue function somewhere. If I change the if condition from jsonParseValue() to true, it doesn’t crash.
The only way to recover is to remove the power completely and plug it in again, a simple press of the reset button doesn’t work. What am I missing?
bool serial4Ready = true; // ready to write data into wifiData array
char recData[255] = "{\"id\":\"env101\",\"type\":\"env\",\"name\":\"Hub temp sensor\",\"firmware\":\"v.1.0\",\"values\":{\"t\": 78.08,\"h\":49.60}}";
/*************************** setup ******************************************************************************************************/
void setup() {
Serial.begin(9600);
delay(50);
}
void loop() {
if (serial4Ready) {
readSerial();
}
}
void readSerial()
{
serial4Ready = false;
decipherReceived(recData);
}
void decipherReceived(char * data) {
// find sensor id and acknowledge data receipt
char sensorId[7];
// check for valid json string
if (strchr(data, '{') != NULL) {
Serial.printf("From sub-hub %d bytes: %s\n\n", strlen(data), data);
if (findJsonValue(data, "id", sensorId) != NULL) { //*** this function call causes a delayed crash
publishSensorData(data);
}
}
Serial.println("data has been published");
}
void publishSensorData(char * data) {
// publish data
Serial.printf("To cloud (%d bytes): \n%s\n\n", strlen(data), &data[0]);
publishResponse("not published", "development mode");
}
void publishResponse(const char *event, const char *data) {
Serial.printf("From cloud: %s, %s\n", event, data);
}
/* json parser library */
char * findJsonValue(char * jsonStr, const char * jsonKey, char * valueChar) {
if (jsonStr == NULL) {return NULL;}
char * res;
res = strstr(jsonStr, jsonKey);
if (res == NULL) {
*valueChar = '\0';
return NULL;
} else {
boolean exitLoop = false;
res = strchr(res, ':');
while (!exitLoop) {
res++;
if ((strchr("\"", *res)) != NULL) {
exitLoop = true;
parseJsonString(res, valueChar);
}
}
}
if (*valueChar == '\0') {
return NULL;
} else {
Serial.printf("returning %s\n", valueChar);
return valueChar;
}
}
char * parseJsonString(char * jsonStr, char * result) {
strcpy(result, jsonStr+1);
// find the next " character (end of string)
char * resEnd = strchr(result, '\"');
if (resEnd != NULL) {
*resEnd = '\0';
} else {
*result = {};
result = NULL;
Serial.println("JSON parse error");
}
return result;
}
The output I receive from running this on an Electron is:
C:\Users\mpete\Downloads>particle serial monitor
Opening serial monitor for com port: "COM3"
Serial monitor opened successfully:
From sub-hub 104 bytes: {"id":"env101","type":"env","name":"Hub temp sensor","firmware":"v.1.0","values":{"t": 78.08,"h":49.60}}
returning env101
To cloud (104 bytes):
{"id":"env101","type":"env","name":"Hub temp sensor","firmware":"v.1.0","values":{"t": 78.08,"h":49.60}}
From cloud: not published, deSerial connection closed.
Caught Interrupt. Cleaning up.
C:\Users\mpete\Downloads>