From 2f38268dcd3de201a529236a1e8e9de136dbc01d Mon Sep 17 00:00:00 2001 From: paulvha Date: Fri, 16 Feb 2024 17:51:58 +0100 Subject: [PATCH 01/41] add ping --- .../WiFiS3/examples/WiFiPing/WiFiPing.ino | 124 ++++++++++++++++++ .../examples/WiFiPing/arduino_secrets.h | 2 + libraries/WiFiS3/src/WiFi.cpp | 17 +++ libraries/WiFiS3/src/WiFi.h | 5 + 4 files changed, 148 insertions(+) create mode 100755 libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino create mode 100755 libraries/WiFiS3/examples/WiFiPing/arduino_secrets.h diff --git a/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino b/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino new file mode 100755 index 000000000..6aa00e6da --- /dev/null +++ b/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino @@ -0,0 +1,124 @@ +/* + Web ICMP Ping + + This sketch pings a device based on the IP address or the hostname + using the WiFi module. By default the attempt is performed 5 times, but can + be changed to max. 255 + + It requires the latest USB Wifi bridge firmware level and WiFiS3 library. + + This example is written for a network using WPA encryption. For + WEP or WPA, change the WiFi.begin() call accordingly. + + created 14 February 2024 + by paulvha + + */ + +#include "WiFiS3.h" +#include "arduino_secrets.h" + +///////please enter your sensitive data in the Secret tab/arduino_secrets.h +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) +int keyIndex = 0; // your network key index number (needed only for WEP) + +int status = WL_IDLE_STATUS; + +/* -------------------------------------------------------------------------- */ +void setup() { +/* -------------------------------------------------------------------------- */ + //Initialize serial and wait for port to open: + Serial.begin(115200); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed. freeze !"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv < WIFI_FIRMWARE_LATEST_VERSION) { + Serial.println("Please upgrade to the WiFi USB bridge firmware. freeze !"); + // don't continue + while (true); + } + + // attempt to connect to WiFi network: + while (status != WL_CONNECTED) { + Serial.print("Attempting to connect to SSID: "); + Serial.println(ssid); + // Connect to WPA/WPA2 network. Change this line if using open or WEP network: + status = WiFi.begin(ssid, pass); + + // wait 10 seconds for connection: + delay(10000); + } + + printWifiStatus(); +} + +/* -------------------------------------------------------------------------- */ +void loop() { +/* -------------------------------------------------------------------------- */ + + // Ping IP + const IPAddress remote_ip(140,82,121,4); + Serial.print("Trying to ping github.com on IP: "); + Serial.println(remote_ip); + + // using default ping count of 5 + float res = WiFi.ping(remote_ip); + + if (res != 0) { + Serial.print("Pin average response time: "); + Serial.print(res); + Serial.println(" ms"); + } + else { + Serial.println("Timeout on IP!"); + } + + // Ping Host + const char* remote_host = "www.google.com"; + Serial.print("Trying to ping host: "); + Serial.println(remote_host); + + // setting ping count to 10 instead of default 5 + float res1 = WiFi.ping(remote_host,10); + + if (res1 != 0) { + Serial.print("Pin average response time: "); + Serial.print(res1); + Serial.println(" ms"); + } + else { + Serial.println("Timeout on host!"); + } + + Serial.println(); + delay(1000); +} + +/* -------------------------------------------------------------------------- */ +void printWifiStatus() { +/* -------------------------------------------------------------------------- */ + // print the SSID of the network you're attached to: + Serial.print("SSID: "); + Serial.println(WiFi.SSID()); + + // print your board's IP address: + IPAddress ip = WiFi.localIP(); + Serial.print("IP Address: "); + Serial.println(ip); + + // print the received signal strength: + long rssi = WiFi.RSSI(); + Serial.print("signal strength (RSSI):"); + Serial.print(rssi); + Serial.println(" dBm"); +} diff --git a/libraries/WiFiS3/examples/WiFiPing/arduino_secrets.h b/libraries/WiFiS3/examples/WiFiPing/arduino_secrets.h new file mode 100755 index 000000000..0c9fdd556 --- /dev/null +++ b/libraries/WiFiS3/examples/WiFiPing/arduino_secrets.h @@ -0,0 +1,2 @@ +#define SECRET_SSID "" +#define SECRET_PASS "" diff --git a/libraries/WiFiS3/src/WiFi.cpp b/libraries/WiFiS3/src/WiFi.cpp index 0717f6731..b4e000d71 100644 --- a/libraries/WiFiS3/src/WiFi.cpp +++ b/libraries/WiFiS3/src/WiFi.cpp @@ -561,6 +561,23 @@ void CWifi::setTimeout(unsigned long timeout) { _timeout = timeout; } +/* -------------------------------------------------------------------------- */ +float CWifi::ping(IPAddress ip, unsigned int count) { +/* -------------------------------------------------------------------------- */ + return ping(ip.toString().c_str(), count); +} + +/* -------------------------------------------------------------------------- */ +float CWifi::ping(const char* host, unsigned int count) { +/* -------------------------------------------------------------------------- */ + modem.begin(); + string res = ""; + if (modem.write(string(PROMPT(_PINGNAME)),res, "%s,%s,%d\r\n", CMD_WRITE(_PINGNAME), host, count)) { + String rsl = res.c_str(); + return rsl.toFloat(); + } + return 0; +} CWifi WiFi; diff --git a/libraries/WiFiS3/src/WiFi.h b/libraries/WiFiS3/src/WiFi.h index 8a50f4178..9fd1f3256 100644 --- a/libraries/WiFiS3/src/WiFi.h +++ b/libraries/WiFiS3/src/WiFi.h @@ -58,6 +58,11 @@ class CWifi { */ static const char* firmwareVersion(); + /* + * PING + */ + float ping(IPAddress ip, unsigned int count = 5); + float ping(const char* host, unsigned int count = 5); /* * Start WiFi connection for OPEN networks From 7af8623e3c0a932044f26af3239fc3b7be62387a Mon Sep 17 00:00:00 2001 From: Andrea Gilardoni Date: Thu, 21 Nov 2024 18:06:52 +0100 Subject: [PATCH 02/41] ping: fix alignment --- libraries/WiFiS3/src/WiFi.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/WiFiS3/src/WiFi.cpp b/libraries/WiFiS3/src/WiFi.cpp index b4e000d71..7413707b0 100644 --- a/libraries/WiFiS3/src/WiFi.cpp +++ b/libraries/WiFiS3/src/WiFi.cpp @@ -564,19 +564,19 @@ void CWifi::setTimeout(unsigned long timeout) { /* -------------------------------------------------------------------------- */ float CWifi::ping(IPAddress ip, unsigned int count) { /* -------------------------------------------------------------------------- */ - return ping(ip.toString().c_str(), count); + return ping(ip.toString().c_str(), count); } /* -------------------------------------------------------------------------- */ float CWifi::ping(const char* host, unsigned int count) { /* -------------------------------------------------------------------------- */ - modem.begin(); - string res = ""; - if (modem.write(string(PROMPT(_PINGNAME)),res, "%s,%s,%d\r\n", CMD_WRITE(_PINGNAME), host, count)) { - String rsl = res.c_str(); - return rsl.toFloat(); - } - return 0; + modem.begin(); + string res = ""; + if (modem.write(string(PROMPT(_PING)), res, "%s,%s,%d\r\n", CMD_WRITE(_PING), host, count)) { + String rsl = res.c_str(); + return rsl.toFloat(); + } + return 0; } CWifi WiFi; From 46e6416a957ec0bf17779e883362cf1a72d8c8c0 Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 22 Nov 2024 11:46:09 +0100 Subject: [PATCH 03/41] ping: make api compatible to WiFiNINA and WiFi101 --- libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino | 16 ++++++++-------- libraries/WiFiS3/src/WiFi.cpp | 14 +++++++------- libraries/WiFiS3/src/WiFi.h | 4 ++-- libraries/WiFiS3/src/WiFiTypes.h | 7 +++++++ 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino b/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino index 6aa00e6da..37fcc418b 100755 --- a/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino +++ b/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino @@ -71,11 +71,11 @@ void loop() { Serial.print("Trying to ping github.com on IP: "); Serial.println(remote_ip); - // using default ping count of 5 - float res = WiFi.ping(remote_ip); + // using default ping count of 1 + int res = WiFi.ping(remote_ip); - if (res != 0) { - Serial.print("Pin average response time: "); + if (res > 0) { + Serial.print("Ping response time: "); Serial.print(res); Serial.println(" ms"); } @@ -88,11 +88,11 @@ void loop() { Serial.print("Trying to ping host: "); Serial.println(remote_host); - // setting ping count to 10 instead of default 5 - float res1 = WiFi.ping(remote_host,10); + // setting ttl to 128 and ping count to 10 + int res1 = WiFi.ping(remote_host, 128, 10); - if (res1 != 0) { - Serial.print("Pin average response time: "); + if (res1 > 0) { + Serial.print("Ping average response time: "); Serial.print(res1); Serial.println(" ms"); } diff --git a/libraries/WiFiS3/src/WiFi.cpp b/libraries/WiFiS3/src/WiFi.cpp index 7413707b0..2599b578c 100644 --- a/libraries/WiFiS3/src/WiFi.cpp +++ b/libraries/WiFiS3/src/WiFi.cpp @@ -562,21 +562,21 @@ void CWifi::setTimeout(unsigned long timeout) { } /* -------------------------------------------------------------------------- */ -float CWifi::ping(IPAddress ip, unsigned int count) { +int CWifi::ping(IPAddress ip, uint8_t ttl, uint8_t count) { /* -------------------------------------------------------------------------- */ - return ping(ip.toString().c_str(), count); + return ping(ip.toString().c_str(), ttl, count); } /* -------------------------------------------------------------------------- */ -float CWifi::ping(const char* host, unsigned int count) { +int CWifi::ping(const char* host, uint8_t ttl, uint8_t count) { /* -------------------------------------------------------------------------- */ + int ret = WL_PING_ERROR; modem.begin(); string res = ""; - if (modem.write(string(PROMPT(_PING)), res, "%s,%s,%d\r\n", CMD_WRITE(_PING), host, count)) { - String rsl = res.c_str(); - return rsl.toFloat(); + if (modem.write(string(PROMPT(_PING)), res, "%s,%s,%d,%d\r\n", CMD_WRITE(_PING), host, ttl, count)) { + ret = atoi(res.c_str()); } - return 0; + return ret; } CWifi WiFi; diff --git a/libraries/WiFiS3/src/WiFi.h b/libraries/WiFiS3/src/WiFi.h index 9fd1f3256..356bc1e47 100644 --- a/libraries/WiFiS3/src/WiFi.h +++ b/libraries/WiFiS3/src/WiFi.h @@ -61,8 +61,8 @@ class CWifi { /* * PING */ - float ping(IPAddress ip, unsigned int count = 5); - float ping(const char* host, unsigned int count = 5); + int ping(IPAddress ip, uint8_t ttl = 128, uint8_t count = 1); + int ping(const char* host, uint8_t ttl = 128, uint8_t count = 1); /* * Start WiFi connection for OPEN networks diff --git a/libraries/WiFiS3/src/WiFiTypes.h b/libraries/WiFiS3/src/WiFiTypes.h index 70be019a5..d72acd95a 100644 --- a/libraries/WiFiS3/src/WiFiTypes.h +++ b/libraries/WiFiS3/src/WiFiTypes.h @@ -31,4 +31,11 @@ enum wl_enc_type { ENC_TYPE_UNKNOWN = 255 }; +typedef enum { + WL_PING_DEST_UNREACHABLE = -1, + WL_PING_TIMEOUT = -2, + WL_PING_UNKNOWN_HOST = -3, + WL_PING_ERROR = -4 +} wl_ping_result_t; + #endif \ No newline at end of file From 030bdf82b36512f8d53f0ee06092b53bd2c2777d Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 22 Nov 2024 11:47:58 +0100 Subject: [PATCH 04/41] ping: fix timeout in case of count > 1 --- libraries/WiFiS3/src/WiFi.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/WiFiS3/src/WiFi.cpp b/libraries/WiFiS3/src/WiFi.cpp index 2599b578c..a7f5047e2 100644 --- a/libraries/WiFiS3/src/WiFi.cpp +++ b/libraries/WiFiS3/src/WiFi.cpp @@ -572,10 +572,13 @@ int CWifi::ping(const char* host, uint8_t ttl, uint8_t count) { /* -------------------------------------------------------------------------- */ int ret = WL_PING_ERROR; modem.begin(); + /* ping timeout is 1s and interval another 1s */ + modem.timeout((count * 2000) + MODEM_TIMEOUT); string res = ""; if (modem.write(string(PROMPT(_PING)), res, "%s,%s,%d,%d\r\n", CMD_WRITE(_PING), host, ttl, count)) { ret = atoi(res.c_str()); } + modem.timeout(MODEM_TIMEOUT); return ret; } From fec1109b3d21ddd204ac5de2ce13aeaff34e4ee6 Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 22 Nov 2024 15:46:20 +0100 Subject: [PATCH 05/41] ping: add missing method --- libraries/WiFiS3/src/WiFi.cpp | 7 +++++++ libraries/WiFiS3/src/WiFi.h | 1 + 2 files changed, 8 insertions(+) diff --git a/libraries/WiFiS3/src/WiFi.cpp b/libraries/WiFiS3/src/WiFi.cpp index a7f5047e2..0a3a80c86 100644 --- a/libraries/WiFiS3/src/WiFi.cpp +++ b/libraries/WiFiS3/src/WiFi.cpp @@ -567,6 +567,13 @@ int CWifi::ping(IPAddress ip, uint8_t ttl, uint8_t count) { return ping(ip.toString().c_str(), ttl, count); } +/* -------------------------------------------------------------------------- */ +int CWifi::ping(const String &hostname, uint8_t ttl, uint8_t count) +/* -------------------------------------------------------------------------- */ +{ + return ping(hostname.c_str(), ttl); +} + /* -------------------------------------------------------------------------- */ int CWifi::ping(const char* host, uint8_t ttl, uint8_t count) { /* -------------------------------------------------------------------------- */ diff --git a/libraries/WiFiS3/src/WiFi.h b/libraries/WiFiS3/src/WiFi.h index 356bc1e47..bbacc5f13 100644 --- a/libraries/WiFiS3/src/WiFi.h +++ b/libraries/WiFiS3/src/WiFi.h @@ -62,6 +62,7 @@ class CWifi { * PING */ int ping(IPAddress ip, uint8_t ttl = 128, uint8_t count = 1); + int ping(const String &hostname, uint8_t ttl = 128, uint8_t count = 1); int ping(const char* host, uint8_t ttl = 128, uint8_t count = 1); /* From 4974e2f4be5a6de7ca569e2192a679bf71cfdb0a Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 27 Nov 2024 10:34:59 +0100 Subject: [PATCH 06/41] WiFiPing: add info about minimum required firmware version --- libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino b/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino index 37fcc418b..4103c6713 100755 --- a/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino +++ b/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino @@ -5,7 +5,7 @@ using the WiFi module. By default the attempt is performed 5 times, but can be changed to max. 255 - It requires the latest USB Wifi bridge firmware level and WiFiS3 library. + It requires at least version 0.5.0 of USB Wifi bridge firmware and WiFiS3 library. This example is written for a network using WPA encryption. For WEP or WPA, change the WiFi.begin() call accordingly. @@ -81,6 +81,7 @@ void loop() { } else { Serial.println("Timeout on IP!"); + Serial.println("Make sure your WiFi firmware version is greater than 0.5.0"); } // Ping Host @@ -98,6 +99,7 @@ void loop() { } else { Serial.println("Timeout on host!"); + Serial.println("Make sure your WiFi firmware version is greater than 0.5.0"); } Serial.println(); From 3a81b22f29f67da0045e2c111fc66fd57ddf43af Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 27 Nov 2024 10:35:52 +0100 Subject: [PATCH 07/41] WiFiPing: remove WIFI_FIRMWARE_LATEST_VERSION check --- libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino b/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino index 4103c6713..248098dcb 100755 --- a/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino +++ b/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino @@ -36,14 +36,7 @@ void setup() { // check for the WiFi module: if (WiFi.status() == WL_NO_MODULE) { - Serial.println("Communication with WiFi module failed. freeze !"); - // don't continue - while (true); - } - - String fv = WiFi.firmwareVersion(); - if (fv < WIFI_FIRMWARE_LATEST_VERSION) { - Serial.println("Please upgrade to the WiFi USB bridge firmware. freeze !"); + Serial.println("Communication with WiFi module failed."); // don't continue while (true); } From fee8ca9afedb0b768ddee7264c26dd6ec76aefd5 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 26 Jun 2024 17:53:18 +0200 Subject: [PATCH 08/41] freertos: start scheduler and loop task on header inclusion --- cores/arduino/main.cpp | 2 ++ .../Arduino_FreeRTOS/src/portable/FSP/port.c | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp index 85e228081..8a1e1b2ff 100644 --- a/cores/arduino/main.cpp +++ b/cores/arduino/main.cpp @@ -64,6 +64,7 @@ void unsecure_registers() { #define str(s) #s extern "C" void Stacktrace_Handler(void); +extern "C" __attribute__((weak)) void start_freertos_on_header_inclusion() {} void arduino_main(void) { @@ -111,6 +112,7 @@ void arduino_main(void) Serial.begin(115200); #endif startAgt(); + start_freertos_on_header_inclusion(); setup(); while (1) { diff --git a/libraries/Arduino_FreeRTOS/src/portable/FSP/port.c b/libraries/Arduino_FreeRTOS/src/portable/FSP/port.c index c0b5938d0..036bd6264 100644 --- a/libraries/Arduino_FreeRTOS/src/portable/FSP/port.c +++ b/libraries/Arduino_FreeRTOS/src/portable/FSP/port.c @@ -225,6 +225,28 @@ static void prvTaskExitError(void); #endif +void loop_thread_func(void* arg) { + setup(); + while (1) + { + loop(); + } +} + +static TaskHandle_t loop_task; +void start_freertos_on_header_inclusion() { + xTaskCreate( + (TaskFunction_t)loop_thread_func, + "Loop Thread", + 4096 / 4, /* usStackDepth in words */ + NULL, /* pvParameters */ + 4, /* uxPriority */ + &loop_task /* pxCreatedTask */ + ); + + vTaskStartScheduler(); +} + /* Arduino specific overrides */ void delay(uint32_t ms) { if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) { From 9666fc21a8bd48a0d0d5814c29be468c4447a06c Mon Sep 17 00:00:00 2001 From: Andrea Gilardoni Date: Mon, 27 May 2024 17:11:17 +0200 Subject: [PATCH 09/41] codestyle unification --- libraries/WiFiS3/src/Modem.cpp | 1 + libraries/WiFiS3/src/WiFi.cpp | 145 ++++++++++++++++----------------- libraries/WiFiS3/src/WiFi.h | 56 ++++++------- 3 files changed, 98 insertions(+), 104 deletions(-) diff --git a/libraries/WiFiS3/src/Modem.cpp b/libraries/WiFiS3/src/Modem.cpp index 3dd1a87cc..c8345637d 100644 --- a/libraries/WiFiS3/src/Modem.cpp +++ b/libraries/WiFiS3/src/Modem.cpp @@ -207,6 +207,7 @@ bool ModemClass::buf_read(const string &prompt, string &data_res) { while( _serial->available() ){ char c = _serial->read(); data_res += c; + if(_serial_debug && _debug_level >= 1) { _serial_debug->print(c); diff --git a/libraries/WiFiS3/src/WiFi.cpp b/libraries/WiFiS3/src/WiFi.cpp index 0a3a80c86..ceef6c99c 100644 --- a/libraries/WiFiS3/src/WiFi.cpp +++ b/libraries/WiFiS3/src/WiFi.cpp @@ -20,10 +20,8 @@ const char* CWifi::firmwareVersion() { return fw_version; } return "99.99.99"; - } - /* -------------------------------------------------------------------------- */ int CWifi::begin(const char* ssid) { /* -------------------------------------------------------------------------- */ @@ -54,7 +52,7 @@ int CWifi::begin(const char* ssid, const char *passphrase) { return WL_CONNECTED; } } - return WL_CONNECT_FAILED; + return WL_CONNECT_FAILED; } /* passphrase is needed so a default one will be set */ @@ -78,7 +76,7 @@ uint8_t CWifi::beginAP(const char *ssid, const char* passphrase) { /* -------------------------------------------------------------------------- */ uint8_t CWifi::beginAP(const char *ssid, const char* passphrase, uint8_t channel) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ string res = ""; modem.begin(); modem.write(string(PROMPT(_MODE)),res, "%s%d\r\n" , CMD_WRITE(_MODE), 2); @@ -97,10 +95,10 @@ uint8_t CWifi::beginAP(const char *ssid, const char* passphrase, uint8_t channel /* -------------------------------------------------------------------------- */ void CWifi::config(IPAddress local_ip) { /* -------------------------------------------------------------------------- */ - IPAddress _gw(local_ip[0],local_ip[1], local_ip[2], 1); - IPAddress _sm(255,255,255,0); - IPAddress dns(0,0,0,0); - return _config(local_ip, _gw, _sm, _gw, dns); + IPAddress _gw(local_ip[0],local_ip[1], local_ip[2], 1); + IPAddress _sm(255,255,255,0); + IPAddress dns(0,0,0,0); + return _config(local_ip, _gw, _sm, _gw, dns); } /* -------------------------------------------------------------------------- */ @@ -116,7 +114,7 @@ void CWifi::_config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPA string gw = to_string(gateway[0]) + "."; gw += to_string(gateway[1]) + "."; gw += to_string(gateway[2]) + "."; - gw += to_string(gateway[3]); + gw += to_string(gateway[3]); string nm = to_string(subnet[0]) + "."; nm += to_string(subnet[1]) + "."; @@ -127,18 +125,18 @@ void CWifi::_config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPA _dns1 += to_string(dns1[1]) + "."; _dns1 += to_string(dns1[2]) + "."; _dns1 += to_string(dns1[3]); - + string _dns2 = to_string(dns2[0]) + "."; _dns2 += to_string(dns2[1]) + "."; _dns2 += to_string(dns2[2]) + "."; - _dns2 += to_string(dns2[3]); + _dns2 += to_string(dns2[3]); ip_ap = local_ip; gw_ap = gateway; nm_ap = subnet; modem.write(PROMPT(_SOFTAPCONFIG),res, "%s%s,%s,%s\r\n" , CMD_WRITE(_SOFTAPCONFIG), ip.c_str(), ip.c_str(), nm.c_str()); - modem.write(string(PROMPT(_SETIP)),res, "%s%s,%s,%s,%s,%s\r\n" , CMD_WRITE(_SETIP), ip.c_str(), gw.c_str(), nm.c_str(),_dns1.c_str(),_dns2.c_str()); + modem.write(string(PROMPT(_SETIP)),res, "%s%s,%s,%s,%s,%s\r\n" , CMD_WRITE(_SETIP), ip.c_str(), gw.c_str(), nm.c_str(),_dns1.c_str(),_dns2.c_str()); } /* -------------------------------------------------------------------------- */ @@ -152,32 +150,32 @@ void CWifi::config(IPAddress local_ip, IPAddress dns_server) { /* -------------------------------------------------------------------------- */ void CWifi::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway) { -/* -------------------------------------------------------------------------- */ - +/* -------------------------------------------------------------------------- */ + IPAddress _sm(255,255,255,0); IPAddress dns(0,0,0,0); - return _config(local_ip, gateway, _sm,dns_server,dns); + return _config(local_ip, gateway, _sm,dns_server,dns); } /* -------------------------------------------------------------------------- */ void CWifi::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet) { /* -------------------------------------------------------------------------- */ - + IPAddress dns(0,0,0,0); - return _config(local_ip, gateway, subnet,dns_server,dns); + return _config(local_ip, gateway, subnet,dns_server,dns); } /* -------------------------------------------------------------------------- */ void CWifi::setDNS(IPAddress dns_server1) { /* -------------------------------------------------------------------------- */ IPAddress dns(0,0,0,0); - return _config(localIP(), gatewayIP(), subnetMask(),dns_server1,dns); + return _config(localIP(), gatewayIP(), subnetMask(),dns_server1,dns); } /* -------------------------------------------------------------------------- */ void CWifi::setDNS(IPAddress dns_server1, IPAddress dns_server2) { /* -------------------------------------------------------------------------- */ - return _config(localIP(), gatewayIP(), subnetMask(),dns_server1,dns_server2); + return _config(localIP(), gatewayIP(), subnetMask(),dns_server1,dns_server2); } /* -------------------------------------------------------------------------- */ @@ -189,29 +187,28 @@ void CWifi::setHostname(const char* name) { /* -------------------------------------------------------------------------- */ int CWifi::disconnect() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ string res = ""; modem.begin(); if(modem.write(string(PROMPT(_DISCONNECT)),res,CMD(_DISCONNECT))) { return 1; - } + } return 0; } /* -------------------------------------------------------------------------- */ void CWifi::end(void) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ string res = ""; modem.begin(); modem.write(string(PROMPT(_SOFTRESETWIFI)),res, "%s" , CMD(_SOFTRESETWIFI)); } - static bool macStr2macArray(uint8_t *mac_out, const char *mac_in) { - if(mac_in[2] != ':' || + if(mac_in[2] != ':' || mac_in[5] != ':' || mac_in[8] != ':' || mac_in[11] != ':' || @@ -227,13 +224,12 @@ static bool macStr2macArray(uint8_t *mac_out, const char *mac_in) { return true; } - /* -------------------------------------------------------------------------- */ uint8_t* CWifi::macAddress(uint8_t* _mac) { -/* -------------------------------------------------------------------------- */ - string res = ""; - modem.begin(); - if(modem.write(string(PROMPT(_MODE)),res, "%s" , CMD_READ(_MODE))) { +/* -------------------------------------------------------------------------- */ + string res = ""; + modem.begin(); + if(modem.write(string(PROMPT(_MODE)),res, "%s" , CMD_READ(_MODE))) { if(atoi(res.c_str()) == 1) { if(modem.write(string(PROMPT(_MACSTA)),res, "%s" , CMD_READ(_MACSTA))) { macStr2macArray(_mac, res.c_str()); @@ -249,9 +245,6 @@ uint8_t* CWifi::macAddress(uint8_t* _mac) { return _mac; } - - - /* -------------------------------------------------------------------------- */ int8_t CWifi::scanNetworks() { /* -------------------------------------------------------------------------- */ @@ -280,7 +273,7 @@ int8_t CWifi::scanNetworks() { ap.encryption_mode = tokens[4]; access_points.push_back(ap); } - } + } } return (int8_t)access_points.size(); @@ -317,10 +310,9 @@ IPAddress CWifi::dnsIP(int n) { return dns_IP; } } - return IPAddress(0,0,0,0); + return IPAddress(0,0,0,0); } - /* -------------------------------------------------------------------------- */ IPAddress CWifi::localIP() { /* -------------------------------------------------------------------------- */ @@ -334,14 +326,14 @@ IPAddress CWifi::localIP() { if(modem.write(string(PROMPT(_MODE)),res, "%s" , CMD_READ(_MODE))) { if(atoi(res.c_str()) == 1) { if(modem.write(string(PROMPT(_IPSTA)),res, "%s%d\r\n" , CMD_WRITE(_IPSTA), IP_ADDR)) { - + local_IP.fromString(res.c_str()); - + } } else if(atoi(res.c_str()) == 2) { if(modem.write(string(PROMPT(_IPSOFTAP)),res, CMD(_IPSOFTAP))) { - + local_IP.fromString(res.c_str()); } } @@ -376,27 +368,26 @@ IPAddress CWifi::gatewayIP() { gateway_IP.fromString(res.c_str()); return gateway_IP; } - return IPAddress(0,0,0,0); + return IPAddress(0,0,0,0); } /* -------------------------------------------------------------------------- */ const char* CWifi::SSID(uint8_t networkItem) { /* -------------------------------------------------------------------------- */ - if(networkItem < access_points.size()) { - return access_points[networkItem].ssid.c_str(); - } - return nullptr; + if(networkItem < access_points.size()) { + return access_points[networkItem].ssid.c_str(); + } + return nullptr; } -/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ int32_t CWifi::RSSI(uint8_t networkItem) { - if(networkItem < access_points.size()) { - return atoi(access_points[networkItem].rssi.c_str()); - } - return -1000; +/* -------------------------------------------------------------------------- */ + if(networkItem < access_points.size()) { + return atoi(access_points[networkItem].rssi.c_str()); + } + return -1000; } -/* -------------------------------------------------------------------------- */ static uint8_t Encr2wl_enc(string e) { if (e == string("open")) { @@ -418,54 +409,52 @@ static uint8_t Encr2wl_enc(string e) { } else { return ENC_TYPE_UNKNOWN; } - } - +} /* -------------------------------------------------------------------------- */ uint8_t CWifi::encryptionType() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ scanNetworks(); string myssid(SSID()); for(unsigned int i = 0; i < access_points.size(); i++) { if(myssid == access_points[i].ssid) { - return Encr2wl_enc(access_points[i].encryption_mode); + return Encr2wl_enc(access_points[i].encryption_mode); } } return ENC_TYPE_UNKNOWN; } - /* -------------------------------------------------------------------------- */ uint8_t CWifi::encryptionType(uint8_t networkItem) { - if(networkItem < access_points.size()) { - return Encr2wl_enc(access_points[networkItem].encryption_mode); - } - return 0; +/* -------------------------------------------------------------------------- */ + if(networkItem < access_points.size()) { + return Encr2wl_enc(access_points[networkItem].encryption_mode); + } + return 0; } -/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ uint8_t* CWifi::BSSID(uint8_t networkItem, uint8_t* bssid) { +/* -------------------------------------------------------------------------- */ if(networkItem < access_points.size()) { for(int i = 0; i < 6; i++) { *(bssid + i) = access_points[networkItem].uint_bssid[i]; } - return bssid; + return bssid; } - return nullptr; + return nullptr; } -/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -uint8_t CWifi::channel(uint8_t networkItem) { +uint8_t CWifi::channel(uint8_t networkItem) { +/* -------------------------------------------------------------------------- */ if(networkItem < access_points.size()) { - return atoi(access_points[networkItem].channel.c_str()); + return atoi(access_points[networkItem].channel.c_str()); } return 0; } -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ const char* CWifi::SSID() { /* -------------------------------------------------------------------------- */ string res = ""; @@ -486,9 +475,9 @@ const char* CWifi::SSID() { return ""; } -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ uint8_t* CWifi::BSSID(uint8_t* bssid) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ string res = ""; if(modem.write(string(PROMPT(_GETBSSID)), res, CMD_READ(_GETBSSID))) { macStr2macArray(bssid, res.c_str()); @@ -497,7 +486,7 @@ uint8_t* CWifi::BSSID(uint8_t* bssid) { return nullptr; } -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ int32_t CWifi::RSSI() { /* -------------------------------------------------------------------------- */ string res = ""; @@ -507,9 +496,9 @@ int32_t CWifi::RSSI() { return 0; } -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ const char* CWifi::softAPSSID() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ string res = ""; if(modem.write(string(PROMPT(_GETSOFTAPSSID)), res, CMD_READ(_GETSOFTAPSSID))) { apssid = res; @@ -520,7 +509,7 @@ const char* CWifi::softAPSSID() { /* -------------------------------------------------------------------------- */ uint8_t CWifi::status() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ modem.begin(); string res = ""; if(modem.write(string(PROMPT(_GETSTATUS)), res, CMD_READ(_GETSTATUS))) { @@ -532,7 +521,7 @@ uint8_t CWifi::status() { /* -------------------------------------------------------------------------- */ int CWifi::hostByName(const char* aHostname, IPAddress& aResult) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ modem.begin(); string res = ""; if(modem.write(string(PROMPT(_GETHOSTBYNAME)),res, "%s%s\r\n" , CMD_WRITE(_GETHOSTBYNAME), aHostname)) { @@ -542,13 +531,15 @@ int CWifi::hostByName(const char* aHostname, IPAddress& aResult) { return 0; } +/* -------------------------------------------------------------------------- */ uint8_t CWifi::reasonCode() { - return 0; +/* -------------------------------------------------------------------------- */ + return 0; } -/* ----------------------------------------------*/ +/* -------------------------------------------------------------------------- */ unsigned long CWifi::getTime() { -/* ----------------------------------------------*/ +/* -------------------------------------------------------------------------- */ modem.begin(); string res = ""; if(modem.write(string(PROMPT(_GETTIME)),res,"%s\r\n", CMD_WRITE(_GETTIME))) { @@ -557,7 +548,9 @@ unsigned long CWifi::getTime() { return 0; } +/* -------------------------------------------------------------------------- */ void CWifi::setTimeout(unsigned long timeout) { +/* -------------------------------------------------------------------------- */ _timeout = timeout; } diff --git a/libraries/WiFiS3/src/WiFi.h b/libraries/WiFiS3/src/WiFi.h index bbacc5f13..6cf797c57 100644 --- a/libraries/WiFiS3/src/WiFi.h +++ b/libraries/WiFiS3/src/WiFi.h @@ -22,30 +22,30 @@ #define WL_MAC_ADDR_LENGTH 6 class CAccessPoint { - public: - std::string ssid; - std::string bssid; - uint8_t uint_bssid[6]; - std::string rssi; - std::string channel; - std::string encryption_mode; +public: + std::string ssid; + std::string bssid; + uint8_t uint_bssid[6]; + std::string rssi; + std::string channel; + std::string encryption_mode; }; class CWifi { -private: - void _config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2); - unsigned long _timeout; - std::vector access_points; - std::string ssid; - std::string apssid; - +private: + void _config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2); + unsigned long _timeout; + std::vector access_points; + std::string ssid; + std::string apssid; + - IPAddress ip_ap = DEFAULT_IP_AP_ADDRESS; - IPAddress gw_ap = DEFAULT_GW_AP_ADDRESS; - IPAddress nm_ap = DEFAULT_NM_AP_ADDRESS; + IPAddress ip_ap = DEFAULT_IP_AP_ADDRESS; + IPAddress gw_ap = DEFAULT_GW_AP_ADDRESS; + IPAddress nm_ap = DEFAULT_NM_AP_ADDRESS; @@ -65,13 +65,13 @@ class CWifi { int ping(const String &hostname, uint8_t ttl = 128, uint8_t count = 1); int ping(const char* host, uint8_t ttl = 128, uint8_t count = 1); - /* - * Start WiFi connection for OPEN networks + /* + * Start WiFi connection for OPEN networks * param ssid: Pointer to the SSID string. */ int begin(const char* ssid); - + /* Start WiFi connection with passphrase * the most secure supported mode will be automatically selected @@ -118,7 +118,7 @@ class CWifi { * param subnet: Static Subnet mask */ void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet); - + /* Change DNS IP configuration * * param dns_server1: IP configuration for DNS server 1 @@ -154,8 +154,8 @@ class CWifi { * Get the interface MAC address. * * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH - * - * the value returned by this function is meaningfull only if called + * + * the value returned by this function is meaningfull only if called * afert a begin (both begin or beginAP) or a ScanNetwork function * otherwise an empty mac address is returned */ @@ -180,9 +180,9 @@ class CWifi { * * return: gateway IP address value */ - IPAddress gatewayIP(); + IPAddress gatewayIP(); - IPAddress dnsIP(int n = 0); + IPAddress dnsIP(int n = 0); /* * Get the interface the AP IP address. @@ -244,8 +244,8 @@ class CWifi { * * return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list - - + + */ uint8_t encryptionType(uint8_t networkItem); uint8_t encryptionType(); @@ -289,7 +289,7 @@ class CWifi { void setTimeout(unsigned long timeout); - + }; extern CWifi WiFi; From af0787a991a2befed636e1d3365a5d269dacad80 Mon Sep 17 00:00:00 2001 From: Andrea Gilardoni Date: Mon, 27 May 2024 17:12:09 +0200 Subject: [PATCH 10/41] added possibility to get fw version of wifi module as uint32 --- libraries/WiFiS3/src/WiFi.cpp | 12 ++++++++++++ libraries/WiFiS3/src/WiFi.h | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/libraries/WiFiS3/src/WiFi.cpp b/libraries/WiFiS3/src/WiFi.cpp index ceef6c99c..a43d32d57 100644 --- a/libraries/WiFiS3/src/WiFi.cpp +++ b/libraries/WiFiS3/src/WiFi.cpp @@ -22,6 +22,18 @@ const char* CWifi::firmwareVersion() { return "99.99.99"; } +/* -------------------------------------------------------------------------- */ +uint32_t CWifi::firmwareVersionU32() { +/* -------------------------------------------------------------------------- */ + uint8_t ret[4]; + string res = ""; + modem.begin(); + if(modem.write(string(PROMPT(_FWVERSION_U32)), res, CMD_READ(_FWVERSION_U32))) { + return res[0] << 16| res[1] << 8 | res[2]; + } + return 0x636363; +} + /* -------------------------------------------------------------------------- */ int CWifi::begin(const char* ssid) { /* -------------------------------------------------------------------------- */ diff --git a/libraries/WiFiS3/src/WiFi.h b/libraries/WiFiS3/src/WiFi.h index 6cf797c57..2b733cfab 100644 --- a/libraries/WiFiS3/src/WiFi.h +++ b/libraries/WiFiS3/src/WiFi.h @@ -57,6 +57,14 @@ class CWifi { * Get firmware version */ static const char* firmwareVersion(); + /* + * Get firmware version U32 + * + * Since version is made in a semver fashion, thus in an integer it will be represented as + * byte 1 (MSB) | byte 2 | byte 3 | byte 4 + * 0 | MAJOR | MINOR | PATCH + */ + uint32_t firmwareVersionU32(); /* * PING From e8175190170fb750c6c1450a34cc09c911777a45 Mon Sep 17 00:00:00 2001 From: Andrea Gilardoni Date: Wed, 17 Jul 2024 18:36:10 +0200 Subject: [PATCH 11/41] Unifying codestyle --- libraries/WiFiS3/src/Modem.cpp | 101 +++++++++++++-------------------- libraries/WiFiS3/src/Modem.h | 6 +- 2 files changed, 44 insertions(+), 63 deletions(-) diff --git a/libraries/WiFiS3/src/Modem.cpp b/libraries/WiFiS3/src/Modem.cpp index c8345637d..60b82c8eb 100644 --- a/libraries/WiFiS3/src/Modem.cpp +++ b/libraries/WiFiS3/src/Modem.cpp @@ -9,96 +9,77 @@ using namespace std; /* -------------------------------------------------------------------------- */ ModemClass::ModemClass(int tx, int rx) : beginned(false), delete_serial(false), _timeout(MODEM_TIMEOUT), trim_results(true), read_by_size(false) { /* -------------------------------------------------------------------------- */ - _serial = new UART(tx,rx); + _serial = new UART(tx,rx); } /* -------------------------------------------------------------------------- */ ModemClass::ModemClass(UART * serial) : beginned(false) , delete_serial(true) , _serial(serial), _timeout(MODEM_TIMEOUT), trim_results(true), read_by_size(false) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ } /* -------------------------------------------------------------------------- */ ModemClass::~ModemClass() { -/* -------------------------------------------------------------------------- */ - if(_serial != nullptr && !delete_serial){ +/* -------------------------------------------------------------------------- */ + if(_serial != nullptr && !delete_serial){ delete _serial; _serial = nullptr; - } + } } /* -------------------------------------------------------------------------- */ void ModemClass::begin(int badurate){ -/* -------------------------------------------------------------------------- */ - if(_serial != nullptr && !beginned) { +/* -------------------------------------------------------------------------- */ + if(_serial != nullptr && !beginned) { _serial->begin(badurate); beginned = true; string res = ""; _serial->flush(); modem.write(string(PROMPT(_SOFTRESETWIFI)),res, "%s" , CMD(_SOFTRESETWIFI)); - } + } } /* -------------------------------------------------------------------------- */ void ModemClass::end(){ -/* -------------------------------------------------------------------------- */ - _serial->end(); +/* -------------------------------------------------------------------------- */ + _serial->end(); } /* -------------------------------------------------------------------------- */ bool ModemClass::passthrough(const uint8_t *data, size_t size) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ _serial->write(data,size); - bool res = false; - bool found = false; - string data_res = ""; - - unsigned long start_time = millis(); - while(millis() - start_time < _timeout && !found){ - while(_serial->available()){ - char c = _serial->read(); - data_res += c; - - if(string::npos != data_res.rfind(RESULT_OK)){ - found = true; - res = true; - break; - } - else if (string::npos != data_res.rfind(RESULT_ERROR)) { - found = true; - res = false; - break; - } - } - } - - if(_serial_debug && _debug_level >= 2) { - _serial_debug->print(" ANSWER (passthrough): "); - _serial_debug->println(data_res.c_str()); - if(res) { - _serial_debug->println(" Result: OK"); - } - else { - _serial_debug->println(" Result: FAILED"); - } - } - + + std::string tmp, data_res; // FIXME + bool res = buf_read(tmp, data_res); + + // if(_serial_debug && _debug_level >= 2) { + // _serial_debug->print(" ANSWER (passthrough): "); + // _serial_debug->println(data_res.c_str()); + // if(res) { + // _serial_debug->println(" Result: OK"); + // } + // else { + // _serial_debug->println(" Result: FAILED"); + // } + // } + return res; } /* -------------------------------------------------------------------------- */ void ModemClass::write_nowait(const string &cmd, string &str, const char * fmt, ...) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ va_list va; va_start (va, fmt); vsnprintf((char *)tx_buff, MAX_BUFF_SIZE, fmt, va); va_end (va); - - if(_serial_debug && _debug_level >= 2) { + + if(_serial_debug && _debug_level >= 2) { _serial_debug->print("REQUEST (passthrough): "); _serial_debug->write(tx_buff,strlen((char *)tx_buff)); _serial_debug->println(); } - + _serial->write(tx_buff,strlen((char *)tx_buff)); return; } @@ -106,13 +87,13 @@ void ModemClass::write_nowait(const string &cmd, string &str, const char * fmt, /* -------------------------------------------------------------------------- */ bool ModemClass::write(const string &prompt, string &data_res, const char * fmt, ...){ -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ data_res.clear(); va_list va; va_start (va, fmt); vsnprintf((char *)tx_buff, MAX_BUFF_SIZE, fmt, va); va_end (va); - + if(_serial_debug) { _serial_debug->println(); _serial_debug->print("REQUEST: "); @@ -121,7 +102,7 @@ bool ModemClass::write(const string &prompt, string &data_res, const char * fmt, } _serial->write(tx_buff,strlen((char *)tx_buff)); - return buf_read(prompt,data_res);; + return buf_read(prompt, data_res);; } @@ -134,7 +115,7 @@ typedef enum { /* -------------------------------------------------------------------------- */ bool ModemClass::read_by_size_finished(string &rx) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ bool rv = false; static bool first_call = true; static ReadBySizeSt_t st = IDLE; @@ -194,7 +175,7 @@ bool ModemClass::read_by_size_finished(string &rx) { /* -------------------------------------------------------------------------- */ bool ModemClass::buf_read(const string &prompt, string &data_res) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ bool res = false; bool found = false; @@ -271,6 +252,7 @@ bool ModemClass::buf_read(const string &prompt, string &data_res) { } } } + if(trim_results) { trim(data_res); } @@ -282,7 +264,7 @@ bool ModemClass::buf_read(const string &prompt, string &data_res) { _serial_debug->println(); } - if(_serial_debug) { + if(_serial_debug) { _serial_debug->print(" ANSWER: "); _serial_debug->println(data_res.c_str()); if(res) { @@ -290,15 +272,14 @@ bool ModemClass::buf_read(const string &prompt, string &data_res) { } else { _serial_debug->println(" Result: FAILED"); - } - } - + } + } return res; } #ifdef ARDUINO_UNOWIFIR4 - ModemClass modem = ModemClass(&Serial2); + ModemClass modem = ModemClass(&Serial2); #else - ModemClass modem = ModemClass(D24,D25); + ModemClass modem = ModemClass(D24,D25); #endif diff --git a/libraries/WiFiS3/src/Modem.h b/libraries/WiFiS3/src/Modem.h index 78539e7e3..fc6fb09f6 100644 --- a/libraries/WiFiS3/src/Modem.h +++ b/libraries/WiFiS3/src/Modem.h @@ -36,18 +36,18 @@ class ModemClass { void read_using_size() { read_by_size = true; - } + } bool beginned; /* calling this function with no argument will enable debug message to be printed on Serial - use first parameter UART *u to redirect debug output to a different serial + use first parameter UART *u to redirect debug output to a different serial level from 0 defaul to 2 (maximum) */ void debug(Stream &u, uint8_t level = 0) { _serial_debug = &u; - + if(level > 2) { level = 2; } From ccd5d5c51515cc18f21a209c40e45fbc221a218d Mon Sep 17 00:00:00 2001 From: Andrea Gilardoni Date: Wed, 17 Jul 2024 18:37:03 +0200 Subject: [PATCH 12/41] Improving parse function in modem class This commit aims to change the logic of the parse function from repeatedly calling a find on the buffer of incoming data to an approach based on FSM for parsing a stream of chars --- libraries/WiFiS3/src/Modem.cpp | 447 +++++++++++++++++++++------------ libraries/WiFiS3/src/Modem.h | 9 +- 2 files changed, 297 insertions(+), 159 deletions(-) diff --git a/libraries/WiFiS3/src/Modem.cpp b/libraries/WiFiS3/src/Modem.cpp index 60b82c8eb..6a2c3a5b5 100644 --- a/libraries/WiFiS3/src/Modem.cpp +++ b/libraries/WiFiS3/src/Modem.cpp @@ -1,8 +1,11 @@ #include "Modem.h" -#define RESULT_OK "OK\r\n" -#define RESULT_ERROR "ERROR\r\n" -#define RESULT_DATA "DATA\r\n" +#define OK_TOKEN "OK" +#define ERROR_TOKEN "ERROR" +#define TERM_TOKEN "\r\n" +#define RESULT_OK OK_TOKEN TERM_TOKEN +#define RESULT_ERROR OK_TOKEN TERM_TOKEN +#define RESULT_DATA "DATA" TERM_TOKEN using namespace std; @@ -49,21 +52,24 @@ bool ModemClass::passthrough(const uint8_t *data, size_t size) { /* -------------------------------------------------------------------------- */ _serial->write(data,size); - std::string tmp, data_res; // FIXME - bool res = buf_read(tmp, data_res); + std::string prompt = DO_NOT_CHECK_CMD, data_res; + auto res = buf_read(prompt, data_res); - // if(_serial_debug && _debug_level >= 2) { - // _serial_debug->print(" ANSWER (passthrough): "); - // _serial_debug->println(data_res.c_str()); - // if(res) { - // _serial_debug->println(" Result: OK"); - // } - // else { - // _serial_debug->println(" Result: FAILED"); - // } - // } + if(_serial_debug && _debug_level >= 2) { + _serial_debug->print(" ANSWER (passthrough): "); + _serial_debug->println(data_res.c_str()); + if(res == Ok) { + _serial_debug->println(" Result: OK"); + } else if(res == Error) { + _serial_debug->println(" Result: ERROR"); + } else if(res == Timeout) { + _serial_debug->println(" Result: TIMEOUT"); + } else { + _serial_debug->println(" Result: ParseError"); + } + } - return res; + return res == Ok; } /* -------------------------------------------------------------------------- */ @@ -102,179 +108,304 @@ bool ModemClass::write(const string &prompt, string &data_res, const char * fmt, } _serial->write(tx_buff,strlen((char *)tx_buff)); - return buf_read(prompt, data_res);; -} + auto res = buf_read(prompt, data_res); + if(_serial_debug) { + _serial_debug->print(" ANSWER: "); + _serial_debug->println(data_res.c_str()); + if(res == Ok) { + _serial_debug->println(" Result: OK"); + } else if(res == Error) { + _serial_debug->println(" Result: ERROR"); + } else if(res == Timeout) { + _serial_debug->println(" Result: TIMEOUT"); + } else { + _serial_debug->println(" Result: ParseError"); + } + } -typedef enum { - IDLE, - WAIT_FOR_SIZE, - WAIT_FOR_DATA -} ReadBySizeSt_t; + return res == Ok; +} /* -------------------------------------------------------------------------- */ -bool ModemClass::read_by_size_finished(string &rx) { +ModemClass::ParseResult ModemClass::buf_read(const string &prompt, string &data_res) { /* -------------------------------------------------------------------------- */ - bool rv = false; - static bool first_call = true; - static ReadBySizeSt_t st = IDLE; - static int data_to_be_received = 0; - static int data_received = 0; - if(first_call) { - first_call = false; - st = WAIT_FOR_SIZE; + /* + * This function implements as FSM that parses basic AT command responses + * The expected syntax should match the following regex + * - (?:\+(\w+)[:=][ ]?(\w*))?(?:\r\n)?(ERROR\r\n|OK\r\n) + * + "ERROR" "OK" + * + "+COMMAND: OK" + * + "+COMMAND: ERROR" + * + "+COMMAND: 1231231OK" (NOTE only one parameter supported) + * + "+COMMAND: 1231231ERROR" (NOTE only one parameter supported) + * - custom sized response: + * + "+COMMAND: 4| 123OK" + */ + enum class at_parse_state_t { + Begin = 0, + Cmd = 1, + Data = 2, + Sized = 3, + ResWaitLF = 4, + Res = 5, + Error = 6, + ParseError = 7, + Ok = 8, + Completed = 9, + }; + + at_parse_state_t state = at_parse_state_t::Begin; + std::string commandName; + + ModemClass::ParseResult res = Error; + unsigned int sized_read_size = 0; + unsigned int sized_read_count = 0; + unsigned int result_parse = 0; + bool restart = false, + consume_char = true; // This flag is used to indicate to consume another character from the stream + + char c; + + // I expect the answer to be in this form: "ERROR" "OK" + // if prompt == DO_NOT_CHECK_CMD + const bool check_prompt = (prompt != DO_NOT_CHECK_CMD); + + if(_serial_debug && _debug_level >= 1) { + _serial_debug->print("RAW: "); } - switch(st) { - case IDLE: - - break; - case WAIT_FOR_SIZE: { - int pos = rx.find("|"); - int pos_space = rx.find(" "); - if(pos != string::npos && pos_space != string::npos) { - string n = rx.substr(pos_space,pos); - int to_be_rx = atoi(n.c_str()); - if(to_be_rx <= 0) { - while( _serial->available() ){ - _serial->read(); - } - rv = true; - first_call = true; - st = IDLE; - } - else { - /* add 4 because OK\r\n is always added at the end of data */ - data_to_be_received = to_be_rx + 4; - data_received = 0; - st = WAIT_FOR_DATA; - } - rx.clear(); + unsigned long start_time = millis(); + while(state != at_parse_state_t::Completed) { + + if(millis() - start_time > _timeout) { + res = Timeout; + break; + } + + if(consume_char && !_serial->available()) { + // if there is nothing available, go to the beginning of the cycle + continue; + } else if(consume_char) { // available is true + c = _serial->read(); + } else if(!consume_char) { + // reset consume_char to true + consume_char = true; + } + + if(_serial_debug && _debug_level >= 1 && consume_char) { + if(c == '\n') { + _serial_debug->print(""); + } else if (c == '\r') { + _serial_debug->print(""); + } else if (c == ' ') { + _serial_debug->print(""); + } else if(c < ' ') { + _serial_debug->print("<"); + _serial_debug->print((unsigned int)c); + _serial_debug->print(">"); + } else { + _serial_debug->print(c); } } - break; - - case WAIT_FOR_DATA: - data_received++; - if(data_received == data_to_be_received) { - rv = true; - first_call = true; - st = IDLE; + if(_serial_debug && _debug_level >= 3) { + _serial_debug->print(" State "); + _serial_debug->println((int)state); + } + + switch(state) { + case at_parse_state_t::Begin: + /* + * In this state we wait for a '+' character, which will mark the beginning of a response + * or the status response code "ERROR" or "OK" + * we need to consume the available buffer if it doesn't match the expected response, + * in order to avoiding dealing with previous responses which were not parsed successfully + */ + + if(c == '+') { + // This line allow to strenghten the checks on the response prompt, + // it is required that passthrough() function is able to know the command prompt, + // provided in the previous call of write_nowait() + // the answer doesn't match the expected form, thus the response received + // is not related to the sent command we need to restart + // restart = !check_prompt; + + commandName += c; // prompt includes also '+' + state = at_parse_state_t::Cmd; + } else if(c == RESULT_OK[result_parse]) { + // the answer doesn't match the expected form, we need to restart + restart = check_prompt; + + state = at_parse_state_t::Ok; + result_parse++; + } else if(c == RESULT_ERROR[result_parse]) { + // the answer doesn't match the expected form, we need to restart + restart = check_prompt; + + state = at_parse_state_t::Error; + result_parse++; } - break; + // if we uncomment this we can force strict response matching + // else { + // state = at_parse_state_t::ParseError; + // } + + break; + case at_parse_state_t::Cmd: + /* + * In this state we parse the command prompt and wait for either ':' or '=' characters + * in order to go the next state + */ + + if(c == ':' || c == '=') { + commandName += c; // prompt includes also ':' + + if (check_prompt && commandName != prompt) { + // the response we got is not the one we were expecting, parse the wrong response till the end + // and start the parse of the next response + restart = true; + commandName = ""; + } + state = at_parse_state_t::Data; - default: - st = IDLE; - break; - } - return rv; -} + data_res = ""; + // state = at_parse_state_t::Data; + } else { // no space should be present in the prompt response + commandName += c; + } + break; + case at_parse_state_t::Data: + /* + * In this state we parse response parameters and push them into data_res + * in case multiple parameters separated by ',' are sent, they will be present in data_res + * - if we encounter we need to wait for + * - if we encounter we need to parse the response status + * - if we encounter '|', the next token will contain binary sized data, the current value in + * in data_res contains the length of the next token + */ + + if(c == '|') { // sized read, the previous parameter is the length + state = at_parse_state_t::Sized; + + sized_read_size = atoi(data_res.c_str()); + data_res.clear(); + } else if(c == '\r') { + state = at_parse_state_t::ResWaitLF; + } else if(c == '\n') { + state = at_parse_state_t::Res; + } else if(trim_results && c != ' ') { + data_res += c; // in case trim_result is true, avoid adding spaces + } else if(!trim_results) { + data_res += c; + } + break; + case at_parse_state_t::Sized: + /* + * In this state we collect exactly sized_read_size characters into data_res + * when we consume all of them we go into Result parse state, where we supposedly + * wait for 'OK' + */ + data_res += c; -/* -------------------------------------------------------------------------- */ -bool ModemClass::buf_read(const string &prompt, string &data_res) { -/* -------------------------------------------------------------------------- */ - bool res = false; - bool found = false; - - if(_serial_debug && _debug_level >= 1) { - _serial_debug->print("RAW: "); - } + if(++sized_read_count == sized_read_size) { + state = at_parse_state_t::Res; + } + break; + case at_parse_state_t::ResWaitLF: + if(c == '\n') { + state = at_parse_state_t::Res; + } - unsigned long start_time = millis(); - while((millis() - start_time < _timeout) && !found){ - while( _serial->available() ){ - char c = _serial->read(); - data_res += c; + /* + * break is volountary not present, to cover for cases where the response status is in the + * following form: '...OK' 'ERROR' + */ + case at_parse_state_t::Res: + /* + * In this state we wait for either an 'O' or an 'E', in order to get an 'OK' + * or 'ERROR' + * The first two cases is when there is no parameter in the response, but just the OK and ERROR tokens + */ + + if(data_res == OK_TOKEN) { + res = Ok; + state = at_parse_state_t::Completed; + } else if(data_res == ERROR_TOKEN) { + res = Error; + state = at_parse_state_t::Completed; + } if(c == RESULT_OK[0]) { // OK response + state = at_parse_state_t::Ok; + result_parse = 1; + } else if(c == RESULT_ERROR[0]) { // Error response + state = at_parse_state_t::Error; + result_parse = 1; + } + // if we uncomment this we can force strict response matching + // else { + // state = at_parse_state_t::ParseError; + // } + break; + case at_parse_state_t::Ok: + /* + * In this state we want to match the exact 'K' response + */ + if(c != RESULT_OK[result_parse++]) { + state = at_parse_state_t::ParseError; + } - - if(_serial_debug && _debug_level >= 1) { - _serial_debug->print(c); + if(result_parse == strlen(RESULT_OK)) { + res = Ok; + state = at_parse_state_t::Completed; } - - - if(read_by_size) { - if(read_by_size_finished(data_res)) { - found = true; - read_by_size = false; - res = true; - if(data_res.size() > 0) { - data_res = data_res.substr(0, data_res.length() - (sizeof(RESULT_OK) - 1)); - } - else { - break; - } - } + break; + case at_parse_state_t::Error: + /* + * In this state we want to match the exact 'RROR' response + */ + + if(c != RESULT_ERROR[result_parse++]) { + state = at_parse_state_t::ParseError; } - else { - if(string::npos != data_res.rfind(RESULT_DATA)) { - data_res = data_res.substr(0, data_res.length() - (sizeof(RESULT_DATA) - 1)); - if(prompt != DO_NOT_CHECK_CMD) { - if(removeAtBegin(data_res, prompt)) { - res = true; - found = true; - } else { - data_res.clear(); - continue; - } - } - else { - res = true; - found = true; - } - break; - } - else if(string::npos != data_res.rfind(RESULT_OK)){ - data_res = data_res.substr(0, data_res.length() - (sizeof(RESULT_OK) - 1) ); - if(prompt != DO_NOT_CHECK_CMD) { - if(removeAtBegin(data_res, prompt)) { - res = true; - found = true; - } else { - data_res.clear(); - continue; - } - } - else { - res = true; - found = true; - } - break; - } - else if (string::npos != data_res.rfind(RESULT_ERROR)) { - found = true; - data_res.substr(0, data_res.length() - (sizeof(RESULT_ERROR) - 1)); - res = false; - break; - } + + if(result_parse == strlen(RESULT_ERROR)) { + res = Error; + state = at_parse_state_t::Completed; } + break; + case at_parse_state_t::ParseError: + res = ParseError; + // if we get a parseError, we go back from the beginning and try again to parse, unitl the timeout expires + state = at_parse_state_t::Begin; + restart = false; + consume_char = false; + break; + case at_parse_state_t::Completed: + break; + } + + if(restart && state == at_parse_state_t::Completed) { + state = at_parse_state_t::Begin; + restart = false; } } - if(trim_results) { - trim(data_res); + if(_serial_debug && _debug_level >= 3) { + _serial_debug->print("Final State "); + _serial_debug->print((int)state); + _serial_debug->print(" res "); + _serial_debug->println((int)res); } + trim_results = true; - read_by_size = false; if(_serial_debug && _debug_level >= 1) { _serial_debug->print("<-RAW END"); _serial_debug->println(); } - if(_serial_debug) { - _serial_debug->print(" ANSWER: "); - _serial_debug->println(data_res.c_str()); - if(res) { - _serial_debug->println(" Result: OK"); - } - else { - _serial_debug->println(" Result: FAILED"); - } - } - return res; } diff --git a/libraries/WiFiS3/src/Modem.h b/libraries/WiFiS3/src/Modem.h index fc6fb09f6..2ec55e42f 100644 --- a/libraries/WiFiS3/src/Modem.h +++ b/libraries/WiFiS3/src/Modem.h @@ -66,7 +66,14 @@ class ModemClass { void timeout(size_t timeout_ms) {_timeout = timeout_ms;} private: - bool buf_read(const std::string &cmd, std::string &data_res); + enum ParseResult { + Ok, + Error, + ParseError, + Timeout + }; + + ParseResult buf_read(const std::string &cmd, std::string &data_res); bool delete_serial; UART * _serial; unsigned long _timeout; From cf5ea5eb9498f0458bf0ce5d7efe78dda8809d0d Mon Sep 17 00:00:00 2001 From: Andrea Gilardoni Date: Thu, 18 Jul 2024 14:51:29 +0200 Subject: [PATCH 13/41] adding a third level of debug --- libraries/WiFiS3/src/Modem.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/WiFiS3/src/Modem.h b/libraries/WiFiS3/src/Modem.h index 2ec55e42f..d69958850 100644 --- a/libraries/WiFiS3/src/Modem.h +++ b/libraries/WiFiS3/src/Modem.h @@ -48,8 +48,8 @@ class ModemClass { void debug(Stream &u, uint8_t level = 0) { _serial_debug = &u; - if(level > 2) { - level = 2; + if(level > 3) { + level = 3; } _debug_level = level; } From f33f6e348440fbaf1b78d1ba870556b8c4e3f678 Mon Sep 17 00:00:00 2001 From: Andrea Gilardoni Date: Mon, 22 Jul 2024 10:56:40 +0200 Subject: [PATCH 14/41] removing unused methods --- libraries/WiFiS3/src/Modem.cpp | 4 ++-- libraries/WiFiS3/src/Modem.h | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/libraries/WiFiS3/src/Modem.cpp b/libraries/WiFiS3/src/Modem.cpp index 6a2c3a5b5..c1dba332f 100644 --- a/libraries/WiFiS3/src/Modem.cpp +++ b/libraries/WiFiS3/src/Modem.cpp @@ -10,13 +10,13 @@ using namespace std; /* -------------------------------------------------------------------------- */ -ModemClass::ModemClass(int tx, int rx) : beginned(false), delete_serial(false), _timeout(MODEM_TIMEOUT), trim_results(true), read_by_size(false) { +ModemClass::ModemClass(int tx, int rx) : beginned(false), delete_serial(false), _timeout(MODEM_TIMEOUT), trim_results(true) { /* -------------------------------------------------------------------------- */ _serial = new UART(tx,rx); } /* -------------------------------------------------------------------------- */ -ModemClass::ModemClass(UART * serial) : beginned(false) , delete_serial(true) , _serial(serial), _timeout(MODEM_TIMEOUT), trim_results(true), read_by_size(false) { +ModemClass::ModemClass(UART * serial) : beginned(false) , delete_serial(true) , _serial(serial), _timeout(MODEM_TIMEOUT), trim_results(true) { /* -------------------------------------------------------------------------- */ } diff --git a/libraries/WiFiS3/src/Modem.h b/libraries/WiFiS3/src/Modem.h index d69958850..3f785bc9d 100644 --- a/libraries/WiFiS3/src/Modem.h +++ b/libraries/WiFiS3/src/Modem.h @@ -35,7 +35,7 @@ class ModemClass { } void read_using_size() { - read_by_size = true; + // read_by_size = true; // deprecated } bool beginned; @@ -79,8 +79,6 @@ class ModemClass { unsigned long _timeout; uint8_t tx_buff[MAX_BUFF_SIZE]; bool trim_results; - bool read_by_size; - bool read_by_size_finished(std::string &rx); Stream * _serial_debug; uint8_t _debug_level = 0; }; From 0f3333b0c6a28f0aab369fec569b77dc5f60265d Mon Sep 17 00:00:00 2001 From: Andrea Gilardoni Date: Thu, 14 Nov 2024 11:18:06 +0100 Subject: [PATCH 15/41] [preferences] adding getType command --- libraries/Preferences/src/Preferences.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Preferences/src/Preferences.cpp b/libraries/Preferences/src/Preferences.cpp index 9bdac4887..f12745546 100644 --- a/libraries/Preferences/src/Preferences.cpp +++ b/libraries/Preferences/src/Preferences.cpp @@ -187,7 +187,7 @@ size_t Preferences::putBytes(const char* key, const void* value, size_t len) { PreferenceType Preferences::getType(const char* key) { string res = ""; if (key != nullptr && strlen(key) > 0) { - if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s\r\n", CMD_WRITE(_PREF_PUT), key)) { + if (modem.write(string(PROMPT(_PREF_TYPE)), res, "%s%s\r\n", CMD_WRITE(_PREF_TYPE), key)) { return static_cast(atoi(res.c_str())); } } From 30ba157841dd05c1e57825d94bbe6ea3af219019 Mon Sep 17 00:00:00 2001 From: Andrea Gilardoni Date: Thu, 14 Nov 2024 11:23:42 +0100 Subject: [PATCH 16/41] [preferences] improving string get and put --- libraries/Preferences/src/Preferences.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libraries/Preferences/src/Preferences.cpp b/libraries/Preferences/src/Preferences.cpp index f12745546..3e689c955 100644 --- a/libraries/Preferences/src/Preferences.cpp +++ b/libraries/Preferences/src/Preferences.cpp @@ -162,8 +162,9 @@ size_t Preferences::putBool(const char* key, const bool value) { size_t Preferences::putString(const char* key, const char* value) { string res = ""; if (key != nullptr && strlen(key) > 0 && value != nullptr && strlen(value) > 0) { - if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%s\r\n", CMD_WRITE(_PREF_PUT), key, PT_STR, value)) { - return atoi(res.c_str()); + modem.write_nowait(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%d\r\n", CMD_WRITE(_PREF_PUT), key, PT_STR, strlen(value)); + if(modem.passthrough((uint8_t *)value, strlen(value))) { + return strlen(value); } } return 0; @@ -307,9 +308,11 @@ bool Preferences::getBool(const char* key, const bool defaultValue) { size_t Preferences::getString(const char* key, char* value, const size_t maxLen) { string res = ""; if (key != nullptr && strlen(key) > 0 && value != nullptr) { + modem.read_using_size(); if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d\r\n", CMD_WRITE(_PREF_GET), key, PT_STR)) { - if (res.length() < maxLen) { + if (res.length()+1 < maxLen) { // take into account \0 at the end strncpy(value, res.c_str(), res.length()); + value[res.length()] = '\0'; return res.length(); } } @@ -320,6 +323,7 @@ size_t Preferences::getString(const char* key, char* value, const size_t maxLen) String Preferences::getString(const char* key, const String defaultValue) { string res = ""; if (key != nullptr && strlen(key) > 0) { + modem.read_using_size(); if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%s\r\n", CMD_WRITE(_PREF_GET), key, PT_STR, defaultValue.c_str())) { return String(res.c_str()); } From 0901777ea0d870e072205cb41ece8f1f26e1fbb8 Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 27 Nov 2024 15:05:05 +0100 Subject: [PATCH 17/41] [preferences] add example for type support checking --- .../examples/TypesCheck/TypesCheck.ino | 400 ++++++++++++++++++ 1 file changed, 400 insertions(+) create mode 100644 libraries/Preferences/examples/TypesCheck/TypesCheck.ino diff --git a/libraries/Preferences/examples/TypesCheck/TypesCheck.ino b/libraries/Preferences/examples/TypesCheck/TypesCheck.ino new file mode 100644 index 000000000..022ccf6d2 --- /dev/null +++ b/libraries/Preferences/examples/TypesCheck/TypesCheck.ino @@ -0,0 +1,400 @@ +/* + This example checks all possible types that can be stored with Preferences library +*/ +#include +#include +Preferences prefs; + +void setup() { + Serial.begin(115200); + + if (!prefs.begin("types")) { // use "types" namespace + Serial.println("Cannot initialize preferences"); + Serial.println("Make sure your WiFi firmware version is greater than 0.3.0"); + while(1) {}; + } + + if (!testChar()) { + return; + } + + if (!testUChar()) { + return; + } + + if (!testShort()) { + return; + } + + if (!testUShort()) { + return; + } + + if (!testInt()) { + return; + } + + if (!testUInt()) { + return; + } + + if (!testLong64()) { + return; + } + + if (!testULong64()) { + return; + } + + if (!testFloat()) { + return; + } + + if (!testDouble()) { + return; + } + + if (!testBytes()) { + return; + } + + if (!testString()) { + return; + } +} + +void loop() { + Serial.println(prefs.freeEntries()); + prefs.clear(); + Serial.println(prefs.freeEntries()); + prefs.end(); + + while(1) {}; +} + +int testChar() { + int8_t data; + int8_t value; + + data = INT8_MAX; + prefs.putChar("char", data); + value = prefs.getChar("char", 0); + if (value != 127) { + Serial.println("getChar MAX Error"); + return 0; + } else { + Serial.print("getChar MAX: "); + Serial.println(value); + } + + data = INT8_MIN; + prefs.putChar("char", data); + value = prefs.getChar("char", 0); + if (value != -128) { + Serial.println("getChar MIN Error"); + return 0; + } else { + Serial.print("getChar MIN: "); + Serial.println(value); + } + + return 1; +} + +int testUChar() { + uint8_t data; + uint8_t value; + + data = UINT8_MAX; + prefs.putUChar("uchar", data); + value = prefs.getUChar("uchar", 0); + if (value != 255) { + Serial.println("getUChar MAX Error"); + return 0; + } else { + Serial.print("getUChar MAX: "); + Serial.println(value); + } + + prefs.remove("uchar"); + + data = 0; + prefs.putUChar("uchar", data); + value = prefs.getUChar("uchar", 1); + if (value != 0) { + Serial.println("getUChar MIN Error"); + return 0; + } else { + Serial.print("getUChar MIN: "); + Serial.println(value); + } + + return 1; +} + +int testShort() { + int16_t data; + int16_t value; + + data = INT16_MAX; + prefs.putShort("short", data); + value = prefs.getShort("short", 0); + if (value != 32767) { + Serial.println("getShort MAX Error"); + return 0; + } else { + Serial.print("getShort MAX: "); + Serial.println(value); + } + + data = INT16_MIN; + prefs.putShort("short", data); + value = prefs.getShort("short", 0); + if (value != -32768) { + Serial.println("getShort MIN Error"); + return 0; + } else { + Serial.print("getShort MIN: "); + Serial.println(value); + } + + return 1; +} + +int testUShort() { + uint16_t data; + uint16_t value; + + data = UINT16_MAX; + prefs.putUShort("ushort", data); + value = prefs.getUShort("ushort", 0); + if (value != 65535U) { + Serial.println("getUShort MAX Error"); + return 0; + } else { + Serial.print("getUShort MAX: "); + Serial.println(value); + } + + data = 0; + prefs.putUShort("ushort", data); + value = prefs.getUShort("ushort", 1); + if (value != 0) { + Serial.println("getUShort MIN Error"); + return 0; + } else { + Serial.print("getUShort MIN: "); + Serial.println(value); + } + + return 1; +} + +int testInt() { + int32_t data; + int32_t value; + + data = INT32_MAX; + prefs.putInt("int", data); + value = prefs.getInt("int", 0); + if (value != 2147483647) { + Serial.println("getInt MAX Error"); + return 0; + } else { + Serial.print("getInt MAX: "); + Serial.println(value); + } + + data = INT32_MIN; + prefs.putInt("int", data); + value = prefs.getInt("int", 0); + if (value != (-2147483647 - 1)) { + Serial.println("getInt MIN Error"); + return 0; + } else { + Serial.print("getInt MIN: "); + Serial.println(value); + } + + return 1; +} + +int testUInt() { + uint32_t data; + uint32_t value; + + data = UINT32_MAX; + prefs.putUInt("uint", data); + value = prefs.getUInt("uint", 0); + if (value != 4294967295U) { + Serial.println("getUInt MAX Error"); + return 0; + } else { + Serial.print("getUInt MAX: "); + Serial.println(value); + } + + data = 0; + prefs.putUInt("uint", data); + value = prefs.getUInt("uint", 1); + if (value != 0) { + Serial.println("getUInt MIN Error"); + return 0; + } else { + Serial.print("getUInt MIN: "); + Serial.println(value); + } + + return 1; +} + +int testLong64() { + int64_t data; + int64_t value; + + data = INT64_MAX; + prefs.putLong64("long", data); + value = prefs.getLong64("long", 0); + if (value != 9223372036854775807LL) { + Serial.println("getLong MAX Error"); + return 0; + } else { + Serial.print("getLong MAX: "); + Serial.println(value); + } + + data = INT64_MIN; + prefs.putLong64("long", data); + value = prefs.getLong64("long", 0); + if (value != (-9223372036854775807LL - 1)) { + Serial.println("getLong MIN Error"); + return 0; + } else { + Serial.print("getLong MIN: "); + Serial.println(value); + } + + return 1; +} + +int testULong64() { + uint64_t data; + uint64_t value; + + data = UINT64_MAX; + prefs.putULong64("ulong", data); + value = prefs.getULong64("ulong", 0); + if (value != 18446744073709551615ULL) { + Serial.println("getULong64 MAX Error"); + return 0; + } else { + Serial.print("getULong64 MAX: "); + Serial.println(value); + } + + data = 0; + prefs.putULong64("ulong", data); + value = prefs.getULong64("ulong", 1); + if (value != 0) { + Serial.println("getULong64 MIN Error"); + return 0; + } else { + Serial.print("getULong64 MIN: "); + Serial.println(value); + } + + return 1; +} + +int testFloat() { + float data; + float value; + + data = FLT_MAX; + prefs.putFloat("float", data); + value = prefs.getFloat("float", 0); + if (value != FLT_MAX) { + Serial.println("getFloat MAX Error"); + return 0; + } else { + Serial.print("getFloat MAX: "); + Serial.println(value); + } + + data = FLT_MIN; + prefs.putFloat("float", data); + value = prefs.getFloat("float", 0); + if (value != FLT_MIN) { + Serial.println("getFloat MIN Error"); + return 0; + } else { + Serial.print("getFloat MIN: "); + Serial.println(value); + } + + return 1; +} + +int testDouble() { + double data; + double value; + + data = DBL_MAX; + prefs.putDouble("double", data); + value = prefs.getDouble("double", 0); + if (value != DBL_MAX) { + Serial.println("getDouble MAX Error"); + return 0; + } else { + Serial.print("getDouble MAX: "); + Serial.println(value); + } + + data = DBL_MIN; + prefs.putDouble("double", data); + value = prefs.getDouble("double", 0); + if (value != DBL_MIN) { + Serial.println("getDouble MIN Error"); + return 0; + } else { + Serial.print("getDouble MIN: "); + Serial.println(value); + } + + return 1; +} + +int testBytes() { + uint8_t data[] = {9, 30, 235, 255, 20, 15, 0, 1, 9, 30, 235, 255, 20, 15, 0, 1, 9, 30, 235, 255, 20, 15, 0, 1, 9, 30, 235, 255, 20, 15, 0, 1}; + size_t len; + + prefs.putBytes("bytes", data, sizeof(data)); + len = prefs.getBytesLength("bytes"); + uint8_t value[len]; + prefs.getBytes("bytes", value, len); + if (memcmp(data, value, len) != 0) { + Serial.println("getBytes Error"); + return 0; + } else { + Serial.println("getBytes OK"); + } + + return 1; +} + +int testString() { + const char* data = "Lorem ipsum dolor sit amet consectetur adipiscing elit."; + String value = "default"; + + prefs.putString("string", data); + value = prefs.getString("string", value); + if (strcmp(data, value.c_str()) != 0) { + Serial.println("getString Error"); + Serial.println("Make sure your WiFi firmware version is greater than 0.5.0"); + return 0; + } else { + Serial.println("getString OK"); + } + + return 1; +} From 8094bbfca2953e1e9147bbc1ef528ab2d63532ca Mon Sep 17 00:00:00 2001 From: Andrea Gilardoni Date: Fri, 24 May 2024 14:10:11 +0200 Subject: [PATCH 18/41] implementing non blocking download functions in ota interface --- libraries/OTAUpdate/src/OTAUpdate.cpp | 43 +++++++++++++++++++++++++++ libraries/OTAUpdate/src/OTAUpdate.h | 6 ++++ 2 files changed, 49 insertions(+) diff --git a/libraries/OTAUpdate/src/OTAUpdate.cpp b/libraries/OTAUpdate/src/OTAUpdate.cpp index 50ce57233..b6ff08335 100644 --- a/libraries/OTAUpdate/src/OTAUpdate.cpp +++ b/libraries/OTAUpdate/src/OTAUpdate.cpp @@ -87,6 +87,49 @@ int OTAUpdate::download(const char* url, const char* file_path) { return ret; } +int OTAUpdate::startDownload(const char* url) { + string res = ""; + int ret = -1; + if ( url != nullptr && strlen(url) > 0) { + modem.timeout(EXTENDED_MODEM_TIMEOUT); + if(modem.write(string(PROMPT(_OTA_DOWNLOAD_START)), res, "%s%s\r\n", CMD_WRITE(_OTA_DOWNLOAD_START), url)) { + ret = atoi(res.c_str()); + } else { + ret = static_cast(Error::Modem); + } + } else { + ret = static_cast(Error::Library); + } + modem.timeout(MODEM_TIMEOUT); + return ret; +} + +int OTAUpdate::startDownload(const char* url, const char* file_path) { + string res = ""; + int ret = -1; + + if ( url != nullptr && strlen(url) > 0 && file_path != nullptr && strlen(file_path) >0) { + modem.timeout(EXTENDED_MODEM_TIMEOUT); + if(modem.write(string(PROMPT(_OTA_DOWNLOAD_START)), res, "%s%s,%s\r\n", CMD_WRITE(_OTA_DOWNLOAD_START), url, file_path)) { + ret = atoi(res.c_str()); + } else { + ret = static_cast(Error::Modem); + } + } else { + ret = static_cast(Error::Library); + } + modem.timeout(MODEM_TIMEOUT); + return ret; +} + +int OTAUpdate::downloadProgress() { + string res = ""; + if (modem.write(string(PROMPT(_OTA_DOWNLOAD_PROGRESS)), res, "%s", CMD(_OTA_DOWNLOAD_PROGRESS))) { + return atoi(res.c_str()); + } + return static_cast(Error::Modem); +} + int OTAUpdate::verify() { string res = ""; if (modem.write(string(PROMPT(_OTA_VERIFY)), res, "%s", CMD(_OTA_VERIFY))) { diff --git a/libraries/OTAUpdate/src/OTAUpdate.h b/libraries/OTAUpdate/src/OTAUpdate.h index 9b1b171c0..69266a9e3 100644 --- a/libraries/OTAUpdate/src/OTAUpdate.h +++ b/libraries/OTAUpdate/src/OTAUpdate.h @@ -42,6 +42,12 @@ class OTAUpdate { int begin(const char* file_path); int download(const char* url); int download(const char* url, const char* file_path); + + int startDownload(const char* url); + int startDownload(const char* url, const char* file_path); + + int downloadProgress(); + int verify(); int update(); int update(const char* file_path); From d8c676b9a0ccf197f7cf22c539c78d721f67cf81 Mon Sep 17 00:00:00 2001 From: Andrea Gilardoni Date: Fri, 24 May 2024 14:10:58 +0200 Subject: [PATCH 19/41] adding example for ota non blocking download --- .../OTANonBlocking/OTANonBlocking.ino | 136 ++++++++++++++++++ .../examples/OTANonBlocking/arduino_secrets.h | 2 + .../examples/OTANonBlocking/root_ca.h | 106 ++++++++++++++ 3 files changed, 244 insertions(+) create mode 100644 libraries/OTAUpdate/examples/OTANonBlocking/OTANonBlocking.ino create mode 100644 libraries/OTAUpdate/examples/OTANonBlocking/arduino_secrets.h create mode 100644 libraries/OTAUpdate/examples/OTANonBlocking/root_ca.h diff --git a/libraries/OTAUpdate/examples/OTANonBlocking/OTANonBlocking.ino b/libraries/OTAUpdate/examples/OTANonBlocking/OTANonBlocking.ino new file mode 100644 index 000000000..2021c4fef --- /dev/null +++ b/libraries/OTAUpdate/examples/OTANonBlocking/OTANonBlocking.ino @@ -0,0 +1,136 @@ +/* + OTANonBlocking + + This sketch demonstrates how to make an OTA Update on the UNO R4 WiFi. + Upload the sketch and wait for the invasion! + +*/ + + +#include "WiFiS3.h" +#include "OTAUpdate.h" +#include "root_ca.h" +#include "arduino_secrets.h" + +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) + +int status = WL_IDLE_STATUS; + +OTAUpdate ota; +static char const OTA_FILE_LOCATION[] = "https://downloads.arduino.cc/ota/UNOR4WIFI_Animation.ota"; + +/* -------------------------------------------------------------------------- */ +void setup() { +/* -------------------------------------------------------------------------- */ + //Initialize serial and wait for port to open: + Serial.begin(115200); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // check for the Wi-Fi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with Wi-Fi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv < WIFI_FIRMWARE_LATEST_VERSION) { + Serial.println("Please upgrade the firmware"); + } + + // attempt to connect to Wi-Fi network: + while (status != WL_CONNECTED) { + Serial.print("Attempting to connect to SSID: "); + Serial.println(ssid); + // Connect to WPA/WPA2 network. Change this line if using open or WEP network: + status = WiFi.begin(ssid, pass); + + // wait 1 seconds for connection: + delay(1000); + } + + printWiFiStatus(); + + Serial.println("ota.begin()"); + int ret = ota.begin("/update.bin"); + if(ret != OTAUpdate::OTA_ERROR_NONE) { + Serial.println("ota.begin() error: "); + Serial.println((int)ret); + return; + } + + Serial.println("ota.setCACert()"); + ret = ota.setCACert(root_ca); + if(ret != OTAUpdate::OTA_ERROR_NONE) { + Serial.println("ota.setCACert() error: "); + Serial.println((int)ret); + return; + } + + Serial.println("ota.startDownload()"); + int ota_size = ota.startDownload(OTA_FILE_LOCATION, "/update.bin"); + if(ota_size <= 0) { + Serial.println("ota.startDownload() error: "); + Serial.println(ota_size); + return; + } + + Serial.println("ota.downloadProgress()"); + while((ret = ota.downloadProgress()) < ota_size) { + Serial.print("Progress "); + Serial.print(ret); + Serial.print("/"); + Serial.println(ota_size); + delay(100); + } + + if(ret < 0){ + Serial.println("ota.downloadProgress() error: "); + Serial.println((int)ret); + return; + } + + Serial.println("ota.verify()"); + ret = ota.verify(); + if(ret != OTAUpdate::OTA_ERROR_NONE) { + Serial.println("ota.verify() error: "); + Serial.println((int)ret); + return; + } +\ + Serial.println("ota.update()"); + ret = ota.update("/update.bin"); + if(ret != OTAUpdate::OTA_ERROR_NONE) { + Serial.println("ota.update() error: "); + Serial.println((int)ret); + return; + } +} + +/* -------------------------------------------------------------------------- */ +void loop() { +/* -------------------------------------------------------------------------- */ + delay(1000); +} + +/* -------------------------------------------------------------------------- */ +void printWiFiStatus() { +/* -------------------------------------------------------------------------- */ + // print the SSID of the network you're attached to: + Serial.print("SSID: "); + Serial.println(WiFi.SSID()); + + // print your board's IP address: + IPAddress ip = WiFi.localIP(); + Serial.print("IP Address: "); + Serial.println(ip); + + // print the received signal strength: + long rssi = WiFi.RSSI(); + Serial.print("signal strength (RSSI):"); + Serial.print(rssi); + Serial.println(" dBm"); +} diff --git a/libraries/OTAUpdate/examples/OTANonBlocking/arduino_secrets.h b/libraries/OTAUpdate/examples/OTANonBlocking/arduino_secrets.h new file mode 100644 index 000000000..0c9fdd556 --- /dev/null +++ b/libraries/OTAUpdate/examples/OTANonBlocking/arduino_secrets.h @@ -0,0 +1,2 @@ +#define SECRET_SSID "" +#define SECRET_PASS "" diff --git a/libraries/OTAUpdate/examples/OTANonBlocking/root_ca.h b/libraries/OTAUpdate/examples/OTANonBlocking/root_ca.h new file mode 100644 index 000000000..57e61f92f --- /dev/null +++ b/libraries/OTAUpdate/examples/OTANonBlocking/root_ca.h @@ -0,0 +1,106 @@ +const char* root_ca = \ +/* GTS Root R1 */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw\n" \ +"CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU\n" \ +"MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw\n" \ +"MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp\n" \ +"Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA\n" \ +"A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo\n" \ +"27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w\n" \ +"Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw\n" \ +"TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl\n" \ +"qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH\n" \ +"szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8\n" \ +"Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk\n" \ +"MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92\n" \ +"wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p\n" \ +"aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN\n" \ +"VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID\n" \ +"AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E\n" \ +"FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb\n" \ +"C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe\n" \ +"QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy\n" \ +"h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4\n" \ +"7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J\n" \ +"ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef\n" \ +"MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/\n" \ +"Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT\n" \ +"6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ\n" \ +"0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm\n" \ +"2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb\n" \ +"bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c\n" \ +"-----END CERTIFICATE-----\n" \ +/* GTS Root R2 */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw\n" \ +"CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU\n" \ +"MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw\n" \ +"MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp\n" \ +"Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA\n" \ +"A4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt\n" \ +"nfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY\n" \ +"6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu\n" \ +"MC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k\n" \ +"RXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg\n" \ +"f9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV\n" \ +"+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo\n" \ +"dDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW\n" \ +"Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa\n" \ +"G73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq\n" \ +"gc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID\n" \ +"AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E\n" \ +"FgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H\n" \ +"vqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8\n" \ +"0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC\n" \ +"B19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u\n" \ +"NmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg\n" \ +"yALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev\n" \ +"HyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6\n" \ +"xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR\n" \ +"TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg\n" \ +"JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV\n" \ +"7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl\n" \ +"6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL\n" \ +"-----END CERTIFICATE-----\n" \ +/* GTS Root R3 */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD\n" \ +"VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG\n" \ +"A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw\n" \ +"WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz\n" \ +"IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi\n" \ +"AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G\n" \ +"jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2\n" \ +"4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW\n" \ +"BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7\n" \ +"VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm\n" \ +"ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X\n" \ +"-----END CERTIFICATE-----\n" \ +/* GTS Root R4 */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD\n" \ +"VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG\n" \ +"A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw\n" \ +"WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz\n" \ +"IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi\n" \ +"AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi\n" \ +"QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR\n" \ +"HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW\n" \ +"BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D\n" \ +"9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8\n" \ +"p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD\n" \ +"-----END CERTIFICATE-----\n" \ +/* GlobalSign R4 */ +"-----BEGIN CERTIFICATE-----\n" \ +"MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD\n" \ +"VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh\n" \ +"bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw\n" \ +"MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g\n" \ +"UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT\n" \ +"BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx\n" \ +"uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV\n" \ +"HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/\n" \ +"+wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147\n" \ +"bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm\n" \ +"-----END CERTIFICATE-----\n"; From 3bd4ebd1f8a2cb07dd4b96289dafce87158bc7fe Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 28 Nov 2024 09:17:10 +0100 Subject: [PATCH 20/41] OTANonBlocking: add info about minimum required firmware version --- libraries/OTAUpdate/examples/OTANonBlocking/OTANonBlocking.ino | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/OTAUpdate/examples/OTANonBlocking/OTANonBlocking.ino b/libraries/OTAUpdate/examples/OTANonBlocking/OTANonBlocking.ino index 2021c4fef..534f77bbe 100644 --- a/libraries/OTAUpdate/examples/OTANonBlocking/OTANonBlocking.ino +++ b/libraries/OTAUpdate/examples/OTANonBlocking/OTANonBlocking.ino @@ -4,6 +4,8 @@ This sketch demonstrates how to make an OTA Update on the UNO R4 WiFi. Upload the sketch and wait for the invasion! + It requires at least version 0.5.0 of USB Wifi bridge firmware + */ @@ -75,6 +77,7 @@ void setup() { if(ota_size <= 0) { Serial.println("ota.startDownload() error: "); Serial.println(ota_size); + Serial.println("Make sure your WiFi firmware version is at least 0.5.0"); return; } From 1085b2408a4cbae28479e98e3670b48e5d87d352 Mon Sep 17 00:00:00 2001 From: alrvid <126816223+alrvid@users.noreply.github.com> Date: Thu, 28 Nov 2024 09:30:30 +0100 Subject: [PATCH 21/41] Initialize local variable for AP config The AP configuration variable wasn't initialized, so the fields contained random data. Then, they were filled using memcpy() with the size of the data to copy, leaving the remainder of the fields containing random data. For example, the pwd variable containing the entered password was copied without null termination into the pwd field, and the rest of the pwd field contained random data. This caused connection failures depending on the content of the random data. --- libraries/ESPhost/examples/ESP32_TEST/ESP32_TEST.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESPhost/examples/ESP32_TEST/ESP32_TEST.ino b/libraries/ESPhost/examples/ESP32_TEST/ESP32_TEST.ino index 579085b35..b0c17ecb5 100644 --- a/libraries/ESPhost/examples/ESP32_TEST/ESP32_TEST.ino +++ b/libraries/ESPhost/examples/ESP32_TEST/ESP32_TEST.ino @@ -297,7 +297,7 @@ void connectAccessPoint() { int i = stoi(ap_str); Serial.println(">>> [APP]: Connecting to Access Point"); - WifiApCfg_t ap; + WifiApCfg_t ap{}; memcpy(ap.ssid,access_point_list[i].ssid,SSID_LENGTH); memcpy(ap.pwd,pwd.c_str(),pwd.size()); memcpy(ap.bssid,access_point_list[i].bssid,BSSID_LENGTH); From 7cfd0e712a77e5ea0717a6303d8f21a179ca13b2 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 28 Nov 2024 10:00:18 +0100 Subject: [PATCH 22/41] examples: uno r4 wifi fix print about required firmware version --- libraries/Preferences/examples/TypesCheck/TypesCheck.ino | 2 +- libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino | 4 ++-- libraries/WiFiS3/examples/WiFiTime/WiFiTime.ino | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/Preferences/examples/TypesCheck/TypesCheck.ino b/libraries/Preferences/examples/TypesCheck/TypesCheck.ino index 022ccf6d2..3ba07014d 100644 --- a/libraries/Preferences/examples/TypesCheck/TypesCheck.ino +++ b/libraries/Preferences/examples/TypesCheck/TypesCheck.ino @@ -390,7 +390,7 @@ int testString() { value = prefs.getString("string", value); if (strcmp(data, value.c_str()) != 0) { Serial.println("getString Error"); - Serial.println("Make sure your WiFi firmware version is greater than 0.5.0"); + Serial.println("Make sure your WiFi firmware version is at least 0.5.0"); return 0; } else { Serial.println("getString OK"); diff --git a/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino b/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino index 248098dcb..62ff33916 100755 --- a/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino +++ b/libraries/WiFiS3/examples/WiFiPing/WiFiPing.ino @@ -74,7 +74,7 @@ void loop() { } else { Serial.println("Timeout on IP!"); - Serial.println("Make sure your WiFi firmware version is greater than 0.5.0"); + Serial.println("Make sure your WiFi firmware version is at least 0.5.0"); } // Ping Host @@ -92,7 +92,7 @@ void loop() { } else { Serial.println("Timeout on host!"); - Serial.println("Make sure your WiFi firmware version is greater than 0.5.0"); + Serial.println("Make sure your WiFi firmware version is at least 0.5.0"); } Serial.println(); diff --git a/libraries/WiFiS3/examples/WiFiTime/WiFiTime.ino b/libraries/WiFiS3/examples/WiFiTime/WiFiTime.ino index 22ab7495a..f027aad34 100644 --- a/libraries/WiFiS3/examples/WiFiTime/WiFiTime.ino +++ b/libraries/WiFiS3/examples/WiFiTime/WiFiTime.ino @@ -73,7 +73,7 @@ void loop() { } else { Serial.println("Error during reading epoch time."); - Serial.println("Make sure your WiFi firmware version is greater than 0.5.0"); + Serial.println("Make sure your WiFi firmware version is at least 0.5.0"); } Serial.println(); From e6500c1fc0cab85ba4527b1767155bb5b2fcb25a Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 28 Nov 2024 10:02:33 +0100 Subject: [PATCH 23/41] WiFiS3 ping add missing parameter --- libraries/WiFiS3/src/WiFi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/WiFiS3/src/WiFi.cpp b/libraries/WiFiS3/src/WiFi.cpp index a43d32d57..17d78fef6 100644 --- a/libraries/WiFiS3/src/WiFi.cpp +++ b/libraries/WiFiS3/src/WiFi.cpp @@ -576,7 +576,7 @@ int CWifi::ping(IPAddress ip, uint8_t ttl, uint8_t count) { int CWifi::ping(const String &hostname, uint8_t ttl, uint8_t count) /* -------------------------------------------------------------------------- */ { - return ping(hostname.c_str(), ttl); + return ping(hostname.c_str(), ttl, count); } /* -------------------------------------------------------------------------- */ From 983e92b023985825a4fa93523ff3110c339333d4 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 28 Nov 2024 11:10:43 +0100 Subject: [PATCH 24/41] WiFiUdp: fix Wsign-compare --- libraries/WiFiS3/src/WiFiUdp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/WiFiS3/src/WiFiUdp.cpp b/libraries/WiFiS3/src/WiFiUdp.cpp index 5337c8360..f229485c6 100644 --- a/libraries/WiFiS3/src/WiFiUdp.cpp +++ b/libraries/WiFiS3/src/WiFiUdp.cpp @@ -181,7 +181,7 @@ int WiFiUDP::_read() { modem.read_using_size(); if(modem.write(string(PROMPT(_UDPREAD)),res, "%s%d,%d\r\n" , CMD_WRITE(_UDPREAD), _sock, size)) { if(res.size() > 0) { - for(int i = 0, rv = 0; i < size && i < res.size(); i++) { + for(uint32_t i = 0, rv = 0; i < size && i < res.size(); i++) { rx_buffer.store((uint8_t)res[i]); rv++; } @@ -218,7 +218,7 @@ int WiFiUDP::read(unsigned char* buf, size_t size) { read_if_needed(size); int rv = 0; bool go_on = true; - for(int i = 0; i < size && go_on; i++) { + for(size_t i = 0; i < size && go_on; i++) { bool is_read = false; *(buf+i) = rx_buffer.read(&is_read); if(is_read) { From 1b2737375321636d4a2847a7a02d967db3e6a60f Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 28 Nov 2024 11:11:16 +0100 Subject: [PATCH 25/41] WiFiSSLClient: fix Wsign-compare --- libraries/WiFiS3/src/WiFiSSLClient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/WiFiS3/src/WiFiSSLClient.cpp b/libraries/WiFiS3/src/WiFiSSLClient.cpp index 91b6951e5..bfe7c488d 100644 --- a/libraries/WiFiS3/src/WiFiSSLClient.cpp +++ b/libraries/WiFiS3/src/WiFiSSLClient.cpp @@ -148,7 +148,7 @@ int WiFiSSLClient::_read() { modem.read_using_size(); if(modem.write(string(PROMPT(_SSLCLIENTRECEIVE)),res, "%s%d,%d\r\n" , CMD_WRITE(_SSLCLIENTRECEIVE), _sock, size)) { if(res.size() > 0) { - for(int i = 0, rv = 0; i < size && i < res.size(); i++) { + for(uint32_t i = 0, rv = 0; i < size && i < res.size(); i++) { rx_buffer->store((uint8_t)res[i]); rv++; } @@ -185,7 +185,7 @@ int WiFiSSLClient::read(uint8_t *buf, size_t size) { read_if_needed(size); int rv = 0; bool go_on = true; - for(int i = 0; i < size && go_on; i++) { + for(size_t i = 0; i < size && go_on; i++) { bool is_read = false; *(buf+i) = rx_buffer->read(&is_read); if(is_read) { From ba39680e53755c1859847f25961efe25564d5362 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 28 Nov 2024 11:11:43 +0100 Subject: [PATCH 26/41] WiFiFileSystem: add missing return value --- libraries/WiFiS3/src/WiFiFileSystem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/WiFiS3/src/WiFiFileSystem.cpp b/libraries/WiFiS3/src/WiFiFileSystem.cpp index 938f2d8b5..8dc7fa8b5 100644 --- a/libraries/WiFiS3/src/WiFiFileSystem.cpp +++ b/libraries/WiFiS3/src/WiFiFileSystem.cpp @@ -20,6 +20,7 @@ size_t WiFiFileSystem::writefile(const char* name, const char* data, size_t size if(modem.passthrough((uint8_t *)data, size)) { return size; } + return 0; } /* -------------------------------------------------------------------------- */ From 9172976f70ff2c47c44a603f7d32a6732d0d4bb2 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 28 Nov 2024 11:12:14 +0100 Subject: [PATCH 27/41] WiFiClient: fix Wreorder --- libraries/WiFiS3/src/WiFiClient.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/WiFiS3/src/WiFiClient.h b/libraries/WiFiS3/src/WiFiClient.h index 81f5afae6..63b019c32 100644 --- a/libraries/WiFiS3/src/WiFiClient.h +++ b/libraries/WiFiS3/src/WiFiClient.h @@ -70,14 +70,13 @@ class WiFiClient : public Client { protected: int _sock; + bool destroy_at_distructor; int _connectionTimeout = 0; void getSocket(); static constexpr uint32_t RX_BUFFER_DIM = 1024; std::shared_ptr> rx_buffer; int _read(); void read_if_needed(size_t s); - bool destroy_at_distructor; - }; From 0a0e7a4bf884457268bb27f340f0daf9eea7fd13 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 28 Nov 2024 11:12:44 +0100 Subject: [PATCH 28/41] WiFiClient: fix Wsign-compare --- libraries/WiFiS3/src/WiFiClient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/WiFiS3/src/WiFiClient.cpp b/libraries/WiFiS3/src/WiFiClient.cpp index 143f92dae..9e6d09261 100644 --- a/libraries/WiFiS3/src/WiFiClient.cpp +++ b/libraries/WiFiS3/src/WiFiClient.cpp @@ -128,7 +128,7 @@ int WiFiClient::_read() { if(modem.write(string(PROMPT(_CLIENTRECEIVE)),res, "%s%d,%d\r\n" , CMD_WRITE(_CLIENTRECEIVE), _sock, size)) { if(res.size() > 0) { - for(int i = 0, rv = 0; i < size && i < res.size(); i++) { + for(uint32_t i = 0, rv = 0; i < size && i < res.size(); i++) { rx_buffer->store((uint8_t)res[i]); rv++; } @@ -168,7 +168,7 @@ int WiFiClient::read(uint8_t *buf, size_t size) { int rv = 0; bool go_on = true; if(_sock >= 0 && rx_buffer != nullptr) { - for(int i = 0; i < size && go_on; i++) { + for(size_t i = 0; i < size && go_on; i++) { bool is_read = false; *(buf+i) = rx_buffer->read(&is_read); if(is_read) { From 118cdb034076a1870959ee6408e1f356b83c2043 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 28 Nov 2024 11:13:07 +0100 Subject: [PATCH 29/41] WiFi: remove unused variable --- libraries/WiFiS3/src/WiFi.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/WiFiS3/src/WiFi.cpp b/libraries/WiFiS3/src/WiFi.cpp index a43d32d57..db95761b5 100644 --- a/libraries/WiFiS3/src/WiFi.cpp +++ b/libraries/WiFiS3/src/WiFi.cpp @@ -25,7 +25,6 @@ const char* CWifi::firmwareVersion() { /* -------------------------------------------------------------------------- */ uint32_t CWifi::firmwareVersionU32() { /* -------------------------------------------------------------------------- */ - uint8_t ret[4]; string res = ""; modem.begin(); if(modem.write(string(PROMPT(_FWVERSION_U32)), res, CMD_READ(_FWVERSION_U32))) { From 6bac645efe2c6a7b1801f138caf6f4274ca6165c Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 28 Nov 2024 11:14:42 +0100 Subject: [PATCH 30/41] Modem: suppress Wunused-parameter --- libraries/WiFiS3/src/Modem.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/WiFiS3/src/Modem.cpp b/libraries/WiFiS3/src/Modem.cpp index c1dba332f..1312c224a 100644 --- a/libraries/WiFiS3/src/Modem.cpp +++ b/libraries/WiFiS3/src/Modem.cpp @@ -75,6 +75,9 @@ bool ModemClass::passthrough(const uint8_t *data, size_t size) { /* -------------------------------------------------------------------------- */ void ModemClass::write_nowait(const string &cmd, string &str, const char * fmt, ...) { /* -------------------------------------------------------------------------- */ + (void)cmd; + (void)str; + va_list va; va_start (va, fmt); vsnprintf((char *)tx_buff, MAX_BUFF_SIZE, fmt, va); From 75bbb30036c4358b298875f2b059e9c37a0e8ae0 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 28 Nov 2024 11:15:34 +0100 Subject: [PATCH 31/41] Modem: add explicit fall through --- libraries/WiFiS3/src/Modem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/WiFiS3/src/Modem.cpp b/libraries/WiFiS3/src/Modem.cpp index 1312c224a..7aa34391a 100644 --- a/libraries/WiFiS3/src/Modem.cpp +++ b/libraries/WiFiS3/src/Modem.cpp @@ -321,6 +321,7 @@ ModemClass::ParseResult ModemClass::buf_read(const string &prompt, string &data_ if(c == '\n') { state = at_parse_state_t::Res; } + /* fall through */ /* * break is volountary not present, to cover for cases where the response status is in the From c7ad09421a03edf72ba131f89facecd551243f94 Mon Sep 17 00:00:00 2001 From: Mattia Pennasilico Date: Thu, 28 Nov 2024 11:19:18 +0100 Subject: [PATCH 32/41] TextWithArduinoGraphics: add note about ArduinoGraphics dependency (#401) * TextWithArduinoGraphics: add note about ArduinoGraphics dependency Co-authored-by: Per Tillisch --- .../TextWithArduinoGraphics/TextWithArduinoGraphics.ino | 3 +++ .../TextWithArduinoGraphicsAsynchronous.ino | 3 +++ 2 files changed, 6 insertions(+) diff --git a/libraries/Arduino_LED_Matrix/examples/TextWithArduinoGraphics/TextWithArduinoGraphics.ino b/libraries/Arduino_LED_Matrix/examples/TextWithArduinoGraphics/TextWithArduinoGraphics.ino index 906e85714..a40fad2f4 100644 --- a/libraries/Arduino_LED_Matrix/examples/TextWithArduinoGraphics/TextWithArduinoGraphics.ino +++ b/libraries/Arduino_LED_Matrix/examples/TextWithArduinoGraphics/TextWithArduinoGraphics.ino @@ -1,3 +1,6 @@ +// TextAnimation works only when ArduinoGraphics is installed and used. +// ArduinoGraphics is an external library and needs to be installed using +// Library Manager. // To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix #include "ArduinoGraphics.h" #include "Arduino_LED_Matrix.h" diff --git a/libraries/Arduino_LED_Matrix/examples/TextWithArduinoGraphicsAsynchronous/TextWithArduinoGraphicsAsynchronous.ino b/libraries/Arduino_LED_Matrix/examples/TextWithArduinoGraphicsAsynchronous/TextWithArduinoGraphicsAsynchronous.ino index d2d48101f..7a6d7239e 100644 --- a/libraries/Arduino_LED_Matrix/examples/TextWithArduinoGraphicsAsynchronous/TextWithArduinoGraphicsAsynchronous.ino +++ b/libraries/Arduino_LED_Matrix/examples/TextWithArduinoGraphicsAsynchronous/TextWithArduinoGraphicsAsynchronous.ino @@ -1,3 +1,6 @@ +// TextAnimation works only when ArduinoGraphics is installed and used. +// ArduinoGraphics is an external library and needs to be installed using +// Library Manager. // To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix and TextAnimation #include "ArduinoGraphics.h" #include "Arduino_LED_Matrix.h" From 443a4044f383840a4cfce2a4ac89267e62f0723b Mon Sep 17 00:00:00 2001 From: Hsubtnarg <101956419+Hsubtnarg@users.noreply.github.com> Date: Wed, 29 May 2024 09:00:58 +1200 Subject: [PATCH 33/41] Serial: split uart events TX_COMPLETE from TX_DATA_EMPTY Use UART_EVEN_TX_COMPLETE to determine when flush() should return --- cores/arduino/Serial.cpp | 26 +++++++++++++++----------- cores/arduino/Serial.h | 3 ++- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/cores/arduino/Serial.cpp b/cores/arduino/Serial.cpp index d905edd90..755ef8014 100644 --- a/cores/arduino/Serial.cpp +++ b/cores/arduino/Serial.cpp @@ -58,12 +58,14 @@ void UART::WrapperCallback(uart_callback_args_t *p_args) { { break; } - case UART_EVENT_TX_COMPLETE: - case UART_EVENT_TX_DATA_EMPTY: + case UART_EVENT_TX_COMPLETE: // This is call when the transmission is complete { - //uint8_t to_enqueue = uart_ptr->txBuffer.available() < uart_ptr->uart_ctrl.fifo_depth ? uart_ptr->txBuffer.available() : uart_ptr->uart_ctrl.fifo_depth; - //while (to_enqueue) { - uart_ptr->tx_done = true; + uart_ptr->tx_complete = true; + break; + } + case UART_EVENT_TX_DATA_EMPTY: // This is called when the buffer is empty + { // Last byte is transmitting, but ready for more data + uart_ptr->tx_empty = true; break; } case UART_EVENT_RX_CHAR: @@ -109,9 +111,10 @@ bool UART::setUpUartIrqs(uart_cfg_t &cfg) { size_t UART::write(uint8_t c) { /* -------------------------------------------------------------------------- */ if(init_ok) { - tx_done = false; + tx_empty = false; + tx_complete = false; R_SCI_UART_Write(&uart_ctrl, &c, 1); - while (!tx_done) {} + while (!tx_empty) {} return 1; } else { @@ -121,9 +124,10 @@ size_t UART::write(uint8_t c) { size_t UART::write(uint8_t* c, size_t len) { if(init_ok) { - tx_done = false; + tx_empty = false; + tx_complete = false; R_SCI_UART_Write(&uart_ctrl, c, len); - while (!tx_done) {} + while (!tx_empty) {} return len; } else { @@ -322,7 +326,7 @@ int UART::read() { /* -------------------------------------------------------------------------- */ void UART::flush() { /* -------------------------------------------------------------------------- */ - while(txBuffer.available()); + while(!tx_complete); } /* -------------------------------------------------------------------------- */ @@ -335,4 +339,4 @@ size_t UART::write_raw(uint8_t* c, size_t len) { i++; } return len; -} \ No newline at end of file +} diff --git a/cores/arduino/Serial.h b/cores/arduino/Serial.h index cc818d466..29a41d2c8 100644 --- a/cores/arduino/Serial.h +++ b/cores/arduino/Serial.h @@ -78,7 +78,8 @@ class UART : public arduino::HardwareSerial { arduino::SafeRingBufferN rxBuffer; arduino::SafeRingBufferN txBuffer; - volatile bool tx_done; + volatile bool tx_empty; + volatile bool tx_complete; sci_uart_instance_ctrl_t uart_ctrl; uart_cfg_t uart_cfg; From 51e2905a93b4bde2daf97622d7d8a8593b9f8f62 Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 29 Nov 2024 12:17:11 +0100 Subject: [PATCH 34/41] Serial: initialize tx flags to avoid locks --- cores/arduino/Serial.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cores/arduino/Serial.cpp b/cores/arduino/Serial.cpp index 755ef8014..e82d76796 100644 --- a/cores/arduino/Serial.cpp +++ b/cores/arduino/Serial.cpp @@ -89,6 +89,8 @@ UART::UART(int _pin_tx, int _pin_rx, int _pin_rts, int _pin_cts): rx_pin(_pin_rx), rts_pin(_pin_rts), cts_pin(_pin_cts), + tx_empty(true), + tx_complete(true), init_ok(false) { /* -------------------------------------------------------------------------- */ uart_cfg.txi_irq = FSP_INVALID_VECTOR; From 149197b2ff38a296fe015c7f9627559ce88e7488 Mon Sep 17 00:00:00 2001 From: Andrea Gilardoni Date: Wed, 4 Dec 2024 10:56:23 +0100 Subject: [PATCH 35/41] Preferences: adding missing return statement --- libraries/Preferences/src/Preferences.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/Preferences/src/Preferences.cpp b/libraries/Preferences/src/Preferences.cpp index 3e689c955..bf731d8e6 100644 --- a/libraries/Preferences/src/Preferences.cpp +++ b/libraries/Preferences/src/Preferences.cpp @@ -350,6 +350,8 @@ size_t Preferences::getBytes(const char* key, void * buf, size_t maxLen) { if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d\r\n", CMD_WRITE(_PREF_GET), key, PT_BLOB)) { if (res.size() >= len && len <= maxLen) { memcpy(buf, (uint8_t*)&res[0], len); + + return len; } } } From 95113d232f06595a824f3f588c7c5dd263f32bff Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 5 Dec 2024 09:21:05 +0100 Subject: [PATCH 36/41] Publish 1.3.1 --- platform.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.txt b/platform.txt index 87cb0603d..38f7aee8e 100644 --- a/platform.txt +++ b/platform.txt @@ -3,7 +3,7 @@ # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification name=Arduino Renesas fsp Boards -version=1.2.2 +version=1.3.1 # Compile variables # ------------------------ From 3a3cfe47b5ad977dd1cbf73eb8cad299edd02f37 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Mon, 9 Dec 2024 16:50:55 +0100 Subject: [PATCH 37/41] Move freertos hook between setup() and loop() This gives the chance for users to create new threads/queues in setup() without race conditions --- cores/arduino/main.cpp | 2 +- libraries/Arduino_FreeRTOS/src/portable/FSP/port.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp index 8a1e1b2ff..1d8c1386a 100644 --- a/cores/arduino/main.cpp +++ b/cores/arduino/main.cpp @@ -112,8 +112,8 @@ void arduino_main(void) Serial.begin(115200); #endif startAgt(); - start_freertos_on_header_inclusion(); setup(); + start_freertos_on_header_inclusion(); while (1) { loop(); diff --git a/libraries/Arduino_FreeRTOS/src/portable/FSP/port.c b/libraries/Arduino_FreeRTOS/src/portable/FSP/port.c index 036bd6264..598de672d 100644 --- a/libraries/Arduino_FreeRTOS/src/portable/FSP/port.c +++ b/libraries/Arduino_FreeRTOS/src/portable/FSP/port.c @@ -226,7 +226,6 @@ static void prvTaskExitError(void); #endif void loop_thread_func(void* arg) { - setup(); while (1) { loop(); From acb578e2610d7566f39fd0e8419ff38e460798a2 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Mon, 9 Dec 2024 16:52:22 +0100 Subject: [PATCH 38/41] Provide FreeRTOS hook only for PortentaC33 --- boards.txt | 2 +- cores/arduino/main.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/boards.txt b/boards.txt index d89c412aa..b6815e8d9 100644 --- a/boards.txt +++ b/boards.txt @@ -12,7 +12,7 @@ portenta_c33.build.fpu=-mfpu=fpv5-sp-d16 portenta_c33.build.float-abi=-mfloat-abi=hard portenta_c33.build.board=PORTENTA_C33 -portenta_c33.build.defines=-DF_CPU=200000000 +portenta_c33.build.defines=-DF_CPU=200000000 -DPROVIDE_FREERTOS_HOOK portenta_c33.vid.0=0x2341 portenta_c33.pid.0=0x0068 portenta_c33.vid.1=0x2341 diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp index 1d8c1386a..24dfa3ec8 100644 --- a/cores/arduino/main.cpp +++ b/cores/arduino/main.cpp @@ -113,7 +113,9 @@ void arduino_main(void) #endif startAgt(); setup(); +#ifdef PROVIDE_FREERTOS_HOOK start_freertos_on_header_inclusion(); +#endif while (1) { loop(); From b83fd201289ab7925d9062064f605dcee2372d20 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 12 Dec 2024 09:53:00 +0100 Subject: [PATCH 39/41] freertos: declare start_freertos_on_header_inclusion only if required --- libraries/Arduino_FreeRTOS/src/portable/FSP/port.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/Arduino_FreeRTOS/src/portable/FSP/port.c b/libraries/Arduino_FreeRTOS/src/portable/FSP/port.c index 598de672d..3fd8c53c9 100644 --- a/libraries/Arduino_FreeRTOS/src/portable/FSP/port.c +++ b/libraries/Arduino_FreeRTOS/src/portable/FSP/port.c @@ -225,6 +225,7 @@ static void prvTaskExitError(void); #endif +#ifdef PROVIDE_FREERTOS_HOOK void loop_thread_func(void* arg) { while (1) { @@ -245,6 +246,7 @@ void start_freertos_on_header_inclusion() { vTaskStartScheduler(); } +#endif /* Arduino specific overrides */ void delay(uint32_t ms) { From 3f6a552612f6f595db1c883647e2bfa834e980d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?BenjaminDanneg=C3=A5rd?= Date: Wed, 18 Dec 2024 16:15:57 +0100 Subject: [PATCH 40/41] RPC api docs added --- libraries/RTC/src/RTC.h | 624 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 593 insertions(+), 31 deletions(-) diff --git a/libraries/RTC/src/RTC.h b/libraries/RTC/src/RTC.h index c0b3f431d..6ef0d6af4 100644 --- a/libraries/RTC/src/RTC.h +++ b/libraries/RTC/src/RTC.h @@ -5,29 +5,97 @@ #include "r_rtc_api.h" #include -struct timeval { - time_t tv_sec; - useconds_t tv_usec; +struct timeval +{ + time_t tv_sec; + useconds_t tv_usec; }; #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -void set_time(time_t t); -void attach_rtc(time_t (*read_rtc)(void), void (*write_rtc)(time_t), void (*init_rtc)(void), int (*isenabled_rtc)(void)); -int gettimeofday(struct timeval *tv, void *tz); -int settimeofday(const struct timeval *tv, const struct timezone *tz); + /** + * @brief Sets the system time. + * + * This function sets the system time to the specified value. + * The time is provided as a `time_t` object, representing the + * number of seconds since the Unix epoch (January 1, 1970). + * + * @param `t` The time to set, expressed as a `time_t` object. + * This value represents the number of seconds since + * the Unix epoch. + */ + void set_time(time_t t); + + /** + * @brief Attaches RTC (Real-Time Clock) handling functions. + * + * This function attaches custom handlers for reading, writing, initializing, + * and checking the status of the RTC. These handlers allow integration with + * an external RTC module or custom RTC implementation. + * + * @param `read_rtc` A pointer to a function that reads the current RTC time + * and returns it as a `time_t` value. + * @param `write_rtc` A pointer to a function that sets the RTC time to the + * specified `time_t` value. + * @param `init_rtc` A pointer to a function that initializes the RTC hardware. + * @param `isenabled_rtc` A pointer to a function that checks whether the RTC + * is enabled, returning an integer (e.g., 1 for enabled, 0 for disabled). + */ + void attach_rtc(time_t (*read_rtc)(void), void (*write_rtc)(time_t), void (*init_rtc)(void), int (*isenabled_rtc)(void)); + + /** + * @brief Retrieves the current time of day. + * + * This function gets the current time, expressed as seconds and microseconds + * since the Unix epoch (00:00:00 UTC, January 1, 1970). The time is stored in + * a `timeval` structure. + * + * @param `tv` A pointer to a `timeval` structure where the current time will be stored. + * The structure contains two fields: + * - `tv_sec`: Seconds since the Unix epoch. + * - `tv_usec`: Microseconds since the last second. + * @param `tz` A pointer to a timezone structure (optional). It is usually set to `nullptr` + * as timezone information is not handled by this function on most systems. + * + * @return Returns `0` on success, or `-1` on failure (e.g., if `tv` is `nullptr`). + */ + int gettimeofday(struct timeval *tv, void *tz); + + /** + * @brief Sets the current time of day and timezone. + * + * This function sets the system's current time and optionally the timezone. + * The new time is specified in a `timeval` structure, which contains the + * number of seconds and microseconds since the Unix epoch (00:00:00 UTC, + * January 1, 1970). + * + * @param `tv` A pointer to a `timeval` structure specifying the new time. + * The structure contains two fields: + * - `tv_sec`: Seconds since the Unix epoch. + * - `tv_usec`: Microseconds since the last second. + * @param `tz` A pointer to a `timezone` structure specifying the timezone (optional). + * + * @return Returns `0` on success, or `-1` on failure (e.g., if `tv` is `nullptr` or the operation is not permitted). + */ + int settimeofday(const struct timeval *tv, const struct timezone *tz); #ifdef __cplusplus } #endif - using stime_t = struct tm; using rtc_cbk_t = void (*)(); -enum class Month : uint8_t { +/** + * @brief Enumeration representing the months of the year. + * + * This enumeration maps the months of the year to numeric values, starting from 0 for January and ending at 11 for December. + */ +enum class Month : uint8_t +{ JANUARY = 0, FEBRUARY, MARCH, @@ -42,10 +110,24 @@ enum class Month : uint8_t { DECEMBER }; +/** + * @brief Converts a `Month` enumeration value to its corresponding integer representation. + * + * This function takes a `Month` enumeration value and returns its integer equivalent. + * + * @param `m` The `Month` enumeration value to convert. + * + * @return The integer representation of the given month. + */ int Month2int(Month m); - -enum class DayOfWeek : uint8_t { +/** + * @brief Enumeration representing the days of the week. + * + * This enumeration maps the days of the week to numeric values. + */ +enum class DayOfWeek : uint8_t +{ MONDAY = 1, TUESDAY = 2, WEDNESDAY = 3, @@ -55,18 +137,50 @@ enum class DayOfWeek : uint8_t { SUNDAY = 0 }; +/** + * @brief Converts a `DayOfWeek` enumeration value to its corresponding integer representation. + * + * This function maps a `DayOfWeek` enumeration value to an integer representation based on + * whether Sunday or Monday is considered the first day of the week. + * + * @param `dow` The `DayOfWeek` enumeration value to convert. + * @param `sunday_first` A boolean flag that determines the starting day of the week: + * - `true`: Sunday is the first day of the week (Sunday = 0, Monday = 1, ...). + * - `false`: Monday is the first day of the week (Monday = 0, Tuesday = 1, ...). + * + * @return The integer representation of the given day of the week, adjusted based on + * the value of `sunday_first`. + */ int DayOfWeek2int(DayOfWeek dow, bool sunday_first); -enum class SaveLight : uint8_t { +enum class SaveLight : uint8_t +{ SAVING_TIME_INACTIVE = 0, SAVING_TIME_ACTIVE }; +/** + * @brief Converts a `SaveLight` enumeration value to its corresponding boolean representation. + * + * This function maps a `SaveLight` enumeration value to a boolean, used to indicate + * whether it is daylight savings time (`true`) or not (`false`). + * + * @param `sl` The `SaveLight` enumeration value to convert. + * + * @return `true` if it is daylight savings time, `false` otherwise. + */ bool SaveLigth2bool(SaveLight sl); -class RTCTime { - private: +/** + * @brief A class representing time in the context of an RTC (Real-Time Clock). + * + * The `RTCTime` class encapsulates time-related information and provides utility methods + * to interact with and manipulate RTC time. + */ +class RTCTime +{ +private: stime_t stime; int day; @@ -78,34 +192,200 @@ class RTCTime { DayOfWeek day_of_week; SaveLight save_light; - public: +public: + /** + * @brief Default constructor for the RTCTime class. + */ RTCTime(); + + /** + * @brief Constructor for the RTCTime class with a given time. + * + * Initializes the RTCTime object with the specified time. + * + * @param `t` A time_t value representing the time to initialize the RTCTime object with. + */ RTCTime(time_t t); + + /** + * @brief Constructor for the RTCTime class with a given `tm` structure. + * + * @param `t` A reference to a struct `tm` that contains the broken-down time to initialize the RTCTime object with. + */ RTCTime(struct tm &t); + + /** + * @brief Constructor for the RTCTime class with specific date and time parameters. + * + * Initializes the RTCTime object with the specified date, time, day of the week, and daylight saving time status. + * + * @param `_day` The day of the month. + * @param `_m` The month of the year (using the Month enum, e.g., JANUARY, FEBRUARY, etc.). + * @param `_year` The year (e.g., 2024). + * @param `_hours` The hour of the day (0-23). + * @param `_minutes` The minute of the hour (0-59). + * @param `_seconds` The second of the minute (0-59). + * @param `_dof` The day of the week (using the DayOfWeek enum, e.g., MONDAY, TUESDAY, etc.). + * @param `_sl` The daylight saving time status (using the SaveLight enum, e.g., DST_ON, DST_OFF). + */ RTCTime(int _day, Month _m, int _year, int _hours, int _minutes, int _seconds, DayOfWeek _dof, SaveLight _sl); + + /** + * @brief Destructor for the RTCTime class. + */ ~RTCTime(); /* setters */ - bool setDayOfMonth(int day); /* day from 1 to 31 */ - bool setMonthOfYear(Month m); /* month from 1 (January) to 12 (December) */ - bool setYear(int year); /* the year 1989 or 2022 */ - bool setHour(int hour); /* from 0 (midnight) to 23 */ - bool setMinute(int minute); /* from 0 to 59 */ - bool setSecond(int second); /* from 0 to 59 */ + /** + * @brief Sets the day of the month. + * + * @param `day` The day of the month. + * + * @return `true` if the day is set successfully, `false` if the day is out of range. + */ + bool setDayOfMonth(int day); + + /** + * @brief Sets the month of the year. + * + * @param `m` The month. + * + * @return `true` if the month is set successfully, `false` if the month is out of range. + */ + bool setMonthOfYear(Month m); + + /** + * @brief Sets the year. + * + * @param `year` The year (e.g., 1989 or 2022). + * + * @return `true` if the year is set successfully, `false` if the year is invalid. + */ + bool setYear(int year); + + /** + * @brief Sets the hour of the day. + * + * @param `hour` The hour. + * + * @return `true` if the hour is set successfully, `false` if the hour is out of range. + */ + bool setHour(int hour); + + /** + * @brief Sets the minute of the hour. + * + * @param `minute` The minute. + * + * @return `true` if the minute is set successfully, `false` if the minute is out of range. + */ + bool setMinute(int minute); + + /** + * @brief Sets the second of the minute. + * + * @param `second` The second. + * + * @return `true` if the second is set successfully, `false` if the second is out of range. + */ + bool setSecond(int second); + + /** + * @brief Sets the day of the week. + * + * @param `d` The day of the week (from the DayOfWeek enumeration). + * + * @return `true` if the day of the week is set successfully, `false` if the value is invalid. + */ bool setDayOfWeek(DayOfWeek d); + + /** + * @brief Sets whether daylight saving time is active. + * + * @param `sl` The SaveLight enumeration value. + * + * @return `true` if the daylight saving time setting is applied successfully, `false` otherwise. + */ bool setSaveLight(SaveLight sl); + + /** + * @brief Sets the time using a Unix timestamp. + * + * @param `time` The Unix timestamp (seconds since January 1, 1970). + * + * @return `true` if the Unix timestamp is set successfully, `false` otherwise. + */ bool setUnixTime(time_t time); + + /** + * @brief Sets the time from a struct tm. + * + * @param `t` A reference to a struct tm that contains the time values. + */ void setTM(struct tm &t); /* Getters */ + /** + * @brief Gets the day of the month. + * + * @return The day of the month. + */ int getDayOfMonth() const; + + /** + * @brief Gets the month of the year. + * + * @return The month. + */ Month getMonth() const; + + /** + * @brief Gets the year. + * + * @return The year. + */ int getYear() const; + + /** + * @brief Gets the hour of the day. + * + * @return The hour. + */ int getHour() const; + + /** + * @brief Gets the minutes of the hour. + * + * @return The minutes. + */ int getMinutes() const; + + /** + * @brief Gets the seconds of the minute. + * + * @return The seconds. + */ int getSeconds() const; + + /** + * @brief Gets the day of the week. + * + * @return The day of the week. + */ DayOfWeek getDayOfWeek() const; + + /** + * @brief Gets the Unix timestamp. + * + * @return The Unix timestamp. + */ time_t getUnixTime(); + + /** + * @brief Gets the time as a struct `tm`. + * + * @return A struct `tm` that contains the time values. + */ struct tm getTmTime(); /** @@ -123,7 +403,14 @@ class RTCTime { operator arduino::String() const; }; -enum class Period { +/** + * @brief Enum class representing different time periods for periodic events. + * + * This enum defines various periods, which represent how often an event occurs in a given second. + * Each value indicates a multiplier for how many times an event occurs in a second. + */ +enum class Period +{ ONCE_EVERY_2_SEC, ONCE_EVERY_1_SEC, N2_TIMES_EVERY_SEC, @@ -136,57 +423,332 @@ enum class Period { N256_TIMES_EVERY_SEC }; -class AlarmMatch { - private: +/** + * @brief Class representing the alarm match system. + * + * This class is used to define how an alarm matches a set of conditions or criteria + * to trigger an action, such as a timer or event. + */ +class AlarmMatch +{ +private: unsigned int match; - public: +public: + /** + * @brief Default constructor for the AlarmMatch class. + */ AlarmMatch(); + + /** + * @brief Destructor for the AlarmMatch class. + */ ~AlarmMatch(); + + /** + * @brief Increments the match time by one second. + * + * This function updates the internal match time by adding one second to the + * current value. + */ void addMatchSecond(); + + /** + * @brief Increments the match time by one minute. + * + * This function updates the internal match time by adding one minute to the + * current value. + */ void addMatchMinute(); + + /** + * @brief Increments the match time by one hour. + * + * This function updates the internal match time by adding one hour to the + * current value. + */ void addMatchHour(); + + /** + * @brief Increments the match time by one day. + * + * This function updates the internal match time by adding one day to the + * current value. + */ void addMatchDay(); + + /** + * @brief Increments the match time by one month. + * + * This function updates the internal match time by adding one month to the + * current value. + */ void addMatchMonth(); + + /** + * @brief Increments the match time by one year. + * + * This function updates the internal match time by adding one year to the + * current value. + */ void addMatchYear(); + + /** + * @brief Increments the match time by one day of the week. + * + * This function updates the internal match time by adding one day to the + * current day of the week. + */ void addMatchDayOfWeek(); + + /** + * @brief Decrements the match time by one second. + * + * This function updates the internal match time by subtracting one second + * from the current second. + */ void removeMatchSecond(); + + /** + * @brief Decrements the match time by one minute. + * + * This function updates the internal match time by subtracting one minute + * from the current minute. + */ void removeMatchMinute(); + + /** + * @brief Decrements the match time by one hour. + * + * This function updates the internal match time by subtracting one hour + * from the current hour. + */ void removeMatchHour(); + + /** + * @brief Decrements the match time by one day. + * + * This function updates the internal match time by subtracting one day + * from the current day. + */ void removeMatchDay(); + + /** + * @brief Decrements the match time by one month. + * + * This function updates the internal match time by subtracting one month + * from the current month. + */ void removeMatchMonth(); + + /** + * @brief Decrements the match time by one year. + * + * This function updates the internal match time by subtracting one year + * from the current year. + */ void removeMatchYear(); + + /** + * @brief Removes the match criteria for the day of the week. + * + * This function updates the internal match time by removing the day of the week + * from the matching criteria. + */ void removeMatchDayOfWeek(); + + /** + * @brief Checks if the current second matches the set criteria. + * + * This function compares the current second with the set match criteria (if any) + * and returns true if there is a match, false otherwise. + * + * @return `True` if the current second matches the criteria, `false` otherwise. + */ bool isMatchingSecond(); + + /** + * @brief Checks if the current minute matches the set criteria. + * + * This function compares the current minute with the set match criteria (if any) + * and returns `true` if there is a match, `false` otherwise. + * + * @return `True` if the current minute matches the criteria, `false` otherwise. + */ bool isMatchingMinute(); + + /** + * @brief Checks if the current hour matches the set criteria. + * + * This function compares the current hour with the set match criteria (if any) + * and returns `true` if there is a match, `false` otherwise. + * + * @return `True` if the current hour matches the criteria, `false` otherwise. + */ bool isMatchingHour(); + + /** + * @brief Checks if the current day matches the set criteria. + * + * This function compares the current day with the set match criteria (if any) + * and returns `true` if there is a match, `false` otherwise. + * + * @return `True` if the current day matches the criteria, `false` otherwise. + */ bool isMatchingDay(); + + /** + * @brief Checks if the current month matches the set criteria. + * + * This function compares the current month with the set match criteria (if any) + * and returns `true` if there is a match, `false` otherwise. + * + * @return `True` if the current month matches the criteria, `false` otherwise. + */ bool isMatchingMonth(); + + /** + * @brief Checks if the current year matches the set criteria. + * + * This function compares the current year with the set match criteria (if any) + * and returns `true` if there is a match, `false` otherwise. + * + * @return `True` if the current year matches the criteria, `false` otherwise. + */ bool isMatchingYear(); - bool isMatchingDayOfWeek(); + /** + * @brief Checks if the current day of the week matches the set criteria. + * + * This function compares the current day of the week with the set match criteria + * (if any) and returns `true` if there is a match, `false` otherwise. + * + * @return `True` if the current day of the week matches the criteria, `false` otherwise. + */ + bool isMatchingDayOfWeek(); }; -class RTClock { - private: +/** + * @brief Class for interfacing with a real-time clock (RTC). + * + * The RTClock class provides functionality to get and set the time, date, and other time-related + * operations, such as day of the week, alarm management, and more. + */ +class RTClock +{ +private: bool is_initialized; - public: +public: + /** + * @brief Constructor to initialize the real-time clock (RTC). + */ RTClock(); + + /** + * @brief Destructor for the real-time clock (RTC). + */ ~RTClock(); + /** + * @brief Initializes the real-time clock (RTC). + * + * @return `True` if the initialization was successful, `false` otherwise. + */ bool begin(); + /** + * @brief Retrieves the current time from the real-time clock (RTC). + * + * This function retrieves the current time from the RTC and stores it in the provided + * RTCTime object. The RTCTime object will be updated with the latest time and date + * information from the RTC module. + * + * @param `t` A reference to an RTCTime object where the current time will be stored. + * + * @return `True` if the time was successfully retrieved and stored in the RTCTime object, + * `false` if there was an error during the operation. + */ bool getTime(RTCTime &t); + /** + * @brief Sets a periodic callback function triggered by the real-time clock (RTC). + * + * This function configures a callback function to be executed at a specific periodic interval, + * as defined by the `Period` parameter. The callback function will be invoked automatically + * by the RTC at the specified rate. + * + * @param `fnc` The callback function to be executed periodically. The function must match + * the `rtc_cbk_t` type signature. + * @param `p` The period at which the callback function should be triggered. This is specified + * as a value from the `Period` enumeration. + * + * @return `True` if the callback was successfully set, `false` otherwise. + */ bool setPeriodicCallback(rtc_cbk_t fnc, Period p); + + /** + * @brief Sets an alarm callback function triggered when the specified conditions are met. + * + * This function configures a callback function to be executed when the real-time clock (RTC) + * matches the specified date and time conditions defined in the `RTCTime` and `AlarmMatch` parameters. + * + * @param `fnc` The callback function to be executed when the alarm triggers. The function must + * match the `rtc_cbk_t` type signature. + * @param `t` The target time for the alarm, specified as an RTCTime object. + * @param `m` The alarm match conditions, specified using the AlarmMatch object. This determines + * which components of the RTCTime must match (e.g., year, month, day). + * + * @return `True` if the alarm callback was successfully set, `false` otherwise. + */ bool setAlarmCallback(rtc_cbk_t fnc, RTCTime &t, AlarmMatch &m); + + /** + * @brief Configures an alarm based on the specified time and matching criteria. + * + * This function sets an alarm on the real-time clock (RTC). The alarm will be triggered + * when the RTC's current time matches the conditions specified by the `RTCTime` and + * `AlarmMatch` parameters. + * + * @param `t` The target time for the alarm, specified as an RTCTime object. + * @param `m` The alarm match conditions, specified using the AlarmMatch object. This determines + * which components of the RTCTime must match. + * + * @return `True` if the alarm was successfully set, `false` otherwise. + */ bool setAlarm(RTCTime &t, AlarmMatch &m); + /** + * @brief Checks if the RTC (Real-Time Clock) is currently running. + * + * This function verifies whether the RTC module is operational and maintaining time. + * + * @return `True` if the RTC is running, `false` otherwise. + */ bool isRunning(); + + /** + * @brief Sets the current time of the RTC (Real-Time Clock). + * + * This function updates the RTC with the provided time. + * + * @param `t` A reference to an RTCTime object containing the desired time to set. + * + * @return `True` if the time was successfully updated, `false` otherwise. + */ bool setTime(RTCTime &t); - bool setTimeIfNotRunning(RTCTime &t); + /** + * @brief Sets the RTC time only if the clock is not currently running. + * + * This function checks if the RTC is stopped and updates its time with the provided + * RTCTime object if the clock is not running. + * + * @param `t` A reference to an RTCTime object containing the desired time to set. + * + * @return `True` if the time was successfully updated, `false` otherwise. + */ + bool setTimeIfNotRunning(RTCTime &t); }; extern RTClock RTC; From 4ee9347e0621e57a5db0494cb35496dee6e50d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?BenjaminDanneg=C3=A5rd?= Date: Wed, 18 Dec 2024 16:21:09 +0100 Subject: [PATCH 41/41] Added api.md file for RTC --- libraries/RTC/docs/api.md | 915 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 915 insertions(+) create mode 100644 libraries/RTC/docs/api.md diff --git a/libraries/RTC/docs/api.md b/libraries/RTC/docs/api.md new file mode 100644 index 000000000..06da4907d --- /dev/null +++ b/libraries/RTC/docs/api.md @@ -0,0 +1,915 @@ +# Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +`class` [`AlarmMatch`](#class_alarm_match) | Class representing the alarm match system. +`class` [`RTClock`](#class_r_t_clock) | Class for interfacing with a real-time clock (RTC). +`class` [`RTCTime`](#class_r_t_c_time) | A class representing time in the context of an RTC (Real-Time Clock). +`struct` [`timeval`](#structtimeval) | + +# class `AlarmMatch` + +Class representing the alarm match system. + +This class is used to define how an alarm matches a set of conditions or criteria to trigger an action, such as a timer or event. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +| [`AlarmMatch`](#class_alarm_match_1a2d54ef9ddc542da32fe103b4e7ab28b3) | Default constructor for the [AlarmMatch](#class_alarm_match) class. | +| [`~AlarmMatch`](#class_alarm_match_1a5afd0d3d3f96c641ecbd3450ca775863) | Destructor for the [AlarmMatch](#class_alarm_match) class. | +| [`addMatchSecond`](#class_alarm_match_1aecccdfaf4a13b856ea39b3563c0047c9) | Increments the match time by one second. | +| [`addMatchMinute`](#class_alarm_match_1aa6c7ff0591e656dde418b47221b03f98) | Increments the match time by one minute. | +| [`addMatchHour`](#class_alarm_match_1aaaa7278c42a02c157f19d7adf630efeb) | Increments the match time by one hour. | +| [`addMatchDay`](#class_alarm_match_1a7750e8bd7fa3d9e8aba05d18549f9e4a) | Increments the match time by one day. | +| [`addMatchMonth`](#class_alarm_match_1a535672e2cf4435a2ef3c194359995813) | Increments the match time by one month. | +| [`addMatchYear`](#class_alarm_match_1a29be33fca9a0993be0e0c53b1f056a89) | Increments the match time by one year. | +| [`addMatchDayOfWeek`](#class_alarm_match_1a2c824482a6096fb8d7d156558dfa017b) | Increments the match time by one day of the week. | +| [`removeMatchSecond`](#class_alarm_match_1a2acb110c3cf78858addfd47b973d384b) | Decrements the match time by one second. | +| [`removeMatchMinute`](#class_alarm_match_1ad07250d87328a2fb737af1aae77cbf6b) | Decrements the match time by one minute. | +| [`removeMatchHour`](#class_alarm_match_1ad2d0f7580893e3fa816f557d48b14dde) | Decrements the match time by one hour. | +| [`removeMatchDay`](#class_alarm_match_1af5fd4dadc4adcae8ede004f66eaa12f6) | Decrements the match time by one day. | +| [`removeMatchMonth`](#class_alarm_match_1a37b940e78e62fc2d3e508b192be2eb68) | Decrements the match time by one month. | +| [`removeMatchYear`](#class_alarm_match_1ac90e5a925727f34b659a41f0c3a4d426) | Decrements the match time by one year. | +| [`removeMatchDayOfWeek`](#class_alarm_match_1ae681f0ee94875bc410a92327dd204b03) | Removes the match criteria for the day of the week. | +| [`isMatchingSecond`](#class_alarm_match_1a52de136a3d64383fb758eea86fcf3946) | Checks if the current second matches the set criteria. | +| [`isMatchingMinute`](#class_alarm_match_1ad4d0dfe998cd89c9a9682737a7aee338) | Checks if the current minute matches the set criteria. | +| [`isMatchingHour`](#class_alarm_match_1a73eab2cb02cd8bb12479022cc52ce54f) | Checks if the current hour matches the set criteria. | +| [`isMatchingDay`](#class_alarm_match_1a9f26a4bdc6febad854218bf9c142651e) | Checks if the current day matches the set criteria. | +| [`isMatchingMonth`](#class_alarm_match_1a536093cce64b2e1c4a351815e1313193) | Checks if the current month matches the set criteria. | +| [`isMatchingYear`](#class_alarm_match_1a0b8748eecf57c8c7f2dffcfba944407e) | Checks if the current year matches the set criteria. | +| [`isMatchingDayOfWeek`](#class_alarm_match_1ac8c8ab1655f28c78c5ec648beeb52ba0) | Checks if the current day of the week matches the set criteria. | + +## Members + +### `AlarmMatch` + +```cpp +AlarmMatch() +``` + +Default constructor for the [AlarmMatch](#class_alarm_match) class. + +
+ +### `~AlarmMatch` + +```cpp +~AlarmMatch() +``` + +Destructor for the [AlarmMatch](#class_alarm_match) class. + +
+ +### `addMatchSecond` + +```cpp +void addMatchSecond() +``` + +Increments the match time by one second. + +This function updates the internal match time by adding one second to the current value. +
+ +### `addMatchMinute` + +```cpp +void addMatchMinute() +``` + +Increments the match time by one minute. + +This function updates the internal match time by adding one minute to the current value. +
+ +### `addMatchHour` + +```cpp +void addMatchHour() +``` + +Increments the match time by one hour. + +This function updates the internal match time by adding one hour to the current value. +
+ +### `addMatchDay` + +```cpp +void addMatchDay() +``` + +Increments the match time by one day. + +This function updates the internal match time by adding one day to the current value. +
+ +### `addMatchMonth` + +```cpp +void addMatchMonth() +``` + +Increments the match time by one month. + +This function updates the internal match time by adding one month to the current value. +
+ +### `addMatchYear` + +```cpp +void addMatchYear() +``` + +Increments the match time by one year. + +This function updates the internal match time by adding one year to the current value. +
+ +### `addMatchDayOfWeek` + +```cpp +void addMatchDayOfWeek() +``` + +Increments the match time by one day of the week. + +This function updates the internal match time by adding one day to the current day of the week. +
+ +### `removeMatchSecond` + +```cpp +void removeMatchSecond() +``` + +Decrements the match time by one second. + +This function updates the internal match time by subtracting one second from the current second. +
+ +### `removeMatchMinute` + +```cpp +void removeMatchMinute() +``` + +Decrements the match time by one minute. + +This function updates the internal match time by subtracting one minute from the current minute. +
+ +### `removeMatchHour` + +```cpp +void removeMatchHour() +``` + +Decrements the match time by one hour. + +This function updates the internal match time by subtracting one hour from the current hour. +
+ +### `removeMatchDay` + +```cpp +void removeMatchDay() +``` + +Decrements the match time by one day. + +This function updates the internal match time by subtracting one day from the current day. +
+ +### `removeMatchMonth` + +```cpp +void removeMatchMonth() +``` + +Decrements the match time by one month. + +This function updates the internal match time by subtracting one month from the current month. +
+ +### `removeMatchYear` + +```cpp +void removeMatchYear() +``` + +Decrements the match time by one year. + +This function updates the internal match time by subtracting one year from the current year. +
+ +### `removeMatchDayOfWeek` + +```cpp +void removeMatchDayOfWeek() +``` + +Removes the match criteria for the day of the week. + +This function updates the internal match time by removing the day of the week from the matching criteria. +
+ +### `isMatchingSecond` + +```cpp +bool isMatchingSecond() +``` + +Checks if the current second matches the set criteria. + +This function compares the current second with the set match criteria (if any) and returns true if there is a match, false otherwise. + +#### Returns +`True` if the current second matches the criteria, `false` otherwise. +
+ +### `isMatchingMinute` + +```cpp +bool isMatchingMinute() +``` + +Checks if the current minute matches the set criteria. + +This function compares the current minute with the set match criteria (if any) and returns `true` if there is a match, `false` otherwise. + +#### Returns +`True` if the current minute matches the criteria, `false` otherwise. +
+ +### `isMatchingHour` + +```cpp +bool isMatchingHour() +``` + +Checks if the current hour matches the set criteria. + +This function compares the current hour with the set match criteria (if any) and returns `true` if there is a match, `false` otherwise. + +#### Returns +`True` if the current hour matches the criteria, `false` otherwise. +
+ +### `isMatchingDay` + +```cpp +bool isMatchingDay() +``` + +Checks if the current day matches the set criteria. + +This function compares the current day with the set match criteria (if any) and returns `true` if there is a match, `false` otherwise. + +#### Returns +`True` if the current day matches the criteria, `false` otherwise. +
+ +### `isMatchingMonth` + +```cpp +bool isMatchingMonth() +``` + +Checks if the current month matches the set criteria. + +This function compares the current month with the set match criteria (if any) and returns `true` if there is a match, `false` otherwise. + +#### Returns +`True` if the current month matches the criteria, `false` otherwise. +
+ +### `isMatchingYear` + +```cpp +bool isMatchingYear() +``` + +Checks if the current year matches the set criteria. + +This function compares the current year with the set match criteria (if any) and returns `true` if there is a match, `false` otherwise. + +#### Returns +`True` if the current year matches the criteria, `false` otherwise. +
+ +### `isMatchingDayOfWeek` + +```cpp +bool isMatchingDayOfWeek() +``` + +Checks if the current day of the week matches the set criteria. + +This function compares the current day of the week with the set match criteria (if any) and returns `true` if there is a match, `false` otherwise. + +#### Returns +`True` if the current day of the week matches the criteria, `false` otherwise. +
+ +# class `RTClock` + +Class for interfacing with a real-time clock (RTC). + +The [RTClock](#class_r_t_clock) class provides functionality to get and set the time, date, and other time-related operations, such as day of the week, alarm management, and more. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +| [`RTClock`](#class_r_t_clock_1a1fefceddd93d040e3f4296c573e0fe34) | Constructor to initialize the real-time clock (RTC). | +| [`~RTClock`](#class_r_t_clock_1a8e569b9095a0a7545278ebf132564492) | Destructor for the real-time clock (RTC). | +| [`begin`](#class_r_t_clock_1ad753f953539b7ec0e56a9f15c358c2c5) | Initializes the real-time clock (RTC). | +| [`getTime`](#class_r_t_clock_1a4c335640f3f62f42dd5ed3fad314e3e7) | Retrieves the current time from the real-time clock (RTC). | +| [`setPeriodicCallback`](#class_r_t_clock_1a47258e8554ded2f597fdb4f6e6c77548) | Sets a periodic callback function triggered by the real-time clock (RTC). | +| [`setAlarmCallback`](#class_r_t_clock_1a7e24b8f5727297ab4974a40fb506d961) | Sets an alarm callback function triggered when the specified conditions are met. | +| [`setAlarm`](#class_r_t_clock_1a04ef8ba0c3ce454ea3b7868f582fae48) | Configures an alarm based on the specified time and matching criteria. | +| [`isRunning`](#class_r_t_clock_1a09d0a22117e98e449dee1d5a74649eb5) | Checks if the RTC (Real-Time Clock) is currently running. | +| [`setTime`](#class_r_t_clock_1a64b98ad69891a6e9b1b85b27f4df7ca3) | Sets the current time of the RTC (Real-Time Clock). | +| [`setTimeIfNotRunning`](#class_r_t_clock_1a4168c5950e860aa7ff1af7b24fed2a94) | Sets the RTC time only if the clock is not currently running. | + +## Members + +### `RTClock` + +```cpp +RTClock() +``` + +Constructor to initialize the real-time clock (RTC). + +
+ +### `~RTClock` + +```cpp +~RTClock() +``` + +Destructor for the real-time clock (RTC). + +
+ +### `begin` + +```cpp +bool begin() +``` + +Initializes the real-time clock (RTC). + +#### Returns +`True` if the initialization was successful, `false` otherwise. +
+ +### `getTime` + +```cpp +bool getTime( RTCTime & t) +``` + +Retrieves the current time from the real-time clock (RTC). + +This function retrieves the current time from the RTC and stores it in the provided [RTCTime](#class_r_t_c_time) object. The [RTCTime](#class_r_t_c_time) object will be updated with the latest time and date information from the RTC module. + +#### Parameters +* `t` A reference to an [RTCTime](#class_r_t_c_time) object where the current time will be stored. + +#### Returns +`True` if the time was successfully retrieved and stored in the [RTCTime](#class_r_t_c_time) object, `false` if there was an error during the operation. +
+ +### `setPeriodicCallback` + +```cpp +bool setPeriodicCallback(rtc_cbk_t fnc, Period p) +``` + +Sets a periodic callback function triggered by the real-time clock (RTC). + +This function configures a callback function to be executed at a specific periodic interval, as defined by the `Period` parameter. The callback function will be invoked automatically by the RTC at the specified rate. + +#### Parameters +* `fnc` The callback function to be executed periodically. The function must match the `rtc_cbk_t` type signature. + +* `p` The period at which the callback function should be triggered. This is specified as a value from the `Period` enumeration. + +#### Returns +`True` if the callback was successfully set, `false` otherwise. +
+ +### `setAlarmCallback` + +```cpp +bool setAlarmCallback(rtc_cbk_t fnc, RTCTime & t, AlarmMatch & m) +``` + +Sets an alarm callback function triggered when the specified conditions are met. + +This function configures a callback function to be executed when the real-time clock (RTC) matches the specified date and time conditions defined in the [RTCTime](#class_r_t_c_time) and [AlarmMatch](#class_alarm_match) parameters. + +#### Parameters +* `fnc` The callback function to be executed when the alarm triggers. The function must match the `rtc_cbk_t` type signature. + +* `t` The target time for the alarm, specified as an [RTCTime](#class_r_t_c_time) object. + +* `m` The alarm match conditions, specified using the [AlarmMatch](#class_alarm_match) object. This determines which components of the [RTCTime](#class_r_t_c_time) must match (e.g., year, month, day). + +#### Returns +`True` if the alarm callback was successfully set, `false` otherwise. +
+ +### `setAlarm` + +```cpp +bool setAlarm( RTCTime & t, AlarmMatch & m) +``` + +Configures an alarm based on the specified time and matching criteria. + +This function sets an alarm on the real-time clock (RTC). The alarm will be triggered when the RTC's current time matches the conditions specified by the [RTCTime](#class_r_t_c_time) and [AlarmMatch](#class_alarm_match) parameters. + +#### Parameters +* `t` The target time for the alarm, specified as an [RTCTime](#class_r_t_c_time) object. + +* `m` The alarm match conditions, specified using the [AlarmMatch](#class_alarm_match) object. This determines which components of the [RTCTime](#class_r_t_c_time) must match. + +#### Returns +`True` if the alarm was successfully set, `false` otherwise. +
+ +### `isRunning` + +```cpp +bool isRunning() +``` + +Checks if the RTC (Real-Time Clock) is currently running. + +This function verifies whether the RTC module is operational and maintaining time. + +#### Returns +`True` if the RTC is running, `false` otherwise. +
+ +### `setTime` + +```cpp +bool setTime( RTCTime & t) +``` + +Sets the current time of the RTC (Real-Time Clock). + +This function updates the RTC with the provided time. + +#### Parameters +* `t` A reference to an [RTCTime](#class_r_t_c_time) object containing the desired time to set. + +#### Returns +`True` if the time was successfully updated, `false` otherwise. +
+ +### `setTimeIfNotRunning` + +```cpp +bool setTimeIfNotRunning( RTCTime & t) +``` + +Sets the RTC time only if the clock is not currently running. + +This function checks if the RTC is stopped and updates its time with the provided [RTCTime](#class_r_t_c_time) object if the clock is not running. + +#### Parameters +* `t` A reference to an [RTCTime](#class_r_t_c_time) object containing the desired time to set. + +#### Returns +`True` if the time was successfully updated, `false` otherwise. +
+ +# class `RTCTime` + +A class representing time in the context of an RTC (Real-Time Clock). + +The [RTCTime](#class_r_t_c_time) class encapsulates time-related information and provides utility methods to interact with and manipulate RTC time. + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +| [`RTCTime`](#class_r_t_c_time_1a924ea08fcfda4cd7bba69d27e6044d8c) | Default constructor for the [RTCTime](#class_r_t_c_time) class. | +| [`RTCTime`](#class_r_t_c_time_1a1845bc8c5cc390e771a8569961821681) | Constructor for the [RTCTime](#class_r_t_c_time) class with a given time. | +| [`RTCTime`](#class_r_t_c_time_1adce8b95b38afbd4c83c95a55ef3199c9) | Constructor for the [RTCTime](#class_r_t_c_time) class with a given `tm` structure. | +| [`RTCTime`](#class_r_t_c_time_1af650d794e8dc4b68e2f7edf8904290c8) | Constructor for the [RTCTime](#class_r_t_c_time) class with specific date and time parameters. | +| [`~RTCTime`](#class_r_t_c_time_1ab8bee04da843e1f4d573b8dc8456045c) | Destructor for the [RTCTime](#class_r_t_c_time) class. | +| [`setDayOfMonth`](#class_r_t_c_time_1af9abac029cfc446635d0418cb026cb05) | Sets the day of the month. | +| [`setMonthOfYear`](#class_r_t_c_time_1ae9b91fdd5ac696f476bca77ab00d3924) | Sets the month of the year. | +| [`setYear`](#class_r_t_c_time_1a03f3a280099446d866dd410c6c0e37ea) | Sets the year. | +| [`setHour`](#class_r_t_c_time_1a314592b177aa3647f52b151b397c615c) | Sets the hour of the day. | +| [`setMinute`](#class_r_t_c_time_1afaa2c25a40be5ad217147fac3b59156a) | Sets the minute of the hour. | +| [`setSecond`](#class_r_t_c_time_1a00b5a03046370aa1d1895863a9a17464) | Sets the second of the minute. | +| [`setDayOfWeek`](#class_r_t_c_time_1aea6e5bd41959cb1eaf4cf3ba81f4f27f) | Sets the day of the week. | +| [`setSaveLight`](#class_r_t_c_time_1a46667e749264e0487193495e9f84b740) | Sets whether daylight saving time is active. | +| [`setUnixTime`](#class_r_t_c_time_1a8d50fa1ee9a132a037500f39845bdabb) | Sets the time using a Unix timestamp. | +| [`setTM`](#class_r_t_c_time_1a8a63142d7699025c78cbbf252b9dbe62) | Sets the time from a struct tm. | +| [`getDayOfMonth`](#class_r_t_c_time_1a42bfdfc2ae6d2cf81ddc0a6f5814f65a) | Gets the day of the month. | +| [`getMonth`](#class_r_t_c_time_1a43aed822be5e9e26efce91050de7aca8) | Gets the month of the year. | +| [`getYear`](#class_r_t_c_time_1ab7ad8a017d1972c4a80f3c63e6140f80) | Gets the year. | +| [`getHour`](#class_r_t_c_time_1a226aec3347c7d2406162af6ddf35ebf6) | Gets the hour of the day. | +| [`getMinutes`](#class_r_t_c_time_1a4569498a7960c995e266b7d23eac98ba) | Gets the minutes of the hour. | +| [`getSeconds`](#class_r_t_c_time_1a86e8e5984d1c0d954836f25d010c9f46) | Gets the seconds of the minute. | +| [`getDayOfWeek`](#class_r_t_c_time_1a72f06ebb1c1368134f6616bc905ca526) | Gets the day of the week. | +| [`getUnixTime`](#class_r_t_c_time_1a7215c300c30e6423c62cac39443871bd) | Gets the Unix timestamp. | +| [`getTmTime`](#class_r_t_c_time_1a7830e079cff08391ef28899e910e79bd) | Gets the time as a struct `tm`. | +| [`toString`](#class_r_t_c_time_1afc343321d5caee657655f7c7d998f4c0) | Returns the ISO 8601 string representation of the date and time. | +| [`operator arduino::String`](#class_r_t_c_time_1a03bf4e2ba6aaab9e829be5b17be55f36) | Returns the ISO 8601 string representation of the date and time by calling the [toString()](#class_r_t_c_time_1afc343321d5caee657655f7c7d998f4c0) method. | + +## Members + +### `RTCTime` + +```cpp +RTCTime() +``` + +Default constructor for the [RTCTime](#class_r_t_c_time) class. + +
+ +### `RTCTime` + +```cpp +RTCTime(time_t t) +``` + +Constructor for the [RTCTime](#class_r_t_c_time) class with a given time. + +Initializes the [RTCTime](#class_r_t_c_time) object with the specified time. + +#### Parameters +* `t` A time_t value representing the time to initialize the [RTCTime](#class_r_t_c_time) object with. +
+ +### `RTCTime` + +```cpp +RTCTime(struct tm & t) +``` + +Constructor for the [RTCTime](#class_r_t_c_time) class with a given `tm` structure. + +#### Parameters +* `t` A reference to a struct `tm` that contains the broken-down time to initialize the [RTCTime](#class_r_t_c_time) object with. +
+ +### `RTCTime` + +```cpp +RTCTime(int _day, Month _m, int _year, int _hours, int _minutes, int _seconds, DayOfWeek _dof, SaveLight _sl) +``` + +Constructor for the [RTCTime](#class_r_t_c_time) class with specific date and time parameters. + +Initializes the [RTCTime](#class_r_t_c_time) object with the specified date, time, day of the week, and daylight saving time status. + +#### Parameters +* `_day` The day of the month. + +* `_m` The month of the year (using the Month enum, e.g., JANUARY, FEBRUARY, etc.). + +* `_year` The year (e.g., 2024). + +* `_hours` The hour of the day (0-23). + +* `_minutes` The minute of the hour (0-59). + +* `_seconds` The second of the minute (0-59). + +* `_dof` The day of the week (using the DayOfWeek enum, e.g., MONDAY, TUESDAY, etc.). + +* `_sl` The daylight saving time status (using the SaveLight enum, e.g., DST_ON, DST_OFF). +
+ +### `~RTCTime` + +```cpp +~RTCTime() +``` + +Destructor for the [RTCTime](#class_r_t_c_time) class. + +
+ +### `setDayOfMonth` + +```cpp +bool setDayOfMonth(int day) +``` + +Sets the day of the month. + +#### Parameters +* `day` The day of the month. + +#### Returns +`true` if the day is set successfully, `false` if the day is out of range. +
+ +### `setMonthOfYear` + +```cpp +bool setMonthOfYear(Month m) +``` + +Sets the month of the year. + +#### Parameters +* `m` The month. + +#### Returns +`true` if the month is set successfully, `false` if the month is out of range. +
+ +### `setYear` + +```cpp +bool setYear(int year) +``` + +Sets the year. + +#### Parameters +* `year` The year (e.g., 1989 or 2022). + +#### Returns +`true` if the year is set successfully, `false` if the year is invalid. +
+ +### `setHour` + +```cpp +bool setHour(int hour) +``` + +Sets the hour of the day. + +#### Parameters +* `hour` The hour. + +#### Returns +`true` if the hour is set successfully, `false` if the hour is out of range. +
+ +### `setMinute` + +```cpp +bool setMinute(int minute) +``` + +Sets the minute of the hour. + +#### Parameters +* `minute` The minute. + +#### Returns +`true` if the minute is set successfully, `false` if the minute is out of range. +
+ +### `setSecond` + +```cpp +bool setSecond(int second) +``` + +Sets the second of the minute. + +#### Parameters +* `second` The second. + +#### Returns +`true` if the second is set successfully, `false` if the second is out of range. +
+ +### `setDayOfWeek` + +```cpp +bool setDayOfWeek(DayOfWeek d) +``` + +Sets the day of the week. + +#### Parameters +* `d` The day of the week (from the DayOfWeek enumeration). + +#### Returns +`true` if the day of the week is set successfully, `false` if the value is invalid. +
+ +### `setSaveLight` + +```cpp +bool setSaveLight(SaveLight sl) +``` + +Sets whether daylight saving time is active. + +#### Parameters +* `sl` The SaveLight enumeration value. + +#### Returns +`true` if the daylight saving time setting is applied successfully, `false` otherwise. +
+ +### `setUnixTime` + +```cpp +bool setUnixTime(time_t time) +``` + +Sets the time using a Unix timestamp. + +#### Parameters +* `time` The Unix timestamp (seconds since January 1, 1970). + +#### Returns +`true` if the Unix timestamp is set successfully, `false` otherwise. +
+ +### `setTM` + +```cpp +void setTM(struct tm & t) +``` + +Sets the time from a struct tm. + +#### Parameters +* `t` A reference to a struct tm that contains the time values. +
+ +### `getDayOfMonth` + +```cpp +int getDayOfMonth() const +``` + +Gets the day of the month. + +#### Returns +The day of the month. +
+ +### `getMonth` + +```cpp +Month getMonth() const +``` + +Gets the month of the year. + +#### Returns +The month. +
+ +### `getYear` + +```cpp +int getYear() const +``` + +Gets the year. + +#### Returns +The year. +
+ +### `getHour` + +```cpp +int getHour() const +``` + +Gets the hour of the day. + +#### Returns +The hour. +
+ +### `getMinutes` + +```cpp +int getMinutes() const +``` + +Gets the minutes of the hour. + +#### Returns +The minutes. +
+ +### `getSeconds` + +```cpp +int getSeconds() const +``` + +Gets the seconds of the minute. + +#### Returns +The seconds. +
+ +### `getDayOfWeek` + +```cpp +DayOfWeek getDayOfWeek() const +``` + +Gets the day of the week. + +#### Returns +The day of the week. +
+ +### `getUnixTime` + +```cpp +time_t getUnixTime() +``` + +Gets the Unix timestamp. + +#### Returns +The Unix timestamp. +
+ +### `getTmTime` + +```cpp +struct tm getTmTime() +``` + +Gets the time as a struct `tm`. + +#### Returns +A struct `tm` that contains the time values. +
+ +### `toString` + +```cpp +arduino::String toString() const +``` + +Returns the ISO 8601 string representation of the date and time. + +#### Returns +String The date and time in the format YYYY-MM-DDTHH:MM:SS. +
+ +### `operator arduino::String` + +```cpp +operator arduino::String() const +``` + +Returns the ISO 8601 string representation of the date and time by calling the [toString()](#class_r_t_c_time_1afc343321d5caee657655f7c7d998f4c0) method. + +#### Returns +String The date and time in the format YYYY-MM-DDTHH:MM:SS. +
+ +# struct `timeval` + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +| [`tv_sec`](#structtimeval_1aef6ddab1064c430758f9f913b7e4a21e) | | +| [`tv_usec`](#structtimeval_1a60486501e203aa76351aae5afee09b98) | | + +## Members + +### `tv_sec` + +```cpp +time_t tv_sec +``` + +
+ +### `tv_usec` + +```cpp +useconds_t tv_usec +``` + +
+