From c228c8b413e607210c8295380e6b258eea36912e Mon Sep 17 00:00:00 2001 From: "Zachary J. Fields" Date: Wed, 7 Aug 2024 18:44:16 -0500 Subject: [PATCH] feat: Notecard example --- .../ArduinoIoTCloud-Advanced.ino | 4 +- .../ArduinoIoTCloud-Basic.ino | 4 +- .../ArduinoIoTCloud-Callbacks.ino | 4 +- .../ArduinoIoTCloud-DeferredOTA.ino | 4 +- .../ArduinoIoTCloud-Notecard.ino | 68 +++++++++++++++++++ .../arduino_secrets.h | 7 ++ .../thingProperties.h | 35 ++++++++++ .../ArduinoIoTCloud-Schedule.ino | 4 +- src/ArduinoIoTCloudNotecard.cpp | 10 +-- src/ArduinoIoTCloudNotecard.h | 19 +++--- 10 files changed, 141 insertions(+), 18 deletions(-) create mode 100644 examples/ArduinoIoTCloud-Notecard/ArduinoIoTCloud-Notecard.ino create mode 100644 examples/ArduinoIoTCloud-Notecard/arduino_secrets.h create mode 100644 examples/ArduinoIoTCloud-Notecard/thingProperties.h diff --git a/examples/ArduinoIoTCloud-Advanced/ArduinoIoTCloud-Advanced.ino b/examples/ArduinoIoTCloud-Advanced/ArduinoIoTCloud-Advanced.ino index 127c67fa..4419ef14 100644 --- a/examples/ArduinoIoTCloud-Advanced/ArduinoIoTCloud-Advanced.ino +++ b/examples/ArduinoIoTCloud-Advanced/ArduinoIoTCloud-Advanced.ino @@ -17,13 +17,15 @@ void setup() { Serial.begin(9600); for(unsigned long const serialBeginTime = millis(); !Serial && (millis() - serialBeginTime <= 5000); ) { } + /* Specify the level of detail for debug messages */ + setDebugMessageLevel(DBG_INFO); + /* This function takes care of connecting your sketch variables to the ArduinoIoTCloud object */ initProperties(); /* Initialize Arduino IoT Cloud library */ ArduinoCloud.begin(ArduinoIoTPreferredConnection); - setDebugMessageLevel(DBG_INFO); ArduinoCloud.printDebugInfo(); } diff --git a/examples/ArduinoIoTCloud-Basic/ArduinoIoTCloud-Basic.ino b/examples/ArduinoIoTCloud-Basic/ArduinoIoTCloud-Basic.ino index 5dfbf02b..4b98be49 100644 --- a/examples/ArduinoIoTCloud-Basic/ArduinoIoTCloud-Basic.ino +++ b/examples/ArduinoIoTCloud-Basic/ArduinoIoTCloud-Basic.ino @@ -25,6 +25,9 @@ void setup() { Serial.begin(9600); for(unsigned long const serialBeginTime = millis(); !Serial && (millis() - serialBeginTime <= 5000); ) { } + /* Specify the level of detail for debug messages */ + setDebugMessageLevel(DBG_INFO); + /* Configure LED pin as an output */ pinMode(LED_BUILTIN, OUTPUT); @@ -34,7 +37,6 @@ void setup() { /* Initialize Arduino IoT Cloud library */ ArduinoCloud.begin(ArduinoIoTPreferredConnection); - setDebugMessageLevel(DBG_INFO); ArduinoCloud.printDebugInfo(); } diff --git a/examples/ArduinoIoTCloud-Callbacks/ArduinoIoTCloud-Callbacks.ino b/examples/ArduinoIoTCloud-Callbacks/ArduinoIoTCloud-Callbacks.ino index 6ce12070..10c609ab 100644 --- a/examples/ArduinoIoTCloud-Callbacks/ArduinoIoTCloud-Callbacks.ino +++ b/examples/ArduinoIoTCloud-Callbacks/ArduinoIoTCloud-Callbacks.ino @@ -33,6 +33,9 @@ void setup() { Serial.begin(9600); for(unsigned long const serialBeginTime = millis(); !Serial && (millis() - serialBeginTime <= 5000); ) { } + /* Specify the level of detail for debug messages */ + setDebugMessageLevel(DBG_INFO); + /* This function takes care of connecting your sketch variables to the ArduinoIoTCloud object */ initProperties(); @@ -51,7 +54,6 @@ void setup() { ArduinoCloud.addCallback(ArduinoIoTCloudEvent::SYNC, doThisOnSync); ArduinoCloud.addCallback(ArduinoIoTCloudEvent::DISCONNECT, doThisOnDisconnect); - setDebugMessageLevel(DBG_INFO); ArduinoCloud.printDebugInfo(); } diff --git a/examples/ArduinoIoTCloud-DeferredOTA/ArduinoIoTCloud-DeferredOTA.ino b/examples/ArduinoIoTCloud-DeferredOTA/ArduinoIoTCloud-DeferredOTA.ino index 52fc8731..5cd27ba5 100644 --- a/examples/ArduinoIoTCloud-DeferredOTA/ArduinoIoTCloud-DeferredOTA.ino +++ b/examples/ArduinoIoTCloud-DeferredOTA/ArduinoIoTCloud-DeferredOTA.ino @@ -58,6 +58,9 @@ void setup() { Serial.begin(9600); for(unsigned long const serialBeginTime = millis(); !Serial && (millis() - serialBeginTime <= 5000); ) { } + /* Specify the level of detail for debug messages */ + setDebugMessageLevel(DBG_INFO); + /* Configure LED pin as an output */ pinMode(LED_BUILTIN, OUTPUT); @@ -70,7 +73,6 @@ void setup() { /* Setup OTA callback */ ArduinoCloud.onOTARequestCb(onOTARequestCallback); - setDebugMessageLevel(DBG_INFO); ArduinoCloud.printDebugInfo(); } diff --git a/examples/ArduinoIoTCloud-Notecard/ArduinoIoTCloud-Notecard.ino b/examples/ArduinoIoTCloud-Notecard/ArduinoIoTCloud-Notecard.ino new file mode 100644 index 00000000..c63adad8 --- /dev/null +++ b/examples/ArduinoIoTCloud-Notecard/ArduinoIoTCloud-Notecard.ino @@ -0,0 +1,68 @@ +/* + This sketch demonstrates how to exchange data between your board and the Arduino IoT Cloud. + + * 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 Notecard, 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 +#include "thingProperties.h" + +#if !defined(LED_BUILTIN) && !defined(ARDUINO_NANO_ESP32) +static int const LED_BUILTIN = 2; +#endif + +/* + * Choose an interrupt capable pin to reduce polling and improve + * the overall responsiveness of the ArduinoIoTCloud library + */ +// #define ATTN_PIN 9 + +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); ) { } + + /* Specify the level of detail for debug messages */ + setDebugMessageLevel(DBG_INFO); + + /* 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 */ +#ifndef ATTN_PIN + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + ArduinoCloud.setNotecardPollInterval(3000); // default: 1000ms, min: 250ms +#else + ArduinoCloud.begin(ArduinoIoTPreferredConnection, ATTN_PIN); +#endif + + ArduinoCloud.printDebugInfo(); +} + +void loop() { + ArduinoCloud.update(); + potentiometer = analogRead(A0); + seconds = millis() / 1000; +} + +/* + * '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-Notecard/arduino_secrets.h b/examples/ArduinoIoTCloud-Notecard/arduino_secrets.h new file mode 100644 index 00000000..d9883ae8 --- /dev/null +++ b/examples/ArduinoIoTCloud-Notecard/arduino_secrets.h @@ -0,0 +1,7 @@ +#include + +/* A complete list of supported boards with WiFi is available here: + * https://github.com/arduino-libraries/ArduinoIoTCloud/#what + */ +#define SECRET_WIFI_SSID "YOUR_WIFI_NETWORK_NAME" +#define SECRET_WIFI_PASS "YOUR_WIFI_PASSWORD" diff --git a/examples/ArduinoIoTCloud-Notecard/thingProperties.h b/examples/ArduinoIoTCloud-Notecard/thingProperties.h new file mode 100644 index 00000000..24dd168e --- /dev/null +++ b/examples/ArduinoIoTCloud-Notecard/thingProperties.h @@ -0,0 +1,35 @@ +#include +#include +#include "arduino_secrets.h" + +/* The Notecard can provide connectivity to almost any board via ESLOV (I2C) + * or UART. An empty string (or the default value provided below) will not + * override the Notecard's existing configuration. + * Learn more at: https://dev.blues.io */ +#define NOTECARD_PRODUCT_UID "com.domain.you:product" + +/* Uncomment the following line to use the Notecard over UART */ +// #define UART_INTERFACE Serial1 + +void onLedChange(); + +bool led; +int potentiometer; +int seconds; + +void initProperties() { + 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); + + if (strncmp(SECRET_WIFI_SSID, "YOUR_WIFI_NETWORK_NAME", sizeof(SECRET_WIFI_SSID))) { + ArduinoIoTPreferredConnection.setWiFiCredentials(SECRET_WIFI_SSID, SECRET_WIFI_PASS); + } +} + +#ifndef UART_INTERFACE +NotecardConnectionHandler ArduinoIoTPreferredConnection(NOTECARD_PRODUCT_UID); +#else +NotecardConnectionHandler ArduinoIoTPreferredConnection(NOTECARD_PRODUCT_UID, UART_INTERFACE); +#endif + diff --git a/examples/ArduinoIoTCloud-Schedule/ArduinoIoTCloud-Schedule.ino b/examples/ArduinoIoTCloud-Schedule/ArduinoIoTCloud-Schedule.ino index c1c1b38f..babf03dd 100644 --- a/examples/ArduinoIoTCloud-Schedule/ArduinoIoTCloud-Schedule.ino +++ b/examples/ArduinoIoTCloud-Schedule/ArduinoIoTCloud-Schedule.ino @@ -17,6 +17,9 @@ void setup() { Serial.begin(9600); for(unsigned long const serialBeginTime = millis(); !Serial && (millis() - serialBeginTime <= 5000); ) { } + /* Specify the level of detail for debug messages */ + setDebugMessageLevel(DBG_INFO); + /* Configure LED pin as an output */ pinMode(LED_BUILTIN, OUTPUT); @@ -26,7 +29,6 @@ void setup() { /* Initialize Arduino IoT Cloud library */ ArduinoCloud.begin(ArduinoIoTPreferredConnection); - setDebugMessageLevel(DBG_INFO); ArduinoCloud.printDebugInfo(); /* Setup one shot schedule example */ diff --git a/src/ArduinoIoTCloudNotecard.cpp b/src/ArduinoIoTCloudNotecard.cpp index 72cc3ce8..ef662c58 100644 --- a/src/ArduinoIoTCloudNotecard.cpp +++ b/src/ArduinoIoTCloudNotecard.cpp @@ -72,8 +72,8 @@ ArduinoIoTCloudNotecard::ArduinoIoTCloudNotecard() ,_message_stream(std::bind(&ArduinoIoTCloudNotecard::sendMessage, this, std::placeholders::_1)) ,_thing(&_message_stream) ,_device(&_message_stream) - ,_notecard_last_read_ms{static_cast(-DEFAULT_READ_INTERVAL_MS)} - ,_notecard_read_interval_ms{DEFAULT_READ_INTERVAL_MS} + ,_notecard_last_poll_ms{static_cast(-DEFAULT_READ_INTERVAL_MS)} + ,_notecard_poll_interval_ms{DEFAULT_READ_INTERVAL_MS} ,_interrupt_pin{-1} ,_data_available{false} #if OTA_ENABLED @@ -278,15 +278,15 @@ bool ArduinoIoTCloudNotecard::available(void) const bool interrupts_enabled = (_interrupt_pin >= 0); const uint32_t now_ms = ::millis(); - bool check_data = ((now_ms - _notecard_last_read_ms) > _notecard_read_interval_ms); + bool check_data = ((now_ms - _notecard_last_poll_ms) > _notecard_poll_interval_ms); if (interrupts_enabled) { - check_data = (_data_available || ((now_ms - _notecard_last_read_ms) > FAILSAFE_READ_INTERVAL_MS)); + check_data = (_data_available || ((now_ms - _notecard_last_poll_ms) > FAILSAFE_READ_INTERVAL_MS)); } if (check_data) { result = _connection->available(); _data_available = ::digitalRead(_interrupt_pin); - _notecard_last_read_ms = now_ms; + _notecard_last_poll_ms = now_ms; } else { result = false; } diff --git a/src/ArduinoIoTCloudNotecard.h b/src/ArduinoIoTCloudNotecard.h index 96b1c85a..10ccf134 100644 --- a/src/ArduinoIoTCloudNotecard.h +++ b/src/ArduinoIoTCloudNotecard.h @@ -71,24 +71,27 @@ class ArduinoIoTCloudNotecard : public ArduinoIoTCloudClass * @param interrupt_pin The interrupt pin to use for the Notecard. * * @note The interrupt pin is optional and only required if you want to - * eliminate the need to poll the Notecard for new data. + * eliminate the need to poll the Notecard for new data. The pin only needs + * to be specified, and will otherwise be configured by the library. * * @return 1 on success, 0 on failure. */ int begin(ConnectionHandler &connection, int interrupt_pin = -1); /** - * @brief Set the Notecard read interval. + * @brief Set the Notecard polling interval. * - * The interval at which the Notecard is polled for new data. The default - * interval is 1000ms, and the minimum interval is 250ms. + * The interval at which the Notecard is polled for new data. * * @param interval_ms The interval in milliseconds. + * @par + * - Minimum: 250ms + * - Default: 1000ms * - * @note The Notecard read interval is ignored if an interrupt pin is + * @note The Notecard poll interval is ignored if an interrupt pin is * provided to the `begin()` function. */ - inline void setNotecardReadInterval(uint32_t interval_ms) { _notecard_read_interval_ms = ((interval_ms < 250) ? 250 : interval_ms); } + inline void setNotecardPollInterval(uint32_t interval_ms) { _notecard_poll_interval_ms = ((interval_ms < 250) ? 250 : interval_ms); } private: @@ -107,8 +110,8 @@ class ArduinoIoTCloudNotecard : public ArduinoIoTCloudClass ArduinoCloudDevice _device; // Notecard member variables - uint32_t _notecard_last_read_ms; - uint32_t _notecard_read_interval_ms; + uint32_t _notecard_last_poll_ms; + uint32_t _notecard_poll_interval_ms; int _interrupt_pin; volatile bool _data_available;