@alteriom/painlessmesh 1.9.5 → 1.9.7
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 +78 -0
- package/CONTRIBUTING.md +3 -3
- package/README.md +60 -184
- package/docs/README.md +1 -1
- package/docs/troubleshooting/common-issues.md +101 -0
- package/docs/troubleshooting/external-device-connection.md +283 -0
- package/examples/bridge/bridge.ino +23 -0
- package/examples/bridge_failover/bridge_failover.ino +27 -0
- package/examples/sendToInternet/sendToInternet.ino +21 -3
- package/library.json +1 -1
- package/library.properties +1 -1
- package/package.json +4 -4
- package/src/AlteriomPainlessMesh.h +3 -3
- package/src/arduino/wifi.hpp +874 -535
- package/src/painlessMesh.h +2 -2
- package/src/painlessMeshSTA.cpp +11 -2
- package/src/painlessmesh/mesh.hpp +6 -2
- package/src/painlessmesh/tcp.hpp +103 -4
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,78 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- TBD
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- TBD
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- TBD
|
|
21
|
+
|
|
22
|
+
## [1.9.7] - 2025-12-13
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- **External Device WiFi AP Connection** (#231) - Fixed DHCP and AP initialization issues preventing phones and computers from connecting to bridge
|
|
27
|
+
- **Root Cause**: When AP was restarted during channel changes, DHCP server was not properly reinitialized due to incomplete WiFi stack reset
|
|
28
|
+
- **Symptom**: External devices (Android phones, Windows 11 computers) cannot connect to mesh WiFi AP or fail to receive IP addresses via DHCP
|
|
29
|
+
- **Solution**: Improved AP restart sequence and DHCP initialization:
|
|
30
|
+
- Added explicit `WiFi.enableAP(true)` for ESP32 to ensure DHCP server starts
|
|
31
|
+
- Changed `softAPdisconnect(false)` to `softAPdisconnect(true)` for proper DHCP shutdown
|
|
32
|
+
- Increased timing delays: 200ms before AP restart + 100ms stabilization after
|
|
33
|
+
- Added logging for AP configuration to aid debugging
|
|
34
|
+
- **Impact**: External devices can now reliably connect to bridge AP for debugging and testing
|
|
35
|
+
|
|
36
|
+
### Documentation
|
|
37
|
+
|
|
38
|
+
- **External Device Connection Guide** - New comprehensive guide for connecting phones/computers to mesh AP
|
|
39
|
+
- Complete connection instructions for Android, Windows, macOS, Linux
|
|
40
|
+
- Troubleshooting section for common connection issues
|
|
41
|
+
- Security best practices and warnings
|
|
42
|
+
- Example debug sessions with network tools
|
|
43
|
+
- Added to bridge examples with detailed setup notes
|
|
44
|
+
|
|
45
|
+
## [1.9.6] - 2025-12-10
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
|
|
49
|
+
- **TCP Connection Retry Improvements** (#231) - Improved TCP connection reliability with increased retries and exponential backoff
|
|
50
|
+
- **Root Cause**: Nodes experience endless loop of WiFi connect → TCP error -14 → WiFi disconnect because the TCP retry mechanism wasn't sufficient for real-world mesh conditions
|
|
51
|
+
- **Symptom**: Mesh connections never fully establish; nodes can discover and get IP from bridge but TCP connection consistently fails
|
|
52
|
+
- **Solution**: Improved TCP connection retry parameters and added exponential backoff:
|
|
53
|
+
- Increased `TCP_CONNECT_STABILIZATION_DELAY_MS` from 100ms to 500ms (more time for network stack to stabilize after IP acquisition)
|
|
54
|
+
- Increased `TCP_CONNECT_RETRY_DELAY_MS` from 500ms to 1000ms (base delay between retries)
|
|
55
|
+
- Increased `TCP_CONNECT_MAX_RETRIES` from 3 to 5 (more retry attempts before giving up)
|
|
56
|
+
- Added exponential backoff: retry delays are 1s, 2s, 4s, 8s, 8s (capped) for attempts 1-5
|
|
57
|
+
- **Impact**: More reliable mesh connection establishment, especially when bridge TCP server is temporarily busy or network is congested
|
|
58
|
+
|
|
59
|
+
### Documentation
|
|
60
|
+
|
|
61
|
+
- **README.md Comprehensive Review** - Updated main README for completeness and accuracy
|
|
62
|
+
- Updated version references from 1.9.2 to 1.9.6
|
|
63
|
+
- Verified all documentation links and references
|
|
64
|
+
- Confirmed package type documentation accuracy
|
|
65
|
+
- Validated installation instructions
|
|
66
|
+
- Updated "Latest Release" section with current features
|
|
67
|
+
- Fixed ArduinoJson v7 code examples (DynamicJsonDocument → JsonDocument)
|
|
68
|
+
- Updated dependency versions in documentation (ArduinoJson 6.x→7.x, TaskScheduler 3.x→4.x)
|
|
69
|
+
- Corrected API Documentation links (GitLab → GitHub Pages)
|
|
70
|
+
- Fixed Contributing section references (master→main, GitLab→GitHub)
|
|
71
|
+
|
|
72
|
+
### Changed
|
|
73
|
+
|
|
74
|
+
- **Version Consistency** - Synchronized version numbers across all distribution files
|
|
75
|
+
- Updated library.properties to v1.9.6
|
|
76
|
+
- Updated library.json to v1.9.6
|
|
77
|
+
- Updated package.json to v1.9.6
|
|
78
|
+
- Ensures consistent versioning for NPM, PlatformIO, and Arduino Library Manager
|
|
79
|
+
|
|
8
80
|
## [1.9.5] - 2025-12-03
|
|
9
81
|
|
|
10
82
|
### Fixed
|
|
@@ -22,6 +94,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
22
94
|
- Nodes that fail initial bridge setup can now retry automatically via mesh connection monitoring
|
|
23
95
|
- **Impact**: More reliable bridge establishment in challenging network conditions
|
|
24
96
|
|
|
97
|
+
- **Isolated Bridge Retry Delay After Failed Promotion** - Fixed slow retry after failed bridge promotion
|
|
98
|
+
- **Root Cause**: When bridge promotion fails, `init()` is called which resets `consecutiveEmptyScans` to 0. The isolated retry task would then wait for 6+ new empty scans (90 seconds) before retrying.
|
|
99
|
+
- **Symptom**: After a failed bridge promotion, retries only happen every ~2 minutes instead of ~60 seconds
|
|
100
|
+
- **Solution**: Added `_isolatedRetryPending` flag that is set when promotion fails. This flag allows the next retry attempt to skip the empty scan threshold check.
|
|
101
|
+
- **Impact**: Faster retry after failed promotion - retries happen at the normal 60 second interval instead of waiting for scan accumulation
|
|
102
|
+
|
|
25
103
|
## [1.9.4] - 2025-12-03
|
|
26
104
|
|
|
27
105
|
### Fixed
|
package/CONTRIBUTING.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Contributing
|
|
2
2
|
|
|
3
|
-
We try to follow the [git flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) development model. Which means that we have a `develop` branch and `
|
|
3
|
+
We try to follow the [git flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) development model. Which means that we have a `develop` branch and `main` branch. All development is done under feature branches, which are (when finished) merged into the development branch. When a new version is released we merge the `develop` branch into the `main` branch.
|
|
4
4
|
|
|
5
5
|
## Git flow
|
|
6
6
|
|
|
@@ -8,9 +8,9 @@ If you would like to use [git flow tools](http://danielkummer.github.io/git-flow
|
|
|
8
8
|
|
|
9
9
|
## Submit a pull request:
|
|
10
10
|
|
|
11
|
-
* If your push triggered a 'you just pushed...' message from
|
|
11
|
+
* If your push triggered a 'you just pushed...' message from GitHub then click on the button provided by that pop up to create a pull request.
|
|
12
12
|
* If not, then create a pull request and point it to your branch.
|
|
13
|
-
* Make sure that you're attempting to merge into `develop` and not `
|
|
13
|
+
* Make sure that you're attempting to merge into `develop` and not `main`.
|
|
14
14
|
* Get your code reviewed by another contributor. If there are no contributors who possess the same set of skills then get them to review it anyway but explain what the code does beforehand and why. Use it as an opportunity for discussion around the feature set, to transfer knowledge, and to possibly [rubber duck](https://en.wikipedia.org/wiki/Rubber_duck_debugging) your code.
|
|
15
15
|
* Once the code is reviewed then have your reviewer merge your code.
|
|
16
16
|
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<div align="center">
|
|
6
6
|
|
|
7
|
-
**Version 1.9.
|
|
7
|
+
**Version 1.9.6** - Latest release with TCP connection improvements and documentation updates
|
|
8
8
|
|
|
9
9
|
[](https://github.com/Alteriom/painlessMesh/actions/workflows/ci.yml)
|
|
10
10
|
[](https://github.com/Alteriom/painlessMesh/actions/workflows/docs.yml)
|
|
@@ -418,7 +418,7 @@ void loop() {
|
|
|
418
418
|
}
|
|
419
419
|
|
|
420
420
|
void receivedCallback(uint32_t from, String& msg) {
|
|
421
|
-
|
|
421
|
+
JsonDocument doc; // ArduinoJson v7
|
|
422
422
|
deserializeJson(doc, msg);
|
|
423
423
|
|
|
424
424
|
if (doc["type"] == 200) { // SensorPackage
|
|
@@ -553,15 +553,24 @@ These are the message types used by applications built on painlessMesh:
|
|
|
553
553
|
- **Event Coordination** - Synchronized displays, distributed processing
|
|
554
554
|
- **Bridge Networks** - Connect mesh to WiFi/Internet/MQTT - [📖 Bridge Guide](BRIDGE_TO_INTERNET.md)
|
|
555
555
|
|
|
556
|
-
## Latest Release: v1.9.
|
|
556
|
+
## Latest Release: v1.9.6 (December 10, 2025)
|
|
557
557
|
|
|
558
|
-
**
|
|
558
|
+
**TCP Connection Improvements & Documentation Update**
|
|
559
|
+
|
|
560
|
+
- ⚡ **TCP Connection Retry Improvements** - Enhanced reliability with exponential backoff (#231)
|
|
561
|
+
- Increased stabilization delay (100ms → 500ms)
|
|
562
|
+
- Increased retry delay (500ms → 1000ms) with exponential backoff
|
|
563
|
+
- More retry attempts (3 → 5) for better connection establishment
|
|
564
|
+
- 📚 **Comprehensive Documentation Review** - Updated README.md for completeness and accuracy
|
|
565
|
+
- 🔄 **Version Consistency** - Aligned version numbers across all distribution channels
|
|
566
|
+
|
|
567
|
+
**Recent Key Features (v1.9.0 - v1.9.5):**
|
|
559
568
|
|
|
560
569
|
- 🔍 **Mesh Connectivity Detection** - New `hasActiveMeshConnections()` and `getLastKnownBridge()` APIs
|
|
561
570
|
- 🌉 **Improved Bridge Detection** - `getPrimaryBridge()` returns last known bridge when disconnected
|
|
562
|
-
- ⚡ **
|
|
563
|
-
-
|
|
564
|
-
-
|
|
571
|
+
- ⚡ **Enhanced TCP Reliability** - Exponential backoff and increased retries for mesh connections
|
|
572
|
+
- 🛡️ **Race Condition Fixes** - Improved bridge status and connection validation
|
|
573
|
+
- 📦 **Consolidated Examples** - Streamlined to 14 essential examples
|
|
565
574
|
- ⚙️ **Configurable Election Timing** - Prevent split-brain with `setElectionStartupDelay()` and `setElectionRandomDelay()`
|
|
566
575
|
|
|
567
576
|
**[📋 Full CHANGELOG](CHANGELOG.md)**
|
|
@@ -572,7 +581,7 @@ These are the message types used by applications built on painlessMesh:
|
|
|
572
581
|
- **[Common Issues](docs/troubleshooting/common-issues.md)** - Troubleshooting guide
|
|
573
582
|
- **[GitHub Issues](https://github.com/Alteriom/painlessMesh/issues)** - Bug reports and feature requests
|
|
574
583
|
- **[Community Forum](https://groups.google.com/forum/#!forum/painlessmesh-user)** - Community support
|
|
575
|
-
- **[API Documentation](
|
|
584
|
+
- **[API Documentation](https://alteriom.github.io/painlessMesh/#/api/doxygen)** - Generated API docs
|
|
576
585
|
|
|
577
586
|
## Development
|
|
578
587
|
|
|
@@ -590,7 +599,7 @@ run-parts --regex catch_ bin/ # Run tests
|
|
|
590
599
|
### Requirements
|
|
591
600
|
|
|
592
601
|
- **ESP32/ESP8266**: Arduino Core 2.0.0+
|
|
593
|
-
- **Dependencies**: ArduinoJson
|
|
602
|
+
- **Dependencies**: ArduinoJson 7.x, TaskScheduler 4.x
|
|
594
603
|
- **Development**: CMake, Ninja, Boost (for desktop testing)
|
|
595
604
|
|
|
596
605
|
### CI/CD Pipeline
|
|
@@ -628,7 +637,7 @@ See [RELEASE_GUIDE.md](RELEASE_GUIDE.md) for complete release documentation.
|
|
|
628
637
|
|
|
629
638
|
## Contributing
|
|
630
639
|
|
|
631
|
-
We try to follow the [git flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) development model. Which means that we have a `develop` branch and `
|
|
640
|
+
We try to follow the [git flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) development model. Which means that we have a `develop` branch and `main` branch. All development is done under feature branches, which are (when finished) merged into the development branch. When a new version is released we merge the `develop` branch into the `main` branch. For more details see the [CONTRIBUTING.md](CONTRIBUTING.md) file.
|
|
632
641
|
|
|
633
642
|
## Funding
|
|
634
643
|
|
|
@@ -638,199 +647,66 @@ If you like the library please consider supporting its development. Your contrib
|
|
|
638
647
|
|
|
639
648
|
**[Donate via PayPal](https://www.paypal.com/paypalme/domlavoie)** • [dominic.lavoie@gmail.com](mailto:dominic.lavoie@gmail.com)
|
|
640
649
|
|
|
641
|
-
## 📚
|
|
642
|
-
|
|
643
|
-
> **� [Visit the Full Documentation Website](https://alteriom.github.io/painlessMesh/)**
|
|
644
|
-
|
|
645
|
-
### 🚀 Getting Started
|
|
646
|
-
|
|
647
|
-
**New to AlteriomPainlessMesh?** Start with these essential guides:
|
|
648
|
-
|
|
649
|
-
| Guide | Description | Link |
|
|
650
|
-
|-------|-------------|------|
|
|
651
|
-
| **🎯 Quick Start** | Get your first mesh running in 5 minutes | [📖 Start Here](https://alteriom.github.io/painlessMesh/#/getting-started/quickstart) |
|
|
652
|
-
| **💾 Installation** | Arduino IDE, PlatformIO, and more | [📖 Install Guide](https://alteriom.github.io/painlessMesh/#/getting-started/installation) |
|
|
653
|
-
| **🌐 First Mesh** | Build a real multi-node network | [📖 Build Now](https://alteriom.github.io/painlessMesh/#/getting-started/first-mesh) |
|
|
654
|
-
|
|
655
|
-
### 📖 API Documentation
|
|
656
|
-
|
|
657
|
-
**Complete reference for all classes, functions, and features:**
|
|
658
|
-
|
|
659
|
-
| Section | Description | Link |
|
|
660
|
-
|---------|-------------|------|
|
|
661
|
-
| **🔧 Core API** | painlessMesh class reference and methods | [📖 Core API](https://alteriom.github.io/painlessMesh/#/api/core-api) |
|
|
662
|
-
| **📦 Doxygen API** | Auto-generated complete API documentation | [📖 Browse API](https://alteriom.github.io/painlessMesh/#/api/doxygen) |
|
|
663
|
-
| **⚙️ Configuration** | All mesh configuration options | [📖 Configure](https://alteriom.github.io/painlessMesh/#/api/configuration) |
|
|
664
|
-
| **🔄 Callbacks** | Event handling and callback patterns | [📖 Events](https://alteriom.github.io/painlessMesh/#/api/callbacks) |
|
|
665
|
-
|
|
666
|
-
### 🎯 Alteriom Extensions
|
|
667
|
-
|
|
668
|
-
**IoT-ready packages for production applications:**
|
|
669
|
-
|
|
670
|
-
| Package | Purpose | Documentation |
|
|
671
|
-
|---------|---------|---------------|
|
|
672
|
-
| **📊 SensorPackage** | Environmental data collection | [📖 Sensor Docs](https://alteriom.github.io/painlessMesh/#/alteriom/overview) |
|
|
673
|
-
| **⚡ CommandPackage** | Device control and automation | [📖 Command Docs](https://alteriom.github.io/painlessMesh/#/alteriom/overview) |
|
|
674
|
-
| **📈 StatusPackage** | Health monitoring and diagnostics | [📖 Status Docs](https://alteriom.github.io/painlessMesh/#/alteriom/overview) |
|
|
675
|
-
|
|
676
|
-
### 🏗️ Advanced Topics
|
|
677
|
-
|
|
678
|
-
**Deep dive into architecture and advanced usage:**
|
|
679
|
-
|
|
680
|
-
| Topic | Description | Link |
|
|
681
|
-
|-------|-------------|------|
|
|
682
|
-
| **🌳 Architecture** | How painlessMesh works internally | [📖 Architecture](https://alteriom.github.io/painlessMesh/#/architecture/mesh-architecture) |
|
|
683
|
-
| **🌉 Bridge to Internet** | Connect mesh to WiFi/Internet/MQTT | [📖 Bridge Guide](BRIDGE_TO_INTERNET.md) |
|
|
684
|
-
| **🔌 Plugin System** | Create custom message packages | [📖 Plugins](https://alteriom.github.io/painlessMesh/#/architecture/plugin-system) |
|
|
685
|
-
| **🎓 Tutorials** | Step-by-step examples and patterns | [📖 Tutorials](https://alteriom.github.io/painlessMesh/#/tutorials/basic-examples) |
|
|
686
|
-
| **🛠️ Troubleshooting** | Common issues and solutions | [📖 Help](https://alteriom.github.io/painlessMesh/#/troubleshooting/common-issues) |
|
|
687
|
-
|
|
688
|
-
### 📝 Quick Reference
|
|
650
|
+
## 📚 Documentation
|
|
689
651
|
|
|
690
|
-
|
|
652
|
+
### 📖 Essential Guides
|
|
691
653
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
654
|
+
| Document | Description |
|
|
655
|
+
|----------|-------------|
|
|
656
|
+
| **[📘 User Guide](USER_GUIDE.md)** | **Complete comprehensive guide** - Everything you need to know |
|
|
657
|
+
| **[🌉 Bridge Guide](BRIDGE_TO_INTERNET.md)** | Connect mesh to Internet, MQTT, and cloud services |
|
|
658
|
+
| **[📋 Documentation Hub](.github/DOCUMENTATION.md)** | Central navigation for all documentation resources |
|
|
659
|
+
| **[🌐 Online Docs](https://alteriom.github.io/painlessMesh/)** | Interactive documentation website with API reference |
|
|
696
660
|
|
|
697
|
-
|
|
661
|
+
### 🚀 Quick Links
|
|
698
662
|
|
|
699
|
-
|
|
700
|
-
-
|
|
701
|
-
-
|
|
663
|
+
**New to AlteriomPainlessMesh?**
|
|
664
|
+
- [Quick Start](docs/getting-started/quickstart.md) - Get your first mesh running in 5 minutes
|
|
665
|
+
- [Installation](docs/getting-started/installation.md) - Arduino IDE and PlatformIO setup
|
|
666
|
+
- [First Mesh](docs/getting-started/first-mesh.md) - Build a multi-node network
|
|
702
667
|
|
|
703
|
-
|
|
668
|
+
**Reference Documentation:**
|
|
669
|
+
- [Core API](docs/api/core-api.md) - painlessMesh class methods
|
|
670
|
+
- [Alteriom Extensions](docs/alteriom/overview.md) - SensorPackage, CommandPackage, StatusPackage
|
|
671
|
+
- [Examples](examples/) - 16 working examples for common scenarios
|
|
704
672
|
|
|
705
|
-
|
|
673
|
+
**Need Help?**
|
|
674
|
+
- [FAQ](docs/troubleshooting/faq.md) - Frequently asked questions
|
|
675
|
+
- [Common Issues](docs/troubleshooting/common-issues.md) - Troubleshooting guide
|
|
676
|
+
- [GitHub Issues](https://github.com/Alteriom/painlessMesh/issues) - Bug reports and support
|
|
706
677
|
|
|
707
|
-
|
|
678
|
+
## 🔧 Quick API Reference
|
|
708
679
|
|
|
680
|
+
**Core Methods:**
|
|
709
681
|
```cpp
|
|
710
682
|
#include "painlessMesh.h"
|
|
711
683
|
|
|
712
684
|
painlessMesh mesh;
|
|
713
|
-
```
|
|
714
|
-
|
|
715
|
-
### Member Functions
|
|
716
|
-
|
|
717
|
-
#### void painlessMesh::init(String ssid, String password, uint16_t port = 5555, WiFiMode_t connectMode = WIFI_AP_STA, _auth_mode authmode = AUTH_WPA2_PSK, uint8_t channel = 1, phy_mode_t phymode = PHY_MODE_11G, uint8_t maxtpw = 82, uint8_t hidden = 0, uint8_t maxconn = 4)
|
|
718
|
-
|
|
719
|
-
Add this to your setup() function.
|
|
720
|
-
Initialize the mesh network. This routine does the following things.
|
|
721
|
-
|
|
722
|
-
- Starts a wifi network
|
|
723
|
-
- Begins searching for other wifi networks that are part of the mesh
|
|
724
|
-
- Logs on to the best mesh network node it finds… if it doesn’t find anything, it starts a new search in 5 seconds.
|
|
725
|
-
|
|
726
|
-
`ssid` = the name of your mesh. All nodes share same AP ssid. They are distinguished by BSSID.
|
|
727
|
-
`password` = wifi password to your mesh.
|
|
728
|
-
`port` = the TCP port that you want the mesh server to run on. Defaults to 5555 if not specified.
|
|
729
|
-
[`connectMode`](https://gitlab.com/painlessMesh/painlessMesh/wikis/connect-mode:-WIFI_AP,-WIFI_STA,-WIFI_AP_STA-mode) = switch between WIFI_AP, WIFI_STA and WIFI_AP_STA (default) mode
|
|
730
|
-
|
|
731
|
-
#### void painlessMesh::stop()
|
|
732
|
-
|
|
733
|
-
Stop the node. This will cause the node to disconnect from all other nodes and stop/sending messages.
|
|
734
|
-
|
|
735
|
-
#### void painlessMesh::update( void )
|
|
736
|
-
|
|
737
|
-
Add this to your loop() function
|
|
738
|
-
This routine runs various maintenance tasks... Not super interesting, but things don't work without it.
|
|
739
|
-
|
|
740
|
-
#### void painlessMesh::onReceive( &receivedCallback )
|
|
741
|
-
|
|
742
|
-
Set a callback routine for any messages that are addressed to this node. Callback routine has the following structure.
|
|
743
|
-
|
|
744
|
-
`void receivedCallback( uint32_t from, String &msg )`
|
|
745
|
-
|
|
746
|
-
Every time this node receives a message, this callback routine will the called. “from” is the id of the original sender of the message, and “msg” is a string that contains the message. The message can be anything. A JSON, some other text string, or binary data.
|
|
747
|
-
|
|
748
|
-
#### void painlessMesh::onNewConnection( &newConnectionCallback )
|
|
749
|
-
|
|
750
|
-
This fires every time the local node makes a new connection. The callback has the following structure.
|
|
751
|
-
|
|
752
|
-
`void newConnectionCallback( uint32_t nodeId )`
|
|
753
685
|
|
|
754
|
-
|
|
686
|
+
// Initialize mesh
|
|
687
|
+
mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
|
|
755
688
|
|
|
756
|
-
|
|
689
|
+
// Main loop - call this in loop()
|
|
690
|
+
mesh.update();
|
|
757
691
|
|
|
758
|
-
|
|
692
|
+
// Send messages
|
|
693
|
+
mesh.sendBroadcast("Hello everyone!");
|
|
694
|
+
mesh.sendSingle(nodeId, "Hello specific node");
|
|
759
695
|
|
|
760
|
-
|
|
696
|
+
// Get information
|
|
697
|
+
uint32_t myId = mesh.getNodeId();
|
|
698
|
+
std::list<uint32_t> nodes = mesh.getNodeList();
|
|
761
699
|
|
|
762
|
-
|
|
700
|
+
// Register callbacks
|
|
701
|
+
mesh.onReceive(&receivedCallback);
|
|
702
|
+
mesh.onNewConnection(&newConnectionCallback);
|
|
703
|
+
mesh.onChangedConnections(&changedConnectionCallback);
|
|
763
704
|
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
`nodeId` is node ID that the request refers to.
|
|
769
|
-
|
|
770
|
-
#### void painlessMesh::onNodeTimeAdjusted( &nodeTimeAdjustedCallback )
|
|
771
|
-
|
|
772
|
-
This fires every time local time is adjusted to synchronize it with mesh time. Callback has the following structure.
|
|
773
|
-
|
|
774
|
-
`void onNodeTimeAdjusted(int32_t offset)`
|
|
775
|
-
|
|
776
|
-
`offset` is the adjustment delta that has been calculated and applied to local clock.
|
|
777
|
-
|
|
778
|
-
#### void onNodeDelayReceived(nodeDelayCallback_t onDelayReceived)
|
|
779
|
-
|
|
780
|
-
This fires when a time delay measurement response is received, after a request was sent. Callback has the following structure.
|
|
781
|
-
|
|
782
|
-
`void onNodeDelayReceived(uint32_t nodeId, int32_t delay)`
|
|
783
|
-
|
|
784
|
-
`nodeId` The node that originated response.
|
|
785
|
-
|
|
786
|
-
`delay` One way network trip delay in microseconds.
|
|
787
|
-
|
|
788
|
-
#### bool painlessMesh::sendBroadcast( String &msg, bool includeSelf = false)
|
|
789
|
-
|
|
790
|
-
Sends msg to every node on the entire mesh network. By default the current node is excluded from receiving the message (`includeSelf = false`). `includeSelf = true` overrides this behavior, causing the `receivedCallback` to be called when sending a broadcast message.
|
|
791
|
-
|
|
792
|
-
returns true if everything works, false if not. Prints an error message to Serial.print, if there is a failure.
|
|
793
|
-
|
|
794
|
-
#### bool painlessMesh::sendSingle(uint32_t dest, String &msg)
|
|
795
|
-
|
|
796
|
-
Sends msg to the node with Id == dest.
|
|
797
|
-
|
|
798
|
-
returns true if everything works, false if not. Prints an error message to Serial.print, if there is a failure.
|
|
799
|
-
|
|
800
|
-
#### String painlessMesh::subConnectionJson()
|
|
801
|
-
|
|
802
|
-
Returns mesh topology in JSON format.
|
|
803
|
-
|
|
804
|
-
#### std::list<uint32_t> painlessMesh::getNodeList()
|
|
805
|
-
|
|
806
|
-
Get a list of all known nodes. This includes nodes that are both directly and indirectly connected to the current node.
|
|
807
|
-
|
|
808
|
-
#### uint32_t painlessMesh::getNodeId( void )
|
|
809
|
-
|
|
810
|
-
Return the chipId of the node that we are running on.
|
|
811
|
-
|
|
812
|
-
#### uint32_t painlessMesh::getNodeTime( void )
|
|
813
|
-
|
|
814
|
-
Returns the mesh timebase microsecond counter. Rolls over 71 minutes from startup of the first node.
|
|
815
|
-
|
|
816
|
-
Nodes try to keep a common time base synchronizing to each other using [an SNTP based protocol](https://gitlab.com/painlessMesh/painlessMesh/wikis/mesh-protocol#time-sync)
|
|
817
|
-
|
|
818
|
-
#### bool painlessMesh::startDelayMeas(uint32_t nodeId)
|
|
819
|
-
|
|
820
|
-
Sends a node a packet to measure network trip delay to that node. Returns true if nodeId is connected to the mesh, false otherwise. After calling this function, user program have to wait to the response in the form of a callback specified by `void painlessMesh::onNodeDelayReceived(nodeDelayCallback_t onDelayReceived)`.
|
|
821
|
-
|
|
822
|
-
nodeDelayCallback_t is a function in the form of `void (uint32_t nodeId, int32_t delay)`.
|
|
823
|
-
|
|
824
|
-
#### void painlessMesh::stationManual( String ssid, String password, uint16_t port, uint8_t *remote_ip )
|
|
825
|
-
|
|
826
|
-
Connects the node to an AP outside the mesh. When specifying a `remote_ip` and `port`, the node opens a TCP connection after establishing the WiFi connection.
|
|
827
|
-
|
|
828
|
-
Note: The mesh must be on the same WiFi channel as the AP.
|
|
829
|
-
|
|
830
|
-
#### void painlessMesh::setDebugMsgTypes( uint16_t types )
|
|
705
|
+
// Debug configuration
|
|
706
|
+
mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
707
|
+
```
|
|
831
708
|
|
|
832
|
-
|
|
833
|
-
ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE
|
|
709
|
+
**For complete API documentation, see [USER_GUIDE.md](USER_GUIDE.md#api-reference) or [online docs](https://alteriom.github.io/painlessMesh/#/api/core-api).**
|
|
834
710
|
|
|
835
711
|
# Funding
|
|
836
712
|
|
package/docs/README.md
CHANGED
|
@@ -115,7 +115,7 @@ Welcome to the comprehensive documentation for the Alteriom fork of painlessMesh
|
|
|
115
115
|
## Quick Links
|
|
116
116
|
|
|
117
117
|
- **[GitHub Repository](https://github.com/Alteriom/painlessMesh)**
|
|
118
|
-
- **[API Documentation](
|
|
118
|
+
- **[API Documentation](https://alteriom.github.io/painlessMesh/#/api/doxygen)**
|
|
119
119
|
- **[Community Forum](https://groups.google.com/forum/#!forum/painlessmesh-user)**
|
|
120
120
|
- **[Issue Tracker](https://github.com/Alteriom/painlessMesh/issues)**
|
|
121
121
|
|
|
@@ -60,6 +60,32 @@ For Arduino IDE, download and install manually from: https://github.com/ESP32Asy
|
|
|
60
60
|
|
|
61
61
|
## Connection Issues
|
|
62
62
|
|
|
63
|
+
### External Devices Cannot Connect to Mesh AP
|
|
64
|
+
|
|
65
|
+
**Symptoms:**
|
|
66
|
+
- Phone or computer can't see the mesh WiFi network
|
|
67
|
+
- Can see network but can't connect
|
|
68
|
+
- Connected but no IP address assigned
|
|
69
|
+
- Connection drops frequently
|
|
70
|
+
|
|
71
|
+
**Solution:**
|
|
72
|
+
|
|
73
|
+
See the dedicated guide for connecting external devices:
|
|
74
|
+
|
|
75
|
+
📖 **[Connecting External Devices Guide](external-device-connection.md)**
|
|
76
|
+
|
|
77
|
+
**Quick Summary:**
|
|
78
|
+
|
|
79
|
+
External devices (phones, computers, test equipment) can connect to the bridge node's WiFi AP for debugging:
|
|
80
|
+
- **SSID**: Your MESH_PREFIX value
|
|
81
|
+
- **Password**: Your MESH_PASSWORD value
|
|
82
|
+
- **IP Range**: 10.x.x.x/24 (DHCP automatic)
|
|
83
|
+
- **Limits**: ESP32 supports 10 devices, ESP8266 supports 4
|
|
84
|
+
|
|
85
|
+
Common issues are DHCP timing, channel changes, and connection limits.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
63
89
|
### Nodes Not Connecting
|
|
64
90
|
|
|
65
91
|
**Symptoms:**
|
|
@@ -149,6 +175,81 @@ void checkMemory() {
|
|
|
149
175
|
}
|
|
150
176
|
```
|
|
151
177
|
|
|
178
|
+
### TCP Connection Error -14 (ERR_CONN)
|
|
179
|
+
|
|
180
|
+
**Symptoms:**
|
|
181
|
+
- Serial output shows: `tcp_err(): error trying to connect -14`
|
|
182
|
+
- Nodes get an IP address but fail to establish mesh connection
|
|
183
|
+
- Connection attempts keep failing and retrying
|
|
184
|
+
|
|
185
|
+
**Cause:**
|
|
186
|
+
|
|
187
|
+
The error -14 (ERR_CONN in LwIP) indicates a TCP connection failure. This typically occurs when:
|
|
188
|
+
1. The TCP server on the target node is not ready when the connection is attempted
|
|
189
|
+
2. There's a timing issue between WiFi association and TCP readiness
|
|
190
|
+
3. Network stack hasn't fully stabilized after IP acquisition
|
|
191
|
+
4. The target node is overloaded or has resource constraints
|
|
192
|
+
|
|
193
|
+
**Solutions:**
|
|
194
|
+
|
|
195
|
+
#### 1. Update AsyncTCP Library (Most Common Fix)
|
|
196
|
+
The error often occurs with older AsyncTCP versions that don't have proper thread safety for ESP32 Arduino Core 3.x:
|
|
197
|
+
|
|
198
|
+
For PlatformIO:
|
|
199
|
+
```ini
|
|
200
|
+
lib_deps =
|
|
201
|
+
esp32async/AsyncTCP @ ^3.4.7
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
For Arduino IDE, install manually from: https://github.com/ESP32Async/AsyncTCP
|
|
205
|
+
|
|
206
|
+
#### 2. Built-in Retry Mechanism
|
|
207
|
+
painlessMesh now includes automatic TCP connection retry with the following behavior:
|
|
208
|
+
- Up to 3 retry attempts with 500ms delay between each
|
|
209
|
+
- 100ms stabilization delay after IP acquisition before first connection attempt
|
|
210
|
+
- Full WiFi reconnection only triggered after all retries are exhausted
|
|
211
|
+
|
|
212
|
+
This helps handle transient timing issues automatically.
|
|
213
|
+
|
|
214
|
+
#### 3. Check Node Resource Usage
|
|
215
|
+
Monitor memory and ensure nodes aren't overloaded:
|
|
216
|
+
|
|
217
|
+
```cpp
|
|
218
|
+
void loop() {
|
|
219
|
+
mesh.update();
|
|
220
|
+
|
|
221
|
+
// Monitor health periodically
|
|
222
|
+
static unsigned long lastCheck = 0;
|
|
223
|
+
if (millis() - lastCheck > 10000) {
|
|
224
|
+
lastCheck = millis();
|
|
225
|
+
Serial.printf("Free heap: %d, WiFi RSSI: %d\n",
|
|
226
|
+
ESP.getFreeHeap(), WiFi.RSSI());
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### 4. Ensure Proper Initialization Order
|
|
232
|
+
Make sure the mesh is properly initialized before connections are attempted:
|
|
233
|
+
|
|
234
|
+
```cpp
|
|
235
|
+
void setup() {
|
|
236
|
+
Serial.begin(115200);
|
|
237
|
+
delay(100); // Let serial initialize
|
|
238
|
+
|
|
239
|
+
mesh.setDebugMsgTypes(ERROR | STARTUP | CONNECTION);
|
|
240
|
+
mesh.init(MESH_PREFIX, MESH_PASSWORD, &userScheduler, MESH_PORT);
|
|
241
|
+
// Add callbacks after init
|
|
242
|
+
mesh.onReceive(&receivedCallback);
|
|
243
|
+
mesh.onNewConnection(&newConnectionCallback);
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
#### 5. Check WiFi Signal Strength
|
|
248
|
+
Poor signal can cause connection timing issues:
|
|
249
|
+
- Ensure nodes are within good WiFi range
|
|
250
|
+
- Check for interference from other 2.4GHz devices
|
|
251
|
+
- Monitor RSSI values (should be above -80 dBm for reliable connections)
|
|
252
|
+
|
|
152
253
|
## Message Delivery Issues
|
|
153
254
|
|
|
154
255
|
### Messages Not Being Received
|