forked from Mjrovai/XIAO_Big_Power_Small_Board-ebook
-
Notifications
You must be signed in to change notification settings - Fork 0
/
chapter_3-5.qmd
643 lines (439 loc) · 41.2 KB
/
chapter_3-5.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
# 3.5 Telemetry and Commands using the MQTT protocol with XIAO ESP32C3 {.unnumbered}
<br />
In the previous section, we learned how to send HTTP GET or POST requests from the XIAO ESP32C3 to a local machine on a local area network via Wi-Fi. In this section, we'll step through: communication protocols, Message Queuing Telemetry Transport (MQTT), telemetry (data gathered from sensors and sent to the cloud), and commands (messages sent from the cloud to a device instructing it to do something).
## 3.5.1 Background Knowledge
### 3.5.1.1 IoT (Internet of Things)
The "I" in IoT stands for Internet---cloud connectivity and services that enable many of the functions of IoT devices, from gathering sensor measurements linked to devices, to sending messages to control actuators. IoT devices typically connect to a single IoT cloud service using standard communication protocols, and this service is tightly integrated with the rest of your IoT application, from AI services making intelligent decisions around data, to web applications for control or reporting.
> 🎓 Data collected from sensors and sent to the cloud is called telemetry.
IoT devices can also receive information from the cloud. This information typically consists of commands---instructions to perform internal actions (such as rebooting or updating firmware) or to actuate (e.g., turning on a light).
### 3.5.1.2 Communication Protocols
There are many popular communication protocols that IoT devices use to communicate with the internet. The most popular are based around the publishing/subscribing of messages through some agent: IoT devices connect to the agent, publish telemetry data and subscribe to commands. Cloud services also connect to the agent, subscribe to all telemetry information, and publish commands to specific devices or groups of devices, as shown in the figure below.
<!-- ![](https://cdn.nlark.com/yuque/0/2023/jpeg/2392200/1685405887281-5e2cd983-ee0b-4964-8fa0-19a212566c9b.jpeg) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_1.jpeg)
MQTT is the most popular communication protocol for IoT devices and will be covered in this section. Other protocols include AMQP and HTTP/HTTPS, which we introduced in the previous section.
### 3.5.1.3 Message Queuing Telemetry Transport (MQTT) <br />
**MQTT** is short for Message Queuing Telemetry Transport. It is a messaging protocol based on the publish/subscribe paradigm under the ISO standard: ISO/IEC PRF 20922. It can be seen as a "bridge for data delivery". It operates on top of the TCP/IP protocol stack and is a publish/subscribe type messaging protocol designed for remote devices with poor hardware performance and poor network conditions. It is a lightweight, open standard messaging transport protocol that can send messages between devices. Originally designed in 1999 for monitoring oil pipelines, it was published as an open standard by IBM 15 years later.
The biggest advantage of MQTT is that it provides a real-time and reliable messaging service for connecting remote devices with minimal code and limited bandwidth. As a low-overhead, low-bandwidth consumption instant communication protocol, it is widely used in IoT, small devices, mobile applications, and so on.
MQTT has one broker and multiple clients. All clients connect to the broker, which then routes messages to the relevant clients. Messages are routed using named topics, not sent directly to a single client. Clients can publish to a topic, and any client subscribed to that topic will receive the message.
<!-- ![image.png](https://cdn.nlark.com/yuque/0/2023/png/2392200/1685406029091-18349e9f-5234-4ece-96b8-a54b33c89e51.png#averageHue=%23dedede&clientId=u93bd6905-9e96-4&from=paste&height=147&id=u2452d2f8&originHeight=367&originWidth=1600&originalType=binary&ratio=2.5&rotation=0&showTitle=false&size=95157&status=done&style=none&taskId=ufa4c6f8c-dd86-4e79-a0b4-601ec923316&title=&width=640) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_2.png)
> ✅ Do some research. If you have a large number of IoT devices, how can you ensure that your MQTT broker can handle all messages?
#### **Some Open Source MQTT Brokers**
While we can set up our own MQTT broker if circumstances allow, you might not be ready to delve into server and application setup yet. If you're just learning, you can start with some open source MQTT brokers.
##### **Eclipse Mosquitto** 🔗 <https://www.mosquitto.org/>
This is an open source MQTT broker. Instead of dealing with the complexities of setting up an MQTT broker as part of this task, this test broker is publicly available at [test.mosquitto.org](https://test.mosquitto.org) and doesn't require account setup. It's a great tool for testing MQTT clients and servers.
<!-- ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2392200/1672296663034-719c868b-07d6-40ef-b93f-a921ab20c39d.png#averageHue=%23e8e8e8&clientId=u11e975e4-de80-4&from=paste&height=1139&id=KctHw&originHeight=2278&originWidth=2822&originalType=binary&ratio=1&rotation=0&showTitle=false&size=691498&status=done&style=stroke&taskId=u7304f2ca-3930-4191-9499-a2fec9b41a4&title=&width=1411) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_3.png)
##### [**shiftr.io**](https://shiftr.io)
An IoT platform for interconnected projects, quickly connect hardware and software with its cloud service and desktop applications. The platform also provides a clear view of all connections, topics, and messages in the network through real-time charts. The [shiftr.io](https://shiftr.io) broker supports MQTT and HTTP for publishing, subscribing, and retrieving messages, and the platform supports free accounts, enough for us to learn and use. They also provide a public server at [public.cloud.shiftr.io](https://public.cloud.shiftr.io) with username `public` on ports 1883 (MQTT) and 8883 (MQTTS). The animated view of connected services and data being exchanged on the public server is very cool, as shown in the image below.
<!-- ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2392200/1672297768227-2b393ad4-5ed5-4124-876e-5a6a410821a1.png#averageHue=%2350a95e&clientId=u11e975e4-de80-4&from=paste&height=956&id=BdfcD&originHeight=1912&originWidth=2758&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1221915&status=done&style=none&taskId=udf5fa428-23ff-469b-b100-65fb6a65596&title=&width=1379) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_4.png)
##### **HiveMQ**
[HiveMQ](https://www.hivemq.com/) is a cloud-based MQTT platform, offering scalable, secure, and reliable IoT communication services. HiveMQ can help enterprises and developers quickly build and manage IoT applications, supporting millions of devices and messages.
<!-- ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2392200/1672299631681-eea9bdd5-00f6-4060-ae3a-0289fd7c946f.png#averageHue=%23dcdcdb&clientId=u52261d13-9bcb-4&from=paste&height=933&id=gy4Pt&originHeight=1866&originWidth=2958&originalType=binary&ratio=1&rotation=0&showTitle=false&size=656631&status=done&style=none&taskId=u0d5a7565-89ff-43c8-bade-c39f1856c73&title=&width=1479) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_5.png)
## 3.5.2 Task 1: Connect the XIAO ESP32C3 to the MQTT Broker
The first step to adding internet control to your smart temperature and humidity meter is to connect the XIAO ESP32C3 to an MQTT broker. <br />
In this part of the section, you'll connect your smart temperature and humidity meter from Section 2.2 to the internet, enabling it to provide telemetry and be remotely controlled. Later in this section, your device will send a telemetry message via MQTT to a public MQTT broker, which will be received by some server code you'll write. This code will check the temperature and humidity values, and send a command message to the device, telling it to turn a buzzer on or off.
<!-- ![](https://cdn.nlark.com/yuque/0/2023/jpeg/2392200/1685406539410-4eeaa463-2bc1-4a31-bc54-699cd635dc82.jpeg) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_6.jpeg)
One real-world use of this setup would be in a large indoor space with many temperature and humidity sensors, such as a farm. Before deciding to turn on air conditioning, data can be gathered from multiple temperature and humidity sensors. If only one sensor reading exceeds the threshold, but other sensor readings are normal, this can prevent the entire air conditioning system from being turned on.
✅ Can you think of other situations where an evaluation of data from multiple sensors is required before issuing a command?
> 💁 Remember, this test broker is public and unsecure, and anyone can listen in on what you're publishing, so it should not be used for any data that needs to be kept confidential.
Follow the related steps below to connect your device to the MQTT broker we introduced earlier: [public.cloud.shiftr.io](https://public.cloud.shiftr.io/).
##### **Add the [arduino-mqtt library](https://github.com/256dpi/arduino-mqtt) **
Before you start programming the XIAO ESP32C3 with the Arduino IDE, you need to add the necessary libraries. Type the library URL 🔗 <https://github.com/256dpi/arduino-mqtt> into your browser's address bar to go to the GitHub page. Click on `Code→Download ZIP` to download the resource pack `arduino-mqtt-master.zip` to your local machine, as shown in the image below.
<!-- ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2392200/1672309298853-fda9fbc3-478f-469d-a27e-4ee45df1c07f.png#averageHue=%23ab997e&clientId=u52261d13-9bcb-4&from=paste&height=933&id=iU4kr&originHeight=1866&originWidth=2528&originalType=binary&ratio=1&rotation=0&showTitle=false&size=581007&status=done&style=stroke&taskId=uc48e4e77-a501-4f68-b00d-5ed87d464f5&title=&width=1264) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_7.png)
From the menu bar, select `Sketch→Include Library→Add .ZIP Library` to add the resource pack `arduino-mqtt-master.zip` you downloaded in the previous step. Continue until you see a message indicating successful library loading.
##### **Run the ESP32 MQTT example **
After the library is loaded successfully, open the "ESP32DevelopmentBoard" example in the Arduino IDE through the following path: `File→Examples→MQTT→ESP32DevelopmentBoard`, as shown in the image below.
<!-- ![L15-企业微信20230530-083807\@2x.png](https://cdn.nlark.com/yuque/0/2023/png/2392200/1685407185576-a93d09c8-4b4a-4efe-b97c-ebae8eb485c8.png#averageHue=%23a8b7a1&clientId=u93bd6905-9e96-4&from=ui&id=ud240e8b3&originHeight=2048&originWidth=2512&originalType=binary&ratio=2.5&rotation=0&showTitle=false&size=919126&status=done&style=stroke&taskId=ud552462a-e744-43df-ab3b-561e98da415&title=) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_8.png)
After the example program is opened, you can see the program as shown below. Then change the `ssid` in the code to your Wi-Fi network name, and change the `pass` in the code to the corresponding Wi-Fi password for your Wi-Fi network.
``` cpp
// This example uses an ESP32 Development Board
// to connect to shiftr.io.
//
// You can check on your device after a successful
// connection here: https://www.shiftr.io/try.
//
// by Joël Gähwiler
// https://github.com/256dpi/arduino-mqtt
#include <WiFi.h>
#include <MQTT.h>
const char ssid[] = "ssid";
const char pass[] = "pass";
WiFiClient net;
MQTTClient client;
unsigned long lastMillis = 0;
void connect() {
Serial.print("checking wifi...");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.print("\nconnecting...");
while (!client.connect("arduino", "public", "public")) {
Serial.print(".");
delay(1000);
}
Serial.println("\nconnected!");
client.subscribe("/hello");
// client.unsubscribe("/hello");
}
void messageReceived(String &topic, String &payload) {
Serial.println("incoming: " + topic + " - " + payload);
// Note: Do not use the client in the callback to publish, subscribe or
// unsubscribe as it may cause deadlocks when other things arrive while
// sending and receiving acknowledgments. Instead, change a global variable,
// or push to a queue and handle it in the loop after calling `client.loop()`.
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, pass);
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported
// by Arduino. You need to set the IP address directly.
client.begin("public.cloud.shiftr.io", net);
client.onMessage(messageReceived);
connect();
}
void loop() {
client.loop();
delay(10); // <- fixes some issues with WiFi stability
if (!client.connected()) {
connect();
}
// publish a message roughly every second.
if (millis() - lastMillis > 1000) {
lastMillis = millis();
client.publish("/hello", "world");
}
}
```
> Get this program from Github <br />
> <https://github.com/mouseart/XIAO-Mastering-Arduino-and-TinyML/tree/main/code/L15_ESP32DevelopmentBoard_XIAO_en>
Run the example and check the serial monitor for: `connected!`. If you see a connected client and flowing messages in the live chart, your XIAO is continuously sending data to this public MQTT broker!
<!-- ![L15-企业微信20230530-085953\@2x.png](https://cdn.nlark.com/yuque/0/2023/png/2392200/1685408670903-a6344b4b-ccc1-421b-b963-d312ce37e2bc.png#averageHue=%23d28d61&clientId=u5f8b12ef-4f69-4&from=ui&id=u60f8e404&originHeight=1490&originWidth=2304&originalType=binary&ratio=2.5&rotation=0&showTitle=false&size=396005&status=done&style=stroke&taskId=u1dd0693d-99ca-445e-a118-5ebc582abcf&title=) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_9.png)
You can see the messages you sent by accessing [public.cloud.shiftr.io](https://public.cloud.shiftr.io/) in your browser. However, because this is a public broker, your device will quickly get lost in the crowd.
<!-- ![L15-企业微信20230530-090730\@2x.png](https://cdn.nlark.com/yuque/0/2023/png/2392200/1685409058799-2501914c-8e09-499a-bd0a-eccbd38f6ca2.png#averageHue=%2350a95e&clientId=u5f8b12ef-4f69-4&from=ui&id=u4ebf8fb0&originHeight=2158&originWidth=3456&originalType=binary&ratio=2.5&rotation=0&showTitle=false&size=1139377&status=done&style=stroke&taskId=u2367aeb5-9b06-4ea7-b13c-7cbc4e027ce&title=) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_10.png)
> 💁 Keep in mind, this test broker is public and insecure. Anyone can listen to what you're publishing, so it should not be used for anything requiring confidentiality.
## 3.5.3 Deep Dive into MQTT
Topics can have a hierarchy, and clients can use wildcards to subscribe to different levels of different hierarchies. For example: you can send temperature telemetry to the `/telemetry/temperature` topic, humidity data to the `/telemetry/humidity` topic, and then subscribe to the `/telemetry/*` topic in your cloud application to receive both temperature and humidity telemetry. When messages are sent, a Quality of Service (QoS) can be specified which determines the guarantee of message delivery.
- At most once: The message is sent only once, and no additional steps are taken by the client and the broker to confirm delivery (Fire and Forget).
- At least once: The message is retried by the sender until it receives an acknowledgment (Acknowledged delivery).
- Exactly once: A two-level handshake is performed by the sender and receiver to ensure that only one copy of the message is received (Assured delivery).
> ✅ In what scenarios might you need to deliver messages on a Fire and Forget basis?
<br />
Although MQTT (Message Queuing Telemetry Transport) has "Message Queuing" in its name (the first two letters of MQTT), it does not actually support message queues. This means that if a client disconnects and then reconnects, it will not receive messages that were sent while it was disconnected, except for those messages that it had already begun processing using the QoS process. A retain flag can be set on a message. If this flag is set, the MQTT broker will store the last message sent on a topic with this flag, and will send it to any clients who subsequently subscribe to that topic. This way, clients always receive the latest message. <br />
MQTT also supports a keep-alive feature to check if the connection is still online during long intervals between messages.<br />
MQTT connections can be public, or encrypted and protected using usernames, passwords, or certificates.
> 💁 MQTT communicates over TCP/IP, the same underlying network protocol as HTTP, but on a different port. You can also communicate with web applications running in a browser over MQTT on websockets, or in situations where firewalls or other network rules block standard MQTT connections.
## 3.5.4 Telemetry
The word "telemetry" comes from Greek roots meaning "remote measurement". Telemetry refers to the act of collecting data from sensors and sending it to the cloud.
> 💁 One of the earliest telemetry devices was invented in France in 1874, sending real-time weather and snow depth data from Mont Blanc to Paris. As there was no wireless technology at the time, it used a physical wire.
Let's go back to the smart thermostat example from Section 1.1.
<!-- ![Smart Thermostat System Architecture](https://cdn.nlark.com/yuque/0/2022/png/2787433/1646104047138-1f6619a2-42c3-4965-aade-fce5fc3c7404.png#averageHue=%23f4f4f4&clientId=u80ed014f-9032-4&from=ui&id=vWoAE&originHeight=334&originWidth=640&originalType=binary&ratio=1&rotation=0&showTitle=true&size=31278&status=done&style=none&taskId=ud0319ffa-679d-44aa-94e0-4ce3b95d52b&title=Smart%20Thermostat%20System%20Architecture "Smart Thermostat System Architecture") -->
<div style="text-align:center;"><img src="https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_11.png" width="400" height="auto" style="margin:0 auto" /><br /><sub>Smart Thermostat System Architecture</sub></div>
The thermostat has temperature sensors to collect telemetry data. It likely has a built-in temperature sensor and may connect to multiple external temperature sensors via wireless protocols such as Low Energy Bluetooth (BLE).
An example of the telemetry data it sends could be:
| Name | Value | Description |
|------------------------|-----------|---------------------------------|
| AC_Temperature | 18°C | The temperature measured by the thermostat's built-in temperature sensor |
| Living_Room_Temperature | 19°C | The temperature measured by a remote temperature sensor named `livingroom` , indicating the room it is in |
| Bedroom_Temperature | 21°C | The temperature measured by a remote temperature sensor named `bedroom` , indicating the room it is in |
Then, the cloud service can use this telemetry data to decide what commands to send to control cooling or heating.
## 3.5.5 Task 2: Sending Telemetry Information from XIAO to MQTT Broker
The next part of adding internet control to your smart hygrothermograph is sending the temperature and humidity telemetry data to the telemetry topic of the MQTT broker. Replace the XIAO of your smart hygrothermograph device from Section 2.2 with the XIAO ESP32C3, as shown in the image below.
<!-- ![](https://cdn.nlark.com/yuque/0/2023/jpeg/2392200/1677402407719-37a5401e-aa7e-4a0c-87c1-005ad51e82e2.jpeg) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_12.jpeg)
Load the following program into the Arduino IDE to test sending telemetry data from your device to the MQTT broker. Note that in this example, we're trying a different MQTT broker than in Task 1: `broker.hivemq.com`, and we've set `XIAO_ESP32C3_Telemetry/` as the subscription name.
``` cpp
////////////////////////////////////////////////////////////////////////////////
// IDE:
// Arduino 2.0.0
// Platform:
// esp32 2.0.5 - https://github.com/espressif/arduino-esp32
// Board:
// XIAO_ESP32C3
// Libraries:
// MQTT 2.5.0 - https://github.com/knolleary/pubsubclient
// ArduinoJson 6.19.4 - https://github.com/bblanchon/ArduinoJson
////////////////////////////////////////////////////////////////////////////////
// Includes
#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include "DHT.h"
#define DHTTYPE DHT20
DHT dht(DHTTYPE);
const char* ssid = "ssid";
const char* password = "pass";
const char* mqtt_server = "broker.hivemq.com";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
float temperature = 0;
float humidity = 0;
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
Wire.begin();
dht.begin();
}
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("XIAO_ESP32")) {
Serial.println("connected");
// Subscribe
client.subscribe("XIAO_ESP32/LEDOUTPUT");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
float temp_hum_val[2] = {0};
if (now - lastMsg > 5000) {
lastMsg = now;
dht.readTempAndHumidity(temp_hum_val);
temperature = temp_hum_val[1];
char tempString[8];
dtostrf(temperature, 1, 2, tempString);
Serial.print("Temperature: ");
Serial.println(tempString);
client.publish("XIAO_ESP32C3_Telemetry/Temperaturedataread", tempString);
humidity = temp_hum_val[0];
char humString[8];
dtostrf(humidity, 1, 2, humString);
Serial.print("Humidity: ");
Serial.println(humString);
client.publish("XIAO_ESP32_Telemetry/Humiditydataread", humString);
}
}
```
> Get this program from Github <br />
> <https://github.com/mouseart/XIAO-Mastering-Arduino-and-TinyML/tree/main/code/L15_MQTTTelemetry_XIAO_en>
Because this example relies on the `PubSubClient.h` library, if you try to compile it directly, you will encounter the error "**PubSubClient.h: No such file or directory**". To resolve this issue, follow the steps below to install the library.
1. Open the Arduino IDE.
2. Go to "Sketch" -> "Include Library" -> "Manage Libraries".
3. In the Library Manager, type "PubSubClient" in the search bar.
4. Look for the "PubSubClient" library by Nick O'Leary and click on it.
5. Click the "Install" button to install the library.
Then modify the `ssid` in the code to your Wi-Fi network name and `pass` to your Wi-Fi password corresponding to your Wi-Fi network name. <br />
After successfully uploading the program, open the serial monitor. If all goes well, you will see the device start sending temperature and humidity data, as shown in the image below.
<!-- ![L15-企业微信20230530-112625\@2x.png](https://cdn.nlark.com/yuque/0/2023/png/2392200/1685417355488-b027a157-0ee4-4c82-ba6d-4d9f978b1036.png#averageHue=%23dd8f60&clientId=u5fccfc03-db3e-4&from=ui&id=u4f02e101&originHeight=1490&originWidth=2792&originalType=binary&ratio=2.5&rotation=0&showTitle=false&size=401970&status=done&style=stroke&taskId=u52a93cca-2497-4cfb-9a77-8ff794d358c&title=) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_13.png)
How can you see the sensor data from another platform? There are many ways, such as [MQTT X](https://mqttx.app/). After downloading and installing the software suitable for your PC system, the interface is as shown in the image below.
<!-- ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2392200/1672371305711-93cbeda7-b1c2-49c0-9314-f6a73f26b959.png#averageHue=%23798c8b&clientId=uebdc8a20-1ffe-4&from=paste&height=800&id=QuSNg&originHeight=1600&originWidth=2560&originalType=binary&ratio=1&rotation=0&showTitle=false&size=380552&status=done&style=stroke&taskId=u85374eb5-a21b-409a-90d5-5ee36e20530&title=&width=1280) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_14.png)
Clicking the `+ New Connection` button will bring you to the connection creation window, as shown in the image below. Fill in `XIAO-DHT20` in the Name box as the connection name. The Host is `broker.hivemq.com` that we set in the program, no other settings are needed, click `Connect` in the upper right corner.
<!-- ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2392200/1672371484572-26df05b7-34e5-4b52-b735-531d26fcc3b2.png#averageHue=%23e3b34d&clientId=uebdc8a20-1ffe-4&from=paste&height=800&id=kRuig&originHeight=1600&originWidth=2560&originalType=binary&ratio=1&rotation=0&showTitle=false&size=369940&status=done&style=stroke&taskId=u89ceb3c2-8375-4f62-ae88-5b191a3607d&title=&width=1280) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_15.png)
Create a new subscription, showing all the information under `XIAO_ESP32C3_Telemetry/`, as shown in the image below.
<!-- ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2392200/1672380401266-438f29b0-e7ef-4032-aeee-92d975550d8d.png#averageHue=%2380807e&clientId=uebdc8a20-1ffe-4&from=paste&height=650&id=sYAEV&originHeight=1300&originWidth=2560&originalType=binary&ratio=1&rotation=0&showTitle=false&size=282606&status=done&style=stroke&taskId=u201ad92f-2a4a-4cbe-82b2-495238a8647&title=&width=1280) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_16.png)
Now, we can see the telemetry data sent from XIAO ESP32C3, as shown in the image below.
<!-- ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2392200/1672380324197-f6cbf58a-f0f7-4feb-8930-cacd685fbf05.png#averageHue=%23fefefd&clientId=uebdc8a20-1ffe-4&from=paste&height=650&id=wvL6N&originHeight=1300&originWidth=2560&originalType=binary&ratio=1&rotation=0&showTitle=false&size=342487&status=done&style=stroke&taskId=ud4c14b99-26ae-4063-8aad-a19af73b6d3&title=&width=1280) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_17.png)
### How often should telemetry be sent?
One question that needs careful consideration with telemetry is: how often should you measure and send data? The answer is --- it depends on the needs of the device being monitored and the task at hand. If you measure frequently, you can indeed respond to changes in the measurements more quickly, but this would cause your device to consume more power, more bandwidth, generate more data, and require more cloud resources to handle. You need to strike a balance between measuring often enough but not too often.
For a thermostat, measuring every few minutes might be enough because the temperature isn't likely to change frequently. If you only measure once a day, then you might be heating your house for nighttime temperatures on a sunny day, and if you measure every second, you'd have thousands of unnecessary repeated temperature measurements which will eat up users' internet speed and bandwidth (which is a problem for people with limited bandwidth plans), and also consume more power, which is a problem for devices like remote sensors that rely on battery power, and further increase the cost of cloud computing resources to process and store them.
If you're monitoring data around a machine in a factory that might cause catastrophic damage and millions in lost revenue if it fails, then measuring multiple times a second may be necessary. Wasting bandwidth is better than missing telemetry data that could signal the need to stop and repair before a machine fails.
> 💁 In this situation, you could consider first using an edge device to handle the telemetry data to reduce dependence on the internet.
### Losing connection
Internet connections can be unreliable, and it's common to lose signal. In this case, what should an IoT device do? Should it lose data, or should it store data until the connection is restored? Again, the answer is --- it depends on the device being monitored.
For a thermostat, data is likely lost once a new temperature measurement has been made. If the current temperature is 19°C, the heating system doesn't care that the temperature 20 minutes ago was 20.5°C; it's the current temperature that dictates whether the heat should be turned on or off.
For some machines, you may want to retain this data, especially if it's being used to look for trends. Some machine learning models can identify anomalies in data streams by looking at a defined time period (e.g., the last hour). This is often used for predictive maintenance, looking for signs that something might be about to fail so you can repair or replace it before disaster strikes. You may want every point of telemetry from a machine sent so it can be used for anomaly detection, so once an IoT device can reconnect, it will send all the telemetry data generated during the internet outage.
IoT device designers should also consider whether an IoT device can operate during an internet outage or if it loses signal due to location. If a smart thermostat is unable to send telemetry data to the cloud due to an internet outage, it should be able to make some limited decisions to control heating.
<!-- > ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2392200/1651566081348-bf19f1fe-a068-4523-9f69-cd85215977fd.png#averageHue=%2390938e&clientId=u52c988bc-8533-4&from=paste&height=861&id=umgQ5&originHeight=1722&originWidth=1080&originalType=binary&ratio=1&rotation=0&showTitle=false&size=3142169&status=done&style=none&taskId=u189a65bd-34a0-47b8-9fe0-c313e189ed3&title=&width=540) <br /> -->
> ![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_18.png) <br />
>This Ferrari became a brick when someone tried to update it in an underground car park... but there was no cell signal there.
For MQTT handling connection interruptions, if necessary, the device and server code will need to be responsible for ensuring message delivery, for example, requiring all sent messages to be replied to by an additional message on the reply topic, and if not, to manually queue them for later resending.
## 3.5.6 Commands
Commands are messages sent by the cloud to a device instructing it to do something. Most often, this involves providing some output via an actuator, but it could be an instruction to the device itself, such as to reboot, or to collect additional telemetry data and send it as a response to the command.
<!-- ![commands.png](https://cdn.nlark.com/yuque/0/2022/png/2787433/1646113961729-48acb652-3ee9-4b08-b101-0fb1dcec0cda.png#averageHue=%23f5f5f5&clientId=ua938bc53-e5a4-4&from=ui&id=i9mV2&originHeight=334&originWidth=640&originalType=binary&ratio=1&rotation=0&showTitle=false&size=31685&status=done&style=none&taskId=uecd0aa71-7b07-4187-ac57-0be39a688cf&title=) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_19.png) <br />
A thermostat could receive a command from the cloud to turn on the heat. Based on the telemetry data from all sensors, if the cloud service has decided that the heat should be turned on, then it sends the appropriate command.
## 3.5.7 Task 3: Send Commands to XIAO via MQTT Broker
Having mastered telemetry, the next step is to send commands to IoT devices via an MQTT broker. In this task, we will try to use a computer with MQTT broker, often called a host computer, to send specific characters and let the Wi-Fi connected XIAO ESP32C3 control a buzzer attached to an expansion board to emit a warning sound.
In the Arduino IDE, load the following program to test sending specific characters (first character is '0') from the MQTT broker to activate the buzzer. We use the MQTT broker: `broker.hivemq.com` in this example.
``` cpp
////////////////////////////////////////////////////////////////////////////////
// IDE:
// Arduino 2.0.0
// Platform:
// esp32 2.0.5 - https://github.com/espressif/arduino-esp32
// Board:
// XIAO_ESP32C3
// Libraries:
// MQTT 2.5.0 - https://github.com/knolleary/pubsubclient
// ArduinoJson 6.19.4 - https://github.com/bblanchon/ArduinoJson
// https://github.com/Seeed-Studio/Seeed_Arduino_MultiGas
////////////////////////////////////////////////////////////////////////////////
// Includes
#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
const char* ssid = "ssid";
const char* password = "pass";
const char* mqtt_server = "broker.hivemq.com";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
int speakerPin = A3;
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
Serial.print((char)payload[i]);
}
if((char)payload[0]=='0'){
Serial.print(" RUN");
digitalWrite(speakerPin, HIGH);
delay(2000);
digitalWrite(speakerPin, LOW);
delay(100);
}
Serial.println();
}
void setup() {
Serial.begin(115200);
pinMode(speakerPin, OUTPUT);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.subscribe("XIAO_ESP32/Recieve");
client.setCallback(callback);
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("XIAO_ESP32")) {
Serial.println("connected");
// Subscribe
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
client.subscribe("XIAO_ESP32/Recieve");
}
client.loop();
}
```
> Get this program from Github <br />
> <https://github.com/mouseart/XIAO-Mastering-Arduino-and-TinyML/tree/main/code/L15_MQTTCommand_XIAO_en>
Then modify the `ssid` in the code to your Wi-Fi network name, and modify the `pass` in the code to the Wi-Fi password corresponding to your Wi-Fi network name. <br />
The logic of the program execution is explained as follows:
``` cpp
client.setServer(mqtt_server, 1883);
client.subscribe("XIAO_ESP32/Recieve");
client.setCallback(callback);
```
During the `setup` stage, the connection between XIAO and the MQTT server is initialized, and the topic subscription settings and callback functions are set. Here we subscribe to the topic `XIAO_ESP32/Recieve` as an example. When we send a message to this topic from the host computer, the corresponding callback function `callback` will be executed:
``` cpp
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
Serial.print((char)payload[i]);
}
if((char)payload[0]=='0'){
Serial.print(" RUN");
digitalWrite(speakerPin, HIGH);
delay(2000);
digitalWrite(speakerPin, LOW);
delay(100);
}
Serial.println();
}
```
Here it will first print out the received message, then extract the character at position `0`. When the character at position `0`, which is the first character, is`0`, it satisfies the condition for the `if` statement to perform an action. Here we connect the XIAO ESP32C3 and the expansion board together. When the condition is met, the buzzer on the expansion board will change its level briefly and beep for 2 seconds, while sending the prompt message`RUN` to the serial port.
In the process of development and testing by readers, you can also try to integrate the receive and send functions of MQTT, and send messages to specific topics in the callback function, so that the sender can ensure that XIAO has received the message.
On the host computer, we use [MQTT X](https://mqttx.app/) to test. Open MQTT X, the interface is as shown in the following figure.
<!-- ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2392200/1672371305711-93cbeda7-b1c2-49c0-9314-f6a73f26b959.png#averageHue=%23798c8b&clientId=uebdc8a20-1ffe-4&from=paste&height=800&id=M8muz&originHeight=1600&originWidth=2560&originalType=binary&ratio=1&rotation=0&showTitle=false&size=380552&status=done&style=stroke&taskId=u85374eb5-a21b-409a-90d5-5ee36e20530&title=&width=1280) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_20.png)
Click the `+ New Connection` button to enter the connection creation window, as shown in the following figure. Fill in the Name box with `XIAO-MQTT-Recieve` as the connection name. Host is the `broker.hivemq.com` we set in the program, and nothing else needs to be set. Click `Connect` at the top right corner. The interface after successful connection is as shown in the following figure.
<!-- ![image.png](https://cdn.nlark.com/yuque/0/2023/png/2392200/1673920699143-0fcdafd5-11ba-4e4c-af07-3c660ff2061e.png#averageHue=%2392d2ad&clientId=u00a9c4a9-6772-4&from=paste&height=800&id=uYxZC&originHeight=1600&originWidth=2560&originalType=binary&ratio=1&rotation=0&showTitle=false&size=320824&status=done&style=stroke&taskId=uf03388f0-d5c9-48ea-876b-9a79cdf8628&title=&width=1280) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_21.png)
Now we can publish messages to the specified topic, which is the topic `XIAO_ESP32/Recieve` we subscribed to on XIAO. Then we enter `00` in the input box of `XIAO_ESP32/Recieve` at the lower right corner of the interface, and then click the send button <img src="https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_22.png" alt="send-button.png" width="30" height="30" /> in the lower right corner.
<!-- ![image.png](https://cdn.nlark.com/yuque/0/2023/png/2392200/1673922637488-6615c8cf-7f3d-409f-bd2a-96f99e6f5ca2.png#averageHue=%23fefefd&clientId=u00a9c4a9-6772-4&from=paste&height=800&id=SALZf&originHeight=1600&originWidth=2560&originalType=binary&ratio=1&rotation=0&showTitle=false&size=379697&status=done&style=stroke&taskId=ub7e7a922-e73e-4fa8-ad07-e160c523179&title=&width=1280) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_23.png)
At this time, in the serial monitor on the PC side, you can see the prompt message received from XIAO, as shown in the following figure, and prompt `RUN`, the buzzer will sound for 2 seconds, indicating that the message has been received.
<!-- ![L15-企业微信20230530-163118\@2x.png](https://cdn.nlark.com/yuque/0/2023/png/2392200/1685435499239-7a3abaf1-aa62-4484-8ff7-1074fd0f487d.png#averageHue=%23d38c61&clientId=u8b044297-98e8-4&from=ui&id=u6ebfb210&originHeight=1490&originWidth=2304&originalType=binary&ratio=2.5&rotation=0&showTitle=false&size=355861&status=done&style=stroke&taskId=u3a91a7a8-65d4-4ab7-bb94-9be485e4ded&title=) -->
![](https://files.seeedstudio.com/wiki/XIAO_Big_Power-Board-ebook-photo/chapter_3-5/chapter_3-5_24.png)
Now, we have successfully driven the buzzer on the expansion board connected to the Wi-Fi connected XIAO ESP32C3 through the instruction sent by the PC side. <br />
The action of the buzzer can be replaced with the control of any peripheral to achieve the desired function.
### Lost connection
If a cloud service needs to send a command to an offline IoT device, what should it do? Again, the answer depends on the situation. If the latest command overwrites the previous one, the previous command may be ignored. If the cloud service sends a command to turn on the heating, and then sends another command to turn off the heating, then the turn-on command can be ignored and does not need to be resent. <br />
If the commands need to be processed in order, such as first moving the robot arm up and then closing the gripper, then they need to be sent in order once the connection is restored.
> ✅ How can device or server code ensure that commands are always sent and processed in order through MQTT if needed?
> ### Using XIAO's Bluetooth function
>
> XIAO nRF52840, XIAO nRF52840 Sense, XIAO ESP32C3 all support Bluetooth function, you can refer to the related Wiki documents to learn how to use the Bluetooth function.
>
> - [Bluetooth Usage on Seeed Studio XIAO ESP32C3](https://wiki.seeedstudio.com/XIAO_ESP32C3_Bluetooth_Usage/)
> - [Bluetooth Usage (Seeed nRF52 Boards Library)](https://wiki.seeedstudio.com/XIAO-BLE-Sense-Bluetooth_Usage/)
> - [Bluetooth Usage (Seeed nrf52 mbed-enabled Boards Library)](https://wiki.seeedstudio.com/XIAO-BLE-Sense-Bluetooth-Usage/)