@alteriom/painlessmesh 1.6.1
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.
- package/CHANGELOG.md +144 -0
- package/LICENSE +674 -0
- package/README.md +434 -0
- package/RELEASE_GUIDE.md +419 -0
- package/docs/DOCUMENTATION_MIGRATION_PLAN.md +176 -0
- package/docs/README.md +71 -0
- package/docs/alteriom/overview.md +508 -0
- package/docs/api/core-api.md +607 -0
- package/docs/architecture/mesh-architecture.md +379 -0
- package/docs/architecture/plugin-system.md +517 -0
- package/docs/getting-started/first-mesh.md +410 -0
- package/docs/getting-started/installation.md +275 -0
- package/docs/getting-started/quickstart.md +158 -0
- package/docs/improvements/README.md +69 -0
- package/docs/troubleshooting/common-issues.md +521 -0
- package/docs/troubleshooting/faq.md +473 -0
- package/docs/tutorials/basic-examples.md +718 -0
- package/docs/wiki/API-Reference.md +246 -0
- package/docs/wiki/Complete-Documentation.md +123 -0
- package/examples/alteriom/README.md +82 -0
- package/examples/alteriom/alteriom.ino +186 -0
- package/examples/alteriom/alteriom_sensor_node.ino +184 -0
- package/examples/alteriom/alteriom_sensor_package.hpp +128 -0
- package/examples/alteriom/improved_sensor_node.ino +246 -0
- package/examples/alteriom/platformio.ini +25 -0
- package/examples/basic/basic.ino +66 -0
- package/examples/basic/platformio.ini +25 -0
- package/examples/bridge/bridge.ino +51 -0
- package/examples/bridge/platformio.ini +25 -0
- package/examples/echoNode/echoNode.ino +33 -0
- package/examples/echoNode/platformio.ini +25 -0
- package/examples/logClient/logClient.ino +109 -0
- package/examples/logClient/platformio.ini +25 -0
- package/examples/logServer/logServer.ino +81 -0
- package/examples/logServer/platformio.ini +25 -0
- package/examples/mqttBridge/mqttBridge.ino +118 -0
- package/examples/mqttBridge/platformio.ini +26 -0
- package/examples/namedMesh/namedMesh.ino +97 -0
- package/examples/namedMesh/platformio.ini +25 -0
- package/examples/otaReceiver/otaReceiver.ino +79 -0
- package/examples/otaReceiver/platformio.ini +25 -0
- package/examples/otaSender/nodemcu32s_connections.JPG +0 -0
- package/examples/otaSender/otaSender.ino +151 -0
- package/examples/otaSender/platformio.ini +25 -0
- package/examples/startHere/platformio.ini +25 -0
- package/examples/startHere/startHere.ino +159 -0
- package/examples/webServer/platformio.ini +27 -0
- package/examples/webServer/webServer.ino +89 -0
- package/keywords.txt +49 -0
- package/library.json +34 -0
- package/library.properties +11 -0
- package/package.json +78 -0
- package/src/AlteriomPainlessMesh.h +98 -0
- package/src/arduino/wifi.hpp +365 -0
- package/src/boost/asynctcp.hpp +279 -0
- package/src/painlessMesh.h +70 -0
- package/src/painlessMeshSTA.cpp +236 -0
- package/src/painlessMeshSTA.h +58 -0
- package/src/painlessTaskOptions.h +4 -0
- package/src/painlessmesh/base64.hpp +111 -0
- package/src/painlessmesh/buffer.hpp +229 -0
- package/src/painlessmesh/callback.hpp +91 -0
- package/src/painlessmesh/configuration.hpp +77 -0
- package/src/painlessmesh/connection.hpp +192 -0
- package/src/painlessmesh/layout.hpp +188 -0
- package/src/painlessmesh/logger.hpp +158 -0
- package/src/painlessmesh/memory.hpp +120 -0
- package/src/painlessmesh/mesh.hpp +560 -0
- package/src/painlessmesh/metrics.hpp +323 -0
- package/src/painlessmesh/ntp.hpp +263 -0
- package/src/painlessmesh/ota.hpp +553 -0
- package/src/painlessmesh/plugin.hpp +188 -0
- package/src/painlessmesh/protocol.hpp +813 -0
- package/src/painlessmesh/router.hpp +322 -0
- package/src/painlessmesh/tcp.hpp +71 -0
- package/src/painlessmesh/validation.hpp +239 -0
- package/src/plugin/performance.hpp +214 -0
- package/src/plugin/remote.hpp +64 -0
- package/src/scheduler.cpp +10 -0
- package/src/wifi.cpp +2 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
# Your First Mesh Network
|
|
2
|
+
|
|
3
|
+
This tutorial builds on the [Quick Start Guide](quickstart.md) to create a more comprehensive mesh network with multiple types of nodes and practical functionality.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
We'll build a mesh network with three types of nodes:
|
|
8
|
+
1. **Sensor Node** - Collects and broadcasts environmental data
|
|
9
|
+
2. **Controller Node** - Receives sensor data and controls devices
|
|
10
|
+
3. **Bridge Node** - Connects mesh to external networks (WiFi/Internet)
|
|
11
|
+
|
|
12
|
+
## Node 1: Sensor Node
|
|
13
|
+
|
|
14
|
+
This node simulates environmental sensors and broadcasts data to the mesh.
|
|
15
|
+
|
|
16
|
+
```cpp
|
|
17
|
+
#include "painlessMesh.h"
|
|
18
|
+
|
|
19
|
+
#define MESH_PREFIX "MyMeshNetwork"
|
|
20
|
+
#define MESH_PASSWORD "somethingSneaky"
|
|
21
|
+
#define MESH_PORT 5555
|
|
22
|
+
|
|
23
|
+
Scheduler userScheduler;
|
|
24
|
+
painlessMesh mesh;
|
|
25
|
+
|
|
26
|
+
// Sensor simulation
|
|
27
|
+
float temperature = 22.5;
|
|
28
|
+
float humidity = 65.0;
|
|
29
|
+
uint32_t sensorId = 1001;
|
|
30
|
+
|
|
31
|
+
// Task to send sensor data every 30 seconds
|
|
32
|
+
Task taskSendSensor(30000, TASK_FOREVER, [](){
|
|
33
|
+
// Simulate sensor readings with some variation
|
|
34
|
+
temperature += random(-10, 10) / 10.0;
|
|
35
|
+
humidity += random(-50, 50) / 10.0;
|
|
36
|
+
|
|
37
|
+
// Keep values in reasonable ranges
|
|
38
|
+
temperature = constrain(temperature, 15.0, 35.0);
|
|
39
|
+
humidity = constrain(humidity, 30.0, 90.0);
|
|
40
|
+
|
|
41
|
+
// Create JSON message
|
|
42
|
+
String msg = "{";
|
|
43
|
+
msg += "\"type\":\"sensor\",";
|
|
44
|
+
msg += "\"nodeId\":" + String(mesh.getNodeId()) + ",";
|
|
45
|
+
msg += "\"sensorId\":" + String(sensorId) + ",";
|
|
46
|
+
msg += "\"temperature\":" + String(temperature, 1) + ",";
|
|
47
|
+
msg += "\"humidity\":" + String(humidity, 1) + ",";
|
|
48
|
+
msg += "\"timestamp\":" + String(mesh.getNodeTime());
|
|
49
|
+
msg += "}";
|
|
50
|
+
|
|
51
|
+
mesh.sendBroadcast(msg);
|
|
52
|
+
Serial.printf("Sent sensor data: T=%.1f°C, H=%.1f%%\n", temperature, humidity);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
void receivedCallback(uint32_t from, String &msg) {
|
|
56
|
+
Serial.printf("Sensor Node: Received from %u: %s\n", from, msg.c_str());
|
|
57
|
+
|
|
58
|
+
// Sensor nodes can respond to commands
|
|
59
|
+
if (msg.indexOf("\"command\":\"read_sensor\"") > 0) {
|
|
60
|
+
// Force immediate sensor reading
|
|
61
|
+
taskSendSensor.forceNextIteration();
|
|
62
|
+
Serial.println("Forced sensor reading requested");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
void newConnectionCallback(uint32_t nodeId) {
|
|
67
|
+
Serial.printf("Sensor Node: New connection to %u\n", nodeId);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
void changedConnectionCallback() {
|
|
71
|
+
Serial.printf("Sensor Node: Changed connections. Nodes: %s\n",
|
|
72
|
+
mesh.subConnectionJson().c_str());
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
void setup() {
|
|
76
|
+
Serial.begin(115200);
|
|
77
|
+
Serial.println("=== Sensor Node Starting ===");
|
|
78
|
+
|
|
79
|
+
mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
80
|
+
mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
|
|
81
|
+
mesh.onReceive(&receivedCallback);
|
|
82
|
+
mesh.onNewConnection(&newConnectionCallback);
|
|
83
|
+
mesh.onChangedConnections(&changedConnectionCallback);
|
|
84
|
+
|
|
85
|
+
userScheduler.addTask(taskSendSensor);
|
|
86
|
+
taskSendSensor.enable();
|
|
87
|
+
|
|
88
|
+
Serial.printf("Sensor Node initialized. Node ID: %u\n", mesh.getNodeId());
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
void loop() {
|
|
92
|
+
mesh.update();
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Node 2: Controller Node
|
|
97
|
+
|
|
98
|
+
This node receives sensor data and can send commands to other nodes.
|
|
99
|
+
|
|
100
|
+
```cpp
|
|
101
|
+
#include "painlessMesh.h"
|
|
102
|
+
|
|
103
|
+
#define MESH_PREFIX "MyMeshNetwork"
|
|
104
|
+
#define MESH_PASSWORD "somethingSneaky"
|
|
105
|
+
#define MESH_PORT 5555
|
|
106
|
+
|
|
107
|
+
Scheduler userScheduler;
|
|
108
|
+
painlessMesh mesh;
|
|
109
|
+
|
|
110
|
+
// Storage for sensor data
|
|
111
|
+
struct SensorData {
|
|
112
|
+
uint32_t nodeId;
|
|
113
|
+
uint32_t sensorId;
|
|
114
|
+
float temperature;
|
|
115
|
+
float humidity;
|
|
116
|
+
uint32_t timestamp;
|
|
117
|
+
bool valid;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
SensorData sensors[10]; // Store data from up to 10 sensors
|
|
121
|
+
int sensorCount = 0;
|
|
122
|
+
|
|
123
|
+
// Task to request sensor data every 60 seconds
|
|
124
|
+
Task taskRequestData(60000, TASK_FOREVER, [](){
|
|
125
|
+
String cmd = "{";
|
|
126
|
+
cmd += "\"type\":\"command\",";
|
|
127
|
+
cmd += "\"command\":\"read_sensor\",";
|
|
128
|
+
cmd += "\"from\":" + String(mesh.getNodeId());
|
|
129
|
+
cmd += "}";
|
|
130
|
+
|
|
131
|
+
mesh.sendBroadcast(cmd);
|
|
132
|
+
Serial.println("Requested sensor data from all nodes");
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Task to display collected data every 45 seconds
|
|
136
|
+
Task taskDisplayData(45000, TASK_FOREVER, [](){
|
|
137
|
+
Serial.println("=== Collected Sensor Data ===");
|
|
138
|
+
for (int i = 0; i < sensorCount; i++) {
|
|
139
|
+
if (sensors[i].valid) {
|
|
140
|
+
Serial.printf("Node %u (Sensor %u): T=%.1f°C, H=%.1f%%, Age=%u seconds\n",
|
|
141
|
+
sensors[i].nodeId, sensors[i].sensorId,
|
|
142
|
+
sensors[i].temperature, sensors[i].humidity,
|
|
143
|
+
(mesh.getNodeTime() - sensors[i].timestamp) / 1000000);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
Serial.println("============================");
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
void storeSensorData(uint32_t nodeId, uint32_t sensorId, float temp, float hum, uint32_t timestamp) {
|
|
150
|
+
// Find existing entry or create new one
|
|
151
|
+
int index = -1;
|
|
152
|
+
for (int i = 0; i < sensorCount; i++) {
|
|
153
|
+
if (sensors[i].nodeId == nodeId && sensors[i].sensorId == sensorId) {
|
|
154
|
+
index = i;
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (index == -1 && sensorCount < 10) {
|
|
160
|
+
index = sensorCount++;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (index != -1) {
|
|
164
|
+
sensors[index].nodeId = nodeId;
|
|
165
|
+
sensors[index].sensorId = sensorId;
|
|
166
|
+
sensors[index].temperature = temp;
|
|
167
|
+
sensors[index].humidity = hum;
|
|
168
|
+
sensors[index].timestamp = timestamp;
|
|
169
|
+
sensors[index].valid = true;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
void receivedCallback(uint32_t from, String &msg) {
|
|
174
|
+
Serial.printf("Controller: Received from %u: %s\n", from, msg.c_str());
|
|
175
|
+
|
|
176
|
+
// Parse sensor data
|
|
177
|
+
if (msg.indexOf("\"type\":\"sensor\"") > 0) {
|
|
178
|
+
// Simple JSON parsing (in production, use ArduinoJson library)
|
|
179
|
+
int tempStart = msg.indexOf("\"temperature\":") + 14;
|
|
180
|
+
int tempEnd = msg.indexOf(",", tempStart);
|
|
181
|
+
float temperature = msg.substring(tempStart, tempEnd).toFloat();
|
|
182
|
+
|
|
183
|
+
int humStart = msg.indexOf("\"humidity\":") + 11;
|
|
184
|
+
int humEnd = msg.indexOf(",", humStart);
|
|
185
|
+
float humidity = msg.substring(humStart, humEnd).toFloat();
|
|
186
|
+
|
|
187
|
+
int sensorStart = msg.indexOf("\"sensorId\":") + 11;
|
|
188
|
+
int sensorEnd = msg.indexOf(",", sensorStart);
|
|
189
|
+
uint32_t sensorId = msg.substring(sensorStart, sensorEnd).toInt();
|
|
190
|
+
|
|
191
|
+
int timeStart = msg.indexOf("\"timestamp\":") + 12;
|
|
192
|
+
int timeEnd = msg.indexOf("}", timeStart);
|
|
193
|
+
uint32_t timestamp = msg.substring(timeStart, timeEnd).toInt();
|
|
194
|
+
|
|
195
|
+
storeSensorData(from, sensorId, temperature, humidity, timestamp);
|
|
196
|
+
|
|
197
|
+
// Trigger actions based on sensor data
|
|
198
|
+
if (temperature > 30.0) {
|
|
199
|
+
Serial.println("WARNING: High temperature detected!");
|
|
200
|
+
// Could send cooling command here
|
|
201
|
+
}
|
|
202
|
+
if (humidity > 80.0) {
|
|
203
|
+
Serial.println("WARNING: High humidity detected!");
|
|
204
|
+
// Could trigger ventilation here
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
void newConnectionCallback(uint32_t nodeId) {
|
|
210
|
+
Serial.printf("Controller: New connection to %u\n", nodeId);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
void changedConnectionCallback() {
|
|
214
|
+
Serial.printf("Controller: Changed connections. Nodes: %s\n",
|
|
215
|
+
mesh.subConnectionJson().c_str());
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
void setup() {
|
|
219
|
+
Serial.begin(115200);
|
|
220
|
+
Serial.println("=== Controller Node Starting ===");
|
|
221
|
+
|
|
222
|
+
// Initialize sensor storage
|
|
223
|
+
for (int i = 0; i < 10; i++) {
|
|
224
|
+
sensors[i].valid = false;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
228
|
+
mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
|
|
229
|
+
mesh.onReceive(&receivedCallback);
|
|
230
|
+
mesh.onNewConnection(&newConnectionCallback);
|
|
231
|
+
mesh.onChangedConnections(&changedConnectionCallback);
|
|
232
|
+
|
|
233
|
+
userScheduler.addTask(taskRequestData);
|
|
234
|
+
userScheduler.addTask(taskDisplayData);
|
|
235
|
+
taskRequestData.enable();
|
|
236
|
+
taskDisplayData.enable();
|
|
237
|
+
|
|
238
|
+
Serial.printf("Controller Node initialized. Node ID: %u\n", mesh.getNodeId());
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
void loop() {
|
|
242
|
+
mesh.update();
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Node 3: Bridge Node
|
|
247
|
+
|
|
248
|
+
This node connects the mesh to WiFi/Internet for external connectivity.
|
|
249
|
+
|
|
250
|
+
```cpp
|
|
251
|
+
#include "painlessMesh.h"
|
|
252
|
+
#include <WiFi.h> // Use <ESP8266WiFi.h> for ESP8266
|
|
253
|
+
|
|
254
|
+
#define MESH_PREFIX "MyMeshNetwork"
|
|
255
|
+
#define MESH_PASSWORD "somethingSneaky"
|
|
256
|
+
#define MESH_PORT 5555
|
|
257
|
+
|
|
258
|
+
// External WiFi credentials
|
|
259
|
+
#define STATION_SSID "YourHomeWiFi"
|
|
260
|
+
#define STATION_PASSWORD "YourWiFiPassword"
|
|
261
|
+
|
|
262
|
+
Scheduler userScheduler;
|
|
263
|
+
painlessMesh mesh;
|
|
264
|
+
|
|
265
|
+
// Task to report bridge status
|
|
266
|
+
Task taskBridgeStatus(30000, TASK_FOREVER, [](){
|
|
267
|
+
String status = "{";
|
|
268
|
+
status += "\"type\":\"bridge_status\",";
|
|
269
|
+
status += "\"nodeId\":" + String(mesh.getNodeId()) + ",";
|
|
270
|
+
status += "\"wifi_connected\":" + String(WiFi.status() == WL_CONNECTED ? "true" : "false") + ",";
|
|
271
|
+
status += "\"wifi_rssi\":" + String(WiFi.RSSI()) + ",";
|
|
272
|
+
status += "\"mesh_connections\":" + String(mesh.getNodeList().size()) + ",";
|
|
273
|
+
status += "\"timestamp\":" + String(mesh.getNodeTime());
|
|
274
|
+
status += "}";
|
|
275
|
+
|
|
276
|
+
mesh.sendBroadcast(status);
|
|
277
|
+
Serial.printf("Bridge Status: WiFi=%s, RSSI=%d, Mesh Nodes=%d\n",
|
|
278
|
+
WiFi.status() == WL_CONNECTED ? "Connected" : "Disconnected",
|
|
279
|
+
WiFi.RSSI(), mesh.getNodeList().size());
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
void receivedCallback(uint32_t from, String &msg) {
|
|
283
|
+
Serial.printf("Bridge: Received from %u: %s\n", from, msg.c_str());
|
|
284
|
+
|
|
285
|
+
// Forward sensor data to external server (example)
|
|
286
|
+
if (msg.indexOf("\"type\":\"sensor\"") > 0 && WiFi.status() == WL_CONNECTED) {
|
|
287
|
+
// Here you could forward to HTTP/MQTT/etc
|
|
288
|
+
Serial.println("Would forward sensor data to external server");
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
void newConnectionCallback(uint32_t nodeId) {
|
|
293
|
+
Serial.printf("Bridge: New mesh connection to %u\n", nodeId);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
void changedConnectionCallback() {
|
|
297
|
+
Serial.printf("Bridge: Mesh topology changed. Nodes: %s\n",
|
|
298
|
+
mesh.subConnectionJson().c_str());
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
void setup() {
|
|
302
|
+
Serial.begin(115200);
|
|
303
|
+
Serial.println("=== Bridge Node Starting ===");
|
|
304
|
+
|
|
305
|
+
// Initialize mesh
|
|
306
|
+
mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
307
|
+
mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
|
|
308
|
+
mesh.onReceive(&receivedCallback);
|
|
309
|
+
mesh.onNewConnection(&newConnectionCallback);
|
|
310
|
+
mesh.onChangedConnections(&changedConnectionCallback);
|
|
311
|
+
|
|
312
|
+
// Connect to external WiFi
|
|
313
|
+
WiFi.begin(STATION_SSID, STATION_PASSWORD);
|
|
314
|
+
Serial.printf("Connecting to WiFi: %s", STATION_SSID);
|
|
315
|
+
|
|
316
|
+
while (WiFi.status() != WL_CONNECTED) {
|
|
317
|
+
delay(500);
|
|
318
|
+
Serial.print(".");
|
|
319
|
+
}
|
|
320
|
+
Serial.println();
|
|
321
|
+
Serial.printf("WiFi connected! IP: %s\n", WiFi.localIP().toString().c_str());
|
|
322
|
+
|
|
323
|
+
userScheduler.addTask(taskBridgeStatus);
|
|
324
|
+
taskBridgeStatus.enable();
|
|
325
|
+
|
|
326
|
+
Serial.printf("Bridge Node initialized. Node ID: %u\n", mesh.getNodeId());
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
void loop() {
|
|
330
|
+
mesh.update();
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Deployment Steps
|
|
335
|
+
|
|
336
|
+
1. **Upload Sensor Node code** to your first ESP32/ESP8266
|
|
337
|
+
2. **Upload Controller Node code** to your second device
|
|
338
|
+
3. **Upload Bridge Node code** to your third device (update WiFi credentials first!)
|
|
339
|
+
4. **Power up all devices** and open Serial Monitors to watch them connect
|
|
340
|
+
5. **Observe the mesh in action**:
|
|
341
|
+
- Sensor nodes broadcast environmental data
|
|
342
|
+
- Controller receives and processes sensor data
|
|
343
|
+
- Bridge provides external connectivity and status updates
|
|
344
|
+
|
|
345
|
+
## What You'll See
|
|
346
|
+
|
|
347
|
+
### Sensor Node Output
|
|
348
|
+
```
|
|
349
|
+
=== Sensor Node Starting ===
|
|
350
|
+
Sensor Node initialized. Node ID: 123456789
|
|
351
|
+
Sensor Node: New connection to 987654321
|
|
352
|
+
Sent sensor data: T=23.2°C, H=67.4%
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Controller Node Output
|
|
356
|
+
```
|
|
357
|
+
=== Controller Node Starting ===
|
|
358
|
+
Controller Node initialized. Node ID: 987654321
|
|
359
|
+
Requested sensor data from all nodes
|
|
360
|
+
Controller: Received from 123456789: {"type":"sensor",...}
|
|
361
|
+
=== Collected Sensor Data ===
|
|
362
|
+
Node 123456789 (Sensor 1001): T=23.2°C, H=67.4%, Age=5 seconds
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Bridge Node Output
|
|
366
|
+
```
|
|
367
|
+
=== Bridge Node Starting ===
|
|
368
|
+
Connecting to WiFi: YourHomeWiFi....
|
|
369
|
+
WiFi connected! IP: 192.168.1.100
|
|
370
|
+
Bridge Node initialized. Node ID: 555444333
|
|
371
|
+
Bridge Status: WiFi=Connected, RSSI=-45, Mesh Nodes=2
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## Key Features Demonstrated
|
|
375
|
+
|
|
376
|
+
- **Automatic Discovery**: Nodes find each other automatically
|
|
377
|
+
- **Message Broadcasting**: Sensor data reaches all interested nodes
|
|
378
|
+
- **JSON Communication**: Structured data exchange
|
|
379
|
+
- **Command System**: Controller can request data from sensors
|
|
380
|
+
- **External Connectivity**: Bridge connects mesh to Internet
|
|
381
|
+
- **Self-Healing**: Network continues working if nodes disconnect
|
|
382
|
+
|
|
383
|
+
## Extending Your Mesh
|
|
384
|
+
|
|
385
|
+
### Add More Sensors
|
|
386
|
+
- Temperature/humidity sensors (DHT22)
|
|
387
|
+
- Motion detectors (PIR)
|
|
388
|
+
- Light sensors (photoresistor)
|
|
389
|
+
- Soil moisture sensors
|
|
390
|
+
|
|
391
|
+
### Add Actuators
|
|
392
|
+
- LED strips for notifications
|
|
393
|
+
- Servo motors for mechanical control
|
|
394
|
+
- Relays for switching devices
|
|
395
|
+
- Buzzers for alerts
|
|
396
|
+
|
|
397
|
+
### External Integrations
|
|
398
|
+
- MQTT broker connectivity
|
|
399
|
+
- HTTP REST API calls
|
|
400
|
+
- Home Assistant integration
|
|
401
|
+
- Cloud database logging
|
|
402
|
+
|
|
403
|
+
## Next Steps
|
|
404
|
+
|
|
405
|
+
- Explore [Custom Packages](../tutorials/custom-packages.md) for type-safe messaging
|
|
406
|
+
- Learn about [Alteriom Extensions](../alteriom/overview.md) for pre-built sensor packages
|
|
407
|
+
- Dive into [Advanced Topics](../advanced/performance.md) for optimization
|
|
408
|
+
- Check out [Troubleshooting](../troubleshooting/common-issues.md) if you encounter issues
|
|
409
|
+
|
|
410
|
+
Congratulations! You now have a working multi-node mesh network with real-world functionality.
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# Installation Guide
|
|
2
|
+
|
|
3
|
+
This guide covers all the different ways to install and set up painlessMesh for your development environment.
|
|
4
|
+
|
|
5
|
+
## Arduino IDE Installation
|
|
6
|
+
|
|
7
|
+
### Method 1: Library Manager (Recommended)
|
|
8
|
+
|
|
9
|
+
1. Open Arduino IDE
|
|
10
|
+
2. Go to **Sketch → Include Library → Manage Libraries**
|
|
11
|
+
3. Search for "painlessMesh"
|
|
12
|
+
4. Install the latest version by "Coopdis"
|
|
13
|
+
5. Install dependencies when prompted:
|
|
14
|
+
- ArduinoJson
|
|
15
|
+
- TaskScheduler
|
|
16
|
+
|
|
17
|
+
### Method 2: Manual Installation
|
|
18
|
+
|
|
19
|
+
1. Download the latest release from [GitHub](https://github.com/Alteriom/painlessMesh/releases)
|
|
20
|
+
2. Extract the ZIP file
|
|
21
|
+
3. Copy the `painlessMesh` folder to your Arduino libraries directory:
|
|
22
|
+
- **Windows**: `Documents\Arduino\libraries\`
|
|
23
|
+
- **macOS**: `~/Documents/Arduino/libraries/`
|
|
24
|
+
- **Linux**: `~/Arduino/libraries/`
|
|
25
|
+
4. Restart Arduino IDE
|
|
26
|
+
|
|
27
|
+
## PlatformIO Installation
|
|
28
|
+
|
|
29
|
+
### Method 1: platformio.ini (Recommended)
|
|
30
|
+
|
|
31
|
+
Add to your `platformio.ini` file:
|
|
32
|
+
|
|
33
|
+
```ini
|
|
34
|
+
[env:esp32dev]
|
|
35
|
+
platform = espressif32
|
|
36
|
+
board = esp32dev
|
|
37
|
+
framework = arduino
|
|
38
|
+
lib_deps =
|
|
39
|
+
painlessMesh
|
|
40
|
+
bblanchon/ArduinoJson@^6.21.3
|
|
41
|
+
arkhipenko/TaskScheduler@^3.7.0
|
|
42
|
+
|
|
43
|
+
# For ESP8266
|
|
44
|
+
[env:esp8266]
|
|
45
|
+
platform = espressif8266
|
|
46
|
+
board = nodemcuv2
|
|
47
|
+
framework = arduino
|
|
48
|
+
lib_deps =
|
|
49
|
+
painlessMesh
|
|
50
|
+
bblanchon/ArduinoJson@^6.21.3
|
|
51
|
+
arkhipenko/TaskScheduler@^3.7.0
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Method 2: PlatformIO Library Manager
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Install via PlatformIO CLI
|
|
58
|
+
pio lib install "painlessMesh"
|
|
59
|
+
|
|
60
|
+
# Or install specific version
|
|
61
|
+
pio lib install "painlessMesh@1.5.0"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Board Support
|
|
65
|
+
|
|
66
|
+
### ESP32 Boards
|
|
67
|
+
painlessMesh supports all ESP32 variants:
|
|
68
|
+
- ESP32 DevKit
|
|
69
|
+
- ESP32-S2
|
|
70
|
+
- ESP32-S3
|
|
71
|
+
- ESP32-C3
|
|
72
|
+
- ESP32-WROOM
|
|
73
|
+
- ESP32-WROVER
|
|
74
|
+
|
|
75
|
+
### ESP8266 Boards
|
|
76
|
+
All ESP8266 boards are supported:
|
|
77
|
+
- NodeMCU
|
|
78
|
+
- Wemos D1 Mini
|
|
79
|
+
- ESP-12E/F
|
|
80
|
+
- ESP-01 (with limitations due to memory)
|
|
81
|
+
|
|
82
|
+
## Dependencies
|
|
83
|
+
|
|
84
|
+
painlessMesh requires these libraries:
|
|
85
|
+
|
|
86
|
+
### Core Dependencies
|
|
87
|
+
- **ArduinoJson** (v6.x) - JSON parsing and generation
|
|
88
|
+
- **TaskScheduler** (v3.x) - Task scheduling system
|
|
89
|
+
|
|
90
|
+
### Platform Dependencies
|
|
91
|
+
- **ESP32 Arduino Core** (v2.0.0+) for ESP32 boards
|
|
92
|
+
- **ESP8266 Arduino Core** (v3.0.0+) for ESP8266 boards
|
|
93
|
+
|
|
94
|
+
## Development Environment Setup
|
|
95
|
+
|
|
96
|
+
### For Library Development
|
|
97
|
+
|
|
98
|
+
If you plan to contribute to painlessMesh or need the latest development version:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Clone the repository
|
|
102
|
+
git clone https://github.com/Alteriom/painlessMesh.git
|
|
103
|
+
cd painlessMesh
|
|
104
|
+
|
|
105
|
+
# Initialize submodules
|
|
106
|
+
git submodule init
|
|
107
|
+
git submodule update
|
|
108
|
+
|
|
109
|
+
# Install test dependencies (for desktop testing)
|
|
110
|
+
cd test
|
|
111
|
+
git clone https://github.com/bblanchon/ArduinoJson.git
|
|
112
|
+
git clone https://github.com/arkhipenko/TaskScheduler.git
|
|
113
|
+
cd ..
|
|
114
|
+
|
|
115
|
+
# Build tests (requires CMake and Ninja)
|
|
116
|
+
cmake -G Ninja .
|
|
117
|
+
ninja
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Desktop Testing (Linux/macOS/Windows)
|
|
121
|
+
|
|
122
|
+
For development and testing on your computer:
|
|
123
|
+
|
|
124
|
+
#### Requirements
|
|
125
|
+
- CMake 3.10+
|
|
126
|
+
- Ninja build system
|
|
127
|
+
- Boost libraries
|
|
128
|
+
- C++14 compatible compiler
|
|
129
|
+
|
|
130
|
+
#### Ubuntu/Debian
|
|
131
|
+
```bash
|
|
132
|
+
sudo apt update
|
|
133
|
+
sudo apt install cmake ninja-build libboost-all-dev build-essential
|
|
134
|
+
|
|
135
|
+
# Clone and build
|
|
136
|
+
git clone https://github.com/Alteriom/painlessMesh.git
|
|
137
|
+
cd painlessMesh
|
|
138
|
+
git submodule update --init
|
|
139
|
+
cmake -G Ninja .
|
|
140
|
+
ninja
|
|
141
|
+
|
|
142
|
+
# Run tests
|
|
143
|
+
run-parts --regex catch_ bin/
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### macOS
|
|
147
|
+
```bash
|
|
148
|
+
# Install dependencies
|
|
149
|
+
brew install cmake ninja boost
|
|
150
|
+
|
|
151
|
+
# Clone and build
|
|
152
|
+
git clone https://github.com/Alteriom/painlessMesh.git
|
|
153
|
+
cd painlessMesh
|
|
154
|
+
git submodule update --init
|
|
155
|
+
cmake -G Ninja .
|
|
156
|
+
ninja
|
|
157
|
+
|
|
158
|
+
# Run tests
|
|
159
|
+
run-parts --regex catch_ bin/
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### Windows
|
|
163
|
+
Use Visual Studio with CMake support or install dependencies via vcpkg:
|
|
164
|
+
|
|
165
|
+
```powershell
|
|
166
|
+
# Install vcpkg first, then:
|
|
167
|
+
vcpkg install boost:x64-windows
|
|
168
|
+
cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=path/to/vcpkg.cmake .
|
|
169
|
+
ninja
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Version Compatibility
|
|
173
|
+
|
|
174
|
+
### Current Stable Version
|
|
175
|
+
- **painlessMesh**: 1.5.x
|
|
176
|
+
- **ArduinoJson**: 6.21.x
|
|
177
|
+
- **TaskScheduler**: 3.7.x
|
|
178
|
+
|
|
179
|
+
### Legacy Support
|
|
180
|
+
- painlessMesh 1.4.x - Compatible with older ESP cores
|
|
181
|
+
- ArduinoJson 5.x - No longer supported
|
|
182
|
+
|
|
183
|
+
## Memory Requirements
|
|
184
|
+
|
|
185
|
+
### ESP32
|
|
186
|
+
- **RAM**: ~50KB minimum for basic mesh functionality
|
|
187
|
+
- **Flash**: ~200KB for core library + your application
|
|
188
|
+
- **Recommended**: 320KB+ RAM for complex applications
|
|
189
|
+
|
|
190
|
+
### ESP8266
|
|
191
|
+
- **RAM**: ~20KB minimum for basic mesh functionality
|
|
192
|
+
- **Flash**: ~150KB for core library + your application
|
|
193
|
+
- **Recommended**: 80KB+ RAM for stable operation
|
|
194
|
+
- **Note**: ESP-01 (512KB flash) may have limitations
|
|
195
|
+
|
|
196
|
+
## Configuration Options
|
|
197
|
+
|
|
198
|
+
### Build Flags
|
|
199
|
+
|
|
200
|
+
Add these to your build configuration if needed:
|
|
201
|
+
|
|
202
|
+
```ini
|
|
203
|
+
# platformio.ini
|
|
204
|
+
build_flags =
|
|
205
|
+
-DPAINLESSMESH_ENABLE_DEBUG=1 # Enable debug output
|
|
206
|
+
-DPAINLESSMESH_MAX_CONNECTIONS=10 # Maximum connections
|
|
207
|
+
-DTASK_SCHEDULER_DEBUG=1 # TaskScheduler debug
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Arduino IDE Defines
|
|
211
|
+
|
|
212
|
+
Add at the top of your sketch:
|
|
213
|
+
|
|
214
|
+
```cpp
|
|
215
|
+
#define PAINLESSMESH_ENABLE_DEBUG 1
|
|
216
|
+
#define PAINLESSMESH_MAX_CONNECTIONS 10
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## IDE-Specific Setup
|
|
220
|
+
|
|
221
|
+
### Visual Studio Code + PlatformIO
|
|
222
|
+
|
|
223
|
+
1. Install the PlatformIO IDE extension
|
|
224
|
+
2. Create new project or open existing
|
|
225
|
+
3. Add library dependencies to `platformio.ini`
|
|
226
|
+
4. Use Ctrl+Shift+P → "PlatformIO: Build" to compile
|
|
227
|
+
|
|
228
|
+
### Arduino IDE 2.0
|
|
229
|
+
|
|
230
|
+
1. Install via Library Manager (same as Arduino IDE 1.x)
|
|
231
|
+
2. Use the new autocomplete features for better development experience
|
|
232
|
+
3. Debugging support available with compatible boards
|
|
233
|
+
|
|
234
|
+
## Verification
|
|
235
|
+
|
|
236
|
+
Test your installation with this minimal example:
|
|
237
|
+
|
|
238
|
+
```cpp
|
|
239
|
+
#include "painlessMesh.h"
|
|
240
|
+
|
|
241
|
+
painlessMesh mesh;
|
|
242
|
+
|
|
243
|
+
void setup() {
|
|
244
|
+
Serial.begin(115200);
|
|
245
|
+
Serial.println("painlessMesh installation test");
|
|
246
|
+
|
|
247
|
+
// If this compiles and uploads successfully, installation is correct
|
|
248
|
+
mesh.init("TestNetwork", "password", 5555);
|
|
249
|
+
Serial.println("painlessMesh initialized successfully!");
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
void loop() {
|
|
253
|
+
mesh.update();
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
If this compiles and uploads without errors, your installation is complete!
|
|
258
|
+
|
|
259
|
+
## Next Steps
|
|
260
|
+
|
|
261
|
+
- Try the [Quick Start Guide](quickstart.md) to create your first mesh
|
|
262
|
+
- Explore [Basic Examples](../tutorials/basic-examples.md)
|
|
263
|
+
- Read about [Mesh Architecture](../architecture/mesh-architecture.md)
|
|
264
|
+
|
|
265
|
+
## Troubleshooting Installation
|
|
266
|
+
|
|
267
|
+
**Library not found errors?**
|
|
268
|
+
- Check that ArduinoJson and TaskScheduler are installed
|
|
269
|
+
- Verify library versions are compatible
|
|
270
|
+
- Try cleaning and rebuilding your project
|
|
271
|
+
|
|
272
|
+
**Compilation errors?**
|
|
273
|
+
- Ensure you're using a supported ESP32/ESP8266 core version
|
|
274
|
+
- Check that your board selection matches your hardware
|
|
275
|
+
- See [Common Issues](../troubleshooting/common-issues.md) for more help
|