I'm building a tide clock that involves going out to the Web to consume a tidal API. Being my first real Arduino project it has a number of unknowns so I've been breaking it down into smaller projects to prove the code. I can consume the API and have been experimenting how to parse the JSON. Accepted ArduinoJSON might be a solution but I thought, based on the amount I had to parse, a bespoke piece of code would be worth trying. It has certainly taught me a lot about the string class! Perhaps not enough.
I've built it up bit by bit to prove it works (and it does!). However I can Serial.Print the value of the global variable tideType and tideTime in the function, but if I try to do this after calling the function getTideDetails from setup the monitor reports this
About to start Get Tide Details
Starting Get Tide Details
About to start Get Tide Details
Starting Get Tide Details
About to start Get Tide Details
Starting Get Tide Details
About to start Get Tide Details
Starting Get Tide Details
About to start Get Tide Details
Starting Get Tide Details....(on and on)
It must be the way I'm handling the strings tideType and tideTime because whenever I try to Serial.print them from setup after the function, it looks like the Arduino restarts. However tideHeight which is a float outputs fine.
Can someone put me out of my misery?
Code below (be kind)
char array[] = "[{\"EventType\":\"LowWater\",\"DateTime\":\"2021-03-05T02:15:00\",\"IsApproximateTime\":false,\"Height\":1.3632871362992067,\"IsApproximateHeight\":false,\"Filtered\":false,\"Date\":\"2021-03-05T00:00:00\"},{\"EventType\":\"HighWater\",\"DateTime\":\"2021-03-05T08:25:00\",\"IsApproximateTime\":false,\"Height\":5.2168696552371623,\"IsApproximateHeight\":false,\"Filtered\":false,\"Date\":\"2021-03-05T00:00:00\"},{\"EventType\":\"LowWater\",\"DateTime\":\"2021-03-05T14:25:00\",\"IsApproximateTime\":false,\"Height\":1.8097719968974781,\"IsApproximateHeight\":false,\"Filtered\":false,\"Date\":\"2021-03-05T00:00:00\",{\"EventType\":\"HighWater\",\"DateTime\":\"2021-03-05T20:47:00\",\"IsApproximateTime\":false,\"Height\":5.3284583370257206,\"IsApproximateHeight\":false,\"Filtered\":false,\"Date\":\"2021-03-05T00:00:00\"";
char *ptr = NULL;
char tideType[9] = "";
char tideTime[10] = "";
float tideHeight = 0;
void setup()
{
Serial.begin(9600);
delay(500);
Serial.println("About to start Get Tide Details");
getTideDetails();
delay(500);
Serial.println("getTideDetails has completed");
Serial.print("Tide type is ");
Serial.println(tideType); //As sson as you do this it appears to restart. Comment this out and it runs normally
//Serial.print("Tide time is ");
//Serial.println(tideTime);
Serial.print("Tide Height is set at ");
Serial.println(tideHeight,4);
}
void getTideDetails(){
Serial.println("Starting Get Tide Details");
ptr = strtok(array, "\",\{[\}"); // takes a list of delimiters
while (ptr != NULL)
{
//Serial.println(ptr);
if (strcmp(ptr, "EventType") == 0) { //Identified tag called EventType
ptr = strtok(NULL, "\",\{[\}:"); //Put the pointer to the next tag
strncpy(tideType, ptr, strlen(ptr)); //copy low or high water across
tideType[strlen(ptr)] = '\0'; //terminate it to avoid corruption
} else if (strcmp(ptr, "DateTime") == 0) { //Identified tage called DateTime
ptr = strtok(NULL, "\",\{[\}"); //skip a tag two avoid unwanted colon
ptr = strtok(NULL, "\",\{[\}"); //Pointer is now at the start of the time element
strncpy(tideTime, ptr, strlen(ptr)); //copy it across to tide time string
tideTime[strlen(ptr)] = '\0'; //terminate it to avoid corruption
} else if (strcmp(ptr, "Height") == 0){ //Identified tag called Height
ptr = strtok(NULL, "\",\{[\}:"); //Pointer is now at the start of the tide height tag
tideHeight = atof(ptr); //Convert to float and assign.
}
ptr = strtok(NULL, "\",\{[\}"); // Move to the next tag
}
}
void loop()
{
// put your main code here, to run repeatedly:
}