Skip to content

Commit fa4e042

Browse files
committed
feat: ArduinoIoTCloudNotecard
1 parent 28f567c commit fa4e042

18 files changed

+918
-50
lines changed

Diff for: .github/workflows/compile-examples.yml

+2
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@ jobs:
2626
- name: Arduino_DebugUtils
2727
- name: ArduinoMqttClient
2828
- name: Arduino_SecureElement
29+
- name: Blues Wireless Notecard
2930
# sketch paths to compile (recursive) for all boards
3031
UNIVERSAL_SKETCH_PATHS: |
3132
- examples/ArduinoIoTCloud-Advanced
3233
- examples/ArduinoIoTCloud-Basic
3334
- examples/ArduinoIoTCloud-Callbacks
35+
- examples/ArduinoIoTCloud-Notecard
3436
- examples/ArduinoIoTCloud-Schedule
3537
- examples/utility/ArduinoIoTCloud_Travis_CI
3638
SKETCHES_REPORTS_PATH: sketches-reports

Diff for: README.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ The `ArduinoIoTCloud` library is the central element of the firmware enabling ce
1515
* **5G**: [`MKR NB 1500`](https://store.arduino.cc/arduino-mkr-nb-1500-1413)
1616
* **LoRa**: [`MKR WAN 1300/1310`](https://store.arduino.cc/mkr-wan-1310)
1717
* **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)
18+
* **Notecard**: [Provides Cellular/LoRa/Satellite/Wi-Fi to any modern board/architecture](examples/ArduinoIoTCloud-Notecard/README.md)
1819

1920
### How?
2021
1) Register your Arduino IoT Cloud capable board via [Arduino IoT Cloud](https://create.arduino.cc/iot) (Devices Section).
@@ -70,7 +71,7 @@ void onLedChange() {
7071

7172
### FAQ
7273
#### Watchdog
73-
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`:
74+
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`:
7475
```C++
7576
ArduinoCloud.begin(ArduinoIoTPreferredConnection, false).
7677
```
@@ -95,5 +96,3 @@ Boards can authenticate to the ArduinoIoTCloud servers using 3 methods:
9596
* `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)
9697

9798
* `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)
98-
99-
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
This sketch demonstrates how to exchange data between your board and the
3+
Arduino IoT Cloud, while using the Notecard for wireless communication.
4+
5+
* Connect a potentiometer (or other analog sensor) to A0.
6+
* When the potentiometer (or sensor) value changes the data is sent to the Cloud.
7+
* When you flip the switch in the Cloud dashboard the onboard LED lights gets turned ON or OFF.
8+
9+
IMPORTANT:
10+
This sketch works with any Wi-Fi, Cellular, LoRa or Satellite enabled Notecard.
11+
12+
The full list of compatible boards can be found here:
13+
- https://github.com/arduino-libraries/ArduinoIoTCloud#what
14+
*/
15+
16+
#include <Notecard.h>
17+
#include "thingProperties.h"
18+
19+
#if !defined(LED_BUILTIN) && !defined(ARDUINO_NANO_ESP32)
20+
static int const LED_BUILTIN = 2;
21+
#endif
22+
23+
/*
24+
* Choose an interrupt capable pin to reduce polling and improve
25+
* the overall responsiveness of the ArduinoIoTCloud library
26+
*/
27+
// #define ATTN_PIN 9
28+
29+
void setup() {
30+
/* Initialize serial and wait up to 5 seconds for port to open */
31+
Serial.begin(9600);
32+
for(unsigned long const serialBeginTime = millis(); !Serial && (millis() - serialBeginTime <= 5000); ) { }
33+
34+
/* Set the debug message level:
35+
* - DBG_ERROR: Only show error messages
36+
* - DBG_WARNING: Show warning and error messages
37+
* - DBG_INFO: Show info, warning, and error messages
38+
* - DBG_DEBUG: Show debug, info, warning, and error messages
39+
* - DBG_VERBOSE: Show all messages
40+
*/
41+
setDebugMessageLevel(DBG_INFO);
42+
43+
/* Configure LED pin as an output */
44+
pinMode(LED_BUILTIN, OUTPUT);
45+
46+
/* This function takes care of connecting your sketch variables to the ArduinoIoTCloud object */
47+
initProperties();
48+
49+
/* Initialize Arduino IoT Cloud library */
50+
#ifndef ATTN_PIN
51+
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
52+
ArduinoCloud.setNotecardPollingInterval(3000); // default: 1000ms, min: 250ms
53+
#else
54+
ArduinoCloud.begin(ArduinoIoTPreferredConnection, ATTN_PIN);
55+
#endif
56+
57+
ArduinoCloud.printDebugInfo();
58+
}
59+
60+
void loop() {
61+
ArduinoCloud.update();
62+
potentiometer = analogRead(A0);
63+
seconds = millis() / 1000;
64+
}
65+
66+
/*
67+
* 'onLedChange' is called when the "led" property of your Thing changes
68+
*/
69+
void onLedChange() {
70+
Serial.print("LED set to ");
71+
Serial.println(led);
72+
digitalWrite(LED_BUILTIN, led);
73+
}

Diff for: examples/ArduinoIoTCloud-Notecard/README.md

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
Notecard Connectivity
2+
=====================
3+
4+
The Notecard is a wireless, secure abstraction for device connectivity, that can
5+
be used to enable _ANY*_ device with I2C, or UART, to connect to the Arduino IoT
6+
Cloud via cellular, LoRa, satellite or Wi-Fi!
7+
8+
As a result, your existing device architecture can now have first class support
9+
in the Arduino IoT Cloud, by using a Notecard as a secure communication channel.
10+
11+
> \*_While any device with I2C/UART may use the Notecard, the Arduino IoT Cloud
12+
> library is not supported by the AVR toolchain. Therefore, devices based on the
13+
> AVR architecture cannot access the Arduino IoT Cloud via the Notecard._
14+
>
15+
> _However, any device (including AVR), may use the Notecard library to send data
16+
> to Notehub, then that data may be routed to any endpoint of your choosing. See the
17+
> [Notecard Routing Guide](https://dev.blues.io/guides-and-tutorials/routing-data-to-cloud)
18+
> for more information..._
19+
20+
Wireless Connectivity Options
21+
-----------------------------
22+
23+
- [Cellular](https://shop.blues.com/collections/notecard/products/notecard-cellular)
24+
- [Cellular + Wi-Fi](https://shop.blues.com/collections/notecard/products/notecard-cell-wifi)
25+
- [Wi-Fi](https://shop.blues.com/collections/notecard/products/wifi-notecard)
26+
- [LoRa](https://shop.blues.com/collections/notecard/products/notecard-lora)
27+
- [Satellite](https://shop.blues.com/products/starnote)
28+
29+
How it Works
30+
------------
31+
32+
**Architecture Diagram:**
33+
34+
```
35+
-------- ------------ ----------- -----------
36+
| | | | | | | |
37+
| Host | | | Secure | | | Arduino |
38+
| MCU |---<I2C/UART>---| Notecard | ( ( Wireless ) ) | Notehub |---<TLS>---| IoT |
39+
| | | | Protocol | | | Cloud |
40+
|______| |__________| |_________| |_________|
41+
```
42+
43+
Getting Started
44+
---------------
45+
46+
### Setup a Notehub Account
47+
48+
Using the Notecard only requires a couple of easy steps:
49+
50+
1. [Purchase a Notecard](https://shop.blues.com/collections/notecard) (and
51+
[Notecarrier](https://shop.blues.com/collections/notecarrier)) that fits the
52+
needs of your device.
53+
> _**NOTE:** We recommend starting with our [Dev Kit](https://shop.blues.com/products/blues-global-starter-kit)
54+
> if you are unsure._
55+
1. [Setup a Notehub account](https://dev.blues.io/quickstart/notecard-quickstart/notecard-and-notecarrier-f/#set-up-notehub).
56+
> _**NOTE:** Notehub accounts are free (no credit card required)._
57+
1. [Create a project on your Notehub account](https://dev.blues.io/quickstart/notecard-quickstart/notecard-and-notecarrier-f/#create-a-notehub-project).
58+
1. In `thingProperties.h`, replace "com.domain.you:product" (from
59+
`NOTECARD_PRODUCT_UID`) with the ProductUID of your new Notehub project.
60+
61+
### Power-up the Device
62+
63+
1. [Connect the Notecard to your Host MCU](https://dev.blues.io/quickstart/notecard-quickstart/notecard-and-notecarrier-f/#connect-your-notecard-and-notecarrier)
64+
1. Flash the `ArduinoIoTCloud-Notecard` example sketch to your device. You
65+
should see the device reporting itself as online in your [Notehub Project](https://notehub.io).
66+
67+
### Associate Notecard to Arduino IoT Cloud
68+
69+
1. Create a "MANUAL Device" in the Arduino IoT Cloud, then [add environment
70+
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).
71+
- `_sn`: \<Device ID\>
72+
- `_secret_key`: \<Secret Key\>
73+
74+
### More Information
75+
76+
For more information about the Notecard and Notehub in general, please see our
77+
[Quickstart Guide](https://dev.blues.io/quickstart/) for a general overview of
78+
how the Notecard and Notehub are designed to work.

Diff for: examples/ArduinoIoTCloud-Notecard/arduino_secrets.h

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include <Arduino_ConnectionHandler.h>
2+
3+
/* If provided, the Wi-Fi Credentials will be passed along to the Notecard. If
4+
* the Notecard supports Wi-Fi, it will attempt to connect to the network using
5+
* these credentials, if not, the Notecard will safely ignore these values. */
6+
#define SECRET_WIFI_SSID "YOUR_WIFI_NETWORK_NAME"
7+
#define SECRET_WIFI_PASS "YOUR_WIFI_PASSWORD"

Diff for: examples/ArduinoIoTCloud-Notecard/thingProperties.h

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include <string.h>
2+
3+
#include <ArduinoIoTCloud.h>
4+
#include <Arduino_ConnectionHandler.h>
5+
#include "arduino_secrets.h"
6+
7+
/* The Notecard can provide connectivity to almost any board via ESLOV (I2C)
8+
* or UART. An empty string (or the default value provided below) will not
9+
* override the Notecard's existing configuration.
10+
* Learn more at: https://dev.blues.io */
11+
#define NOTECARD_PRODUCT_UID "com.domain.you:product"
12+
13+
/* Uncomment the following line to use the Notecard over UART */
14+
// #define UART_INTERFACE Serial1
15+
16+
void onLedChange();
17+
18+
bool led;
19+
int potentiometer;
20+
int seconds;
21+
22+
#ifndef UART_INTERFACE
23+
NotecardConnectionHandler ArduinoIoTPreferredConnection(NOTECARD_PRODUCT_UID);
24+
#else
25+
NotecardConnectionHandler ArduinoIoTPreferredConnection(NOTECARD_PRODUCT_UID, UART_INTERFACE);
26+
#endif
27+
28+
void initProperties() {
29+
ArduinoCloud.addProperty(led, Permission::ReadWrite).onUpdate(onLedChange);
30+
ArduinoCloud.addProperty(potentiometer, Permission::Read).publishOnChange(10);
31+
ArduinoCloud.addProperty(seconds, Permission::Read).publishEvery(5 * MINUTES);
32+
33+
if (::strncmp(SECRET_WIFI_SSID, "YOUR_WIFI_NETWORK_NAME", sizeof(SECRET_WIFI_SSID))) {
34+
ArduinoIoTPreferredConnection.setWiFiCredentials(SECRET_WIFI_SSID, SECRET_WIFI_PASS);
35+
}
36+
}

Diff for: keywords.txt

+10
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ getThingId KEYWORD2
2525
setDeviceId KEYWORD2
2626
getDeviceId KEYWORD2
2727
getConnection KEYWORD2
28+
getInternalTime KEYWORD2
29+
getLocalTime KEYWORD2
2830
addCallback KEYWORD2
2931
addProperty KEYWORD2
3032

@@ -46,6 +48,14 @@ getBrokerPort KEYWORD2
4648
setOTAStorage KEYWORD2
4749
reconnect KEYWORD2
4850

51+
# ArduinoIoTCloudNotecard.h
52+
begin KEYWORD2
53+
setNotecardPollingInterval KEYWORD2
54+
55+
# OTA
56+
onOTARequestCallbackFunc KEYWORD2
57+
onOTARequestCb KEYWORD2
58+
4959
#######################################
5060
# Constants (LITERAL1)
5161
#######################################

Diff for: library.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ sentence=This library allows connecting to the Arduino IoT Cloud service.
66
paragraph=It provides a ConnectionManager to handle connection/disconnection, property-change updates and events callbacks. The supported boards are MKR GSM, MKR1000 and WiFi101.
77
category=Communication
88
url=https://github.com/arduino-libraries/ArduinoIoTCloud
9-
architectures=mbed,samd,esp8266,mbed_nano,mbed_portenta,mbed_nicla,esp32,mbed_opta,mbed_giga,renesas_portenta,renesas_uno,mbed_edge
9+
architectures=mbed,samd,esp8266,mbed_nano,mbed_portenta,mbed_nicla,esp32,mbed_opta,mbed_giga,renesas_portenta,renesas_uno,mbed_edge,stm32
1010
includes=ArduinoIoTCloud.h
1111
depends=Arduino_ConnectionHandler,Arduino_DebugUtils,Arduino_SecureElement,ArduinoMqttClient,ArduinoECCX08,RTCZero,Adafruit SleepyDog Library,ArduinoHttpClient

Diff for: src/AIoTC_Config.h

+25-8
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
#ifndef ARDUINO_AIOTC_CONFIG_H_
1919
#define ARDUINO_AIOTC_CONFIG_H_
2020

21+
#if defined __has_include
22+
#if __has_include (<Notecard.h>)
23+
#define HAS_NOTECARD
24+
#endif
25+
#endif
26+
2127
#include <ArduinoECCX08Config.h>
2228

2329
/******************************************************************************
@@ -52,6 +58,8 @@
5258
* AUTOMATICALLY CONFIGURED DEFINES
5359
******************************************************************************/
5460

61+
#if !defined(HAS_NOTECARD)
62+
5563
#if defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_NANO_33_IOT)
5664
#define OTA_STORAGE_SNU (1)
5765
#else
@@ -114,11 +122,6 @@
114122
#define HAS_TCP
115123
#endif
116124

117-
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) || defined(ARDUINO_OPTA) || defined(ARDUINO_GIGA)
118-
#define BEAR_SSL_CLIENT_IBUF_SIZE (16384 + 325) // Allows download from storage API
119-
#define BOARD_STM32H7
120-
#endif
121-
122125
#if defined(ARDUINO_NANO_RP2040_CONNECT)
123126
#define BEAR_SSL_CLIENT_IBUF_SIZE (16384 + 325) // Allows download from storage API
124127
#endif
@@ -138,6 +141,13 @@
138141
#define BOARD_HAS_SECURE_ELEMENT
139142
#endif
140143

144+
#endif // HAS_NOTECARD
145+
146+
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) || defined(ARDUINO_OPTA) || defined(ARDUINO_GIGA)
147+
#define BEAR_SSL_CLIENT_IBUF_SIZE (16384 + 325) // Allows download from storage API
148+
#define BOARD_STM32H7
149+
#endif
150+
141151
/******************************************************************************
142152
* CONSTANTS
143153
******************************************************************************/
@@ -146,12 +156,19 @@
146156
#define AIOT_CONFIG_LPWAN_UPDATE_RETRY_DELAY_ms (10000UL)
147157
#endif
148158

149-
#if defined(HAS_TCP)
159+
#if defined(HAS_NOTECARD) || defined(HAS_TCP)
150160
#define AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms (1000UL)
151161
#define AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms (32000UL)
152162

153-
#define AIOT_CONFIG_THING_ID_REQUEST_RETRY_DELAY_ms (2000UL)
154-
#define AIOT_CONFIG_MAX_THING_ID_REQUEST_RETRY_DELAY_ms (32000UL)
163+
#if defined(HAS_NOTECARD)
164+
// 10x the standard delays for Notecard
165+
#define AIOT_CONFIG_THING_ID_REQUEST_RETRY_DELAY_ms (20000UL)
166+
#define AIOT_CONFIG_MAX_THING_ID_REQUEST_RETRY_DELAY_ms (320000UL)
167+
#else
168+
#define AIOT_CONFIG_THING_ID_REQUEST_RETRY_DELAY_ms (2000UL)
169+
#define AIOT_CONFIG_MAX_THING_ID_REQUEST_RETRY_DELAY_ms (32000UL)
170+
#endif
171+
155172
#define AIOT_CONFIG_THING_ID_REQUEST_MAX_RETRY_CNT (10UL)
156173

157174
#define AIOT_CONFIG_DEVICE_REGISTERED_RETRY_DELAY_k (10UL)

Diff for: src/ArduinoIoTCloud.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,9 @@ class ArduinoIoTCloudClass
161161
OnCloudEventCallback _cloud_event_callback[3];
162162
};
163163

164-
#ifdef HAS_TCP
164+
#if defined(HAS_NOTECARD)
165+
#include "ArduinoIoTCloudNotecard.h"
166+
#elif defined(HAS_TCP)
165167
#include "ArduinoIoTCloudTCP.h"
166168
#elif defined(HAS_LORA)
167169
#include "ArduinoIoTCloudLPWAN.h"

Diff for: src/ArduinoIoTCloudDevice.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
#include <AIoTC_Config.h>
1616

17-
#ifdef HAS_TCP
17+
#if defined(HAS_NOTECARD) || defined(HAS_TCP)
1818

1919
#include "ArduinoIoTCloudDevice.h"
2020
#include "interfaces/CloudProcess.h"
@@ -146,4 +146,4 @@ ArduinoCloudDevice::State ArduinoCloudDevice::handleDisconnected() {
146146
return State::Disconnected;
147147
}
148148

149-
#endif /* HAS_TCP */
149+
#endif /* HAS_NOTECARD || HAS_TCP */

0 commit comments

Comments
 (0)