Skip to content

Commit 473e760

Browse files
authored
Merge pull request #235 from mikeysklar/mqtt-keep-alive
new example mqtt_airlift_subscribe_time_keepalive.ino
2 parents 7f01eab + fef830e commit 473e760

File tree

2 files changed

+250
-2
lines changed

2 files changed

+250
-2
lines changed
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
/***************************************************
2+
mqtt_airlift_subscribe_time_keepalive
3+
4+
Example demonstrating MQTT subscription and manual
5+
KeepAlive handling for AirLift (ESP32 / NINA-FW)
6+
devices using the Adafruit_MQTT_Library.
7+
8+
This example:
9+
* Connects an AirLift device to WiFi
10+
* Subscribes to io.adafruit.com/time/ISO-8601
11+
* Manually manages MQTT KeepAlive intervals
12+
* Sends periodic MQTT PINGs to maintain the
13+
MQTT session (workaround for NINA-FW behavior)
14+
15+
Written by Bruce Conrad.
16+
MIT license, all text above must be included in
17+
any redistribution.
18+
****************************************************/
19+
20+
#include <SPI.h>
21+
#include <WiFiNINA.h>
22+
#include "Adafruit_MQTT.h"
23+
#include "Adafruit_MQTT_Client.h"
24+
25+
/************************* WiFi Setup *********************************/
26+
// Update for your WiFi network.
27+
#define WIFI_SSID "YOUR_WIFI_SSID"
28+
#define WIFI_PASS "YOUR_WIFI_PASSWORD"
29+
30+
/************************* Adafruit IO Setup ***************************/
31+
#define AIO_SERVER "io.adafruit.com"
32+
#define AIO_SERVERPORT 1883 // use 8883 for MQTTS
33+
#define AIO_USERNAME "YOUR_ADAFRUIT_IO_USERNAME"
34+
#define AIO_KEY "YOUR_ADAFRUIT_IO_KEY"
35+
36+
/************************* AirLift Pin Setup ***************************/
37+
// These are the pins you provided and known-good.
38+
#define SPIWIFI SPI
39+
#define SPIWIFI_SS 13
40+
#define SPIWIFI_IRQ 11
41+
#define SPIWIFI_RESET 12
42+
#define ESP32_GPIO0 -1
43+
44+
/*************************** Timing / Params ***************************/
45+
// MQTT KeepAlive interval (seconds). The client must send at least one
46+
// packet (e.g., PINGREQ) within this interval or the MQTT server will
47+
// disconnect the session.
48+
#define AIRLIFT_KEEPALIVE 30
49+
50+
// Safety margin (seconds) to subtract before sending a manual PING.
51+
// AirLift/NINA-FW firmware does not reliably handle automatic MQTT
52+
// KeepAlive packets, and real-world testing shows a 10 second margin
53+
// prevents premature disconnects (“No socket available”).
54+
#define KEEPALIVE_SAFETY_MARGIN 10
55+
56+
#define MAX_MQTT_RETRIES 5
57+
#define SUBSCRIBE_WAIT_MS 1500
58+
59+
// Time (milliseconds) between manual MQTT PING operations.
60+
#define PING_PERIOD_MS \
61+
((AIRLIFT_KEEPALIVE - KEEPALIVE_SAFETY_MARGIN) * 1000)
62+
63+
/*************************** MQTT Objects ******************************/
64+
WiFiClient client;
65+
66+
Adafruit_MQTT_Client mqtt(
67+
&client,
68+
AIO_SERVER,
69+
AIO_SERVERPORT,
70+
AIO_USERNAME,
71+
AIO_KEY
72+
);
73+
74+
Adafruit_MQTT_Subscribe time_subscription =
75+
Adafruit_MQTT_Subscribe(&mqtt, "time/ISO-8601");
76+
77+
/*************************** State Vars *******************************/
78+
unsigned long ping_clk = 0;
79+
long ping_cnt = 0;
80+
81+
/*************************** MQTT Connect ******************************/
82+
void MQTT_connect() {
83+
84+
unsigned long start = millis();
85+
long attempts = 0;
86+
87+
while (attempts < MAX_MQTT_RETRIES) {
88+
attempts++;
89+
90+
Serial.print("MQTT Connect Attempt #");
91+
Serial.print(attempts);
92+
Serial.print(" ... ");
93+
94+
int8_t ret = mqtt.connect();
95+
96+
if (ret == 0) {
97+
Serial.print("Connected in ");
98+
Serial.print(millis() - start);
99+
Serial.println(" ms");
100+
ping_clk = millis();
101+
return;
102+
}
103+
104+
Serial.println(mqtt.connectErrorString(ret));
105+
Serial.println("Retrying in 5 seconds...");
106+
mqtt.disconnect();
107+
delay(5000);
108+
}
109+
110+
Serial.println("ERROR: Maximum MQTT connect attempts exceeded.");
111+
while (1) delay(10);
112+
}
113+
114+
/*************************** MQTT PING Logic ***************************/
115+
void MQTT_ping() {
116+
if ((millis() - ping_clk) < PING_PERIOD_MS) return;
117+
118+
ping_cnt++;
119+
unsigned long start = millis();
120+
121+
Serial.print("PING #");
122+
Serial.print(ping_cnt);
123+
Serial.print(" ... ");
124+
125+
for (int i = 0; i < MAX_MQTT_RETRIES; i++) {
126+
127+
if (mqtt.ping()) {
128+
Serial.print("OK (");
129+
Serial.print(millis() - start);
130+
Serial.println(" ms)");
131+
ping_clk = millis();
132+
return;
133+
}
134+
135+
Serial.print("fail ");
136+
delay(1000);
137+
}
138+
139+
Serial.println("\nERROR: No MQTT PING response. Halting.");
140+
while (1) delay(10);
141+
}
142+
143+
/*************************** WiFi Init *********************************/
144+
void initWiFi() {
145+
146+
// IMPORTANT: passes the *SPI object* (SPIWIFI), not a pin
147+
WiFi.setPins(SPIWIFI_SS, SPIWIFI_IRQ, SPIWIFI_RESET, ESP32_GPIO0, &SPIWIFI);
148+
149+
Serial.println("Starting AirLift WiFi...");
150+
151+
if (WiFi.status() == WL_NO_SHIELD) {
152+
Serial.println("ERROR: Communication with AirLift failed.");
153+
while (1) delay(10);
154+
}
155+
156+
Serial.print("NINA-FW Version: ");
157+
Serial.println(WiFi.firmwareVersion());
158+
159+
int status = WL_IDLE_STATUS;
160+
161+
while (status != WL_CONNECTED) {
162+
Serial.print("Connecting to SSID: ");
163+
Serial.println(WIFI_SSID);
164+
165+
status = WiFi.begin(WIFI_SSID, WIFI_PASS);
166+
167+
while (WiFi.localIP()[0] == 0) {
168+
delay(50);
169+
}
170+
}
171+
172+
Serial.println("WiFi connected.");
173+
printCurrentNet();
174+
printWiFiData();
175+
}
176+
177+
/*************************** Helpers ***********************************/
178+
void printCurrentNet() {
179+
Serial.print("SSID: ");
180+
Serial.print(WiFi.SSID());
181+
182+
byte bssid[6];
183+
WiFi.BSSID(bssid);
184+
185+
Serial.print(" BSSID: ");
186+
printMacAddress(bssid);
187+
188+
Serial.print(" RSSI: ");
189+
Serial.print(WiFi.RSSI());
190+
191+
Serial.print(" Encryption: ");
192+
Serial.println(WiFi.encryptionType(), HEX);
193+
}
194+
195+
void printWiFiData() {
196+
Serial.print("IP: ");
197+
Serial.print(WiFi.localIP());
198+
199+
Serial.print(" Gateway: ");
200+
Serial.print(WiFi.gatewayIP());
201+
202+
Serial.print(" Subnet: ");
203+
Serial.print(WiFi.subnetMask());
204+
205+
byte mac[6];
206+
WiFi.macAddress(mac);
207+
208+
Serial.print(" MAC: ");
209+
printMacAddress(mac);
210+
}
211+
212+
void printMacAddress(byte mac[]) {
213+
for (int i = 5; i >= 0; i--) {
214+
if (mac[i] < 16) Serial.print("0");
215+
Serial.print(mac[i], HEX);
216+
if (i > 0) Serial.print(":");
217+
}
218+
Serial.print(" ");
219+
}
220+
221+
/*************************** Setup *************************************/
222+
void setup() {
223+
Serial.begin(115200);
224+
while (!Serial) delay(10);
225+
226+
Serial.println("MQTT AirLift Subscribe + KeepAlive Example");
227+
228+
initWiFi();
229+
230+
mqtt.setKeepAliveInterval(AIRLIFT_KEEPALIVE);
231+
mqtt.subscribe(&time_subscription);
232+
233+
MQTT_connect();
234+
}
235+
236+
/*************************** Main Loop *********************************/
237+
void loop() {
238+
239+
MQTT_ping();
240+
241+
Adafruit_MQTT_Subscribe *subscription =
242+
mqtt.readSubscription(SUBSCRIBE_WAIT_MS);
243+
244+
if (subscription == &time_subscription) {
245+
Serial.print("TIME FEED: ");
246+
Serial.println((char *)time_subscription.lastread);
247+
}
248+
}

library.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
name=Adafruit MQTT Library
2-
version=2.6.1
2+
version=2.6.2
33
author=Adafruit
44
maintainer=Adafruit <[email protected]>
55
sentence=MQTT library that supports the FONA, ESP8266, ESP32, Yun, and generic Arduino Client hardware.
66
paragraph=Simple MQTT library that supports the bare minimum to publish and subscribe to topics.
77
category=Communication
88
url=https://github.com/adafruit/Adafruit_MQTT_Library
99
architectures=*
10-
depends=Adafruit SleepyDog Library, Adafruit FONA Library, WiFi101
10+
depends=Adafruit SleepyDog Library, Adafruit FONA Library, WiFi101, WiFiNINA_-_Adafruit_Fork

0 commit comments

Comments
 (0)