Recently I started some tests controlling water heater with temperature sensor data as described in detail here
So far I've been testing a small dataset to control water temperature that is quite easy to write down by myself.
#include <NTPClient.h>
#include <WiFi.h>
#include <WiFiUdp.h>
//WiFi Conf
const char *ssid = "ssid_addr";
const char *password = "wifi_password";
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
unsigned long current_time;
// Sensors Conf (fixed value just to test relay response)
float temperature = 30.5;
//Relay Conf
const int relay = 26;
struct SetPoint {
unsigned long time;
float temperature;
};
#define DATA_SIZE 8
SetPoint scen1[DATA_SIZE] = {
{1616952559, 32.4},
{1616952739, 10.2},
{1616952859, 10.4},
{1616952867, 40.2},
{1616952927, 20.4},
{1616952928, 35.2},
{1616952945, 22.4},
{1616952947, 28.2}
};
unsigned int pos = 0;
void setup() {
Serial.begin(115200);
pinMode(relay, OUTPUT);
WiFi.begin(ssid, password);
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
Serial.print ( "." );
}
timeClient.begin();
}
void loop() {
timeClient.update();
long current_time = timeClient.getEpochTime();
if (pos < DATA_SIZE && current_time >= scen1[pos].time) {
set_thermostat(/*data[pos].temperature, temperature*/);
pos++;
}
Serial.println(timeClient.getEpochTime());
Serial.println(timeClient.getFormattedTime());
Serial.println(pos);
delay(3000);
}
void set_thermostat() {
if (temperature < scen1[pos].temperature) {
digitalWrite (relay, HIGH);
}
else if (temperature > scen1[pos].temperature) {
digitalWrite (relay, LOW);
}
}
But now I'm planning to use a larger file with different datapoints and an option is to store them in a sdcard and, then, the microcontroller parses each line to control the temperature with an interval of three hours.
There will be about 720 lines with the following structure ("Scen" is the temperature simulation scenarios that will be the reference to turn the relays on or off):
Time,UNIX,Scen1,Scen2,Scen3
21/04/2021 00:00:00,1618963200,"27.45","29.01","30.85"
21/04/2021 21:00:00,1619038800,"26.16","27.82","29.75"
21/04/2021 06:00:00,1618984800,"25.28","26.83","29.02"
21/04/2021 09:00:00,1618995600,"24.62","26.49","28.51"
21/04/2021 12:00:00,1619006400,"27.19","29.47","29.53"
21/04/2021 15:00:00,1619017200,"30.65","34.07","30.50"
21/04/2021 18:00:00,1619028000,"31.87","35.78","31.78"
21/04/2021 21:00:00,1619038800,"30.43","35.20","30.88"
22/04/2021 00:00:00,1619049600,"28.45","31.86","29.47"
The problem is that it is hard to find out how to parse data from the file into two variables (UNIX Time and temperature), for each temperature scenario, as used here:
struct SetPoint {
unsigned long time;
float temperature;
};
#define DATA_SIZE 8
//scenario 1 array
SetPoint scen1[DATA_SIZE] = {
{1616952559, 32.4},
{1616952739, 10.2},
{1616952859, 10.4},
{1616952867, 40.2},
{1616952927, 20.4},
{1616952928, 35.2},
{1616952945, 22.4},
{1616952947, 28.2}
};
Is there an effective way to get what I'm looking for?
strtok()
on the resulting c-string (please avoid theString
class). Note that strtok alters the c-string. Please try googling for a strtok tutorial and try it out. Maybe that is already what you need. (strtok is a bit difficult to understand at first, but it is a really good way to tokenize a string)