@alteriom/painlessmesh 1.8.14 → 1.9.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.
- package/BRIDGE_TO_INTERNET.md +229 -0
- package/CHANGELOG.md +89 -1
- package/CONTRIBUTING.md +79 -0
- package/README.md +70 -143
- package/docs/README.md +1 -0
- package/docs/api/shared-gateway.md +1207 -0
- package/docs/troubleshooting/common-issues.md +28 -0
- package/docs/troubleshooting/faq.md +113 -12
- package/examples/basic/test/simulator/CMakeLists.txt +40 -0
- package/examples/basic/test/simulator/README.md +149 -0
- package/examples/basic/test/simulator/firmware/basic_firmware.hpp +117 -0
- package/examples/basic/test/simulator/scenarios/basic_mesh_test.yaml +81 -0
- package/examples/bridge/bridge.ino +17 -4
- package/examples/bridge_failover/README.md +81 -0
- package/examples/bridge_failover/bridge_failover.ino +51 -6
- package/examples/sharedGateway/README.md +235 -0
- package/examples/{meshCommandNode → sharedGateway}/platformio.ini +3 -2
- package/examples/sharedGateway/sharedGateway.ino +303 -0
- package/library.json +3 -22
- package/library.properties +1 -1
- package/package.json +3 -3
- package/src/arduino/wifi.hpp +380 -13
- package/src/painlessmesh/gateway.hpp +2120 -0
- package/src/painlessmesh/mesh.hpp +1034 -6
- package/src/painlessmesh/message_tracker.hpp +311 -0
- package/src/painlessmesh/protocol.hpp +6 -0
- package/DOCUMENTATION_INDEX.md +0 -146
- package/docs/API_DESIGN_GUIDELINES.md +0 -414
- package/docs/ARDUINO_LIBRARY_MANAGER_SUBMISSION.md +0 -331
- package/docs/BOOLEAN_NAMING_CONVENTION.md +0 -235
- package/docs/BRIDGE_FAILOVER.md +0 -512
- package/docs/BRIDGE_HEALTH_MONITORING.md +0 -293
- package/docs/CHANNEL_SYNCHRONIZATION.md +0 -209
- package/docs/CREATE_MISSING_RELEASES.md +0 -321
- package/docs/DOCUMENTATION_MIGRATION_PLAN.md +0 -176
- package/docs/FAQ_VERSION_NUMBERS.md +0 -152
- package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +0 -1062
- package/docs/MESH_TOPOLOGY_GUIDE.md +0 -992
- package/docs/MESH_TOPOLOGY_PROGRESS.md +0 -422
- package/docs/MQTT_BRIDGE_COMMANDS.md +0 -894
- package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +0 -324
- package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +0 -576
- package/docs/MQTT_SCHEMA_COMPLIANCE.md +0 -340
- package/docs/MQTT_SCHEMA_PROPOSALS.md +0 -446
- package/docs/MQTT_SCHEMA_REVIEW.md +0 -690
- package/docs/OTA_COMMANDS_REFERENCE.md +0 -554
- package/docs/PHASE1_GUIDE.md +0 -349
- package/docs/PHASE2_GUIDE.md +0 -543
- package/docs/QUICK_REFERENCE_VERSIONING.md +0 -127
- package/docs/RELEASE_AGENT_SUMMARY.md +0 -386
- package/docs/SCHEMA_VALIDATION_CHECKLIST.md +0 -222
- package/docs/VERSION_MANAGEMENT.md +0 -213
- package/docs/archive/DOCUSAURUS_DEPLOYMENT.md +0 -166
- package/docs/archive/FEATURE_PROPOSALS.md +0 -337
- package/docs/archive/LIBRARY_JSON_FIX.md +0 -98
- package/docs/archive/LIBRARY_STRUCTURE_FIX.md +0 -215
- package/docs/archive/PHASE1_IMPLEMENTATION.md +0 -325
- package/docs/archive/PHASE2_IMPLEMENTATION.md +0 -567
- package/docs/archive/RELEASE_SUMMARY.md +0 -173
- package/docs/archive/SCONS_BUILD_FIX.md +0 -313
- package/docs/archive/TRIGGER_RELEASE.md +0 -280
- package/docs/archive/VECTOR_INCLUDE_FIX.md +0 -129
- package/docs/archive/ota-and-status-enhancements.md +0 -911
- package/docs/archive/ota-status-architecture-diagrams.md +0 -658
- package/docs/archive/ota-status-quick-reference.md +0 -284
- package/docs/design/.gitkeep +0 -1
- package/docs/design/STATION_CREDENTIALS_DESIGN.md +0 -182
- package/docs/development/ARDUINO_COMPLIANCE_SUMMARY.md +0 -71
- package/docs/development/CODE_REFACTORING_RECOMMENDATIONS.md +0 -1011
- package/docs/development/DOCKER_TESTING.md +0 -196
- package/docs/development/PLATFORMIO_USAGE.md +0 -180
- package/docs/development/TESTING_SUMMARY.md +0 -126
- package/docs/development/contributing.md +0 -301
- package/docs/development/documentation.md +0 -583
- package/docs/features/DIAGNOSTICS_API.md +0 -534
- package/docs/implementation/BRIDGE_ARCHITECTURE_IMPLEMENTATION.md +0 -340
- package/docs/implementation/BRIDGE_HEALTH_MONITORING_IMPLEMENTATION.md +0 -213
- package/docs/implementation/BRIDGE_STATUS_FEATURE.md +0 -635
- package/docs/implementation/DIAGNOSTICS_API_IMPLEMENTATION.md +0 -232
- package/docs/implementation/IMPLEMENTATION_COMPLETE.md +0 -228
- package/docs/implementation/IMPLEMENTATION_NTP_TIME_SYNC.md +0 -325
- package/docs/implementation/IMPLEMENTATION_SUMMARY.md +0 -316
- package/docs/implementation/MESSAGE_QUEUE_IMPLEMENTATION.md +0 -405
- package/docs/implementation/MULTI_BRIDGE_IMPLEMENTATION.md +0 -520
- package/docs/implementation/NTP_TIME_SYNC_FEATURE.md +0 -392
- package/docs/improvements/FUTURE_PROPOSALS.md +0 -1016
- package/docs/improvements/IMPLEMENTATION_HISTORY.md +0 -1091
- package/docs/improvements/OTA_STATUS_ENHANCEMENTS.md +0 -709
- package/docs/improvements/README.md +0 -212
- package/docs/internal/CUSTOM_AGENT_ANALYSIS.md +0 -391
- package/docs/internal/ISSUE_65_VERIFICATION.md +0 -947
- package/docs/internal/ISSUE_66_CLOSURE.md +0 -249
- package/docs/internal/ISSUE_66_STATUS.md +0 -316
- package/docs/internal/PR_SUMMARY.md +0 -315
- package/docs/internal/REVIEW_SUMMARY.md +0 -332
- package/docs/multi-bridge-setup.md +0 -1025
- package/docs/platformio-publishing.md +0 -255
- package/docs/platformio-setup-summary.md +0 -121
- package/docs/releases/ANNOUNCEMENT_v1.8.6.md +0 -63
- package/docs/releases/ANNOUNCEMENT_v1.8.7.md +0 -113
- package/docs/releases/BRIDGE_STATUS_SELF_REGISTRATION_FIX.md +0 -221
- package/docs/releases/FEATURE_HISTORY.md +0 -543
- package/docs/releases/GITHUB_RELEASE_v1.8.6.md +0 -71
- package/docs/releases/GITHUB_RELEASE_v1.8.7.md +0 -90
- package/docs/releases/PATCH_v1.7.2.md +0 -262
- package/docs/releases/PATCH_v1.7.3.md +0 -262
- package/docs/releases/PATCH_v1.7.4.md +0 -219
- package/docs/releases/PHASE1_SUMMARY.md +0 -246
- package/docs/releases/PHASE2_SUMMARY.md +0 -499
- package/docs/releases/PUBLISH_v1.8.0_INSTRUCTIONS.md +0 -163
- package/docs/releases/QUICK_START_RELEASES.md +0 -113
- package/docs/releases/RELEASE_CHECKLIST_1.8.10.md +0 -331
- package/docs/releases/RELEASE_CHECKLIST_1.8.9.md +0 -207
- package/docs/releases/RELEASE_CHECKLIST_v1.7.4.md +0 -253
- package/docs/releases/RELEASE_CHECKLIST_v1.7.5.md +0 -315
- package/docs/releases/RELEASE_CHECKLIST_v1.7.6.md +0 -389
- package/docs/releases/RELEASE_CHECKLIST_v1.8.0.md +0 -331
- package/docs/releases/RELEASE_CHECKLIST_v1.8.2.md +0 -309
- package/docs/releases/RELEASE_NOTES_1.7.0.md +0 -539
- package/docs/releases/RELEASE_NOTES_1.8.10.md +0 -239
- package/docs/releases/RELEASE_NOTES_1.8.9.md +0 -213
- package/docs/releases/RELEASE_NOTES_v1.8.0.md +0 -685
- package/docs/releases/RELEASE_NOTES_v1.8.1.md +0 -221
- package/docs/releases/RELEASE_NOTES_v1.8.2.md +0 -421
- package/docs/releases/RELEASE_NOTES_v1.8.3.md +0 -292
- package/docs/releases/RELEASE_NOTES_v1.8.4.md +0 -277
- package/docs/releases/RELEASE_NOTES_v1.8.6.md +0 -205
- package/docs/releases/RELEASE_NOTES_v1.8.7.md +0 -184
- package/docs/releases/RELEASE_PLAN_v1.7.6.md +0 -816
- package/docs/releases/RELEASE_SUMMARY_1.8.10.md +0 -193
- package/docs/releases/RELEASE_SUMMARY_v1.7.4.md +0 -276
- package/docs/releases/RELEASE_SUMMARY_v1.7.5.md +0 -322
- package/docs/releases/RELEASE_SUMMARY_v1.7.6.md +0 -436
- package/docs/releases/RELEASE_SUMMARY_v1.7.7.md +0 -391
- package/docs/releases/RELEASE_SUMMARY_v1.7.8.md +0 -523
- package/docs/releases/RELEASE_SUMMARY_v1.7.9.md +0 -542
- package/docs/troubleshooting/ARDUINO_IDE_VERSION_FIX_SUMMARY.md +0 -229
- package/docs/troubleshooting/ARDUINO_LIBRARY_NAME_FIX.md +0 -197
- package/docs/troubleshooting/CRASH_QUICK_REF.md +0 -93
- package/docs/troubleshooting/ESP32_C6_COMPATIBILITY.md +0 -157
- package/docs/troubleshooting/FREERTOS_ASSERTION_FAILURE.md +0 -288
- package/docs/troubleshooting/FREERTOS_FIX_IMPLEMENTATION.md +0 -267
- package/docs/troubleshooting/NPM_PUBLISHING_ISSUE_SUMMARY.md +0 -110
- package/docs/troubleshooting/PAINLESSMESH_V1.7.4_COMPILATION_ISSUES.md +0 -547
- package/docs/troubleshooting/QUICK_FIX_FREERTOS.md +0 -164
- package/docs/troubleshooting/SENSOR_NODE_CONNECTION_CRASH.md +0 -264
- package/docs/troubleshooting/station-reconnection-issues.md +0 -172
- package/docs/v1.7.7_MQTT_IMPROVEMENTS.md +0 -794
- package/docs/wiki/API-Reference.md +0 -246
- package/docs/wiki/Complete-Documentation.md +0 -123
- package/examples/alteriomImproved/alteriom_sensor_package.hpp +0 -224
- package/examples/alteriomImproved/improved_sensor_node.ino +0 -248
- package/examples/alteriomImproved/platformio.ini +0 -32
- package/examples/alteriomMetricsHealth/alteriom_sensor_package.hpp +0 -796
- package/examples/alteriomMetricsHealth/metrics_health_node.ino +0 -429
- package/examples/alteriomMetricsHealth/platformio.ini +0 -26
- package/examples/alteriomPhase1/alteriom_sensor_package.hpp +0 -224
- package/examples/alteriomPhase1/phase1_features.ino +0 -242
- package/examples/alteriomPhase1/platformio.ini +0 -26
- package/examples/alteriomPhase2/alteriom_sensor_package.hpp +0 -224
- package/examples/alteriomPhase2/phase2_features.ino +0 -186
- package/examples/alteriomPhase2/platformio.ini +0 -26
- package/examples/alteriomSensorNode/alteriom_sensor_node.ino +0 -186
- package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +0 -1227
- package/examples/alteriomSensorNode/platformio.ini +0 -26
- package/examples/bridge/alteriom_sensor_package.hpp +0 -1170
- package/examples/bridge/bridge_health_monitoring_example.ino +0 -188
- package/examples/bridge/enhanced_mqtt_bridge.hpp +0 -610
- package/examples/bridge/enhanced_mqtt_bridge_example.ino +0 -226
- package/examples/bridge/mesh_event_publisher.hpp +0 -253
- package/examples/bridge/mesh_topology_reporter.hpp +0 -303
- package/examples/bridge/mqtt_command_bridge.hpp +0 -459
- package/examples/bridge/mqtt_status_bridge.hpp +0 -519
- package/examples/bridgeAwareSensorNode/alteriom_sensor_package.hpp +0 -1227
- package/examples/bridgeAwareSensorNode/bridgeAwareSensorNode.ino +0 -342
- package/examples/bridgeAwareSensorNode/platformio.ini +0 -26
- package/examples/diagnosticsExample/diagnosticsExample.ino +0 -171
- package/examples/diagnosticsExample/platformio.ini +0 -26
- package/examples/echoNode/echoNode.ino +0 -33
- package/examples/echoNode/platformio.ini +0 -26
- package/examples/meshCommandNode/alteriom_sensor_package.hpp +0 -235
- package/examples/meshCommandNode/meshCommandNode.ino +0 -265
- package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +0 -235
- package/examples/mqttCommandBridge/mesh_event_publisher.hpp +0 -253
- package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +0 -303
- package/examples/mqttCommandBridge/mqttCommandBridge.ino +0 -254
- package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +0 -462
- package/examples/mqttCommandBridge/platformio.ini +0 -27
- package/examples/mqttStatusBridge/mqttStatusBridge.ino +0 -218
- package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +0 -522
- package/examples/mqttStatusBridge/platformio.ini +0 -27
- package/examples/mqttTopologyTest/README.md +0 -467
- package/examples/mqttTopologyTest/mqttTopologyTest.ino +0 -754
- package/examples/mqttTopologyTest/platformio.ini +0 -27
- package/examples/multi_bridge/README.md +0 -346
- package/examples/multi_bridge/primary_bridge.ino +0 -96
- package/examples/multi_bridge/regular_node.ino +0 -141
- package/examples/multi_bridge/secondary_bridge.ino +0 -111
- package/examples/ntpTimeSyncBridge/alteriom_sensor_package.hpp +0 -1383
- package/examples/ntpTimeSyncBridge/ntpTimeSyncBridge.ino +0 -86
- package/examples/ntpTimeSyncNode/alteriom_sensor_package.hpp +0 -1383
- package/examples/ntpTimeSyncNode/ntpTimeSyncNode.ino +0 -109
- package/examples/queued_alarms/README.md +0 -390
- package/examples/queued_alarms/queued_alarms.ino +0 -265
- package/examples/routing_demo/README.md +0 -172
- package/examples/routing_demo/routing_demo.ino +0 -102
- package/examples/rtcIntegration/README.md +0 -294
- package/examples/rtcIntegration/rtcIntegration.ino +0 -210
|
@@ -105,6 +105,29 @@ To prevent oscillation:
|
|
|
105
105
|
#define INITIAL_BRIDGE false
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
+
### Channel Detection (Automatic)
|
|
109
|
+
|
|
110
|
+
**Critical for Bridge Discovery:**
|
|
111
|
+
|
|
112
|
+
Regular nodes **must** use channel auto-detection (channel=0) to discover bridges. This is because:
|
|
113
|
+
|
|
114
|
+
1. Bridge nodes operate on the **router's WiFi channel** (e.g., channel 6)
|
|
115
|
+
2. Regular nodes scanning on a fixed channel (e.g., channel 1) cannot see bridges on different channels
|
|
116
|
+
3. Channel auto-detection scans all channels to find the mesh
|
|
117
|
+
|
|
118
|
+
The example code automatically uses channel=0:
|
|
119
|
+
```cpp
|
|
120
|
+
// Regular node initialization with auto-detection
|
|
121
|
+
mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT, WIFI_AP_STA, 0);
|
|
122
|
+
// ^ channel=0
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**What happens:**
|
|
126
|
+
- Node scans all WiFi channels (1-13) to find the mesh SSID
|
|
127
|
+
- Detects the channel where the bridge/mesh is operating
|
|
128
|
+
- Joins the mesh on that channel
|
|
129
|
+
- Ensures proper bridge discovery and mesh connectivity
|
|
130
|
+
|
|
108
131
|
## Setup Instructions
|
|
109
132
|
|
|
110
133
|
You can choose between two deployment modes:
|
|
@@ -237,6 +260,14 @@ mesh.setElectionTimeout(5000);
|
|
|
237
260
|
// Prevents nodes with poor signal from becoming bridges when isolated
|
|
238
261
|
mesh.setMinimumBridgeRSSI(-80);
|
|
239
262
|
|
|
263
|
+
// Set startup delay before first election check (default: 60000 ms = 60 seconds)
|
|
264
|
+
// Longer delays allow more time for mesh formation, reducing split-brain risk
|
|
265
|
+
mesh.setElectionStartupDelay(90000); // 90 seconds
|
|
266
|
+
|
|
267
|
+
// Set random delay range for elections (default: 1000-3000 ms)
|
|
268
|
+
// Longer delays reduce simultaneous election risk when multiple nodes start together
|
|
269
|
+
mesh.setElectionRandomDelay(10000, 30000); // 10-30 seconds
|
|
270
|
+
|
|
240
271
|
// Set bridge status broadcast interval
|
|
241
272
|
mesh.setBridgeStatusInterval(30000);
|
|
242
273
|
|
|
@@ -337,12 +368,62 @@ bool amBridge = mesh.isBridge();
|
|
|
337
368
|
|
|
338
369
|
**Symptoms**: Regular nodes show "No primary bridge available!" and "Known bridges: 0"
|
|
339
370
|
|
|
371
|
+
**Root Cause**: Regular nodes must use channel auto-detection (channel=0) to discover bridges on the router's channel.
|
|
372
|
+
|
|
340
373
|
**Solutions**:
|
|
374
|
+
- **CRITICAL**: Initialize regular nodes with `channel=0` for auto-detection:
|
|
375
|
+
```cpp
|
|
376
|
+
mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT, WIFI_AP_STA, 0);
|
|
377
|
+
```
|
|
341
378
|
- Verify bridge node successfully connected to router (check serial output)
|
|
342
379
|
- Ensure mesh network name and password match on all nodes
|
|
343
380
|
- Check that nodes are on the same WiFi channel as the router/bridge
|
|
344
381
|
- Wait a few seconds after startup for initial discovery
|
|
345
382
|
- Bridge now broadcasts immediately on startup and when nodes connect (fixed in v1.8.4+)
|
|
383
|
+
- **Note**: The example code has been updated to use channel=0 by default
|
|
384
|
+
|
|
385
|
+
### Split-Brain Scenario (Multiple Bridges)
|
|
386
|
+
|
|
387
|
+
**Symptoms**: When nodes start simultaneously, both become bridges and don't see each other
|
|
388
|
+
|
|
389
|
+
**Root Cause**: Race condition - both nodes detect "no bridge" after startup period, run isolated elections, each wins their own election and becomes a bridge.
|
|
390
|
+
|
|
391
|
+
**Why This Happens**:
|
|
392
|
+
1. Both nodes initialize as regular nodes with `INITIAL_BRIDGE = false`
|
|
393
|
+
2. After 60s startup period, both detect "no bridge exists"
|
|
394
|
+
3. Both trigger elections with short 1-3s random delay
|
|
395
|
+
4. If mesh connection hasn't formed yet, each runs an isolated election
|
|
396
|
+
5. Each node wins its own election and becomes a bridge
|
|
397
|
+
6. Once both are bridges, they stop scanning for mesh nodes
|
|
398
|
+
|
|
399
|
+
**Solutions**:
|
|
400
|
+
|
|
401
|
+
**Option 1: Increase Startup Delay (Recommended)**
|
|
402
|
+
```cpp
|
|
403
|
+
// Allow more time for mesh formation before elections start
|
|
404
|
+
mesh.setElectionStartupDelay(90000); // 90 seconds instead of default 60 seconds
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
**Option 2: Increase Random Election Delay**
|
|
408
|
+
```cpp
|
|
409
|
+
// Provide more mesh discovery time when elections trigger
|
|
410
|
+
mesh.setElectionRandomDelay(10000, 30000); // 10-30 seconds instead of 1-3 seconds
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
**Option 3: Combine Both**
|
|
414
|
+
```cpp
|
|
415
|
+
mesh.setElectionStartupDelay(90000); // 90 second startup delay
|
|
416
|
+
mesh.setElectionRandomDelay(10000, 30000); // 10-30 second random delay
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
**Option 4: Stagger Node Startup**
|
|
420
|
+
- Power on nodes 10-20 seconds apart
|
|
421
|
+
- First node establishes mesh, second node discovers it
|
|
422
|
+
|
|
423
|
+
**Option 5: Use Pre-Designated Bridge**
|
|
424
|
+
- Set `INITIAL_BRIDGE = true` on one node only
|
|
425
|
+
- Guarantees single bridge from startup
|
|
426
|
+
- Good for fixed deployments
|
|
346
427
|
|
|
347
428
|
### Bridge Reports No Internet When Router Has Internet
|
|
348
429
|
|
|
@@ -34,6 +34,12 @@
|
|
|
34
34
|
// - Deterministic winner selection with tiebreakers
|
|
35
35
|
// - Seamless promotion to bridge role
|
|
36
36
|
// - Bridge takeover announcements
|
|
37
|
+
// - Automatic mesh channel detection for bridge discovery
|
|
38
|
+
//
|
|
39
|
+
// Important Note:
|
|
40
|
+
// Regular nodes MUST use channel auto-detection (channel=0) to discover
|
|
41
|
+
// bridges that are operating on the router's WiFi channel. The example
|
|
42
|
+
// automatically uses channel=0 for this purpose.
|
|
37
43
|
//
|
|
38
44
|
//************************************************************
|
|
39
45
|
|
|
@@ -122,15 +128,31 @@ void setup() {
|
|
|
122
128
|
Serial.println("This node will start as the primary bridge\n");
|
|
123
129
|
|
|
124
130
|
// Initialize as bridge with automatic channel detection
|
|
125
|
-
mesh.initAsBridge(MESH_PREFIX, MESH_PASSWORD,
|
|
126
|
-
|
|
127
|
-
|
|
131
|
+
bool bridgeSuccess = mesh.initAsBridge(MESH_PREFIX, MESH_PASSWORD,
|
|
132
|
+
ROUTER_SSID, ROUTER_PASSWORD,
|
|
133
|
+
&userScheduler, MESH_PORT);
|
|
134
|
+
|
|
135
|
+
if (!bridgeSuccess) {
|
|
136
|
+
Serial.println("✗ Failed to initialize as bridge!");
|
|
137
|
+
Serial.println("Router unreachable - falling back to regular node with failover");
|
|
138
|
+
|
|
139
|
+
// Fallback: Initialize as regular node with bridge failover enabled
|
|
140
|
+
// This allows automatic promotion to bridge when router becomes available
|
|
141
|
+
// channel=0 enables automatic mesh channel detection
|
|
142
|
+
mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT, WIFI_AP_STA, 0);
|
|
143
|
+
mesh.setRouterCredentials(ROUTER_SSID, ROUTER_PASSWORD);
|
|
144
|
+
mesh.enableBridgeFailover(true);
|
|
145
|
+
mesh.setElectionTimeout(5000);
|
|
146
|
+
|
|
147
|
+
Serial.println("✓ Running as regular node - will auto-promote when router available");
|
|
148
|
+
}
|
|
128
149
|
} else {
|
|
129
150
|
Serial.println("Mode: REGULAR NODE (Failover Enabled)");
|
|
130
151
|
Serial.println("This node can become bridge via election\n");
|
|
131
152
|
|
|
132
|
-
// Initialize as regular node
|
|
133
|
-
mesh
|
|
153
|
+
// Initialize as regular node with auto-channel detection
|
|
154
|
+
// channel=0 enables automatic mesh channel detection
|
|
155
|
+
mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT, WIFI_AP_STA, 0);
|
|
134
156
|
|
|
135
157
|
// Configure for automatic bridge failover
|
|
136
158
|
mesh.setRouterCredentials(ROUTER_SSID, ROUTER_PASSWORD);
|
|
@@ -140,6 +162,14 @@ void setup() {
|
|
|
140
162
|
// Optional: Set minimum RSSI for isolated bridge elections (default: -80 dBm)
|
|
141
163
|
// This prevents nodes with poor signal from becoming bridges when isolated
|
|
142
164
|
// mesh.setMinimumBridgeRSSI(-80); // Uncomment to customize threshold
|
|
165
|
+
|
|
166
|
+
// Optional: Configure election timing to prevent split-brain when nodes start simultaneously
|
|
167
|
+
// Longer startup delay allows more time for mesh formation before elections begin
|
|
168
|
+
// mesh.setElectionStartupDelay(90000); // 90 seconds (default: 60 seconds)
|
|
169
|
+
|
|
170
|
+
// Optional: Increase random delay to reduce simultaneous election risk
|
|
171
|
+
// Longer delays provide more mesh discovery time when multiple nodes detect missing bridge
|
|
172
|
+
// mesh.setElectionRandomDelay(10000, 30000); // 10-30 seconds (default: 1-3 seconds)
|
|
143
173
|
}
|
|
144
174
|
|
|
145
175
|
// Register callbacks
|
|
@@ -172,6 +202,7 @@ void loop() {
|
|
|
172
202
|
Serial.println("\n--- Bridge Status ---");
|
|
173
203
|
Serial.printf("I am bridge: %s\n", mesh.isBridge() ? "YES" : "NO");
|
|
174
204
|
Serial.printf("Internet available: %s\n", mesh.hasInternetConnection() ? "YES" : "NO");
|
|
205
|
+
Serial.printf("Mesh connections active: %s\n", mesh.hasActiveMeshConnections() ? "YES" : "NO");
|
|
175
206
|
|
|
176
207
|
auto bridges = mesh.getBridges();
|
|
177
208
|
Serial.printf("Known bridges: %d\n", bridges.size());
|
|
@@ -189,7 +220,21 @@ void loop() {
|
|
|
189
220
|
Serial.printf("Primary bridge: %u (RSSI: %d dBm)\n",
|
|
190
221
|
primary->nodeId, primary->routerRSSI);
|
|
191
222
|
} else {
|
|
192
|
-
|
|
223
|
+
// Provide more context about why no primary bridge
|
|
224
|
+
if (!mesh.hasActiveMeshConnections()) {
|
|
225
|
+
Serial.println("No primary bridge: This node is disconnected from mesh");
|
|
226
|
+
// Show last known bridge info if available
|
|
227
|
+
auto lastKnown = mesh.getLastKnownBridge();
|
|
228
|
+
if (lastKnown) {
|
|
229
|
+
Serial.printf(" Last known bridge: %u (RSSI: %d dBm, last seen %u ms ago)\n",
|
|
230
|
+
lastKnown->nodeId, lastKnown->routerRSSI,
|
|
231
|
+
millis() - lastKnown->lastSeen);
|
|
232
|
+
}
|
|
233
|
+
} else if (bridges.empty()) {
|
|
234
|
+
Serial.println("No primary bridge: No bridges discovered yet");
|
|
235
|
+
} else {
|
|
236
|
+
Serial.println("No primary bridge: Known bridges timed out or lost Internet");
|
|
237
|
+
}
|
|
193
238
|
}
|
|
194
239
|
Serial.println("--------------------\n");
|
|
195
240
|
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Shared Gateway Example
|
|
2
|
+
|
|
3
|
+
This example demonstrates the **Shared Gateway Mode** feature of painlessMesh. Unlike Bridge Mode where only one node connects to the router, Shared Gateway Mode allows **ALL nodes** to connect to the same WiFi router while maintaining mesh connectivity.
|
|
4
|
+
|
|
5
|
+
## What is Shared Gateway Mode?
|
|
6
|
+
|
|
7
|
+
In a traditional painlessMesh network:
|
|
8
|
+
- Regular nodes only communicate over the mesh
|
|
9
|
+
- Bridge nodes connect to a router AND the mesh
|
|
10
|
+
- Only the bridge can access the Internet
|
|
11
|
+
|
|
12
|
+
With Shared Gateway Mode:
|
|
13
|
+
- **All nodes** connect to the same WiFi router
|
|
14
|
+
- **All nodes** maintain mesh connectivity
|
|
15
|
+
- **Any node** can access the Internet directly
|
|
16
|
+
- Provides redundant Internet paths
|
|
17
|
+
|
|
18
|
+
## Architecture
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Internet
|
|
22
|
+
│
|
|
23
|
+
Router
|
|
24
|
+
┌─────────────┼─────────────┐
|
|
25
|
+
│ │ │
|
|
26
|
+
Node A Node B Node C
|
|
27
|
+
(AP+STA) (AP+STA) (AP+STA)
|
|
28
|
+
│ │ │
|
|
29
|
+
└─────────────┼─────────────┘
|
|
30
|
+
Mesh Network
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Hardware Requirements
|
|
34
|
+
|
|
35
|
+
- **ESP32** or **ESP8266** microcontroller
|
|
36
|
+
- WiFi router within range of all nodes
|
|
37
|
+
- USB cable for programming and serial monitoring
|
|
38
|
+
|
|
39
|
+
## Configuration
|
|
40
|
+
|
|
41
|
+
Edit the following defines in `sharedGateway.ino`:
|
|
42
|
+
|
|
43
|
+
```cpp
|
|
44
|
+
// Mesh network settings (must match across all nodes)
|
|
45
|
+
#define MESH_PREFIX "SharedGatewayMesh" // Your mesh network name
|
|
46
|
+
#define MESH_PASSWORD "meshPassword123" // Your mesh network password
|
|
47
|
+
#define MESH_PORT 5555 // TCP port (default: 5555)
|
|
48
|
+
|
|
49
|
+
// Router settings (your WiFi router)
|
|
50
|
+
#define ROUTER_SSID "YourRouterSSID" // Your WiFi router name
|
|
51
|
+
#define ROUTER_PASSWORD "YourRouterPassword" // Your WiFi router password
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Building and Uploading
|
|
55
|
+
|
|
56
|
+
### Using PlatformIO (Recommended)
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# For ESP32
|
|
60
|
+
pio run -e esp32 -t upload
|
|
61
|
+
|
|
62
|
+
# For ESP8266
|
|
63
|
+
pio run -e esp8266 -t upload
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Using Arduino IDE
|
|
67
|
+
|
|
68
|
+
1. Open `sharedGateway.ino` in Arduino IDE
|
|
69
|
+
2. Install the required libraries:
|
|
70
|
+
- ArduinoJson
|
|
71
|
+
- TaskScheduler
|
|
72
|
+
- painlessMesh
|
|
73
|
+
- AsyncTCP (ESP32) or ESPAsyncTCP (ESP8266)
|
|
74
|
+
3. Select your board (ESP32 or ESP8266)
|
|
75
|
+
4. Click Upload
|
|
76
|
+
|
|
77
|
+
## Expected Serial Output
|
|
78
|
+
|
|
79
|
+
After uploading, open Serial Monitor at 115200 baud. You should see:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
================================================
|
|
83
|
+
painlessMesh - Shared Gateway Example
|
|
84
|
+
================================================
|
|
85
|
+
|
|
86
|
+
Initializing Shared Gateway Mode...
|
|
87
|
+
|
|
88
|
+
Mesh SSID: SharedGatewayMesh
|
|
89
|
+
Mesh Port: 5555
|
|
90
|
+
Router SSID: YourRouterSSID
|
|
91
|
+
|
|
92
|
+
=== Shared Gateway Mode Initialization ===
|
|
93
|
+
Step 1: Scanning for router YourRouterSSID to detect channel...
|
|
94
|
+
✓ Router connected on channel 6
|
|
95
|
+
✓ Router IP: 192.168.1.105
|
|
96
|
+
Step 2: Initializing mesh on channel 6...
|
|
97
|
+
Step 3: Establishing router connection in shared gateway mode...
|
|
98
|
+
=== Shared Gateway Mode Active ===
|
|
99
|
+
Mesh Prefix: SharedGatewayMesh
|
|
100
|
+
Mesh Channel: 6 (synced with router)
|
|
101
|
+
Router: YourRouterSSID
|
|
102
|
+
Port: 5555
|
|
103
|
+
Mode: AP+STA (all nodes can connect to router)
|
|
104
|
+
|
|
105
|
+
✓ Shared Gateway Mode initialized successfully!
|
|
106
|
+
|
|
107
|
+
================================================
|
|
108
|
+
Node ID: 2748965421
|
|
109
|
+
Shared Gateway Mode: Active
|
|
110
|
+
Router IP: 192.168.1.105
|
|
111
|
+
Router Channel: 6
|
|
112
|
+
================================================
|
|
113
|
+
|
|
114
|
+
Status broadcasts will be sent every 10 seconds.
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Status Broadcast Output
|
|
118
|
+
|
|
119
|
+
Every 10 seconds, you'll see:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
========== STATUS BROADCAST ==========
|
|
123
|
+
Node ID: 2748965421
|
|
124
|
+
Router: Connected
|
|
125
|
+
IP: 192.168.1.105
|
|
126
|
+
RSSI: -45 dBm
|
|
127
|
+
Channel: 6
|
|
128
|
+
Mesh Nodes: 2
|
|
129
|
+
Shared Gateway Mode: Yes
|
|
130
|
+
Free Heap: 45320 bytes
|
|
131
|
+
Uptime: 120 seconds
|
|
132
|
+
=======================================
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Use Cases
|
|
136
|
+
|
|
137
|
+
### Industrial Sensor Networks
|
|
138
|
+
All sensor nodes can independently send data to cloud services, providing redundancy if any individual node loses connection.
|
|
139
|
+
|
|
140
|
+
### Fish Farm Monitoring
|
|
141
|
+
Critical O2 alarms can reach the cloud through any available path, ensuring no alerts are missed.
|
|
142
|
+
|
|
143
|
+
### Smart Building Systems
|
|
144
|
+
HVAC and security data maintains connectivity through redundant paths for maximum reliability.
|
|
145
|
+
|
|
146
|
+
### Remote Monitoring
|
|
147
|
+
Environmental monitoring stations with shared WiFi infrastructure can relay through nearby nodes if needed.
|
|
148
|
+
|
|
149
|
+
## Troubleshooting
|
|
150
|
+
|
|
151
|
+
### Router Connection Fails
|
|
152
|
+
|
|
153
|
+
**Symptoms:** `✗ Failed to initialize Shared Gateway Mode!`
|
|
154
|
+
|
|
155
|
+
**Solutions:**
|
|
156
|
+
1. Verify router SSID and password are correct
|
|
157
|
+
2. Ensure the router is powered on and within range
|
|
158
|
+
3. Check that the router is operating on 2.4GHz (5GHz not supported)
|
|
159
|
+
4. Try moving the node closer to the router
|
|
160
|
+
|
|
161
|
+
### Mesh Not Forming
|
|
162
|
+
|
|
163
|
+
**Symptoms:** `Mesh Nodes: 0` even with multiple nodes
|
|
164
|
+
|
|
165
|
+
**Solutions:**
|
|
166
|
+
1. Ensure all nodes use the same `MESH_PREFIX` and `MESH_PASSWORD`
|
|
167
|
+
2. Verify all nodes are using the same router (same channel)
|
|
168
|
+
3. Check that nodes are within WiFi range of each other
|
|
169
|
+
4. Restart all nodes simultaneously
|
|
170
|
+
|
|
171
|
+
### Frequent Router Disconnections
|
|
172
|
+
|
|
173
|
+
**Symptoms:** Router status alternates between Connected/Disconnected
|
|
174
|
+
|
|
175
|
+
**Solutions:**
|
|
176
|
+
1. Check router signal strength (RSSI should be > -70 dBm)
|
|
177
|
+
2. Move nodes closer to the router
|
|
178
|
+
3. Reduce number of devices on the router
|
|
179
|
+
4. Check for WiFi interference
|
|
180
|
+
|
|
181
|
+
### Low Memory Warnings
|
|
182
|
+
|
|
183
|
+
**Symptoms:** `Free Heap` decreasing or node crashes
|
|
184
|
+
|
|
185
|
+
**Solutions:**
|
|
186
|
+
1. Reduce JSON document sizes in your code
|
|
187
|
+
2. Limit the number of mesh nodes
|
|
188
|
+
3. Use ESP32 instead of ESP8266 for larger networks
|
|
189
|
+
|
|
190
|
+
## API Reference
|
|
191
|
+
|
|
192
|
+
### Key Method
|
|
193
|
+
|
|
194
|
+
```cpp
|
|
195
|
+
bool initAsSharedGateway(
|
|
196
|
+
String meshPrefix, // Mesh network name
|
|
197
|
+
String meshPassword, // Mesh network password
|
|
198
|
+
String routerSSID, // Router SSID to connect to
|
|
199
|
+
String routerPassword, // Router password
|
|
200
|
+
Scheduler* scheduler, // Task scheduler
|
|
201
|
+
uint16_t port = 5555 // TCP port (optional)
|
|
202
|
+
);
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Returns:** `true` if initialization succeeded, `false` if router connection failed.
|
|
206
|
+
|
|
207
|
+
### Status Methods
|
|
208
|
+
|
|
209
|
+
```cpp
|
|
210
|
+
// Check if shared gateway mode is active
|
|
211
|
+
bool isSharedGatewayMode();
|
|
212
|
+
|
|
213
|
+
// Get router connection status
|
|
214
|
+
WiFi.status() == WL_CONNECTED
|
|
215
|
+
|
|
216
|
+
// Get router IP address
|
|
217
|
+
WiFi.localIP()
|
|
218
|
+
|
|
219
|
+
// Get router signal strength
|
|
220
|
+
WiFi.RSSI()
|
|
221
|
+
|
|
222
|
+
// Get current WiFi channel
|
|
223
|
+
WiFi.channel()
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Related Documentation
|
|
227
|
+
|
|
228
|
+
- [Shared Gateway Design Document](../../docs/design/SHARED_GATEWAY_DESIGN.md)
|
|
229
|
+
- [Bridge Mode Example](../bridge/README.md)
|
|
230
|
+
- [Bridge Failover Example](../bridge_failover/README.md)
|
|
231
|
+
- [painlessMesh Documentation](https://gitlab.com/painlessMesh/painlessMesh/-/wikis/home)
|
|
232
|
+
|
|
233
|
+
## License
|
|
234
|
+
|
|
235
|
+
This example is part of painlessMesh and is released under the same license.
|
|
@@ -7,6 +7,7 @@ lib_deps =
|
|
|
7
7
|
arkhipenko/TaskScheduler
|
|
8
8
|
|
|
9
9
|
lib_ldf_mode = deep+
|
|
10
|
+
|
|
10
11
|
[env:esp8266]
|
|
11
12
|
platform = espressif8266
|
|
12
13
|
board = nodemcuv2
|
|
@@ -14,7 +15,7 @@ framework = arduino
|
|
|
14
15
|
lib_extra_dirs = ../../
|
|
15
16
|
lib_deps =
|
|
16
17
|
${env.lib_deps}
|
|
17
|
-
|
|
18
|
+
esp32async/ESPAsyncTCP@^2.0.0
|
|
18
19
|
|
|
19
20
|
[env:esp32]
|
|
20
21
|
platform = espressif32
|
|
@@ -23,4 +24,4 @@ framework = arduino
|
|
|
23
24
|
lib_extra_dirs = ../../
|
|
24
25
|
lib_deps =
|
|
25
26
|
${env.lib_deps}
|
|
26
|
-
|
|
27
|
+
esp32async/AsyncTCP
|