|
| 1 | +# ESP32-C6 Time Synchronization Example |
| 2 | + |
| 3 | +This example demonstrates the time synchronization system implemented in Martos RTOS using ESP-NOW communication protocol. The system implements a **Local Voting Protocol** that allows time to accelerate but prevents it from going backwards, ensuring monotonic time progression. |
| 4 | + |
| 5 | +## Features |
| 6 | + |
| 7 | +- **Time Synchronization**: Synchronizes time across multiple ESP32-C6 nodes using broadcast messages |
| 8 | +- **ESP-NOW Communication**: Uses ESP-NOW for low-latency peer-to-peer communication |
| 9 | +- **Local Voting Protocol**: Implements dynamic time acceleration algorithm with monotonic time guarantee |
| 10 | +- **Broadcast-based Sync**: Uses broadcast messages for efficient multi-node synchronization |
| 11 | +- **Quality Monitoring**: Tracks synchronization quality and peer performance |
| 12 | +- **Cross-platform**: Compatible with ESP32 (Xtensa) and ESP32-C6 (RISC-V) platforms |
| 13 | + |
| 14 | +## Architecture |
| 15 | + |
| 16 | +The example consists of several key components: |
| 17 | + |
| 18 | +1. **TimeSyncManager**: Main synchronization controller |
| 19 | +2. **ESP-NOW Protocol**: Communication layer for time data exchange |
| 20 | +3. **Sync Algorithm**: Core synchronization algorithm with dynamic correction |
| 21 | +4. **Timer Integration**: Integration with Martos timer system |
| 22 | + |
| 23 | +## Configuration |
| 24 | + |
| 25 | +The synchronization system is configured with the following parameters: |
| 26 | + |
| 27 | +- **Sync Interval**: 500ms (default broadcast frequency) |
| 28 | +- **Max Correction**: 1000μs (default maximum time correction per cycle) |
| 29 | +- **Acceleration Factor**: 0.1 (default acceleration rate) |
| 30 | +- **Deceleration Factor**: 0.05 (default deceleration rate) |
| 31 | +- **Max Peers**: 10 (maximum number of participants considered in consensus) |
| 32 | + |
| 33 | +## Usage |
| 34 | + |
| 35 | +### Building and Flashing |
| 36 | + |
| 37 | +```bash |
| 38 | +# Build the example |
| 39 | +cargo build --release --example time-sync |
| 40 | + |
| 41 | +# Flash to ESP32 (adjust port as needed) |
| 42 | +espflash flash --release --example time-sync /dev/ttyUSB0 |
| 43 | +``` |
| 44 | + |
| 45 | +### Running Multiple Nodes |
| 46 | + |
| 47 | +To test synchronization between multiple nodes: |
| 48 | + |
| 49 | +1. Flash the example to multiple ESP32-C6 devices (ESP32 and ESP32-C6) |
| 50 | +2. Ensure devices are within ESP-NOW communication range |
| 51 | +3. Monitor serial output to see synchronization progress |
| 52 | +4. Watch the `diff` value decrease as synchronization improves |
| 53 | + |
| 54 | +### Expected Output |
| 55 | + |
| 56 | +``` |
| 57 | +ESP32-C6: Setup time synchronization! |
| 58 | +ESP32-C6: Time synchronization setup complete! |
| 59 | +ESP32-C6: Received timestamp: 30288013μs, corrected time: 936751μs, diff: 29351262μs |
| 60 | +ESP32-C6: Current offset: 100000μs |
| 61 | +ESP32-C6: Received timestamp: 32278010μs, corrected time: 3036532μs, diff: 29241478μs |
| 62 | +ESP32-C6: Current offset: 200000μs |
| 63 | +ESP32-C6: Received timestamp: 34268014μs, corrected time: 5136548μs, diff: 29131466μs |
| 64 | +ESP32-C6: Current offset: 200000μs |
| 65 | +ESP32-C6: Received timestamp: 36258013μs, corrected time: 7136562μs, diff: 29121451μs |
| 66 | +ESP32-C6: Current offset: 300000μs |
| 67 | +ESP32-C6: Received timestamp: 38248009μs, corrected time: 9236609μs, diff: 29011400μs |
| 68 | +ESP32-C6: Current offset: 400000μs |
| 69 | +ESP32-C6: Received timestamp: 40238008μs, corrected time: 11336665μs, diff: 28901343μs |
| 70 | +ESP32-C6: Current offset: 400000μs |
| 71 | +ESP32-C6: Received timestamp: 42228012μs, corrected time: 13336653μs, diff: 28891359μs |
| 72 | +ESP32-C6: Current offset: 500000μs |
| 73 | +ESP32-C6: Received timestamp: 44218013μs, corrected time: 15436722μs, diff: 28781291μs |
| 74 | +ESP32-C6: Current offset: 600000μs |
| 75 | +ESP32-C6: Received timestamp: 46208013μs, corrected time: 17538108μs, diff: 28669905μs |
| 76 | +``` |
| 77 | + |
| 78 | +**Key observations:** |
| 79 | +- `Received timestamp`: Time from the remote node |
| 80 | +- `corrected time`: Local time adjusted by the synchronization offset |
| 81 | +- `diff`: Time difference between remote and local (should decrease over time) |
| 82 | +- `Current offset`: Virtual time offset applied to local time |
| 83 | + |
| 84 | +## Synchronization Algorithm |
| 85 | + |
| 86 | +The example implements a **Local Voting Protocol** algorithm with the following characteristics: |
| 87 | + |
| 88 | +1. **Broadcast Communication**: Nodes send time broadcasts every 2 seconds |
| 89 | +2. **Time Difference Calculation**: Compares received timestamps with local corrected time |
| 90 | +3. **Monotonic Time**: Time can only accelerate, never go backwards |
| 91 | +4. **Dynamic Correction**: Applies corrections based on weighted peer consensus |
| 92 | +5. **Convergence Detection**: Algorithm detects when nodes are synchronized |
| 93 | + |
| 94 | +### Algorithm Details |
| 95 | + |
| 96 | +- **Acceleration Factor**: 0.1 (default; tune for convergence) |
| 97 | +- **Deceleration Factor**: 0.05 (default; tune for stability) |
| 98 | +- **Max Correction**: 1000μs (default; increase carefully for faster initial sync) |
| 99 | +- **Convergence Threshold**: 50% of max correction threshold |
| 100 | + |
| 101 | +## Customization |
| 102 | + |
| 103 | +// Broadcast-only: peers are not managed explicitly |
| 104 | + |
| 105 | +### Adjusting Synchronization Parameters |
| 106 | + |
| 107 | +```rust |
| 108 | +let sync_config = SyncConfig { |
| 109 | + sync_interval_ms: 1000, // More frequent broadcasts |
| 110 | + max_correction_threshold_us: 50000, // Smaller corrections |
| 111 | + acceleration_factor: 0.9, // More aggressive acceleration |
| 112 | + deceleration_factor: 0.7, // More aggressive deceleration |
| 113 | + // ... other parameters |
| 114 | +}; |
| 115 | +``` |
| 116 | + |
| 117 | +### Monitoring Synchronization Quality |
| 118 | + |
| 119 | +```rust |
| 120 | +println!("Quality: {:.2}, Offset: {}μs", |
| 121 | + sync_manager.get_sync_quality(), |
| 122 | + sync_manager.get_time_offset_us()); |
| 123 | +``` |
| 124 | + |
| 125 | +## Troubleshooting |
| 126 | + |
| 127 | +### No Synchronization |
| 128 | + |
| 129 | +- Check ESP-NOW communication range |
| 130 | +- Ensure synchronization is enabled |
| 131 | + |
| 132 | +### Poor Synchronization Quality |
| 133 | + |
| 134 | +- Increase sync frequency |
| 135 | +- Adjust acceleration/deceleration factors |
| 136 | +- Check network conditions |
| 137 | + |
| 138 | +### Large Time Corrections |
| 139 | + |
| 140 | +- Reduce max correction threshold |
| 141 | +- Increase sync interval |
| 142 | +- Check for network delays |
| 143 | + |
| 144 | +## Performance Considerations |
| 145 | + |
| 146 | +- **CPU Usage**: Synchronization processing is lightweight |
| 147 | +- **Network Traffic**: Minimal ESP-NOW traffic (few bytes per sync cycle) |
| 148 | +- **Power Consumption**: ESP-NOW is power-efficient for IoT applications |
| 149 | + |
| 150 | +## Cross-Platform Compatibility |
| 151 | + |
| 152 | +This example is designed to work seamlessly between ESP32 (Xtensa) and ESP32-C6 (RISC-V) platforms: |
| 153 | + |
| 154 | +- **ESP-NOW Compatibility**: ESP-NOW works between different ESP chipset architectures |
| 155 | +- **Shared Protocol**: Both platforms use the same synchronization message format |
| 156 | +- **Automatic Detection**: The system automatically detects and adapts to the target platform |
| 157 | +- **Unified API**: Same Martos API works on both platforms |
| 158 | + |
| 159 | +### Testing Cross-Platform Synchronization |
| 160 | + |
| 161 | +1. Flash ESP32 example to an ESP32 device |
| 162 | +2. Flash ESP32-C6 example to an ESP32-C6 device |
| 163 | +3. Both devices will automatically discover and synchronize with each other |
| 164 | +4. Monitor both serial outputs to see synchronization progress |
| 165 | + |
| 166 | +## Future Enhancements |
| 167 | + |
| 168 | +- **Encryption**: Add ESP-NOW encryption for secure time synchronization |
| 169 | +- **Mesh Support**: Extend to multi-hop mesh networks |
| 170 | +- **GPS Integration**: Use GPS for absolute time reference |
| 171 | +- **Adaptive Algorithms**: Implement machine learning-based synchronization |
0 commit comments