@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.
Files changed (208) hide show
  1. package/BRIDGE_TO_INTERNET.md +229 -0
  2. package/CHANGELOG.md +89 -1
  3. package/CONTRIBUTING.md +79 -0
  4. package/README.md +70 -143
  5. package/docs/README.md +1 -0
  6. package/docs/api/shared-gateway.md +1207 -0
  7. package/docs/troubleshooting/common-issues.md +28 -0
  8. package/docs/troubleshooting/faq.md +113 -12
  9. package/examples/basic/test/simulator/CMakeLists.txt +40 -0
  10. package/examples/basic/test/simulator/README.md +149 -0
  11. package/examples/basic/test/simulator/firmware/basic_firmware.hpp +117 -0
  12. package/examples/basic/test/simulator/scenarios/basic_mesh_test.yaml +81 -0
  13. package/examples/bridge/bridge.ino +17 -4
  14. package/examples/bridge_failover/README.md +81 -0
  15. package/examples/bridge_failover/bridge_failover.ino +51 -6
  16. package/examples/sharedGateway/README.md +235 -0
  17. package/examples/{meshCommandNode → sharedGateway}/platformio.ini +3 -2
  18. package/examples/sharedGateway/sharedGateway.ino +303 -0
  19. package/library.json +3 -22
  20. package/library.properties +1 -1
  21. package/package.json +3 -3
  22. package/src/arduino/wifi.hpp +380 -13
  23. package/src/painlessmesh/gateway.hpp +2120 -0
  24. package/src/painlessmesh/mesh.hpp +1034 -6
  25. package/src/painlessmesh/message_tracker.hpp +311 -0
  26. package/src/painlessmesh/protocol.hpp +6 -0
  27. package/DOCUMENTATION_INDEX.md +0 -146
  28. package/docs/API_DESIGN_GUIDELINES.md +0 -414
  29. package/docs/ARDUINO_LIBRARY_MANAGER_SUBMISSION.md +0 -331
  30. package/docs/BOOLEAN_NAMING_CONVENTION.md +0 -235
  31. package/docs/BRIDGE_FAILOVER.md +0 -512
  32. package/docs/BRIDGE_HEALTH_MONITORING.md +0 -293
  33. package/docs/CHANNEL_SYNCHRONIZATION.md +0 -209
  34. package/docs/CREATE_MISSING_RELEASES.md +0 -321
  35. package/docs/DOCUMENTATION_MIGRATION_PLAN.md +0 -176
  36. package/docs/FAQ_VERSION_NUMBERS.md +0 -152
  37. package/docs/IMPLEMENTATION_PLAN_MESH_TOPOLOGY.md +0 -1062
  38. package/docs/MESH_TOPOLOGY_GUIDE.md +0 -992
  39. package/docs/MESH_TOPOLOGY_PROGRESS.md +0 -422
  40. package/docs/MQTT_BRIDGE_COMMANDS.md +0 -894
  41. package/docs/MQTT_BRIDGE_IMPLEMENTATION_SUMMARY.md +0 -324
  42. package/docs/MQTT_COMMAND_SCHEMA_PROPOSAL.md +0 -576
  43. package/docs/MQTT_SCHEMA_COMPLIANCE.md +0 -340
  44. package/docs/MQTT_SCHEMA_PROPOSALS.md +0 -446
  45. package/docs/MQTT_SCHEMA_REVIEW.md +0 -690
  46. package/docs/OTA_COMMANDS_REFERENCE.md +0 -554
  47. package/docs/PHASE1_GUIDE.md +0 -349
  48. package/docs/PHASE2_GUIDE.md +0 -543
  49. package/docs/QUICK_REFERENCE_VERSIONING.md +0 -127
  50. package/docs/RELEASE_AGENT_SUMMARY.md +0 -386
  51. package/docs/SCHEMA_VALIDATION_CHECKLIST.md +0 -222
  52. package/docs/VERSION_MANAGEMENT.md +0 -213
  53. package/docs/archive/DOCUSAURUS_DEPLOYMENT.md +0 -166
  54. package/docs/archive/FEATURE_PROPOSALS.md +0 -337
  55. package/docs/archive/LIBRARY_JSON_FIX.md +0 -98
  56. package/docs/archive/LIBRARY_STRUCTURE_FIX.md +0 -215
  57. package/docs/archive/PHASE1_IMPLEMENTATION.md +0 -325
  58. package/docs/archive/PHASE2_IMPLEMENTATION.md +0 -567
  59. package/docs/archive/RELEASE_SUMMARY.md +0 -173
  60. package/docs/archive/SCONS_BUILD_FIX.md +0 -313
  61. package/docs/archive/TRIGGER_RELEASE.md +0 -280
  62. package/docs/archive/VECTOR_INCLUDE_FIX.md +0 -129
  63. package/docs/archive/ota-and-status-enhancements.md +0 -911
  64. package/docs/archive/ota-status-architecture-diagrams.md +0 -658
  65. package/docs/archive/ota-status-quick-reference.md +0 -284
  66. package/docs/design/.gitkeep +0 -1
  67. package/docs/design/STATION_CREDENTIALS_DESIGN.md +0 -182
  68. package/docs/development/ARDUINO_COMPLIANCE_SUMMARY.md +0 -71
  69. package/docs/development/CODE_REFACTORING_RECOMMENDATIONS.md +0 -1011
  70. package/docs/development/DOCKER_TESTING.md +0 -196
  71. package/docs/development/PLATFORMIO_USAGE.md +0 -180
  72. package/docs/development/TESTING_SUMMARY.md +0 -126
  73. package/docs/development/contributing.md +0 -301
  74. package/docs/development/documentation.md +0 -583
  75. package/docs/features/DIAGNOSTICS_API.md +0 -534
  76. package/docs/implementation/BRIDGE_ARCHITECTURE_IMPLEMENTATION.md +0 -340
  77. package/docs/implementation/BRIDGE_HEALTH_MONITORING_IMPLEMENTATION.md +0 -213
  78. package/docs/implementation/BRIDGE_STATUS_FEATURE.md +0 -635
  79. package/docs/implementation/DIAGNOSTICS_API_IMPLEMENTATION.md +0 -232
  80. package/docs/implementation/IMPLEMENTATION_COMPLETE.md +0 -228
  81. package/docs/implementation/IMPLEMENTATION_NTP_TIME_SYNC.md +0 -325
  82. package/docs/implementation/IMPLEMENTATION_SUMMARY.md +0 -316
  83. package/docs/implementation/MESSAGE_QUEUE_IMPLEMENTATION.md +0 -405
  84. package/docs/implementation/MULTI_BRIDGE_IMPLEMENTATION.md +0 -520
  85. package/docs/implementation/NTP_TIME_SYNC_FEATURE.md +0 -392
  86. package/docs/improvements/FUTURE_PROPOSALS.md +0 -1016
  87. package/docs/improvements/IMPLEMENTATION_HISTORY.md +0 -1091
  88. package/docs/improvements/OTA_STATUS_ENHANCEMENTS.md +0 -709
  89. package/docs/improvements/README.md +0 -212
  90. package/docs/internal/CUSTOM_AGENT_ANALYSIS.md +0 -391
  91. package/docs/internal/ISSUE_65_VERIFICATION.md +0 -947
  92. package/docs/internal/ISSUE_66_CLOSURE.md +0 -249
  93. package/docs/internal/ISSUE_66_STATUS.md +0 -316
  94. package/docs/internal/PR_SUMMARY.md +0 -315
  95. package/docs/internal/REVIEW_SUMMARY.md +0 -332
  96. package/docs/multi-bridge-setup.md +0 -1025
  97. package/docs/platformio-publishing.md +0 -255
  98. package/docs/platformio-setup-summary.md +0 -121
  99. package/docs/releases/ANNOUNCEMENT_v1.8.6.md +0 -63
  100. package/docs/releases/ANNOUNCEMENT_v1.8.7.md +0 -113
  101. package/docs/releases/BRIDGE_STATUS_SELF_REGISTRATION_FIX.md +0 -221
  102. package/docs/releases/FEATURE_HISTORY.md +0 -543
  103. package/docs/releases/GITHUB_RELEASE_v1.8.6.md +0 -71
  104. package/docs/releases/GITHUB_RELEASE_v1.8.7.md +0 -90
  105. package/docs/releases/PATCH_v1.7.2.md +0 -262
  106. package/docs/releases/PATCH_v1.7.3.md +0 -262
  107. package/docs/releases/PATCH_v1.7.4.md +0 -219
  108. package/docs/releases/PHASE1_SUMMARY.md +0 -246
  109. package/docs/releases/PHASE2_SUMMARY.md +0 -499
  110. package/docs/releases/PUBLISH_v1.8.0_INSTRUCTIONS.md +0 -163
  111. package/docs/releases/QUICK_START_RELEASES.md +0 -113
  112. package/docs/releases/RELEASE_CHECKLIST_1.8.10.md +0 -331
  113. package/docs/releases/RELEASE_CHECKLIST_1.8.9.md +0 -207
  114. package/docs/releases/RELEASE_CHECKLIST_v1.7.4.md +0 -253
  115. package/docs/releases/RELEASE_CHECKLIST_v1.7.5.md +0 -315
  116. package/docs/releases/RELEASE_CHECKLIST_v1.7.6.md +0 -389
  117. package/docs/releases/RELEASE_CHECKLIST_v1.8.0.md +0 -331
  118. package/docs/releases/RELEASE_CHECKLIST_v1.8.2.md +0 -309
  119. package/docs/releases/RELEASE_NOTES_1.7.0.md +0 -539
  120. package/docs/releases/RELEASE_NOTES_1.8.10.md +0 -239
  121. package/docs/releases/RELEASE_NOTES_1.8.9.md +0 -213
  122. package/docs/releases/RELEASE_NOTES_v1.8.0.md +0 -685
  123. package/docs/releases/RELEASE_NOTES_v1.8.1.md +0 -221
  124. package/docs/releases/RELEASE_NOTES_v1.8.2.md +0 -421
  125. package/docs/releases/RELEASE_NOTES_v1.8.3.md +0 -292
  126. package/docs/releases/RELEASE_NOTES_v1.8.4.md +0 -277
  127. package/docs/releases/RELEASE_NOTES_v1.8.6.md +0 -205
  128. package/docs/releases/RELEASE_NOTES_v1.8.7.md +0 -184
  129. package/docs/releases/RELEASE_PLAN_v1.7.6.md +0 -816
  130. package/docs/releases/RELEASE_SUMMARY_1.8.10.md +0 -193
  131. package/docs/releases/RELEASE_SUMMARY_v1.7.4.md +0 -276
  132. package/docs/releases/RELEASE_SUMMARY_v1.7.5.md +0 -322
  133. package/docs/releases/RELEASE_SUMMARY_v1.7.6.md +0 -436
  134. package/docs/releases/RELEASE_SUMMARY_v1.7.7.md +0 -391
  135. package/docs/releases/RELEASE_SUMMARY_v1.7.8.md +0 -523
  136. package/docs/releases/RELEASE_SUMMARY_v1.7.9.md +0 -542
  137. package/docs/troubleshooting/ARDUINO_IDE_VERSION_FIX_SUMMARY.md +0 -229
  138. package/docs/troubleshooting/ARDUINO_LIBRARY_NAME_FIX.md +0 -197
  139. package/docs/troubleshooting/CRASH_QUICK_REF.md +0 -93
  140. package/docs/troubleshooting/ESP32_C6_COMPATIBILITY.md +0 -157
  141. package/docs/troubleshooting/FREERTOS_ASSERTION_FAILURE.md +0 -288
  142. package/docs/troubleshooting/FREERTOS_FIX_IMPLEMENTATION.md +0 -267
  143. package/docs/troubleshooting/NPM_PUBLISHING_ISSUE_SUMMARY.md +0 -110
  144. package/docs/troubleshooting/PAINLESSMESH_V1.7.4_COMPILATION_ISSUES.md +0 -547
  145. package/docs/troubleshooting/QUICK_FIX_FREERTOS.md +0 -164
  146. package/docs/troubleshooting/SENSOR_NODE_CONNECTION_CRASH.md +0 -264
  147. package/docs/troubleshooting/station-reconnection-issues.md +0 -172
  148. package/docs/v1.7.7_MQTT_IMPROVEMENTS.md +0 -794
  149. package/docs/wiki/API-Reference.md +0 -246
  150. package/docs/wiki/Complete-Documentation.md +0 -123
  151. package/examples/alteriomImproved/alteriom_sensor_package.hpp +0 -224
  152. package/examples/alteriomImproved/improved_sensor_node.ino +0 -248
  153. package/examples/alteriomImproved/platformio.ini +0 -32
  154. package/examples/alteriomMetricsHealth/alteriom_sensor_package.hpp +0 -796
  155. package/examples/alteriomMetricsHealth/metrics_health_node.ino +0 -429
  156. package/examples/alteriomMetricsHealth/platformio.ini +0 -26
  157. package/examples/alteriomPhase1/alteriom_sensor_package.hpp +0 -224
  158. package/examples/alteriomPhase1/phase1_features.ino +0 -242
  159. package/examples/alteriomPhase1/platformio.ini +0 -26
  160. package/examples/alteriomPhase2/alteriom_sensor_package.hpp +0 -224
  161. package/examples/alteriomPhase2/phase2_features.ino +0 -186
  162. package/examples/alteriomPhase2/platformio.ini +0 -26
  163. package/examples/alteriomSensorNode/alteriom_sensor_node.ino +0 -186
  164. package/examples/alteriomSensorNode/alteriom_sensor_package.hpp +0 -1227
  165. package/examples/alteriomSensorNode/platformio.ini +0 -26
  166. package/examples/bridge/alteriom_sensor_package.hpp +0 -1170
  167. package/examples/bridge/bridge_health_monitoring_example.ino +0 -188
  168. package/examples/bridge/enhanced_mqtt_bridge.hpp +0 -610
  169. package/examples/bridge/enhanced_mqtt_bridge_example.ino +0 -226
  170. package/examples/bridge/mesh_event_publisher.hpp +0 -253
  171. package/examples/bridge/mesh_topology_reporter.hpp +0 -303
  172. package/examples/bridge/mqtt_command_bridge.hpp +0 -459
  173. package/examples/bridge/mqtt_status_bridge.hpp +0 -519
  174. package/examples/bridgeAwareSensorNode/alteriom_sensor_package.hpp +0 -1227
  175. package/examples/bridgeAwareSensorNode/bridgeAwareSensorNode.ino +0 -342
  176. package/examples/bridgeAwareSensorNode/platformio.ini +0 -26
  177. package/examples/diagnosticsExample/diagnosticsExample.ino +0 -171
  178. package/examples/diagnosticsExample/platformio.ini +0 -26
  179. package/examples/echoNode/echoNode.ino +0 -33
  180. package/examples/echoNode/platformio.ini +0 -26
  181. package/examples/meshCommandNode/alteriom_sensor_package.hpp +0 -235
  182. package/examples/meshCommandNode/meshCommandNode.ino +0 -265
  183. package/examples/mqttCommandBridge/alteriom_sensor_package.hpp +0 -235
  184. package/examples/mqttCommandBridge/mesh_event_publisher.hpp +0 -253
  185. package/examples/mqttCommandBridge/mesh_topology_reporter.hpp +0 -303
  186. package/examples/mqttCommandBridge/mqttCommandBridge.ino +0 -254
  187. package/examples/mqttCommandBridge/mqtt_command_bridge.hpp +0 -462
  188. package/examples/mqttCommandBridge/platformio.ini +0 -27
  189. package/examples/mqttStatusBridge/mqttStatusBridge.ino +0 -218
  190. package/examples/mqttStatusBridge/mqtt_status_bridge.hpp +0 -522
  191. package/examples/mqttStatusBridge/platformio.ini +0 -27
  192. package/examples/mqttTopologyTest/README.md +0 -467
  193. package/examples/mqttTopologyTest/mqttTopologyTest.ino +0 -754
  194. package/examples/mqttTopologyTest/platformio.ini +0 -27
  195. package/examples/multi_bridge/README.md +0 -346
  196. package/examples/multi_bridge/primary_bridge.ino +0 -96
  197. package/examples/multi_bridge/regular_node.ino +0 -141
  198. package/examples/multi_bridge/secondary_bridge.ino +0 -111
  199. package/examples/ntpTimeSyncBridge/alteriom_sensor_package.hpp +0 -1383
  200. package/examples/ntpTimeSyncBridge/ntpTimeSyncBridge.ino +0 -86
  201. package/examples/ntpTimeSyncNode/alteriom_sensor_package.hpp +0 -1383
  202. package/examples/ntpTimeSyncNode/ntpTimeSyncNode.ino +0 -109
  203. package/examples/queued_alarms/README.md +0 -390
  204. package/examples/queued_alarms/queued_alarms.ino +0 -265
  205. package/examples/routing_demo/README.md +0 -172
  206. package/examples/routing_demo/routing_demo.ino +0 -102
  207. package/examples/rtcIntegration/README.md +0 -294
  208. 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
- ROUTER_SSID, ROUTER_PASSWORD,
127
- &userScheduler, MESH_PORT);
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.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
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
- Serial.println("No primary bridge available!");
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
- me-no-dev/ESPAsyncTCP
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
- mathieucarbou/AsyncTCP
27
+ esp32async/AsyncTCP