Skip to content
This repository was archived by the owner on Feb 4, 2023. It is now read-only.

Commit ae256ca

Browse files
authored
Add AsyncWebServer_MQTT_RP2040W example
To demo how to use AsyncWebServer and AsyncMQTT_Generic together
1 parent e9bfe03 commit ae256ca

File tree

1 file changed

+340
-0
lines changed

1 file changed

+340
-0
lines changed
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
/****************************************************************************************************************************
2+
Async_AdvancedWebServer_MQTT_RP2040W.ino
3+
4+
AsyncMqttClient_Generic is a library for ESP32, ESP8266, Protenta_H7, STM32F7, etc. with current AsyncTCP support
5+
6+
Based on and modified from :
7+
8+
1) async-mqtt-client (https://github.com/marvinroger/async-mqtt-client)
9+
10+
Built by Khoi Hoang https://github.com/khoih-prog/AsyncMqttClient_Generic
11+
*****************************************************************************************************************************/
12+
13+
#if !( defined(ARDUINO_RASPBERRY_PI_PICO_W) )
14+
#error For RASPBERRY_PI_PICO_W only
15+
#endif
16+
17+
// Debug Level from 0 to 4
18+
#define _ASYNCTCP_RP2040W_LOGLEVEL_ 1
19+
#define _ASYNC_MQTT_LOGLEVEL_ 1
20+
21+
#if (_ASYNC_MQTT_LOGLEVEL_ > 3)
22+
#warning Using RASPBERRY_PI_PICO_W with CYC43439 WiFi
23+
#endif
24+
25+
#include <WiFi.h>
26+
27+
#include <Ticker.h>
28+
29+
// Check connection every 1s
30+
#define MQTT_CHECK_INTERVAL_MS 1000
31+
32+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
33+
#include <AsyncMqtt_Generic.h>
34+
35+
#include <AsyncWebServer_RP2040W.h>
36+
37+
#include <Ticker.h> // https://github.com/sstaub/Ticker
38+
39+
#define WIFI_SSID "your_SSID"
40+
#define WIFI_PASSWORD "your_PASSWORD"
41+
42+
AsyncWebServer server(80);
43+
AsyncMqttClient mqttClient;
44+
45+
#define MQTT_HOST "broker.emqx.io" // Broker address
46+
#define MQTT_PORT 1883
47+
48+
const char *PubTopic = "async-mqtt/RP2040W_Pub"; // Topic to publish
49+
50+
int status = WL_IDLE_STATUS;
51+
52+
void connectToMqtt();
53+
void connectToMqttLoop();
54+
55+
// Repeat forever, millis() resolution
56+
Ticker connectToMqttTicker(connectToMqttLoop, MQTT_CHECK_INTERVAL_MS, 0, MILLIS);
57+
58+
bool connectedWiFi = false;
59+
bool connectedMQTT = false;
60+
61+
void printWifiStatus()
62+
{
63+
// print the SSID of the network you're attached to:
64+
Serial.print("Connected to SSID: ");
65+
Serial.println(WiFi.SSID());
66+
67+
// print your board's IP address:
68+
IPAddress ip = WiFi.localIP();
69+
Serial.print("Local IP Address: ");
70+
Serial.println(ip);
71+
72+
// print the received signal strength:
73+
long rssi = WiFi.RSSI();
74+
Serial.print("Signal strength (RSSI):");
75+
Serial.print(rssi);
76+
Serial.println(" dBm");
77+
}
78+
79+
bool connectToWifi()
80+
{
81+
// check for the WiFi module:
82+
if (WiFi.status() == WL_NO_MODULE)
83+
{
84+
Serial.println("Communication with WiFi module failed!");
85+
86+
// don't continue
87+
while (true);
88+
}
89+
90+
Serial.print(F("Connecting to SSID: "));
91+
Serial.println(WIFI_SSID);
92+
93+
#define MAX_NUM_WIFI_CONNECT_TRIES_PER_LOOP 20
94+
95+
uint8_t numWiFiConnectTries = 0;
96+
97+
// attempt to connect to WiFi network
98+
while ( (status != WL_CONNECTED) && (numWiFiConnectTries++ < MAX_NUM_WIFI_CONNECT_TRIES_PER_LOOP) )
99+
{
100+
status = WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
101+
102+
delay(500);
103+
}
104+
105+
if (status != WL_CONNECTED)
106+
{
107+
// Restart for Portenta as something is very wrong
108+
Serial.println("Resetting. Can't connect to any WiFi");
109+
110+
NVIC_SystemReset();
111+
}
112+
113+
printWifiStatus();
114+
115+
connectedWiFi = (status == WL_CONNECTED);
116+
117+
return (status == WL_CONNECTED);
118+
}
119+
120+
bool isWiFiConnected()
121+
{
122+
// You can change longer or shorter depending on your network response
123+
// Shorter => more responsive, but more ping traffic
124+
static uint8_t theTTL = 10;
125+
126+
// Use ping() to test TCP connections
127+
if (WiFi.ping(WiFi.gatewayIP(), theTTL) == theTTL)
128+
{
129+
return true;
130+
}
131+
132+
return false;
133+
}
134+
135+
void connectToMqttLoop()
136+
{
137+
//if ( (WiFi.status() == WL_CONNECTED) && (WiFi.RSSI() != 0) ) // temporary workaround
138+
if (isWiFiConnected())
139+
{
140+
if (!connectedMQTT)
141+
{
142+
mqttClient.connect();
143+
}
144+
145+
if (!connectedWiFi)
146+
{
147+
Serial.println("WiFi reconnected");
148+
connectedWiFi = true;
149+
}
150+
}
151+
else
152+
{
153+
if (connectedWiFi)
154+
{
155+
Serial.println("WiFi disconnected. Reconnecting");
156+
connectedWiFi = false;
157+
158+
connectToWifi();
159+
}
160+
}
161+
}
162+
163+
void connectToMqtt()
164+
{
165+
Serial.println("Connecting to MQTT...");
166+
mqttClient.connect();
167+
}
168+
169+
void printSeparationLine()
170+
{
171+
Serial.println("************************************************");
172+
}
173+
174+
void onMqttConnect(bool sessionPresent)
175+
{
176+
Serial.print("Connected to MQTT broker: ");
177+
Serial.print(MQTT_HOST);
178+
Serial.print(", port: ");
179+
Serial.println(MQTT_PORT);
180+
Serial.print("PubTopic: ");
181+
Serial.println(PubTopic);
182+
183+
connectedMQTT = true;
184+
185+
printSeparationLine();
186+
Serial.print("Session present: ");
187+
Serial.println(sessionPresent);
188+
189+
uint16_t packetIdSub = mqttClient.subscribe(PubTopic, 2);
190+
Serial.print("Subscribing at QoS 2, packetId: ");
191+
Serial.println(packetIdSub);
192+
193+
mqttClient.publish(PubTopic, 0, true, "RP2040W Test1");
194+
Serial.println("Publishing at QoS 0");
195+
196+
uint16_t packetIdPub1 = mqttClient.publish(PubTopic, 1, true, "RP2040W Test2");
197+
Serial.print("Publishing at QoS 1, packetId: ");
198+
Serial.println(packetIdPub1);
199+
200+
uint16_t packetIdPub2 = mqttClient.publish(PubTopic, 2, true, "RP2040W Test3");
201+
Serial.print("Publishing at QoS 2, packetId: ");
202+
Serial.println(packetIdPub2);
203+
204+
printSeparationLine();
205+
}
206+
207+
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason)
208+
{
209+
(void) reason;
210+
211+
connectedMQTT = false;
212+
213+
Serial.println("Disconnected from MQTT.");
214+
}
215+
216+
void onMqttSubscribe(const uint16_t& packetId, const uint8_t& qos)
217+
{
218+
Serial.println("Subscribe acknowledged.");
219+
Serial.print(" packetId: ");
220+
Serial.println(packetId);
221+
Serial.print(" qos: ");
222+
Serial.println(qos);
223+
}
224+
225+
void onMqttUnsubscribe(const uint16_t& packetId)
226+
{
227+
Serial.println("Unsubscribe acknowledged.");
228+
Serial.print(" packetId: ");
229+
Serial.println(packetId);
230+
}
231+
232+
void onMqttMessage(char* topic, char* payload, const AsyncMqttClientMessageProperties& properties,
233+
const size_t& len, const size_t& index, const size_t& total)
234+
{
235+
char message[len + 1];
236+
237+
memcpy(message, payload, len);
238+
message[len] = 0;
239+
240+
Serial.println("Publish received.");
241+
Serial.print(" topic: ");
242+
Serial.println(topic);
243+
Serial.print(" message: ");
244+
Serial.println(message);
245+
Serial.print(" qos: ");
246+
Serial.println(properties.qos);
247+
Serial.print(" dup: ");
248+
Serial.println(properties.dup);
249+
Serial.print(" retain: ");
250+
Serial.println(properties.retain);
251+
Serial.print(" len: ");
252+
Serial.println(len);
253+
Serial.print(" index: ");
254+
Serial.println(index);
255+
Serial.print(" total: ");
256+
Serial.println(total);
257+
}
258+
259+
void onMqttPublish(const uint16_t& packetId)
260+
{
261+
Serial.println("Publish acknowledged.");
262+
Serial.print(" packetId: ");
263+
Serial.println(packetId);
264+
}
265+
266+
void setup()
267+
{
268+
Serial.begin(115200);
269+
270+
while (!Serial && millis() < 5000);
271+
272+
delay(200);
273+
274+
Serial.print("\nStart Async_AdvancedWebServer_MQTT_RP2040W on ");
275+
Serial.println(BOARD_NAME);
276+
Serial.println(ASYNC_MQTT_GENERIC_VERSION);
277+
278+
///////////////////////////////////
279+
280+
connectToWifi();
281+
282+
///////////////////////////////////
283+
284+
mqttClient.onConnect(onMqttConnect);
285+
mqttClient.onDisconnect(onMqttDisconnect);
286+
mqttClient.onSubscribe(onMqttSubscribe);
287+
mqttClient.onUnsubscribe(onMqttUnsubscribe);
288+
mqttClient.onMessage(onMqttMessage);
289+
mqttClient.onPublish(onMqttPublish);
290+
291+
mqttClient.setServer(MQTT_HOST, MQTT_PORT);
292+
293+
connectToMqttTicker.start(); //start the ticker.
294+
295+
connectToMqtt();
296+
297+
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request)
298+
{
299+
request->send(200, "text/plain", "Hello from RP2040W!");
300+
});
301+
302+
server.begin();
303+
}
304+
305+
void heartBeatPrint()
306+
{
307+
static int num = 1;
308+
309+
Serial.print(F("H"));
310+
311+
if (num == 80)
312+
{
313+
Serial.println();
314+
num = 1;
315+
}
316+
else if (num++ % 10 == 0)
317+
{
318+
Serial.print(F(" "));
319+
}
320+
}
321+
322+
void check_status()
323+
{
324+
static unsigned long checkstatus_timeout = 0;
325+
326+
#define STATUS_CHECK_INTERVAL 10000L
327+
328+
// Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change.
329+
if ((millis() > checkstatus_timeout) /*|| (checkstatus_timeout == 0)*/)
330+
{
331+
heartBeatPrint();
332+
checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL;
333+
}
334+
}
335+
336+
void loop()
337+
{
338+
connectToMqttTicker.update(); //update the ticker.
339+
check_status();
340+
}

0 commit comments

Comments
 (0)