Skip to content

Commit

Permalink
feat: ArduinoIoTCloudNotecard
Browse files Browse the repository at this point in the history
  • Loading branch information
zfields committed Sep 9, 2024
1 parent 28f567c commit 58a886b
Show file tree
Hide file tree
Showing 18 changed files with 930 additions and 50 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/compile-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ jobs:
- name: Arduino_DebugUtils
- name: ArduinoMqttClient
- name: Arduino_SecureElement
- name: Blues Wireless Notecard
# sketch paths to compile (recursive) for all boards
UNIVERSAL_SKETCH_PATHS: |
- examples/ArduinoIoTCloud-Advanced
- examples/ArduinoIoTCloud-Basic
- examples/ArduinoIoTCloud-Callbacks
- examples/ArduinoIoTCloud-Notecard
- examples/ArduinoIoTCloud-Schedule
- examples/utility/ArduinoIoTCloud_Travis_CI
SKETCHES_REPORTS_PATH: sketches-reports
Expand Down
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@
[![codecov](https://codecov.io/gh/arduino-libraries/ArduinoIoTCloud/branch/master/graph/badge.svg)](https://codecov.io/gh/arduino-libraries/ArduinoIoTCloud)

### What?

The `ArduinoIoTCloud` library is the central element of the firmware enabling certain Arduino boards to connect to the [Arduino IoT Cloud](https://www.arduino.cc/en/IoT/HomePage). The following boards are supported:

* **WiFi**: [`MKR 1000`](https://store.arduino.cc/arduino-mkr1000-wifi), [`MKR WiFi 1010`](https://store.arduino.cc/arduino-mkr-wifi-1010), [`Nano 33 IoT`](https://store.arduino.cc/arduino-nano-33-iot), [`Portenta H7`](https://store.arduino.cc/portenta-h7), [`Nano RP2040 Connect`](https://store.arduino.cc/products/arduino-nano-rp2040-connect), [`Nicla Vision`](https://store.arduino.cc/products/nicla-vision), [`OPTA WiFi`](https://store.arduino.cc/products/opta-wifi), [`GIGA R1 WiFi`](https://store.arduino.cc/products/giga-r1-wifi), [`Portenta C33`](https://store.arduino.cc/products/portenta-c33), [`UNO R4 WiFi`](https://store.arduino.cc/products/uno-r4-wifi), [`Nano ESP32`](https://store.arduino.cc/products/nano-esp32), [`ESP8266`](https://github.com/esp8266/Arduino/releases/tag/2.5.0), [`ESP32`](https://github.com/espressif/arduino-esp32/releases/tag/2.0.5)
* **GSM**: [`MKR GSM 1400`](https://store.arduino.cc/arduino-mkr-gsm-1400-1415)
* **5G**: [`MKR NB 1500`](https://store.arduino.cc/arduino-mkr-nb-1500-1413)
* **LoRa**: [`MKR WAN 1300/1310`](https://store.arduino.cc/mkr-wan-1310)
* **Ethernet**: [`Portenta H7`](https://store.arduino.cc/products/portenta-h7) + [`Vision Shield Ethernet`](https://store.arduino.cc/products/arduino-portenta-vision-shield-ethernet), [`Max Carrier`](https://store.arduino.cc/products/portenta-max-carrier), [`Breakout`](https://store.arduino.cc/products/arduino-portenta-breakout), [`Portenta Machine Control`](https://store.arduino.cc/products/arduino-portenta-machine-control), [`OPTA WiFi`](https://store.arduino.cc/products/opta-wifi), [`OPTA RS485`](https://store.arduino.cc/products/opta-rs485), [`OPTA Lite`](https://store.arduino.cc/products/opta-lite), [`Portenta C33`](https://store.arduino.cc/products/portenta-c33) + [`Vision Shield Ethernet`](https://store.arduino.cc/products/arduino-portenta-vision-shield-ethernet)
* **Notecard**: [Provides Cellular/LoRa/Satellite/Wi-Fi to any modern board/architecture](examples/ArduinoIoTCloud-Notecard/README.md)

### How?

1) Register your Arduino IoT Cloud capable board via [Arduino IoT Cloud](https://create.arduino.cc/iot) (Devices Section).
2) Create a new logical representation known as a [Thing](https://create.arduino.cc/iot/things).

Expand All @@ -29,7 +32,9 @@ The `ArduinoIoTCloud` library is the central element of the firmware enabling ce
- **Properties**: Qualities defining the characteristics of a system. A _Property_ can be defined as *read-only* (`READ`) to indicate that Arduino IoT Cloud can read the data, but cannot change the value of such _Property_. On the other end, it may be designated to be **read-and-write** (`READWRITE`), allowing Arduino IoT Cloud to remotely change the property’s value and trigger an event notification on the device. It is also possible to mark properties as *write-only* (`WRITE`) which means the cloud can write to this property but not read its value (this limits data transmission for properties which are used to trigger events only).

### How-to-use

* `thingProperties.h`

```C++
void onLedChange();
/* ... */
Expand All @@ -46,6 +51,7 @@ WiFiConnectionHandler ArduinoIoTPreferredConnection("SECRET_SSID", "SECRET_PASS"
```
* `MyCloudApplication.ino`
```C++
#include "thingProperties.h"
Expand All @@ -69,31 +75,36 @@ void onLedChange() {
```

### FAQ

#### Watchdog
The [1.0.0](https://github.com/arduino-libraries/ArduinoIoTCloud/releases/tag/1.0.0) release of this library adds watchdog functionality to all ATSAMD21G18 based cloud connected boards. A watchdog is simply an electronic timer counting down from a preset start value which, upon reaching zero, triggers a reset of the microcontroller. It can be used to automatically recover from temporary hardware faults or unrecoverable software errors. In order to avoid the watchdog from reaching zero the countdown timer needs to be regularly re-set to its start value. This is happening within `ArduinoCloud.update()` which is periodically called at the start of the `loop()` function. Although the watchdog is automatically enabled it can be disabled by setting the second parameter of `ArduinoCloud.begin(...)` to `false`:

The [1.0.0](https://github.com/arduino-libraries/ArduinoIoTCloud/releases/tag/1.0.0) release of this library adds watchdog functionality to all ATSAMD21G18 based cloud connected boards. A watchdog is simply an electronic timer counting down from a preset start value which, upon reaching zero, triggers a reset of the microcontroller. It can be used to automatically recover from temporary hardware faults or unrecoverable software errors. In order to avoid the watchdog from reaching zero the countdown timer needs to be regularly re-set to its start value. This is happening within `ArduinoCloud.update()` which is periodically called at the start of the `loop()` function. Although the watchdog is automatically enabled it can be disabled by setting the second parameter of `ArduinoCloud.begin(...)` to `false`:

```C++
ArduinoCloud.begin(ArduinoIoTPreferredConnection, false).
```

Whatchdog is enabled by default using the following boards: [`MKR 1000`](https://store.arduino.cc/arduino-mkr1000-wifi), [`MKR WiFi 1010`](https://store.arduino.cc/arduino-mkr-wifi-1010), [`MKR GSM 1400`](https://store.arduino.cc/arduino-mkr-gsm-1400-1415), [`MKR NB 1500`](https://store.arduino.cc/arduino-mkr-nb-1500-1413), [`MKR WAN 1300/1310`](https://store.arduino.cc/mkr-wan-1310), [`Nano 33 IoT`](https://store.arduino.cc/arduino-nano-33-iot), [`Portenta H7`](https://store.arduino.cc/portenta-h7), [`Nano RP2040 Connect`](https://store.arduino.cc/products/arduino-nano-rp2040-connect), [`Nicla Vision`](https://store.arduino.cc/products/nicla-vision), [`OPTA WiFi`](https://store.arduino.cc/products/opta-wifi), [`OPTA RS485`](https://store.arduino.cc/products/opta-rs485), [`OPTA Lite`](https://store.arduino.cc/products/opta-lite), [`GIGA R1 WiFi`](https://store.arduino.cc/products/giga-r1-wifi)

#### Device can not subscribe to `THING_ID`

```
ArduinoIoTCloudTCP::handle_SubscribeMqttTopics could not subscribe to /a/t/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/e/i
```

In this case either the device has not been associated with the thing within the Arduino IoT Cloud GUI configuration or there's a typo in the thing ID.

#### OTA

OTA is supported by the following boards:
[`MKR WiFi 1010`](https://store.arduino.cc/arduino-mkr-wifi-1010), [`Nano 33 IoT`](https://store.arduino.cc/arduino-nano-33-iot), [`Portenta H7`](https://store.arduino.cc/portenta-h7), [`Nano RP2040 Connect`](https://store.arduino.cc/products/arduino-nano-rp2040-connect), [`Nicla Vision`](https://store.arduino.cc/products/nicla-vision), [`OPTA WiFi`](https://store.arduino.cc/products/opta-wifi), [`OPTA RS485`](https://store.arduino.cc/products/opta-rs485), [`OPTA Lite`](https://store.arduino.cc/products/opta-lite), [`GIGA R1 WiFi`](https://store.arduino.cc/products/giga-r1-wifi), [`Nano ESP32`](https://store.arduino.cc/products/nano-esp32), [`ESP32`](https://github.com/espressif/arduino-esp32/releases/tag/2.0.5)

#### Authentication

Boards can authenticate to the ArduinoIoTCloud servers using 3 methods:

* `DEVICE_LOGIN_NAME` and `DEVICE_KEY`. This values are defined in the `thingProperties.h` file and included in the Sketch. Boards that are using this method are: [`UNO R4 WiFi`](https://store.arduino.cc/products/uno-r4-wifi), [`Nano ESP32`](https://store.arduino.cc/products/nano-esp32), [`ESP8266`](https://github.com/esp8266/Arduino/releases/tag/2.5.0), [`ESP32`](https://github.com/espressif/arduino-esp32/releases/tag/2.0.5)

* `DEVICE_CERTIFICATE` and `PRIVATE_KEY`. This values are stored inside the board secure element during the device provisioning phase. Boards that are using this method are: [`MKR 1000`](https://store.arduino.cc/arduino-mkr1000-wifi), [`MKR WiFi 1010`](https://store.arduino.cc/arduino-mkr-wifi-1010), [`MKR GSM 1400`](https://store.arduino.cc/arduino-mkr-gsm-1400-1415), [`MKR NB 1500`](https://store.arduino.cc/arduino-mkr-nb-1500-1413), [`Nano 33 IoT`](https://store.arduino.cc/arduino-nano-33-iot), [`Portenta H7`](https://store.arduino.cc/portenta-h7), [`Nano RP2040 Connect`](https://store.arduino.cc/products/arduino-nano-rp2040-connect), [`Nicla Vision`](https://store.arduino.cc/products/nicla-vision), [`OPTA WiFi`](https://store.arduino.cc/products/opta-wifi), [`OPTA RS485`](https://store.arduino.cc/products/opta-rs485), [`OPTA Lite`](https://store.arduino.cc/products/opta-lite), [`GIGA R1 WiFi`](https://store.arduino.cc/products/giga-r1-wifi), [`Portenta C33`](https://store.arduino.cc/products/portenta-c33)

* `APP_EUI` and `APP_KEY`. This values are defined in the `thingProperties.h` file and included in the Sketch. Boards that are using this method are: [`MKR WAN 1300/1310`](https://store.arduino.cc/mkr-wan-1310)


73 changes: 73 additions & 0 deletions examples/ArduinoIoTCloud-Notecard/ArduinoIoTCloud-Notecard.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
This sketch demonstrates how to exchange data between your board and the
Arduino IoT Cloud, while using the Notecard for wireless communication.
* 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 any Wi-Fi, Cellular, LoRa or Satellite enabled Notecard.
The full list of compatible boards can be found here:
- https://github.com/arduino-libraries/ArduinoIoTCloud#what
*/

#include <Notecard.h>
#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); ) { }

/* 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_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.setNotecardPollingInterval(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);
}
78 changes: 78 additions & 0 deletions examples/ArduinoIoTCloud-Notecard/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
Notecard Connectivity
=====================

The Notecard is a wireless, secure abstraction for device connectivity, that can
be used to enable _ANY*_ device with I2C, or UART, to connect to the Arduino IoT
Cloud via cellular, LoRa, satellite or Wi-Fi!

As a result, your existing device architecture can now have first class support
in the Arduino IoT Cloud, by using a Notecard as a secure communication channel.

> \*_While any device with I2C/UART may use the Notecard, the Arduino IoT Cloud
> library is not supported by the AVR toolchain. Therefore, devices based on the
> AVR architecture cannot access the Arduino IoT Cloud via the Notecard._
>
> _However, any device (including AVR), may use the Notecard library to send data
> to Notehub, then that data may be routed to any endpoint of your choosing. See the
> [Notecard Routing Guide](https://dev.blues.io/guides-and-tutorials/routing-data-to-cloud)
> for more information..._
Wireless Connectivity Options
-----------------------------

- [Cellular](https://shop.blues.com/collections/notecard/products/notecard-cellular)
- [Cellular + Wi-Fi](https://shop.blues.com/collections/notecard/products/notecard-cell-wifi)
- [Wi-Fi](https://shop.blues.com/collections/notecard/products/wifi-notecard)
- [LoRa](https://shop.blues.com/collections/notecard/products/notecard-lora)
- [Satellite](https://shop.blues.com/products/starnote)

How it Works
------------

**Architecture Diagram:**

```
-------- ------------ ----------- -----------
| | | | | | | |
| Host | | | Secure | | | Arduino |
| MCU |---<I2C/UART>---| Notecard | ( ( Wireless ) ) | Notehub |---<TLS>---| IoT |
| | | | Protocol | | | Cloud |
|______| |__________| |_________| |_________|
```

Getting Started
---------------

### Setup a Notehub Account

Using the Notecard only requires a couple of easy steps:

1. [Purchase a Notecard](https://shop.blues.com/collections/notecard) (and
[Notecarrier](https://shop.blues.com/collections/notecarrier)) that fits the
needs of your device.
> _**NOTE:** We recommend starting with our [Dev Kit](https://shop.blues.com/products/blues-global-starter-kit)
> if you are unsure._
1. [Setup a Notehub account](https://dev.blues.io/quickstart/notecard-quickstart/notecard-and-notecarrier-f/#set-up-notehub).
> _**NOTE:** Notehub accounts are free (no credit card required)._
1. [Create a project on your Notehub account](https://dev.blues.io/quickstart/notecard-quickstart/notecard-and-notecarrier-f/#create-a-notehub-project).
1. In `thingProperties.h`, replace "com.domain.you:product" (from
`NOTECARD_PRODUCT_UID`) with the ProductUID of your new Notehub project.

### Power-up the Device

1. [Connect the Notecard to your Host MCU](https://dev.blues.io/quickstart/notecard-quickstart/notecard-and-notecarrier-f/#connect-your-notecard-and-notecarrier)
1. Flash the `ArduinoIoTCloud-Notecard` example sketch to your device. You
should see the device reporting itself as online in your [Notehub Project](https://notehub.io).

### Associate Notecard to Arduino IoT Cloud

1. Create a "MANUAL Device" in the Arduino IoT Cloud, then [add environment
variables for the "Device ID" and "Secret Key" to your Notecard in Notehub](https://dev.blues.io/guides-and-tutorials/notecard-guides/understanding-environment-variables/#setting-a-notehub-device-variable).
- `_sn`: \<Device ID\>
- `_secret_key`: \<Secret Key\>

### More Information

For more information about the Notecard and Notehub in general, please see our
[Quickstart Guide](https://dev.blues.io/quickstart/) for a general overview of
how the Notecard and Notehub are designed to work.
7 changes: 7 additions & 0 deletions examples/ArduinoIoTCloud-Notecard/arduino_secrets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <Arduino_ConnectionHandler.h>

/* If provided, the Wi-Fi Credentials will be passed along to the Notecard. If
* the Notecard supports Wi-Fi, it will attempt to connect to the network using
* these credentials, if not, the Notecard will safely ignore these values. */
#define SECRET_WIFI_SSID "YOUR_WIFI_NETWORK_NAME"
#define SECRET_WIFI_PASS "YOUR_WIFI_PASSWORD"
36 changes: 36 additions & 0 deletions examples/ArduinoIoTCloud-Notecard/thingProperties.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include <string.h>

#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>
#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;

#ifndef UART_INTERFACE
NotecardConnectionHandler ArduinoIoTPreferredConnection(NOTECARD_PRODUCT_UID);
#else
NotecardConnectionHandler ArduinoIoTPreferredConnection(NOTECARD_PRODUCT_UID, UART_INTERFACE);
#endif

void initProperties() {
ArduinoCloud.addProperty(led, Permission::ReadWrite).onUpdate(onLedChange);
ArduinoCloud.addProperty(potentiometer, Permission::Read).publishOnChange(10);
ArduinoCloud.addProperty(seconds, 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);
}
}
10 changes: 10 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ getThingId KEYWORD2
setDeviceId KEYWORD2
getDeviceId KEYWORD2
getConnection KEYWORD2
getInternalTime KEYWORD2
getLocalTime KEYWORD2
addCallback KEYWORD2
addProperty KEYWORD2

Expand All @@ -46,6 +48,14 @@ getBrokerPort KEYWORD2
setOTAStorage KEYWORD2
reconnect KEYWORD2

# ArduinoIoTCloudNotecard.h
begin KEYWORD2
setNotecardPollingInterval KEYWORD2

# OTA
onOTARequestCallbackFunc KEYWORD2
onOTARequestCb KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ sentence=This library allows connecting to the Arduino IoT Cloud service.
paragraph=It provides a ConnectionManager to handle connection/disconnection, property-change updates and events callbacks. The supported boards are MKR GSM, MKR1000 and WiFi101.
category=Communication
url=https://github.com/arduino-libraries/ArduinoIoTCloud
architectures=mbed,samd,esp8266,mbed_nano,mbed_portenta,mbed_nicla,esp32,mbed_opta,mbed_giga,renesas_portenta,renesas_uno,mbed_edge
architectures=mbed,samd,esp8266,mbed_nano,mbed_portenta,mbed_nicla,esp32,mbed_opta,mbed_giga,renesas_portenta,renesas_uno,mbed_edge,stm32
includes=ArduinoIoTCloud.h
depends=Arduino_ConnectionHandler,Arduino_DebugUtils,Arduino_SecureElement,ArduinoMqttClient,ArduinoECCX08,RTCZero,Adafruit SleepyDog Library,ArduinoHttpClient
Loading

0 comments on commit 58a886b

Please sign in to comment.