@alteriom/painlessmesh 1.9.19 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +168 -0
  2. package/README.md +102 -63
  3. package/RELEASE_GUIDE.md +147 -8
  4. package/examples/alteriom/README.md +4 -4
  5. package/examples/alteriom/alteriom_custom_package_template.hpp +320 -0
  6. package/examples/alteriom/alteriom_sensor_package.hpp +1 -1
  7. package/examples/alteriom/mppt_example/alteriom_mppt_example.ino +208 -0
  8. package/examples/bridge_failover/bridge_failover.ino +17 -0
  9. package/examples/sendToInternet/CMakeLists.txt +54 -0
  10. package/examples/sendToInternet/PC_NODE_README.md +517 -0
  11. package/examples/sendToInternet/README.md +39 -1
  12. package/examples/sendToInternet/build.sh +153 -0
  13. package/examples/sendToInternet/mock_server_test.ino +361 -0
  14. package/examples/sendToInternet/pc_mesh_node.cpp +361 -0
  15. package/examples/tcpRetryConfig/README.md +110 -0
  16. package/examples/tcpRetryConfig/platformio.ini +26 -0
  17. package/examples/tcpRetryConfig/tcpRetryConfig.ino +154 -0
  18. package/keywords.txt +3 -0
  19. package/library.json +4 -1
  20. package/library.properties +1 -1
  21. package/package.json +3 -3
  22. package/src/AlteriomPainlessMesh.h +6 -14
  23. package/src/arduino/wifi.hpp +352 -114
  24. package/src/connection.cpp +10 -0
  25. package/src/painlessMesh.h +2 -15
  26. package/src/painlessTaskOptions.h +9 -0
  27. package/src/painlessmesh/buffer.hpp +4 -1
  28. package/src/painlessmesh/configuration.hpp +13 -2
  29. package/src/painlessmesh/connection.hpp +36 -21
  30. package/src/painlessmesh/gateway.hpp +0 -1061
  31. package/src/painlessmesh/mesh.hpp +102 -107
  32. package/src/painlessmesh/message_queue.hpp +25 -15
  33. package/src/painlessmesh/metrics.hpp +2 -262
  34. package/src/painlessmesh/plugin.hpp +27 -5
  35. package/src/painlessmesh/tcp.hpp +158 -29
  36. package/src/painlessmesh/validation.hpp +0 -143
  37. package/docs/README.md +0 -132
  38. package/docs/alteriom/overview.md +0 -531
  39. package/docs/api/core-api.md +0 -607
  40. package/docs/api/shared-gateway.md +0 -1207
  41. package/docs/architecture/mesh-architecture.md +0 -399
  42. package/docs/architecture/plugin-system.md +0 -517
  43. package/docs/getting-started/arduino-manual-install.md +0 -313
  44. package/docs/getting-started/first-mesh.md +0 -410
  45. package/docs/getting-started/installation.md +0 -275
  46. package/docs/getting-started/quickstart.md +0 -158
  47. package/docs/troubleshooting/common-issues.md +0 -679
  48. package/docs/troubleshooting/debugging.md +0 -455
  49. package/docs/troubleshooting/external-device-connection.md +0 -283
  50. package/docs/troubleshooting/faq.md +0 -574
  51. package/docs/tutorials/basic-examples.md +0 -718
