|
| 1 | +########## |
| 2 | +OpenThread |
| 3 | +########## |
| 4 | + |
| 5 | +About |
| 6 | +----- |
| 7 | + |
| 8 | +The OpenThread library provides support for creating Thread network devices using ESP32 SoCs with IEEE 802.15.4 radio support. The library offers two different programming interfaces for interacting with the OpenThread stack: |
| 9 | + |
| 10 | +* **Stream-based CLI enhanced with Helper Functions API**: Command-line interface helper functions that send OpenThread CLI commands and parse responses |
| 11 | +* **Classes API**: Object-oriented classes that directly call OpenThread API functions |
| 12 | + |
| 13 | +The OpenThread library is built on top of `ESP OpenThread <https://github.com/espressif/esp-openthread>`_ and provides a high-level Arduino-style interface for creating Thread devices. |
| 14 | + |
| 15 | +Thread Protocol Overview |
| 16 | +************************ |
| 17 | + |
| 18 | +Thread is an IPv6-based, low-power wireless mesh networking protocol designed for smart home and IoT applications. It provides secure, reliable, and scalable connectivity for battery-powered devices. |
| 19 | + |
| 20 | +**Key Features:** |
| 21 | + |
| 22 | +* **IPv6-based**: Native IPv6 addressing and routing |
| 23 | +* **Mesh Networking**: Self-healing mesh topology with automatic routing |
| 24 | +* **Low Power**: Optimized for battery-operated devices |
| 25 | +* **Security**: Built-in security features including encryption and authentication |
| 26 | +* **Scalability**: Supports up to 250+ devices per network |
| 27 | +* **Reliability**: Automatic route discovery and self-healing capabilities |
| 28 | + |
| 29 | +Thread Network Topology |
| 30 | +*********************** |
| 31 | + |
| 32 | +.. code-block:: text |
| 33 | +
|
| 34 | + ┌─────────────────┐ |
| 35 | + │ Internet │ |
| 36 | + └─────────────────┘ |
| 37 | + ▲ |
| 38 | + │ |
| 39 | + │ |
| 40 | + ┌─────────────────┐ |
| 41 | + │ Wi-Fi Router │ |
| 42 | + │ │ |
| 43 | + └─────────────────┘ |
| 44 | + │ |
| 45 | + ┌───────────────┴───────────────┐ |
| 46 | + │ │ |
| 47 | + ▼ ▼ |
| 48 | + ┌───────────────────────┐ ┌──────────────────┐ |
| 49 | + │ Other Wi-Fi Devices │ │ Thread Border │ |
| 50 | + │ │ │ Router │ |
| 51 | + └───────────────────────┘ └──────────────────┘ |
| 52 | + │ |
| 53 | + │ Thread Network |
| 54 | + │ |
| 55 | + ┌─────────────────────────┼─────────────────────────┐ |
| 56 | + │ │ │ |
| 57 | + ▼ ▼ ▼ |
| 58 | + ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ |
| 59 | + │ Thread Leader │◄─────►│ Thread Router │◄─────►│ Thread Child │ |
| 60 | + │ │ │ │ │ │ |
| 61 | + └─────────────────┘ └─────────────────┘ └─────────────────┘ |
| 62 | + │ │ │ |
| 63 | + └──────────────────────────┴──────────────────────────┘ |
| 64 | + Other Thread Nodes |
| 65 | +
|
| 66 | +
|
| 67 | +**Thread Device Roles:** |
| 68 | + |
| 69 | +* **Leader**: Manages the Thread network, assigns router IDs, and maintains network state. This device shall be powered by a wall adapter. |
| 70 | +* **Router**: Extends network range, routes messages, maintains network topology. This device shall be powered by a wall adapter. |
| 71 | +* **Child**: End device that can sleep for extended periods (battery-powered devices). It can be powered by a battery or a wall adapter. |
| 72 | +* **Detached**: Device not currently participating in a Thread network. |
| 73 | +* **Disabled**: The Thread stack and interface is disabled. |
| 74 | + |
| 75 | +**Other Thread Network Devices:** |
| 76 | + |
| 77 | +* **Thread Border Router**: A device that connects a Thread network to other IP-based networks in the extrenal world. The Thread Border Router is connected to both the Thread network and external IP networks (like Wi-Fi router), enabling Thread devices to communicate with devices on other networks and the Internet. A Border Router can be implemented on a device with any Thread device role (Leader, Router, or Child). It can also act as gateway to other protocols such as MQTT or Zigbee. |
| 78 | + |
| 79 | +OpenThread Library Structure |
| 80 | +---------------------------- |
| 81 | + |
| 82 | +**The library provides two main programming interfaces:** |
| 83 | + |
| 84 | +* **CLI Helper Functions API**: Functions that interact with OpenThread through the CLI interface |
| 85 | + * ``otGetRespCmd()``: Execute CLI command and get response |
| 86 | + * ``otExecCommand()``: Execute CLI command with arguments |
| 87 | + * ``otPrintRespCLI()``: Execute CLI command and print response to Stream |
| 88 | + * ``OpenThreadCLI``: Stream-based CLI interface class |
| 89 | + |
| 90 | +* **Classes API**: Object-oriented classes that directly call OpenThread API functions |
| 91 | + * ``OpenThread``: Main class for managing Thread network operations |
| 92 | + * ``DataSet``: Class for managing Thread operational datasets |
| 93 | + |
| 94 | +OpenThread Class |
| 95 | +**************** |
| 96 | + |
| 97 | +The ``OpenThread`` class is the main entry point for Thread operations using the Classes API. It provides direct access to OpenThread API functions for managing the Thread network. |
| 98 | + |
| 99 | +* **Network Management**: Starting, stopping, and managing the Thread network |
| 100 | +* **Device Role Management**: Getting and monitoring device role (Leader, Router, Child, Detached, Disabled) |
| 101 | +* **Dataset Management**: Setting and getting operational dataset parameters |
| 102 | +* **Address Management**: Getting mesh-local addresses, RLOC, and multicast addresses |
| 103 | +* **Network Information**: Getting network name, channel, PAN ID, and other network parameters |
| 104 | + |
| 105 | +The ``OpenThread`` class is implemented as a singleton, meaning there's only one instance available globally. You access it directly as ``OThread`` without creating an instance. |
| 106 | + |
| 107 | +.. toctree:: |
| 108 | + :maxdepth: 2 |
| 109 | + |
| 110 | + openthread_core |
| 111 | + |
| 112 | +DataSet Class |
| 113 | +************* |
| 114 | + |
| 115 | +The ``DataSet`` class provides a convenient way to manage Thread operational datasets. It allows you to create, configure, and apply operational datasets to the Thread network. |
| 116 | + |
| 117 | +* **Dataset Creation**: Create new operational datasets |
| 118 | +* **Parameter Configuration**: Set network name, channel, PAN ID, network key, and extended PAN ID |
| 119 | +* **Dataset Application**: Apply datasets to the Thread network |
| 120 | +* **Dataset Retrieval**: Get current dataset parameters |
| 121 | + |
| 122 | +.. toctree:: |
| 123 | + :maxdepth: 2 |
| 124 | + |
| 125 | + openthread_dataset |
| 126 | + |
| 127 | +OpenThreadCLI |
| 128 | +************* |
| 129 | + |
| 130 | +The ``OpenThreadCLI`` class provides a Stream-based interface for interacting with the OpenThread CLI. It allows you to send CLI commands and receive responses programmatically. |
| 131 | + |
| 132 | +* **CLI Interface**: Stream-based interface for sending commands and receiving responses |
| 133 | +* **Command Execution**: Execute OpenThread CLI commands programmatically |
| 134 | +* **Response Handling**: Parse and handle CLI command responses |
| 135 | +* **Console Mode**: Interactive console mode for debugging and testing |
| 136 | + |
| 137 | +.. toctree:: |
| 138 | + :maxdepth: 2 |
| 139 | + |
| 140 | + openthread_cli |
| 141 | + |
| 142 | +CLI Helper Functions API |
| 143 | +************************* |
| 144 | + |
| 145 | +The CLI Helper Functions API provides utility functions for executing OpenThread CLI commands and parsing responses. This API is useful when you need to interact with OpenThread through the CLI interface. |
| 146 | + |
| 147 | +* **Command Execution**: Execute CLI commands with arguments |
| 148 | +* **Response Parsing**: Get and parse CLI command responses |
| 149 | +* **Error Handling**: Handle CLI command errors and return codes |
| 150 | + |
| 151 | +**Key Functions:** |
| 152 | + |
| 153 | +* ``otGetRespCmd()``: Execute CLI command and get response string |
| 154 | +* ``otExecCommand()``: Execute CLI command with arguments and error handling |
| 155 | +* ``otPrintRespCLI()``: Execute CLI command and print response to Stream |
| 156 | + |
| 157 | +For detailed documentation on the CLI Helper Functions API, see the :doc:`openthread_cli` documentation. |
| 158 | + |
| 159 | +Supported Hardware |
| 160 | +------------------ |
| 161 | + |
| 162 | +The OpenThread library requires ESP32 SoCs with IEEE 802.15.4 radio support: |
| 163 | + |
| 164 | +* **ESP32-H2**: Native Thread support with IEEE 802.15.4 radio |
| 165 | +* **ESP32-C6**: Thread support with IEEE 802.15.4 radio (when Thread is enabled) |
| 166 | +* **ESP32-C5**: Thread support with IEEE 802.15.4 radio (when Thread is enabled) |
| 167 | + |
| 168 | +**Note:** Thread support must be enabled in the ESP-IDF configuration (``CONFIG_OPENTHREAD_ENABLED``). This is done automatically when using the ESP32 Arduino OpenThread library. |
| 169 | + |
| 170 | +Common Problems and Issues |
| 171 | +-------------------------- |
| 172 | + |
| 173 | +Troubleshooting |
| 174 | +--------------- |
| 175 | + |
| 176 | +Common Issues |
| 177 | +************* |
| 178 | + |
| 179 | +**Thread network not starting** |
| 180 | + * Ensure the device has IEEE 802.15.4 radio support (ESP32-H2, ESP32-C6, ESP32-C5) |
| 181 | + * Check that Thread is enabled in ESP-IDF configuration (``CONFIG_OPENTHREAD_ENABLED``) |
| 182 | + * Verify that ``OpenThread::begin()`` is called before using Thread functions |
| 183 | + * Check Serial Monitor for initialization errors |
| 184 | + |
| 185 | +**Device not joining network** |
| 186 | + * Verify the operational dataset parameters (network name, network key, channel, PAN ID) |
| 187 | + * Ensure the device is within range of the Thread network |
| 188 | + * Check that the network key and extended PAN ID match the network you're trying to join |
| 189 | + * Verify the device role is not "Detached" |
| 190 | + |
| 191 | +**CLI commands not working** |
| 192 | + * Ensure ``OpenThreadCLI::begin()`` is called before using CLI functions |
| 193 | + * Check that ``OpenThreadCLI::startConsole()`` is called with a valid Stream |
| 194 | + * Verify the CLI is properly initialized and running |
| 195 | + * Check Serial Monitor for CLI initialization errors |
| 196 | + |
| 197 | +**Address not available** |
| 198 | + * Wait for the device to join the Thread network (role should be Child, Router, or Leader) |
| 199 | + * Check that the network interface is up using ``networkInterfaceUp()`` |
| 200 | + * Verify the device has obtained a mesh-local address |
| 201 | + * Check network connectivity using ``getRloc()`` or ``getMeshLocalEid()`` |
| 202 | + |
| 203 | +**Dataset not applying** |
| 204 | + * Ensure all required dataset parameters are set (network name, network key, channel) |
| 205 | + * Verify the dataset is valid before applying |
| 206 | + * Check that OpenThread is started before applying the dataset |
| 207 | + * Verify the dataset parameters match the target network |
| 208 | + |
| 209 | +Initialization Order |
| 210 | +******************** |
| 211 | + |
| 212 | +For proper initialization, follow this order: |
| 213 | + |
| 214 | +1. Initialize OpenThread stack: ``OpenThread::begin()`` |
| 215 | +2. Initialize OpenThreadCLI (if using CLI): ``OpenThreadCLI::begin()`` |
| 216 | +3. Start CLI console (if using CLI): ``OpenThreadCLI::startConsole()`` |
| 217 | +4. Configure dataset (if needed): Create and configure ``DataSet`` |
| 218 | +5. Apply dataset (if needed): ``OThread.commitDataSet(dataset)`` |
| 219 | +6. Start Thread network: ``OThread.start()`` |
| 220 | +7. Bring network interface up: ``OThread.networkInterfaceUp()`` |
| 221 | + |
| 222 | +Example |
| 223 | +------- |
| 224 | + |
| 225 | +Basic OpenThread Setup |
| 226 | +********************** |
| 227 | + |
| 228 | +Using the Classes API: |
| 229 | + |
| 230 | +.. code-block:: arduino |
| 231 | +
|
| 232 | + #include <OThread.h> |
| 233 | +
|
| 234 | + void setup() { |
| 235 | + Serial.begin(115200); |
| 236 | + |
| 237 | + // Initialize OpenThread stack |
| 238 | + OpenThread::begin(); |
| 239 | + |
| 240 | + // Wait for OpenThread to be ready |
| 241 | + while (!OThread) { |
| 242 | + delay(100); |
| 243 | + } |
| 244 | + |
| 245 | + // Create and configure dataset |
| 246 | + DataSet dataset; |
| 247 | + dataset.initNew(); |
| 248 | + dataset.setNetworkName("MyThreadNetwork"); |
| 249 | + dataset.setChannel(15); |
| 250 | + |
| 251 | + // Apply dataset and start network |
| 252 | + OThread.commitDataSet(dataset); |
| 253 | + OThread.start(); |
| 254 | + OThread.networkInterfaceUp(); |
| 255 | + |
| 256 | + // Print network information |
| 257 | + OpenThread::otPrintNetworkInformation(Serial); |
| 258 | + } |
| 259 | +
|
| 260 | +Using the CLI Helper Functions API: |
| 261 | + |
| 262 | +.. code-block:: arduino |
| 263 | +
|
| 264 | + #include <OThread.h> |
| 265 | + #include <OThreadCLI.h> |
| 266 | + #include <OThreadCLI_Util.h> |
| 267 | +
|
| 268 | + void setup() { |
| 269 | + Serial.begin(115200); |
| 270 | + |
| 271 | + // Initialize OpenThread stack |
| 272 | + OpenThread::begin(); |
| 273 | + |
| 274 | + // Initialize and start CLI |
| 275 | + OThreadCLI.begin(); |
| 276 | + OThreadCLI.startConsole(Serial); |
| 277 | + |
| 278 | + // Wait for CLI to be ready |
| 279 | + while (!OThreadCLI) { |
| 280 | + delay(100); |
| 281 | + } |
| 282 | + |
| 283 | + // Execute CLI commands |
| 284 | + char resp[256]; |
| 285 | + if (otGetRespCmd("state", resp)) { |
| 286 | + Serial.printf("Thread state: %s\r\n", resp); |
| 287 | + } |
| 288 | + |
| 289 | + if (otExecCommand("networkname", "MyThreadNetwork", NULL)) { |
| 290 | + Serial.println("Network name set successfully"); |
| 291 | + } |
| 292 | + |
| 293 | + if (otExecCommand("ifconfig", "up", NULL)) { |
| 294 | + Serial.println("Network interface up"); |
| 295 | + } |
| 296 | + } |
| 297 | +
|
0 commit comments