diff --git a/ampel-firmware/co2_sensor.cpp b/ampel-firmware/co2_sensor.cpp index 430b945575fe37c115351a741cf90caffa549e64..0850128e81a7d1826673a370f79eea8a348fc310 100644 --- a/ampel-firmware/co2_sensor.cpp +++ b/ampel-firmware/co2_sensor.cpp @@ -22,7 +22,7 @@ namespace sensor { uint16_t co2 = 0; float temperature = 0; float humidity = 0; - String timestamp = ""; + char timestamp[23]; int16_t stable_measurements = 0; uint32_t waiting_color = color::blue; bool should_calibrate = false; @@ -168,7 +168,7 @@ namespace sensor { if (freshData) { // checkTimerDeviation(); - timestamp = ntp::getLocalTime(); + ntp::getLocalTime(timestamp); co2 = scd30.getCO2(); temperature = scd30.getTemperature(); humidity = scd30.getHumidity(); diff --git a/ampel-firmware/co2_sensor.h b/ampel-firmware/co2_sensor.h index dd18bcf312048448ea665ad61b12ccb14b6f27c4..3a2b6f8976f1ffaab6cd024f2b2964a5ecfc564a 100644 --- a/ampel-firmware/co2_sensor.h +++ b/ampel-firmware/co2_sensor.h @@ -22,7 +22,7 @@ namespace sensor { extern uint16_t co2; extern float temperature; extern float humidity; - extern String timestamp; + extern char timestamp[23]; void initialize(); bool processData(); diff --git a/ampel-firmware/config.public.h b/ampel-firmware/config.public.h index feb7f4e612f0fecb0b268f58b7b8fbdee04cb6ff..1ca67666cb3f76cb20ca1a9d03dc1b38d6bc3558 100644 --- a/ampel-firmware/config.public.h +++ b/ampel-firmware/config.public.h @@ -144,7 +144,7 @@ */ # define NTP_SERVER "pool.ntp.org" -# define UTC_OFFSET_IN_SECONDS 3600 // [s] 3600 for UTC+1 +# define UTC_OFFSET_IN_SECONDS 7200 // [s] 3600 for UTC+1, 7200 for UTC+1 and daylight saving time /** * Others diff --git a/ampel-firmware/csv_writer.cpp b/ampel-firmware/csv_writer.cpp index 2a7f462a4a750ed7565a8ff8318d6a608cbf12a0..7720e67493b4b3205296826686aac68454489842 100644 --- a/ampel-firmware/csv_writer.cpp +++ b/ampel-firmware/csv_writer.cpp @@ -6,7 +6,7 @@ namespace config { } namespace csv_writer { unsigned long last_written_at = 0; - String last_successful_write = ""; + char last_successful_write[23]; #if defined(ESP8266) /** @@ -132,11 +132,11 @@ namespace csv_writer { return csv_file; } - void log(const String &timeStamp, const int16_t &co2, const float &temperature, const float &humidity) { + void log(const char *timestamp, const int16_t &co2, const float &temperature, const float &humidity) { led_effects::onBoardLEDOn(); File csv_file = openOrCreate(); char csv_line[42]; - snprintf(csv_line, sizeof(csv_line), "%s;%d;%.1f;%.1f\r\n", timeStamp.c_str(), co2, temperature, humidity); + snprintf(csv_line, sizeof(csv_line), "%s;%d;%.1f;%.1f\r\n", timestamp, co2, temperature, humidity); if (csv_file) { size_t written_bytes = csv_file.print(csv_line); csv_file.close(); @@ -145,7 +145,7 @@ namespace csv_writer { } else { Serial.print(F("CSV - Wrote : ")); Serial.print(csv_line); - last_successful_write = ntp::getLocalTime(); + ntp::getLocalTime(last_successful_write); } updateFsInfo(); delay(50); @@ -156,7 +156,7 @@ namespace csv_writer { led_effects::onBoardLEDOff(); } - void logIfTimeHasCome(const String &timeStamp, const int16_t &co2, const float &temperature, const float &humidity) { + void logIfTimeHasCome(const char *timeStamp, const int16_t &co2, const float &temperature, const float &humidity) { unsigned long now = seconds(); if (now - last_written_at > config::csv_interval) { last_written_at = now; diff --git a/ampel-firmware/csv_writer.h b/ampel-firmware/csv_writer.h index 080d5cdcc2e4b2e5aa17617118120f5c5213dac6..ab4a87b2972e8b3ae597e637a6f309da0d829658 100644 --- a/ampel-firmware/csv_writer.h +++ b/ampel-firmware/csv_writer.h @@ -20,9 +20,9 @@ namespace config { extern uint16_t csv_interval; // [s] } namespace csv_writer { - extern String last_successful_write; + extern char last_successful_write[23]; void initialize(); - void logIfTimeHasCome(const String &timeStamp, const int16_t &co2, const float &temperature, const float &humidity); + void logIfTimeHasCome(const char* timestamp, const int16_t &co2, const float &temperature, const float &humidity); int getAvailableSpace(); extern const String filename; diff --git a/ampel-firmware/lorawan.cpp b/ampel-firmware/lorawan.cpp index 70a02e1c8325a21a42f63402956d497264baf3d8..57fa7441e3f21e836a4a75721e47be14b63dbc85 100644 --- a/ampel-firmware/lorawan.cpp +++ b/ampel-firmware/lorawan.cpp @@ -33,7 +33,7 @@ void os_getDevKey(u1_t *buf) { namespace lorawan { bool waiting_for_confirmation = false; bool connected = false; - String last_transmission = ""; + char last_transmission[23] = ""; void initialize() { Serial.println(F("Starting LoRaWAN. Frequency plan : " LMIC_FREQUENCY_PLAN " MHz.")); @@ -65,8 +65,10 @@ namespace lorawan { } void onEvent(ev_t ev) { + char current_time[23]; + ntp::getLocalTime(current_time); Serial.print("LoRa - "); - Serial.print(ntp::getLocalTime()); + Serial.print(current_time); Serial.print(" - "); switch (ev) { case EV_JOINING: @@ -113,7 +115,7 @@ namespace lorawan { Serial.println(F("EV_REJOIN_FAILED")); break; case EV_TXCOMPLETE: - last_transmission = ntp::getLocalTime(); + ntp::getLocalTime(last_transmission); Serial.println(F("EV_TXCOMPLETE")); break; case EV_TXSTART: diff --git a/ampel-firmware/lorawan.h b/ampel-firmware/lorawan.h index 6cf1226f72f7385e075ff387c160d0dbdefa2ffd..45f462b2ef761066797ccd2ff114762088b5c628 100644 --- a/ampel-firmware/lorawan.h +++ b/ampel-firmware/lorawan.h @@ -39,7 +39,7 @@ namespace config { namespace lorawan { extern bool waiting_for_confirmation; extern bool connected; - extern String last_transmission; + extern char last_transmission[]; void initialize(); void process(); void preparePayloadIfTimeHasCome(const int16_t &co2, const float &temp, const float &hum); diff --git a/ampel-firmware/mqtt.cpp b/ampel-firmware/mqtt.cpp index 516090744a5ac7c8cfed9cfdee02391b5bb78d4e..1037aa5c64a1701bbda39e984ee8ed0904f5cf27 100644 --- a/ampel-firmware/mqtt.cpp +++ b/ampel-firmware/mqtt.cpp @@ -25,7 +25,7 @@ namespace mqtt { String publish_topic; const char *json_sensor_format; - String last_successful_publish = ""; + char last_successful_publish[23] = ""; void initialize(String &topic) { json_sensor_format = PSTR("{\"time\":\"%s\", \"co2\":%d, \"temp\":%.1f, \"rh\":%.1f}"); @@ -41,17 +41,17 @@ namespace mqtt { " (Sends local IP and SSID via MQTT. Can be useful to find sensor)"); } - void publish(const String ×tamp, int16_t co2, float temperature, float humidity) { + void publish(const char *timestamp, int16_t co2, float temperature, float humidity) { if (WiFi.status() == WL_CONNECTED && mqttClient.connected()) { led_effects::onBoardLEDOn(); Serial.print(F("MQTT - Publishing message ... ")); char payload[75]; // Should be enough for json... - snprintf(payload, sizeof(payload), json_sensor_format, timestamp.c_str(), co2, temperature, humidity); + snprintf(payload, sizeof(payload), json_sensor_format, timestamp, co2, temperature, humidity); // Topic is the same as clientID. e.g. 'CO2sensors/ESP3d03da' if (mqttClient.publish(publish_topic.c_str(), payload)) { Serial.println(F("OK")); - last_successful_publish = ntp::getLocalTime(); + ntp::getLocalTime(last_successful_publish); } else { Serial.println(F("Failed.")); } @@ -120,12 +120,12 @@ namespace mqtt { } } - void publishIfTimeHasCome(const String &timeStamp, const int16_t &co2, const float &temp, const float &hum) { + void publishIfTimeHasCome(const char *timestamp, const int16_t &co2, const float &temp, const float &hum) { // Send message via MQTT according to sending interval unsigned long now = seconds(); if (now - last_sent_at > config::mqtt_sending_interval) { last_sent_at = now; - publish(timeStamp, co2, temp, hum); + publish(timestamp, co2, temp, hum); } } diff --git a/ampel-firmware/mqtt.h b/ampel-firmware/mqtt.h index aaaa95621d10cdf0a8608700654a89b360563989..9167c47dda720528f138ff048630d399e6656984 100644 --- a/ampel-firmware/mqtt.h +++ b/ampel-firmware/mqtt.h @@ -11,11 +11,11 @@ namespace config { extern uint16_t mqtt_sending_interval; // [s] } namespace mqtt { - extern String last_successful_publish; + extern char last_successful_publish[]; extern bool connected; void initialize(String &topic); void keepConnection(); - void publishIfTimeHasCome(const String &timeStamp, const int16_t &co2, const float &temp, const float &hum); + void publishIfTimeHasCome(const char *timestamp, const int16_t &co2, const float &temp, const float &hum); void setMQTTinterval(int32_t sending_interval); void sendInfoAboutLocalNetwork(); diff --git a/ampel-firmware/src/lib/NTPClient-master/NTPClient.cpp b/ampel-firmware/src/lib/NTPClient-master/NTPClient.cpp index 048a82a4bcec1d3885070fbb83db764f60369080..1b52de5af6eefae690044fa9138222fb3aa78d1b 100644 --- a/ampel-firmware/src/lib/NTPClient-master/NTPClient.cpp +++ b/ampel-firmware/src/lib/NTPClient-master/NTPClient.cpp @@ -152,19 +152,17 @@ int NTPClient::getSeconds() { return (this->getEpochTime() % 60); } -String NTPClient::getFormattedTime(unsigned long secs) { +void NTPClient::getFormattedTime(char *formatted_time, unsigned long secs) { unsigned long rawTime = secs ? secs : this->getEpochTime(); unsigned int hours = (rawTime % 86400L) / 3600; unsigned int minutes = (rawTime % 3600) / 60; unsigned int seconds = rawTime % 60; - char formatted_time[9]; - snprintf(formatted_time, sizeof(formatted_time), "%02d:%02d:%02d", hours, minutes, seconds); - return String(formatted_time); + snprintf(formatted_time, 9, "%02d:%02d:%02d", hours, minutes, seconds); } // Based on https://github.com/PaulStoffregen/Time/blob/master/Time.cpp -String NTPClient::getFormattedDate(unsigned long secs) { +void NTPClient::getFormattedDate(char *formatted_date, unsigned long secs) { unsigned long rawTime = (secs ? secs : this->getEpochTime()) / 86400L; // in days unsigned long days = 0, year = 1970; uint8_t month; @@ -187,11 +185,9 @@ String NTPClient::getFormattedDate(unsigned long secs) { month++; // jan is month 1 rawTime++; // first day is day 1 - char formatted_date[23]; - snprintf(formatted_date, sizeof(formatted_date), "%4lu-%02d-%02lu %s%+03d", - year, month, rawTime, this->getFormattedTime(secs).c_str(), this->_timeOffset / 3600); - - return String(formatted_date); + char formatted_time[9]; + this->getFormattedTime(formatted_time, secs); + snprintf(formatted_date, 23, "%4lu-%02d-%02lu %s%+03d", year, month, rawTime, formatted_time, this->_timeOffset / 3600); } void NTPClient::end() { diff --git a/ampel-firmware/src/lib/NTPClient-master/NTPClient.h b/ampel-firmware/src/lib/NTPClient-master/NTPClient.h index ad450706490679ee8a459c5471efec167e419d21..3349dbb7df998fc931874c3f1ec86cda07fc3f80 100644 --- a/ampel-firmware/src/lib/NTPClient-master/NTPClient.h +++ b/ampel-firmware/src/lib/NTPClient-master/NTPClient.h @@ -80,7 +80,7 @@ class NTPClient { /** * @return secs argument (or 0 for current time) formatted like `hh:mm:ss` */ - String getFormattedTime(unsigned long secs = 0); + void getFormattedTime(char *formatted_time, unsigned long secs = 0); /** * @return time in seconds since Jan. 1, 1970 @@ -91,7 +91,7 @@ class NTPClient { * @return secs argument (or 0 for current date) formatted to ISO 8601 * like `2004-02-12T15:19:21+00:00` */ - String getFormattedDate(unsigned long secs = 0); + void getFormattedDate(char *formatted_date, unsigned long secs = 0); /** * Stops the underlying UDP client diff --git a/ampel-firmware/util.cpp b/ampel-firmware/util.cpp index 31df19dd856e5c3f17b5eb929979660eb27db715..b548810958e8eda32ecd2beaf1c0dbbd54a88b61 100644 --- a/ampel-firmware/util.cpp +++ b/ampel-firmware/util.cpp @@ -33,8 +33,8 @@ namespace ntp { timeClient.update(); } - String getLocalTime() { - return timeClient.getFormattedDate(); + void getLocalTime(char *timestamp) { + timeClient.getFormattedDate(timestamp); } } diff --git a/ampel-firmware/util.h b/ampel-firmware/util.h index 2997933480b06db67b18a09bafa2d156d8b7e7b5..40f87ca0d7e05fcc738c3cc18f44a0da1cfdd748 100644 --- a/ampel-firmware/util.h +++ b/ampel-firmware/util.h @@ -21,7 +21,7 @@ namespace ntp { void initialize(); void update(); - String getLocalTime(); + void getLocalTime(char* timestamp); } namespace util { diff --git a/ampel-firmware/web_server.cpp b/ampel-firmware/web_server.cpp index c9dfeab5e2546703dc2968f5eefa45799d86282a..a9572fd347800aa4f2e59ce6ab7577f029b5e708 100644 --- a/ampel-firmware/web_server.cpp +++ b/ampel-firmware/web_server.cpp @@ -226,15 +226,15 @@ namespace web_server { // Body snprintf_P(content, sizeof(content), body_template, SENSOR_ID.c_str(), sensor::co2, sensor::temperature, - sensor::humidity, sensor::timestamp.c_str(), config::measurement_timestep, + sensor::humidity, sensor::timestamp, config::measurement_timestep, #ifdef AMPEL_CSV - csv_writer::last_successful_write.c_str(), config::csv_interval, csv_writer::getAvailableSpace() / 1024, + csv_writer::last_successful_write, config::csv_interval, csv_writer::getAvailableSpace() / 1024, #endif #ifdef AMPEL_MQTT - mqtt::connected ? "Yes" : "No", mqtt::last_successful_publish.c_str(), config::mqtt_sending_interval, + mqtt::connected ? "Yes" : "No", mqtt::last_successful_publish, config::mqtt_sending_interval, #endif #if defined(AMPEL_LORAWAN) && defined(ESP32) - lorawan::connected ? "Yes" : "No", LMIC_FREQUENCY_PLAN, lorawan::last_transmission.c_str(), + lorawan::connected ? "Yes" : "No", LMIC_FREQUENCY_PLAN, lorawan::last_transmission, config::lorawan_sending_interval, #endif config::temperature_offset, config::auto_calibrate_sensor ? "Yes" : "No", SENSOR_ID.c_str(), SENSOR_ID.c_str(),