@@ -1,574 +0,0 @@
1
- # Frequently Asked Questions
2
-
3
- ## General Questions
4
-
5
- ### Q: What is painlessMesh?
6
-
7
- **A:** painlessMesh is a library that makes it easy to create mesh networks with ESP8266 and ESP32 devices. It automatically handles:
8
- - Node discovery and connection
9
- - Message routing between nodes
10
- - Network topology management
11
- - Time synchronization across all nodes
12
- - Self-healing when nodes join or leave
13
-
14
- ### Q: How many nodes can I have in a mesh?
15
-
16
- **A:** The practical limit depends on your ESP model and memory constraints:
17
- - **ESP8266**: 10-20 nodes typically, limited by ~80KB RAM
18
- - **ESP32**: 20-50+ nodes, limited by ~320KB RAM
19
- - Network diameter should stay under 5-7 hops for good performance
20
- - Each node can connect to 2-10 other nodes depending on memory
21
-
22
- ### Q: What's the range of the mesh network?
23
-
24
- **A:** Each WiFi connection has typical range of:
25
- - **Indoor**: 30-50 meters
26
- - **Outdoor (line of sight)**: 100-200 meters
27
- - **Through walls**: 10-30 meters depending on construction
28
-
29
- The mesh extends this by hopping through intermediate nodes. Total range depends on your network topology.
30
-
31
- ### Q: Do I need a WiFi router for the mesh to work?
32
-
33
- **A:** No! painlessMesh creates its own network. Nodes communicate directly with each other without needing internet or a router. However, you can add bridge nodes that connect the mesh to external networks.
34
-
35
- ## Technical Questions
36
-
37
- ### Q: How does message routing work?
38
-
39
- **A:** painlessMesh uses a tree topology with automatic routing:
40
-
41
- 1. **Broadcast messages** are sent to all nodes via flood routing
42
- 2. **Single messages** use shortest-path routing to specific nodes
43
- 3. **Neighbor messages** go only to directly connected nodes
44
- 4. Routing tables update automatically as topology changes
45
-
46
- See [Message Routing](../architecture/routing.md) for details.
47
-
48
- ### Q: Are messages guaranteed to be delivered?
49
-
50
- **A:** painlessMesh provides **best-effort delivery**:
51
- - TCP connections provide reliability between directly connected nodes
52
- - No end-to-end delivery guarantees across multiple hops
53
- - Network partitions or node failures can cause message loss
54
- - For critical messages, implement application-level acknowledgments
55
-
56
- ### Q: How accurate is time synchronization?
57
-
58
- **A:** Time sync accuracy is typically:
59
- - **Direct connections**: ±1-5 milliseconds
60
- - **Multi-hop**: ±10-50 milliseconds depending on network load
61
- - **Stability**: Good for coordinating actions within ~100ms windows
62
- - Clock drift is corrected automatically every few minutes
63
-
64
- ### Q: Can I mix ESP8266 and ESP32 in the same mesh?
65
-
66
- **A:** Yes! ESP8266 and ESP32 devices work together seamlessly in the same mesh. However:
67
- - ESP8266 nodes will have fewer connections due to memory limits
68
- - ESP32 nodes may become hubs due to their higher capacity
69
- - Message size limits should account for ESP8266 constraints
70
-
71
- ## Development Questions
72
-
73
- ### Q: Which Arduino libraries do I need?
74
-
75
- **A:** painlessMesh requires:
76
- ```cpp
77
- // Core dependencies (install these)
78
- #include "painlessMesh.h"
79
- #include "ArduinoJson.h" // v6.x
80
- #include "TaskScheduler.h" // v3.x
81
-
82
- // Platform libraries (built-in)
83
- #include "WiFi.h" // ESP32
84
- #include "ESP8266WiFi.h" // ESP8266
85
- ```
86
-
87
- ### Q: Can I use painlessMesh with other WiFi libraries?
88
-
89
- **A:** painlessMesh manages WiFi internally and may conflict with other WiFi code. If you need external WiFi:
90
- - Use bridge nodes that connect the mesh to external networks
91
- - Avoid calling WiFi functions directly in mesh nodes
92
- - Consider time-division approaches (mesh mode vs. WiFi mode)
93
-
94
- ### Q: How do I send sensor data efficiently?
95
-
96
- **A:** Use the plugin system for type-safe, efficient messaging:
97
-
98
- ```cpp
99
- // Define custom package
100
- class SensorPackage : public painlessmesh::plugin::BroadcastPackage {
101
- public:
102
- float temperature, humidity;
103
- uint32_t timestamp;
104
-
105
- SensorPackage() : BroadcastPackage(100) {}
106
- // ... implement serialization methods
107
- };
108
-
109
- // Send data
110
- SensorPackage sensor;
111
- sensor.temperature = readTemperature();
112
- sensor.humidity = readHumidity();
113
- sensor.timestamp = mesh.getNodeTime();
114
- mesh.sendPackage(&sensor);
115
- ```
116
-
117
- ### Q: How do I handle different message types?
118
-
119
- **A:** Use the plugin system with type-specific handlers:
120
-
121
- ```cpp
122
- // Register handlers for different types
123
- mesh.onPackage(SENSOR_DATA, handleSensorData);
124
- mesh.onPackage(COMMAND_MSG, handleCommand);
125
- mesh.onPackage(STATUS_MSG, handleStatus);
126
-
127
- // Or use the raw callback with type checking
128
- mesh.onReceive([](uint32_t from, String& msg) {
129
- DynamicJsonDocument doc(1024);
130
- deserializeJson(doc, msg);
131
-
132
- int msgType = doc["type"];
133
- switch(msgType) {
134
- case SENSOR_DATA:
135
- // Handle sensor data
136
- break;
137
- case COMMAND_MSG:
138
- // Handle commands
139
- break;
140
- }
141
- });
142
- ```
143
-
144
- ## Network Design Questions
145
-
146
- ### Q: What's the best network topology?
147
-
148
- **A:** For most applications, aim for a **balanced tree**:
149
- - Avoid long chains (high latency)
150
- - Avoid star topologies (bottlenecks at center)
151
- - Distribute connections evenly
152
- - Place high-capacity nodes (ESP32) as hubs
153
- - Keep network diameter under 5-7 hops
154
-
155
- ### Q: How do I make the mesh more reliable?
156
-
157
- **A:** Follow these best practices:
158
-
159
- 1. **Power supply**: Use stable, adequate power sources
160
- 2. **Placement**: Ensure good WiFi coverage between nodes
161
- 3. **Memory management**: Monitor and optimize memory usage
162
- 4. **Error handling**: Implement callbacks for connection events
163
- 5. **Redundancy**: Design for node failures
164
- 6. **Testing**: Test with realistic loads and distances
165
-
166
- ### Q: Can nodes sleep or use deep sleep?
167
-
168
- **A:** Node sleep modes affect mesh connectivity:
169
-
170
- - **Light sleep**: Node stays connected but may miss messages
171
- - **Deep sleep**: Node disconnects from mesh entirely
172
- - **Modem sleep**: WiFi radio sleeps between messages (automatic)
173
-
174
- For battery-powered nodes:
175
- ```cpp
176
- void enterSleepMode() {
177
- // Send status before sleeping
178
- StatusPackage status;
179
- status.sleepDuration = 300; // 5 minutes
180
- mesh.sendPackage(&status);
181
-
182
- // Give time for message to send
183
- delay(1000);
184
-
185
- // Disconnect cleanly
186
- mesh.stop();
187
-
188
- // Deep sleep
189
- ESP.deepSleep(300e6); // 5 minutes in microseconds
190
- }
191
- ```
192
-
193
- ## Performance Questions
194
-
195
- ### Q: Why are my messages slow?
196
-
197
- **A:** Common causes of slow message delivery:
198
-
199
- 1. **Network topology**: Long chains or bottlenecked hubs
200
- 2. **Message frequency**: Too many messages causing congestion
201
- 3. **Message size**: Large messages take longer to transmit
202
- 4. **CPU load**: Other tasks interfering with mesh processing
203
- 5. **WiFi interference**: Congested 2.4GHz band
204
-
205
- ### Q: How can I optimize performance?
206
-
207
- **A:** Performance optimization strategies:
208
-
209
- ```cpp
210
- // 1. Reduce message frequency
211
- Task slowTask(30000, TASK_FOREVER, &sendData); // Every 30s instead of 1s
212
-
213
- // 2. Compact message format
214
- String msg = "{\"t\":" + String(temp) + ",\"h\":" + String(hum) + "}";
215
-
216
- // 3. Batch multiple values
217
- String msg = "{\"sensors\":[" + temp + "," + hum + "," + pressure + "]}";
218
-
219
- // 4. Use appropriate routing
220
- mesh.sendSingle(targetNode, msg); // Instead of broadcast when possible
221
-
222
- // 5. Optimize task timing
223
- mesh.update(); // Call regularly but don't block
224
- yield(); // Allow other tasks to run
225
- ```
226
-
227
- ### Q: How much memory does painlessMesh use?
228
-
229
- **A:** Typical memory usage:
230
- - **Core library**: ~20-30KB
231
- - **Per connection**: ~5-10KB
232
- - **Message buffers**: ~2-5KB per connection
233
- - **JSON processing**: ~1-2KB per message
234
-
235
- Monitor memory usage:
236
- ```cpp
237
- void checkMemory() {
238
- Serial.printf("Free heap: %u bytes\n", ESP.getFreeHeap());
239
- Serial.printf("Largest block: %u bytes\n", ESP.getMaxAllocHeap());
240
- }
241
- ```
242
-
243
- ## Security Questions
244
-
245
- ### Q: Is painlessMesh secure?
246
-
247
- **A:** Current security features are basic:
248
- - **Network password**: WPA2 protection for WiFi connections
249
- - **No message encryption**: Messages are sent in plaintext
250
- - **No authentication**: Any device with the password can join
251
-
252
- ### Q: How can I improve security?
253
-
254
- **A:** Security enhancement options:
255
-
256
- ```cpp
257
- // 1. Change default passwords regularly
258
- #define MESH_PASSWORD "UniquePassword123!" // Use strong passwords
259
-
260
- // 2. Implement application-level encryption
261
- String encryptMessage(String plaintext) {
262
- // Add your encryption here
263
- return encryptedMessage;
264
- }
265
-
266
- // 3. Validate message sources
267
- mesh.onReceive([](uint32_t from, String& msg) {
268
- if (!isAuthorizedNode(from)) {
269
- Serial.printf("Ignoring message from unauthorized node: %u\n", from);
270
- return;
271
- }
272
- processMessage(msg);
273
- });
274
-
275
- // 4. Use message authentication
276
- String createSecureMessage(String data) {
277
- String timestamp = String(mesh.getNodeTime());
278
- String signature = calculateHMAC(data + timestamp + secretKey);
279
- return "{\"data\":\"" + data + "\",\"time\":" + timestamp +
280
- ",\"sig\":\"" + signature + "\"}";
281
- }
282
- ```
283
-
284
- ### Q: Can someone intercept my mesh messages?
285
-
286
- **A:** Yes, without additional encryption:
287
- - WiFi traffic can be intercepted with standard tools
288
- - Messages are JSON plaintext by default
289
- - Network password only protects WiFi association
290
- - Consider application-level encryption for sensitive data
291
-
292
- ## Integration Questions
293
-
294
- ### Q: Can I connect the mesh to the internet?
295
-
296
- **A:** Yes, using bridge nodes. **Important:** Only the bridge node has internet access - regular mesh nodes do NOT have internet access.
297
-
298
- **Architecture:**
299
- ```text
300
- Internet
301
- |
302
- Router (WiFi)
303
- |
304
- Bridge Node (AP+STA mode) ← Only this node has internet access
305
- |
306
- Mesh Network
307
- / | \
308
- Node1 Node2 Node3... ← These nodes do NOT have internet access
309
- ```
310
-
311
- **Bridge Node Setup:**
312
- ```cpp
313
- // Bridge node connects to both mesh and internet
314
- void setup() {
315
- // Modern approach: Auto-detect channel and connect
316
- mesh.initAsBridge(MESH_PREFIX, MESH_PASSWORD,
317
- ROUTER_SSID, ROUTER_PASSWORD,
318
- &userScheduler, MESH_PORT);
319
-
320
- mesh.onReceive(&receivedCallback);
321
- }
322
-
323
- // Forward mesh data to internet services
324
- void receivedCallback(uint32_t from, String& msg) {
325
- // Bridge forwards messages to HTTP server, MQTT broker, etc.
326
- if (WiFi.status() == WL_CONNECTED) {
327
- httpClient.POST("http://myserver.com/api/data", msg);
328
- }
329
- }
330
- ```
331
-
332
- **Regular Nodes:**
333
- ```cpp
334
- // Regular nodes send data TO the bridge (no direct internet access)
335
- void setup() {
336
- mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
337
- mesh.onReceive(&receivedCallback);
338
- }
339
-
340
- void sendDataToInternet() {
341
- // Regular nodes send to bridge, which forwards to internet
342
- String data = "{\"sensor\":\"temp\",\"value\":25.5}";
343
- mesh.sendSingle(bridgeNodeId, data);
344
- // Bridge will forward this to internet services
345
- }
346
- ```
347
-
348
- See [BRIDGE_TO_INTERNET.md](../../BRIDGE_TO_INTERNET.md) for complete documentation.
349
-
350
- ### Q: Why can't my regular mesh nodes access the Internet / make HTTP requests?
351
-
352
- **A:** This is expected behavior. **Only the bridge node has internet access** - regular mesh nodes only communicate with other mesh nodes.
353
-
354
- **Why this happens:**
355
-
356
- ESP8266/ESP32 WiFi hardware can only operate on one channel at a time. In a mesh network:
357
-
358
- - **Bridge node** uses `WIFI_AP_STA` mode:
359
- - Access Point (AP) for mesh on channel X
360
- - Station (STA) connected to router on channel X
361
- - Has internet access via router
362
-
363
- - **Regular nodes** use `WIFI_AP` mode:
364
- - Access Point (AP) for mesh only
365
- - No router connection
366
- - No internet access
367
-
368
- **Solution - Forward through bridge:**
369
-
370
- ```cpp
371
- // ==== BRIDGE NODE ====
372
- #include "HTTPClient.h"
373
-
374
- void receivedCallback(uint32_t from, String& msg) {
375
- // Parse message from mesh nodes
376
- DynamicJsonDocument doc(1024);
377
- deserializeJson(doc, msg);
378
-
379
- // Forward to internet service
380
- if (WiFi.status() == WL_CONNECTED) {
381
- HTTPClient http;
382
- http.begin("http://api.example.com/data");
383
- http.addHeader("Content-Type", "application/json");
384
- http.POST(msg);
385
- http.end();
386
- }
387
- }
388
-
389
- // ==== REGULAR NODE ====
390
- void sendDataToCloud() {
391
- // Create message
392
- String msg = "{\"sensor\":\"temp\",\"value\":25.5}";
393
-
394
- // Send to bridge (NOT directly to internet!)
395
- mesh.sendSingle(bridgeNodeId, msg);
396
-
397
- // Bridge will forward to internet service
398
- }
399
- ```
400
-
401
- **Common mistake:**
402
-
403
- ```cpp
404
- // ❌ This will NOT work on regular mesh nodes:
405
- HTTPClient http;
406
- http.begin("http://api.example.com/data");
407
- http.POST(data); // ERROR: No internet connection!
408
-
409
- // ✅ Correct approach - send to bridge:
410
- mesh.sendSingle(bridgeNodeId, data); // Bridge forwards to internet
411
- ```
412
-
413
- **Architecture patterns:**
414
-
415
- 1. **Single bridge**: One node connects to router, others forward through it
416
- 2. **Bridge failover**: Multiple nodes have router credentials, automatic failover
417
- 3. **Multi-bridge**: Multiple simultaneous bridges for load balancing
418
-
419
- See [BRIDGE_TO_INTERNET.md](../../BRIDGE_TO_INTERNET.md) and [BRIDGE_FAILOVER.md](../BRIDGE_FAILOVER.md).
420
-
421
- ### Q: Can I use MQTT with painlessMesh?
422
-
423
- **A:** Yes, through bridge nodes or by running MQTT alongside the mesh:
424
-
425
- ```cpp
426
- #include "PubSubClient.h"
427
-
428
- WiFiClient wifiClient;
429
- PubSubClient mqttClient(wifiClient);
430
-
431
- // Bridge mesh messages to MQTT
432
- mesh.onReceive([](uint32_t from, String& msg) {
433
- String topic = "mesh/node/" + String(from);
434
- mqttClient.publish(topic.c_str(), msg.c_str());
435
- });
436
-
437
- // Bridge MQTT messages to mesh
438
- void mqttCallback(char* topic, byte* payload, unsigned int length) {
439
- String msg = String((char*)payload);
440
- mesh.sendBroadcast(msg);
441
- }
442
- ```
443
-
444
- ### Q: How do I integrate with home automation systems?
445
-
446
- **A:** Common integration approaches:
447
-
448
- 1. **HTTP REST API**: Bridge node exposes REST endpoints
449
- 2. **MQTT**: Bridge publishes sensor data to MQTT broker
450
- 3. **Home Assistant**: Use MQTT discovery or custom integration
451
- 4. **Node-RED**: Connect via MQTT or HTTP
452
- 5. **Direct integration**: Custom protocol over TCP/WebSocket
453
-
454
- ## Alteriom-Specific Questions
455
-
456
- ### Q: What are Alteriom extensions?
457
-
458
- **A:** Alteriom provides pre-built packages for common IoT use cases:
459
-
460
- - **SensorPackage**: Environmental sensor data (temperature, humidity, pressure)
461
- - **CommandPackage**: Device control commands
462
- - **StatusPackage**: Device health monitoring
463
-
464
- See [Alteriom Overview](../alteriom/overview.md) for details.
465
-
466
- ### Q: Can I use Alteriom packages in my own projects?
467
-
468
- **A:** Yes! The Alteriom packages are examples you can:
469
- - Use directly in your projects
470
- - Modify for your specific needs
471
- - Use as templates for your own packages
472
-
473
- ```cpp
474
- #include "examples/alteriom/alteriom_sensor_package.hpp"
475
- using namespace alteriom;
476
-
477
- // Use directly
478
- SensorPackage sensor;
479
- sensor.temperature = 25.0;
480
- mesh.sendPackage(&sensor);
481
-
482
- // Or extend for your needs
483
- class MySensorPackage : public SensorPackage {
484
- public:
485
- float lightLevel = 0.0; // Add custom field
486
- // ... implement serialization
487
- };
488
- ```
489
-
490
- ## Troubleshooting Questions
491
-
492
- ### Q: My ESP keeps crashing. What should I check?
493
-
494
- **A:** Common crash causes:
495
-
496
- 1. **Memory issues**: Monitor heap usage
497
- 2. **Power supply**: Ensure stable, adequate power
498
- 3. **Stack overflow**: Reduce recursion, large local variables
499
- 4. **Watchdog timeout**: Add `yield()` calls in long loops
500
- 5. **Hardware issues**: Bad connections, damaged ESP
501
-
502
- Enable crash debugging:
503
- ```cpp
504
- // ESP32
505
- #include "esp_system.h"
506
- esp_core_dump_init();
507
-
508
- // ESP8266
509
- Serial.println("Last reset reason: " + ESP.getResetReason());
510
- ```
511
-
512
- ### Q: Why can't I see debug messages?
513
-
514
- **A:** Debug message troubleshooting:
515
-
516
- ```cpp
517
- void setup() {
518
- Serial.begin(115200);
519
- delay(1000); // Wait for serial to initialize
520
-
521
- // Enable debug messages BEFORE mesh.init()
522
- mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
523
-
524
- mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
525
-
526
- Serial.println("Setup completed"); // Test message
527
- }
528
- ```
529
-
530
- Check:
531
- - Correct baud rate (115200)
532
- - Serial cable supports data (not just power)
533
- - Debug messages enabled before mesh initialization
534
- - Serial monitor connected to correct COM port
535
-
536
- ### Q: Messages work sometimes but not always. Why?
537
-
538
- **A:** Intermittent message issues usually indicate:
539
-
540
- 1. **Memory pressure**: Messages dropped when low memory
541
- 2. **Network congestion**: Too many messages simultaneously
542
- 3. **Connection instability**: Nodes connecting/disconnecting
543
- 4. **Power issues**: Voltage drops during transmission
544
- 5. **WiFi interference**: Other 2.4GHz devices
545
-
546
- Add reliability checks:
547
- ```cpp
548
- bool sendReliableMessage(String msg) {
549
- bool sent = mesh.sendBroadcast(msg);
550
- if (!sent) {
551
- Serial.println("Failed to send - will retry");
552
- delay(1000);
553
- return mesh.sendBroadcast(msg); // Retry once
554
- }
555
- return true;
556
- }
557
- ```
558
-
559
- ## Getting More Help
560
-
561
- If your question isn't answered here:
562
-
563
- 1. Check [Common Issues](common-issues.md) for detailed troubleshooting
564
- 2. Search the [GitHub Issues](https://github.com/Alteriom/painlessMesh/issues)
565
- 3. Post in the [Community Forum](https://groups.google.com/forum/#!forum/painlessmesh-user)
566
- 4. Review the [API Documentation](../api/core-api.md)
567
- 5. Look at [Example Code](../tutorials/basic-examples.md) for working implementations
568
-
569
- When asking for help, include:
570
- - Hardware details (ESP32/ESP8266 model)
571
- - Library versions
572
- - Complete code example
573
- - Serial output with debug enabled
574
- - Network topology description