Skip to content

Commit b933578

Browse files
committed
feat: NotecardConnectionHandler
1 parent f39958c commit b933578

13 files changed

+1459
-32
lines changed

.github/workflows/compile-examples.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ jobs:
3535
- name: MKRNB
3636
- name: MKRWAN
3737
- name: Arduino_Cellular
38+
- name: Blues Wireless Notecard
3839
ARDUINOCORE_MBED_STAGING_PATH: extras/ArduinoCore-mbed
3940
ARDUINOCORE_API_STAGING_PATH: extras/ArduinoCore-API
4041
SKETCHES_REPORTS_PATH: sketches-reports
@@ -135,7 +136,7 @@ jobs:
135136
# Install ESP8266 platform via Boards Manager
136137
- name: esp8266:esp8266
137138
source-url: https://arduino.esp8266.com/stable/package_esp8266com_index.json
138-
version: 2.5.0
139+
version: 3.1.2
139140
- board:
140141
platform-name: esp32:esp32
141142
platforms: |

README.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,25 @@ Arduino Library for network connections management
66
[![Spell Check status](https://github.com/arduino-libraries/Arduino_ConnectionHandler/actions/workflows/spell-check.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_ConnectionHandler/actions/workflows/spell-check.yml)
77

88
Library for handling and managing network connections by providing keep-alive functionality and automatic reconnection in case of connection-loss. It supports the following boards:
9-
* **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/products/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)
9+
10+
* **Wi-Fi**: [`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/products/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)
1011
* **GSM**: [`MKR GSM 1400`](https://store.arduino.cc/arduino-mkr-gsm-1400-1415)
1112
* **5G**: [`MKR NB 1500`](https://store.arduino.cc/arduino-mkr-nb-1500-1413)
1213
* **LoRa**: [`MKR WAN 1300/1310`](https://store.arduino.cc/mkr-wan-1310)
1314
* **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)
15+
* **Notecard**: [Provides Cellular/LoRa/Satellite/Wi-Fi to any modern board/architecture](https://shop.blues.com/collections/notecard)
1416

1517
### How-to-use
1618

1719
```C++
1820
#include <Arduino_ConnectionHandler.h>
1921
/* ... */
20-
#if defined(BOARD_HAS_ETHERNET)
22+
#if defined(BOARD_HAS_NOTECARD)
23+
NotecardConnectionHandler conMan("com.domain.you:product");
24+
#elif defined(BOARD_HAS_ETHERNET)
2125
EthernetConnectionHandler conMan;
2226
#elif defined(BOARD_HAS_WIFI)
23-
WiFiConnectionHandler conMan("SECRET_SSID", "SECRET_PASS");
27+
WiFiConnectionHandler conMan("SECRET_WIFI_SSID", "SECRET_WIFI_PASS");
2428
#elif defined(BOARD_HAS_GSM)
2529
GSMConnectionHandler conMan("SECRET_PIN", "SECRET_APN", "SECRET_GSM_LOGIN", "SECRET_GSM_PASS");
2630
#elif defined(BOARD_HAS_NB)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/* SECRET_ fields are in `arduino_secrets.h` (included below)
2+
*
3+
* If using a Host + Notecard connected over I2C you'll need a
4+
* NotecardConnectionHandler object as follows:
5+
*
6+
* NotecardConnectionHandler conMan(NOTECARD_PRODUCT_UID);
7+
*
8+
* If using a Host + Notecard connected over Serial you'll need a
9+
* NotecardConnectionHandler object as follows:
10+
*
11+
* NotecardConnectionHandler conMan(NOTECARD_PRODUCT_UID, UART_INTERFACE);
12+
*/
13+
14+
#include <Notecard.h> // MUST include this first to enable Notecard support
15+
#include <Arduino_ConnectionHandler.h>
16+
17+
#include "arduino_secrets.h"
18+
19+
/* Uncomment the following line to use this example in a manner that is more
20+
* compatible with LoRa.
21+
*/
22+
// #define USE_NOTE_LORA
23+
24+
#ifndef USE_NOTE_LORA
25+
#define CONN_TOGGLE_MS 60000
26+
#else
27+
#define CONN_TOGGLE_MS 300000
28+
#endif
29+
30+
/* The Notecard can provide connectivity to almost any board via ESLOV (I2C)
31+
* or UART. An empty string (or the default value provided below) will not
32+
* override the Notecard's existing configuration.
33+
* Learn more at: https://dev.blues.io */
34+
#define NOTECARD_PRODUCT_UID "com.domain.you:product"
35+
36+
/* Uncomment the following line to use the Notecard over UART */
37+
// #define UART_INTERFACE Serial1
38+
39+
#ifndef UART_INTERFACE
40+
NotecardConnectionHandler conMan(NOTECARD_PRODUCT_UID);
41+
#else
42+
NotecardConnectionHandler conMan(NOTECARD_PRODUCT_UID, UART_INTERFACE);
43+
#endif
44+
45+
bool attemptConnect = false;
46+
uint32_t lastConnToggleMs = 0;
47+
48+
void setup() {
49+
/* Initialize serial debug port and wait up to 5 seconds for port to open */
50+
Serial.begin(9600);
51+
for(unsigned long const serialBeginTime = millis(); !Serial && (millis() - serialBeginTime <= 5000); ) { }
52+
53+
/* Set the debug message level:
54+
* - DBG_ERROR: Only show error messages
55+
* - DBG_WARNING: Show warning and error messages
56+
* - DBG_INFO: Show info, warning, and error messages
57+
* - DBG_DEBUG: Show debug, info, warning, and error messages
58+
* - DBG_VERBOSE: Show all messages
59+
*/
60+
setDebugMessageLevel(DBG_INFO);
61+
62+
/* Add callbacks to the ConnectionHandler object to get notified of network
63+
* connection events. */
64+
conMan.addCallback(NetworkConnectionEvent::CONNECTED, onNetworkConnect);
65+
conMan.addCallback(NetworkConnectionEvent::DISCONNECTED, onNetworkDisconnect);
66+
conMan.addCallback(NetworkConnectionEvent::ERROR, onNetworkError);
67+
68+
/* First call to `check()` initializes the connection to the Notecard. While
69+
* not strictly necessary, it cleans up the logging from this application.
70+
*/
71+
conMan.check();
72+
73+
#ifndef USE_NOTE_LORA
74+
/* Set the Wi-Fi credentials for the Notecard */
75+
String ssid = SECRET_WIFI_SSID;
76+
if (ssid.length() > 0 && ssid != "NETWORK NAME") {
77+
conMan.setWiFiCredentials(SECRET_WIFI_SSID, SECRET_WIFI_PASS);
78+
}
79+
#else
80+
conMan.setInboundPollingInterval(720); // poll twice per day
81+
#endif
82+
83+
/* Confirm Interface */
84+
Serial.print("Network Adapter Interface: ");
85+
if (NetworkAdapter::NOTECARD == conMan.getInterface()) {
86+
Serial.print("Notecard ");
87+
Serial.print(conMan.getNotecardUid());
88+
#ifndef UART_INTERFACE
89+
Serial.println(" (via I2C)");
90+
#else
91+
Serial.println(" (via UART)");
92+
#endif
93+
} else {
94+
Serial.println("ERROR: Unexpected Interface");
95+
while(1);
96+
}
97+
98+
/* Display the Arduino IoT Cloud Device ID */
99+
displayCachedDeviceId();
100+
}
101+
102+
void loop() {
103+
/* Toggle the connection every `CONN_TOGGLE_MS` milliseconds */
104+
if ((millis() - lastConnToggleMs) > CONN_TOGGLE_MS) {
105+
Serial.println("Toggling connection...");
106+
if (attemptConnect) {
107+
displayCachedDeviceId();
108+
conMan.connect();
109+
} else {
110+
conMan.disconnect();
111+
}
112+
attemptConnect = !attemptConnect;
113+
lastConnToggleMs = millis();
114+
}
115+
116+
/* The following code keeps on running connection workflows on our
117+
* ConnectionHandler object, hence allowing reconnection in case of failure
118+
* and notification of connect/disconnect event if enabled (see
119+
* addConnectCallback/addDisconnectCallback) NOTE: any use of delay() within
120+
* the loop or methods called from it will delay the execution of .update(),
121+
* which might not guarantee the correct functioning of the ConnectionHandler
122+
* object.
123+
*/
124+
conMan.check();
125+
}
126+
127+
void displayCachedDeviceId() {
128+
Serial.print("Cached Arduino IoT Cloud Device ID: ");
129+
Serial.println(conMan.getDeviceId());
130+
}
131+
132+
void onNetworkConnect() {
133+
Serial.println(">>>> CONNECTED to network");
134+
}
135+
136+
void onNetworkDisconnect() {
137+
Serial.println(">>>> DISCONNECTED from network");
138+
}
139+
140+
void onNetworkError() {
141+
Serial.println(">>>> ERROR");
142+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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 may now have access to the
9+
Arduino IoT Cloud by using a Notecard to provide a secure communication channel.
10+
11+
> \*_While any device with I2C/UART may use the Notecard, the AVR architecture
12+
> is not supported by the Arduino IoT Cloud library. Therefore, those devices
13+
> are ineligible for use with the Notecard._
14+
15+
Wireless Connectivity Options
16+
-----------------------------
17+
18+
- [Cellular](https://shop.blues.com/collections/notecard/products/notecard-cellular)
19+
- [Cellular + Wi-Fi](https://shop.blues.com/collections/notecard/products/notecard-cell-wifi)
20+
- [Wi-Fi](https://shop.blues.com/collections/notecard/products/wifi-notecard)
21+
- [LoRa](https://shop.blues.com/collections/notecard/products/notecard-lora)
22+
- [Satellite](https://shop.blues.com/products/starnote)
23+
24+
How it Works
25+
------------
26+
27+
**Architecture Diagram:**
28+
29+
```
30+
-------- ------------ ----------- -----------
31+
| | | | | | | |
32+
| Host | | | Secure | | | Arduino |
33+
| MCU |---<I2C/UART>---| Notecard | ( ( Wireless ) ) | Notehub |---<TLS>---| IoT |
34+
| | | | Protocol | | | Cloud |
35+
|______| |__________| |_________| |_________|
36+
```
37+
38+
Getting Started
39+
---------------
40+
41+
- Quick Start Guide: https://dev.blues.io/quickstart/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/* If provided, the Wi-Fi Credentials will be passed along to the Notecard. If
2+
* the Notecard supports Wi-Fi, it will attempt to connect to the network using
3+
* these credentials, if not, the Notecard will safely ignore these values. */
4+
const char SECRET_WIFI_SSID[] = "NETWORK NAME";
5+
const char SECRET_WIFI_PASS[] = "NETWORK PASSWORD";

examples/ConnectionHandlerDemo/ConnectionHandlerDemo.ino

+71-10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
/* SECRET_ fields are in arduino_secrets.h included above
2-
* if using a WiFi board (Arduino MKR1000, MKR WiFi 1010, Nano 33 IoT, UNO
1+
/* SECRET_ fields are in `arduino_secrets.h` (included below)
2+
*
3+
* If using a WiFi board (Arduino MKR1000, MKR WiFi 1010, Nano 33 IoT, UNO
34
* WiFi Rev 2 or ESP8266/32), create a WiFiConnectionHandler object by adding
4-
* Network Name (SECRET_SSID) and password (SECRET_PASS) in the arduino_secrets.h
5-
* file (or Secrets tab in Create Web Editor).
5+
* Network Name (SECRET_WIFI_SSID) and password (SECRET_WIFI_PASS) in the
6+
* arduino_secrets.h file (or Secrets tab in Create Web Editor).
67
*
7-
* WiFiConnectionHandler conMan(SECRET_SSID, SECRET_PASS);
8+
* WiFiConnectionHandler conMan(SECRET_WIFI_SSID, SECRET_WIFI_PASS);
89
*
910
* If using a MKR GSM 1400 or other GSM boards supporting the same API you'll
1011
* need a GSMConnectionHandler object as follows
@@ -27,14 +28,21 @@
2728
*
2829
*/
2930

31+
#include <Arduino_ConnectionHandler.h>
32+
3033
#include "arduino_secrets.h"
3134

32-
#include <Arduino_ConnectionHandler.h>
35+
#define CONN_TOGGLE_MS 60000
36+
37+
#if !(defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_LORA) || \
38+
defined(BOARD_HAS_NB) || defined(BOARD_HAS_ETHERNET) || defined(BOARD_HAS_CATM1_NBIOT))
39+
#error "Please check Arduino Connection Handler supported boards list: https://github.com/arduino-libraries/Arduino_ConnectionHandler/blob/master/README.md"
40+
#endif
3341

3442
#if defined(BOARD_HAS_ETHERNET)
3543
EthernetConnectionHandler conMan(SECRET_IP, SECRET_DNS, SECRET_GATEWAY, SECRET_NETMASK);
3644
#elif defined(BOARD_HAS_WIFI)
37-
WiFiConnectionHandler conMan(SECRET_SSID, SECRET_PASS);
45+
WiFiConnectionHandler conMan(SECRET_WIFI_SSID, SECRET_WIFI_PASS);
3846
#elif defined(BOARD_HAS_GSM)
3947
GSMConnectionHandler conMan(SECRET_PIN, SECRET_APN, SECRET_GSM_USER, SECRET_GSM_PASS);
4048
#elif defined(BOARD_HAS_NB)
@@ -47,19 +55,73 @@ CatM1ConnectionHandler conMan(SECRET_PIN, SECRET_APN, SECRET_GSM_USER, SECRET_GS
4755
CellularConnectionHandler conMan(SECRET_PIN, SECRET_APN, SECRET_GSM_USER, SECRET_GSM_PASS);
4856
#endif
4957

58+
bool attemptConnect = false;
59+
uint32_t lastConnToggleMs = 0;
60+
5061
void setup() {
62+
/* Initialize serial debug port and wait up to 5 seconds for port to open */
5163
Serial.begin(9600);
52-
/* Give a few seconds for the Serial connection to be available */
53-
delay(4000);
64+
for(unsigned long const serialBeginTime = millis(); !Serial && (millis() - serialBeginTime <= 5000); ) { }
65+
5466
#ifndef __AVR__
67+
/* Set the debug message level:
68+
* - DBG_ERROR: Only show error messages
69+
* - DBG_WARNING: Show warning and error messages
70+
* - DBG_INFO: Show info, warning, and error messages
71+
* - DBG_DEBUG: Show debug, info, warning, and error messages
72+
* - DBG_VERBOSE: Show all messages
73+
*/
5574
setDebugMessageLevel(DBG_INFO);
5675
#endif
76+
77+
/* Add callbacks to the ConnectionHandler object to get notified of network
78+
* connection events. */
5779
conMan.addCallback(NetworkConnectionEvent::CONNECTED, onNetworkConnect);
5880
conMan.addCallback(NetworkConnectionEvent::DISCONNECTED, onNetworkDisconnect);
5981
conMan.addCallback(NetworkConnectionEvent::ERROR, onNetworkError);
82+
83+
Serial.print("Network Adapter Interface: ");
84+
switch (conMan.getInterface()) {
85+
case NetworkAdapter::WIFI:
86+
Serial.println("Wi-Fi");
87+
break;
88+
case NetworkAdapter::ETHERNET:
89+
Serial.println("Ethernet");
90+
break;
91+
case NetworkAdapter::NB:
92+
Serial.println("Narrowband");
93+
break;
94+
case NetworkAdapter::GSM:
95+
Serial.println("GSM");
96+
break;
97+
case NetworkAdapter::LORA:
98+
Serial.println("LoRa");
99+
break;
100+
case NetworkAdapter::CATM1:
101+
Serial.println("Category M1");
102+
break;
103+
case NetworkAdapter::CELL:
104+
Serial.println("Cellular");
105+
break;
106+
default:
107+
Serial.println("Unknown");
108+
break;
109+
}
60110
}
61111

62112
void loop() {
113+
/* Toggle the connection every `CONN_TOGGLE_MS` milliseconds */
114+
if ((millis() - lastConnToggleMs) > CONN_TOGGLE_MS) {
115+
Serial.println("Toggling connection...");
116+
if (attemptConnect) {
117+
conMan.connect();
118+
} else {
119+
conMan.disconnect();
120+
}
121+
attemptConnect = !attemptConnect;
122+
lastConnToggleMs = millis();
123+
}
124+
63125
/* The following code keeps on running connection workflows on our
64126
* ConnectionHandler object, hence allowing reconnection in case of failure
65127
* and notification of connect/disconnect event if enabled (see
@@ -68,7 +130,6 @@ void loop() {
68130
* which might not guarantee the correct functioning of the ConnectionHandler
69131
* object.
70132
*/
71-
72133
conMan.check();
73134
}
74135

examples/ConnectionHandlerDemo/arduino_secrets.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Required for WiFiConnectionHandler
2-
const char SECRET_SSID[] = "NETWORK NAME";
3-
const char SECRET_PASS[] = "NETWORK PASSWORD";
2+
const char SECRET_WIFI_SSID[] = "NETWORK NAME";
3+
const char SECRET_WIFI_PASS[] = "NETWORK PASSWORD";
44

55
// Required for GSMConnectionHandler
6-
const char SECRET_APN[] = "MOBILE PROVIDER APN ADDRESS";
7-
const char SECRET_PIN[] = "0000"; // Required for NBConnectionHandler
8-
const char SECRET_GSM_USER[] = "GSM USERNAME";
9-
const char SECRET_GSM_PASS[] = "GSM PASSWORD";
6+
const char SECRET_APN[] = "MOBILE PROVIDER APN ADDRESS";
7+
const char SECRET_PIN[] = "0000"; // Required for NBConnectionHandler
8+
const char SECRET_GSM_USER[] = "GSM USERNAME";
9+
const char SECRET_GSM_PASS[] = "GSM PASSWORD";
1010

1111
// Required for LoRaConnectionHandler
1212
const char SECRET_APP_EUI[] = "APP_EUI";

library.properties

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ name=Arduino_ConnectionHandler
22
version=0.9.0
33
author=Ubi de Feo, Cristian Maglie, Andrea Catozzi, Alexander Entinger et al.
44
maintainer=Arduino <[email protected]>
5-
sentence=Arduino Library for network connection management (WiFi, GSM, NB, [Ethernet])
5+
sentence=Arduino Library for network connection management (WiFi, GSM, NB, [Ethernet], Notecard)
66
paragraph=Originally part of ArduinoIoTCloud
77
category=Communication
88
url=https://github.com/arduino-libraries/Arduino_ConnectionHandler
9-
architectures=samd,esp32,esp8266,mbed,megaavr,mbed_nano,mbed_portenta,mbed_nicla,mbed_opta,mbed_giga,renesas_portenta,renesas_uno,mbed_edge
10-
depends=Arduino_DebugUtils, WiFi101, WiFiNINA, MKRGSM, MKRNB, MKRWAN
9+
architectures=samd,esp32,esp8266,mbed,megaavr,mbed_nano,mbed_portenta,mbed_nicla,mbed_opta,mbed_giga,renesas_portenta,renesas_uno,mbed_edge,stm32
10+
depends=Arduino_DebugUtils, WiFi101, WiFiNINA, MKRGSM, MKRNB, MKRWAN, Blues Wireless Notecard (>=1.6.0)

0 commit comments

Comments
 (0)