Skip to content

Commit 1a137c6

Browse files
committed
feat: NotecardConnectionManager
1 parent f39958c commit 1a137c6

13 files changed

+1635
-33
lines changed

.github/workflows/compile-examples.yml

+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

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.vscode/

README.md

+23-4
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,30 @@ 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)
10-
* **GSM**: [`MKR GSM 1400`](https://store.arduino.cc/arduino-mkr-gsm-1400-1415)
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),
11+
[`Notecard`](https://shop.blues.com/collections/notecard)
12+
* **GSM**: [`MKR GSM 1400`](https://store.arduino.cc/arduino-mkr-gsm-1400-1415), [`Notecard`](https://shop.blues.com/collections/notecard)
13+
* **LTE**: [`Notecard`](https://shop.blues.com/collections/notecard)
1114
* **5G**: [`MKR NB 1500`](https://store.arduino.cc/arduino-mkr-nb-1500-1413)
12-
* **LoRa**: [`MKR WAN 1300/1310`](https://store.arduino.cc/mkr-wan-1310)
15+
* **LoRa**: [`MKR WAN 1300/1310`](https://store.arduino.cc/mkr-wan-1310), [`Notecard`](https://shop.blues.com/collections/notecard)
1316
* **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)
17+
* **Satellite**: [`Notecard`](https://shop.blues.com/collections/notecard)
18+
19+
#### More About Notecard Connectivity
20+
21+
The Notecard is a wireless, secure abstraction for device connectivity, that can
22+
be used to enable _ANY*_ device with I2C, or UART, to connect to the Arduino IoT
23+
Cloud via cellular, LoRa, satellite or Wi-Fi (including the devices listed
24+
above)!
25+
26+
As a result, the STM32 architecture has now been added to this library. If you
27+
have an STM32 device, you are now able to connect it to the Arduino IoT Cloud by
28+
using a Notecard to provide a secure communication channel.
29+
30+
> \*_Unfortunately, the AVR architecture is not supported by the Arduino IoT
31+
> Cloud library. Therefore, those devices are ineligible for use with the
32+
> Notecard._
1433
1534
### How-to-use
1635

@@ -20,7 +39,7 @@ Library for handling and managing network connections by providing keep-alive fu
2039
#if defined(BOARD_HAS_ETHERNET)
2140
EthernetConnectionHandler conMan;
2241
#elif defined(BOARD_HAS_WIFI)
23-
WiFiConnectionHandler conMan("SECRET_SSID", "SECRET_PASS");
42+
WiFiConnectionHandler conMan("SECRET_WIFI_SSID", "SECRET_WIFI_PASS");
2443
#elif defined(BOARD_HAS_GSM)
2544
GSMConnectionHandler conMan("SECRET_PIN", "SECRET_APN", "SECRET_GSM_LOGIN", "SECRET_GSM_PASS");
2645
#elif defined(BOARD_HAS_NB)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
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 configure the library in a manner that is
20+
* more 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+
#ifndef USE_NOTE_LORA
63+
/* Set the debug message level:
64+
* - NotehubLogLevel::Error: Only show error messages
65+
* - NotehubLogLevel::Warning: Show warning and error messages
66+
* - NotehubLogLevel::Info: Show info, warning, and error messages (default)
67+
* - NotehubLogLevel::Debug: Show debug, info, warning, and error messages
68+
* - NotehubLogLevel::Verbose: Show all messages
69+
*/
70+
conMan.enableNotehubLogging(NotecardConnectionHandler::NotehubLogLevel::Info);
71+
#else
72+
conMan.disableNotehubLogging();
73+
#endif
74+
75+
/* Add callbacks to the ConnectionHandler object to get notified of network
76+
* connection events. */
77+
conMan.addCallback(NetworkConnectionEvent::CONNECTED, onNetworkConnect);
78+
conMan.addCallback(NetworkConnectionEvent::DISCONNECTED, onNetworkDisconnect);
79+
conMan.addCallback(NetworkConnectionEvent::ERROR, onNetworkError);
80+
81+
Serial.print("Network Adapter Interface: ");
82+
if (NetworkAdapter::NOTECARD == conMan.getInterface()) {
83+
Serial.print("Notecard ");
84+
Serial.print(conMan.getNotecardUid());
85+
#ifndef UART_INTERFACE
86+
Serial.println(" (via I2C)");
87+
#else
88+
Serial.println(" (via UART)");
89+
#endif
90+
} else {
91+
Serial.println("Unexpected");
92+
}
93+
94+
#ifndef USE_NOTE_LORA
95+
/* Set the Wi-Fi credentials for the Notecard */
96+
String ssid = SECRET_WIFI_SSID;
97+
if (ssid.length() > 0 && ssid != "NETWORK NAME") {
98+
conMan.setWiFiCredentials(SECRET_WIFI_SSID, SECRET_WIFI_PASS);
99+
}
100+
#endif
101+
}
102+
103+
void loop() {
104+
/* Toggle the connection every `CONN_TOGGLE_MS` milliseconds */
105+
if ((millis() - lastConnToggleMs) > CONN_TOGGLE_MS) {
106+
Serial.println("Toggling connection...");
107+
if (attemptConnect) {
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 onNetworkConnect() {
128+
Serial.println(">>>> CONNECTED to network");
129+
}
130+
131+
void onNetworkDisconnect() {
132+
Serial.println(">>>> DISCONNECTED from network");
133+
}
134+
135+
void onNetworkError() {
136+
Serial.println(">>>> ERROR");
137+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/* A complete list of supported boards with WiFi is available here:
2+
* https://github.com/arduino-libraries/Arduino_ConnectionHandler/blob/master/README.md
3+
*/
4+
const char SECRET_WIFI_SSID[] = "NETWORK NAME";
5+
const char SECRET_WIFI_PASS[] = "NETWORK PASSWORD";

examples/ConnectionHandlerDemo/ConnectionHandlerDemo.ino

+95-11
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
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 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, Serial);
12+
*
13+
* If using a WiFi board (Arduino MKR1000, MKR WiFi 1010, Nano 33 IoT, UNO
314
* 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).
15+
* Network Name (SECRET_WIFI_SSID) and password (SECRET_WIFI_PASS) in the
16+
* arduino_secrets.h file (or Secrets tab in Create Web Editor).
617
*
7-
* WiFiConnectionHandler conMan(SECRET_SSID, SECRET_PASS);
18+
* WiFiConnectionHandler conMan(SECRET_WIFI_SSID, SECRET_WIFI_PASS);
819
*
920
* If using a MKR GSM 1400 or other GSM boards supporting the same API you'll
1021
* need a GSMConnectionHandler object as follows
@@ -27,14 +38,31 @@
2738
*
2839
*/
2940

41+
#include <Arduino_ConnectionHandler.h>
42+
3043
#include "arduino_secrets.h"
3144

32-
#include <Arduino_ConnectionHandler.h>
45+
#define CONN_TOGGLE_MS 60000
46+
47+
#if !(defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_LORA) || \
48+
defined(BOARD_HAS_NB) || defined(BOARD_HAS_ETHERNET) || defined(BOARD_HAS_CATM1_NBIOT))
49+
#error "Please check Arduino Connection Handler supported boards list: https://github.com/arduino-libraries/Arduino_ConnectionHandler/blob/master/README.md"
50+
#endif
3351

34-
#if defined(BOARD_HAS_ETHERNET)
52+
#if defined(USE_NOTECARD)
53+
/* The Notecard can provide connectivity to almost any board via ESLOV (I2C)
54+
* or UART. An empty string (or the default value provided below) will not
55+
* override the Notecard's existing configuration.
56+
* Learn more at: https://dev.blues.io */
57+
#define NOTECARD_PRODUCT_UID "com.domain.you:product"
58+
#endif
59+
60+
#if defined(USE_NOTECARD)
61+
NotecardConnectionHandler conMan(NOTECARD_PRODUCT_UID);
62+
#elif defined(BOARD_HAS_ETHERNET)
3563
EthernetConnectionHandler conMan(SECRET_IP, SECRET_DNS, SECRET_GATEWAY, SECRET_NETMASK);
3664
#elif defined(BOARD_HAS_WIFI)
37-
WiFiConnectionHandler conMan(SECRET_SSID, SECRET_PASS);
65+
WiFiConnectionHandler conMan(SECRET_WIFI_SSID, SECRET_WIFI_PASS);
3866
#elif defined(BOARD_HAS_GSM)
3967
GSMConnectionHandler conMan(SECRET_PIN, SECRET_APN, SECRET_GSM_USER, SECRET_GSM_PASS);
4068
#elif defined(BOARD_HAS_NB)
@@ -47,19 +75,76 @@ CatM1ConnectionHandler conMan(SECRET_PIN, SECRET_APN, SECRET_GSM_USER, SECRET_GS
4775
CellularConnectionHandler conMan(SECRET_PIN, SECRET_APN, SECRET_GSM_USER, SECRET_GSM_PASS);
4876
#endif
4977

78+
bool attemptConnect = false;
79+
uint32_t lastConnToggleMs = 0;
80+
5081
void setup() {
82+
/* Initialize serial debug port and wait up to 5 seconds for port to open */
5183
Serial.begin(9600);
52-
/* Give a few seconds for the Serial connection to be available */
53-
delay(4000);
84+
for(unsigned long const serialBeginTime = millis(); !Serial && (millis() - serialBeginTime <= 5000); ) { }
85+
5486
#ifndef __AVR__
87+
/* Set the debug message level:
88+
* - DBG_ERROR: Only show error messages
89+
* - DBG_WARNING: Show warning and error messages
90+
* - DBG_INFO: Show info, warning, and error messages
91+
* - DBG_DEBUG: Show debug, info, warning, and error messages
92+
* - DBG_VERBOSE: Show all messages
93+
*/
5594
setDebugMessageLevel(DBG_INFO);
5695
#endif
96+
97+
/* Add callbacks to the ConnectionHandler object to get notified of network
98+
* connection events. */
5799
conMan.addCallback(NetworkConnectionEvent::CONNECTED, onNetworkConnect);
58100
conMan.addCallback(NetworkConnectionEvent::DISCONNECTED, onNetworkDisconnect);
59101
conMan.addCallback(NetworkConnectionEvent::ERROR, onNetworkError);
102+
103+
Serial.print("Network Adapter Interface: ");
104+
switch (conMan.getInterface()) {
105+
case NetworkAdapter::WIFI:
106+
Serial.println("Wi-Fi");
107+
break;
108+
case NetworkAdapter::ETHERNET:
109+
Serial.println("Ethernet");
110+
break;
111+
case NetworkAdapter::NB:
112+
Serial.println("Narrowband");
113+
break;
114+
case NetworkAdapter::GSM:
115+
Serial.println("GSM");
116+
break;
117+
case NetworkAdapter::LORA:
118+
Serial.println("LoRa");
119+
break;
120+
case NetworkAdapter::CATM1:
121+
Serial.println("Category M1");
122+
break;
123+
case NetworkAdapter::CELL:
124+
Serial.println("Cellular");
125+
break;
126+
case NetworkAdapter::NOTECARD:
127+
Serial.println("Notecard");
128+
break;
129+
default:
130+
Serial.println("Unknown");
131+
break;
132+
}
60133
}
61134

62135
void loop() {
136+
/* Toggle the connection every `CONN_TOGGLE_MS` milliseconds */
137+
if ((millis() - lastConnToggleMs) > CONN_TOGGLE_MS) {
138+
Serial.println("Toggling connection...");
139+
if (attemptConnect) {
140+
conMan.connect();
141+
} else {
142+
conMan.disconnect();
143+
}
144+
attemptConnect = !attemptConnect;
145+
lastConnToggleMs = millis();
146+
}
147+
63148
/* The following code keeps on running connection workflows on our
64149
* ConnectionHandler object, hence allowing reconnection in case of failure
65150
* and notification of connect/disconnect event if enabled (see
@@ -68,7 +153,6 @@ void loop() {
68153
* which might not guarantee the correct functioning of the ConnectionHandler
69154
* object.
70155
*/
71-
72156
conMan.check();
73157
}
74158

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)

src/Arduino_ConnectionHandler.h

+6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
#include <Arduino.h>
3030
#include "Arduino_ConnectionHandlerDefinitions.h"
3131

32+
#if defined(USE_NOTECARD)
33+
#include "Arduino_NotecardConnectionHandler.h"
34+
#else
35+
3236
#if defined(BOARD_HAS_WIFI)
3337
#include "Arduino_WiFiConnectionHandler.h"
3438
#endif
@@ -57,4 +61,6 @@
5761
#include "Arduino_CellularConnectionHandler.h"
5862
#endif
5963

64+
#endif // USE_NOTECARD
65+
6066
#endif /* CONNECTION_HANDLER_H_ */

0 commit comments

Comments
 (0)