From cc13683fc704cb531762a92c2da0c5027647f340 Mon Sep 17 00:00:00 2001 From: Giampaolo Mancini Date: Wed, 25 Sep 2024 12:32:48 +0200 Subject: [PATCH] Add "Block for OTA" example --- .../ArduinoIoTCloud-BlockForOTA.ino | 97 +++++++++++++++++++ .../arduino_secrets.h | 38 ++++++++ .../thingProperties.h | 58 +++++++++++ 3 files changed, 193 insertions(+) create mode 100644 examples/ArduinoIoTCloud-BlockForOTA/ArduinoIoTCloud-BlockForOTA.ino create mode 100644 examples/ArduinoIoTCloud-BlockForOTA/arduino_secrets.h create mode 100644 examples/ArduinoIoTCloud-BlockForOTA/thingProperties.h diff --git a/examples/ArduinoIoTCloud-BlockForOTA/ArduinoIoTCloud-BlockForOTA.ino b/examples/ArduinoIoTCloud-BlockForOTA/ArduinoIoTCloud-BlockForOTA.ino new file mode 100644 index 00000000..d682ff2b --- /dev/null +++ b/examples/ArduinoIoTCloud-BlockForOTA/ArduinoIoTCloud-BlockForOTA.ino @@ -0,0 +1,97 @@ +/* + This sketch demonstrates how to optimize OTA in case of complex loop(). + + * Connect a potentiometer (or other analog sensor) to A0. + * When the potentiometer (or sensor) value changes the data is sent to the Cloud. + * When you flip the switch in the Cloud dashboard the onboard LED lights gets turned ON or OFF. + + IMPORTANT: + This sketch works with WiFi, GSM, NB, Ethernet and Lora enabled boards supported by Arduino IoT Cloud. + On a LoRa board, if it is configured as a class A device (default and preferred option), + values from Cloud dashboard are received only after a value is sent to Cloud. + + The full list of compatible boards can be found here: + - https://github.com/arduino-libraries/ArduinoIoTCloud#what +*/ + +#include "thingProperties.h" + +#if !defined(LED_BUILTIN) && !defined(ARDUINO_NANO_ESP32) +static int const LED_BUILTIN = 2; +#endif + +bool block_for_ota { false }; +bool ota_started { false }; + +bool onOTARequestCallback() { + block_for_ota = true; + ota_started = true; + return true; +} + +constexpr unsigned long printInterval { 1000 }; +unsigned long printNow { printInterval }; + +void setup() { + /* Initialize serial and wait up to 5 seconds for port to open */ + Serial.begin(9600); + for(unsigned long const serialBeginTime = millis(); !Serial && (millis() - serialBeginTime <= 5000); ) { } + + /* Set the debug message level: + * - DBG_ERROR: Only show error messages + * - DBG_WARNING: Show warning and error messages + * - DBG_INFO: Show info, warning, and error messages + * - DBG_DEBUG: Show debug, info, warning, and error messages + * - DBG_VERBOSE: Show all messages + */ + setDebugMessageLevel(DBG_VERBOSE); + + /* Configure LED pin as an output */ + pinMode(LED_BUILTIN, OUTPUT); + + /* This function takes care of connecting your sketch variables to the ArduinoIoTCloud object */ + initProperties(); + + /* Initialize Arduino IoT Cloud library */ + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + + /* Setup OTA callback */ + ArduinoCloud.onOTARequestCb(onOTARequestCallback); + + ArduinoCloud.printDebugInfo(); +} + +void loop() { + // When OTA is available, stay there until it completes. + // The rest of the loop() does not run and the sketch + // restarts automatically at the end of the OTA process. + while (block_for_ota) { + ArduinoCloud.update(); + if (ota_started) { + Serial.print("Waiting for OTA to finish..."); + ota_started = false; + } + if (millis() > printNow) { + Serial.print("."); + printNow = millis() + printInterval; + } + } + + ArduinoCloud.update(); + potentiometer = analogRead(A0); + seconds = millis() / 1000; + + if (millis() > printNow) { + Serial.println(millis()); + printNow = millis() + printInterval; + } +} + +/* + * 'onLedChange' is called when the "led" property of your Thing changes + */ +void onLedChange() { + Serial.print("LED set to "); + Serial.println(led); + digitalWrite(LED_BUILTIN, led); +} diff --git a/examples/ArduinoIoTCloud-BlockForOTA/arduino_secrets.h b/examples/ArduinoIoTCloud-BlockForOTA/arduino_secrets.h new file mode 100644 index 00000000..0be56888 --- /dev/null +++ b/examples/ArduinoIoTCloud-BlockForOTA/arduino_secrets.h @@ -0,0 +1,38 @@ +#include + +/* A complete list of supported boards with WiFi is available here: + * https://github.com/arduino-libraries/ArduinoIoTCloud/#what + */ +#if defined(BOARD_HAS_WIFI) + #define SECRET_WIFI_SSID "YOUR_WIFI_NETWORK_NAME" + #define SECRET_WIFI_PASS "YOUR_WIFI_PASSWORD" +#endif + +/* ESP8266 ESP32 */ +#if defined(BOARD_HAS_SECRET_KEY) + #define SECRET_DEVICE_KEY "my-device-password" +#endif + +/* MKR GSM 1400 */ /* MKR NB 1500 */ /* Portenta CAT.M1/NB IoT GNSS Shield */ +/* Portenta H7 and C33 + Portenta Mid Carrier + 4G Module */ +#if defined(BOARD_HAS_GSM) || defined(BOARD_HAS_NB) || \ + defined(BOARD_HAS_CATM1_NBIOT) || defined(BOARD_HAS_CELLULAR) + #define SECRET_PIN "" + #define SECRET_APN "" + #define SECRET_LOGIN "" + #define SECRET_PASS "" +#endif + +/* MKR WAN 1300/1310 */ +#if defined(BOARD_HAS_LORA) + #define SECRET_APP_EUI "" + #define SECRET_APP_KEY "" +#endif + +/* Portenta H7 + Ethernet shield */ +#if defined(BOARD_HAS_ETHERNET) + #define SECRET_OPTIONAL_IP "" + #define SECRET_OPTIONAL_DNS "" + #define SECRET_OPTIONAL_GATEWAY "" + #define SECRET_OPTIONAL_NETMASK "" +#endif diff --git a/examples/ArduinoIoTCloud-BlockForOTA/thingProperties.h b/examples/ArduinoIoTCloud-BlockForOTA/thingProperties.h new file mode 100644 index 00000000..a354b38f --- /dev/null +++ b/examples/ArduinoIoTCloud-BlockForOTA/thingProperties.h @@ -0,0 +1,58 @@ +#include +#include +#include "arduino_secrets.h" + +#if !(defined(HAS_TCP) || defined(HAS_LORA)) + #error "Please check Arduino IoT Cloud supported boards list: https://github.com/arduino-libraries/ArduinoIoTCloud/#what" +#endif + +#if defined(BOARD_HAS_SECRET_KEY) + #define BOARD_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" +#endif + +#if defined(HAS_LORA) + #define THING_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" +#endif + +void onLedChange(); + +bool led; +int potentiometer; +int seconds; + +void initProperties() { +#if defined(BOARD_HAS_SECRET_KEY) + ArduinoCloud.setBoardId(BOARD_ID); + ArduinoCloud.setSecretDeviceKey(SECRET_DEVICE_KEY); +#endif +#if defined(HAS_TCP) + ArduinoCloud.addProperty(led, Permission::Write).onUpdate(onLedChange); + ArduinoCloud.addProperty(potentiometer, Permission::Read).publishOnChange(10); + ArduinoCloud.addProperty(seconds, Permission::Read).publishOnChange(1); +#elif defined(HAS_LORA) + ArduinoCloud.addProperty(led, 1, Permission::ReadWrite).onUpdate(onLedChange); + ArduinoCloud.addProperty(potentiometer, 2, Permission::Read).publishOnChange(10); + ArduinoCloud.addProperty(seconds, 3, Permission::Read).publishEvery(5 * MINUTES); + + ArduinoCloud.setThingId(THING_ID); +#endif +} + +#if defined(BOARD_HAS_ETHERNET) + /* DHCP mode */ + //EthernetConnectionHandler ArduinoIoTPreferredConnection; + /* Manual mode. It will fallback in DHCP mode if SECRET_OPTIONAL_IP is invalid or equal to "0.0.0.0" */ + EthernetConnectionHandler ArduinoIoTPreferredConnection(SECRET_OPTIONAL_IP, SECRET_OPTIONAL_DNS, SECRET_OPTIONAL_GATEWAY, SECRET_OPTIONAL_NETMASK); +#elif defined(BOARD_HAS_WIFI) + WiFiConnectionHandler ArduinoIoTPreferredConnection(SECRET_WIFI_SSID, SECRET_WIFI_PASS); +#elif defined(BOARD_HAS_GSM) + GSMConnectionHandler ArduinoIoTPreferredConnection(SECRET_PIN, SECRET_APN, SECRET_LOGIN, SECRET_PASS); +#elif defined(BOARD_HAS_LORA) + LoRaConnectionHandler ArduinoIoTPreferredConnection(SECRET_APP_EUI, SECRET_APP_KEY, _lora_band::EU868, NULL, _lora_class::CLASS_A); +#elif defined(BOARD_HAS_NB) + NBConnectionHandler ArduinoIoTPreferredConnection(SECRET_PIN, SECRET_APN, SECRET_LOGIN, SECRET_PASS); +#elif defined(BOARD_HAS_CATM1_NBIOT) + CatM1ConnectionHandler ArduinoIoTPreferredConnection(SECRET_PIN, SECRET_APN, SECRET_LOGIN, SECRET_PASS); +#elif defined(BOARD_HAS_CELLULAR) + CellularConnectionHandler ArduinoIoTPreferredConnection(SECRET_PIN, SECRET_APN, SECRET_LOGIN, SECRET_PASS); +#endif