This ESP-IDF component provides a simple API for IEEE 802.15.4 communication using the ESP32's built-in IEEE 802.15.4 radio. It supports initializing the transceiver, transmitting and receiving frames, setting receive callbacks, and dynamically switching channels (11-26) in promiscuous mode.
- Initialize the IEEE 802.15.4 radio in promiscuous mode for flexible frame capture.
- Transmit and receive IEEE 802.15.4 frames with support for custom frame structures.
- Register callbacks to process received frames with RSSI and LQI information.
- Dynamically switch channels (11-26) without reinitializing the radio.
- Built on top of ESP-IDF's
esp_ieee802154component andshoderico/ieee802154_framefor frame handling.
- ESP-IDF v5.0 or later (tested with v5.4.1).
- ESP32 with IEEE 802.15.4 support (e.g., ESP32-C6, ESP32-H2).
- Non-Volatile Storage (NVS) initialized before using the component.
- FreeRTOS for task and message buffer management.
This component is available on the ESP Component Registry. To add it to your ESP-IDF project, run:
idf.py add-dependency "shoderico/ieee802154_transceiver^1.0.0"Alternatively, clone the component into your project's components directory and update your CMakeLists.txt to include it.
-
Initialize NVS: Initialize NVS before using the component:
esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret);
-
Initialize the Transceiver: Set up the transceiver on a specific channel (11-26):
esp_err_t ret = ieee802154_transceiver_init(11); if (ret != ESP_OK) { // Handle error }
-
Set a Receive Callback: Define a callback to process received frames:
void rx_callback(ieee802154_frame_t *frame, esp_ieee802154_frame_info_t *frame_info, void *user_data) { printf("Received frame: payloadLen=%d, RSSI=%d, LQI=%d\n", frame->payloadLen, frame_info->rssi, frame_info->lqi); } ieee802154_transceiver_set_rx_callback(rx_callback, NULL);
When a frame is received, the ESP-IDF's
esp_ieee802154_receive_doneinterrupt function is triggered. By callingieee802154_transceiver_handle_receive_donefrom this function, the registered callback (e.g.,rx_callback) is invoked:void esp_ieee802154_receive_done(uint8_t *frame, esp_ieee802154_frame_info_t *frame_info) { ieee802154_transceiver_handle_receive_done(frame, frame_info); }
-
Transmit a Frame: Create and send an IEEE 802.15.4 frame:
uint8_t payload[] = "Hello, IEEE 802.15.4!"; ieee802154_frame_t frame = { .fcf = { .frameType = IEEE802154_FRAME_TYPE_DATA, // 001 .securityEnabled = 0, // 0 .framePending = 0, // 0 .ackRequest = 1, // 1 .panIdCompression = 1, // 1 .reserved = 0, // 0 .sequenceNumberSuppression = 0, // 0 .informationElementsPresent = 0, // 0 .destAddrMode = IEEE802154_ADDR_MODE_SHORT, // 10 .frameVersion = IEEE802154_VERSION_2006, // 01 .srcAddrMode = IEEE802154_ADDR_MODE_SHORT // 10 }, .sequenceNumber = 0x02, .destPanId = 0x1234, .destAddress = {0xFF, 0xFF}, // Broadcast .srcPanId = 0x1234, .srcAddress = {0x9A, 0xBC}, .payloadLen = strlen((char *)payload), .payload = payload } ieee802154_transceiver_transmit(&frame);
-
Deinitialize: Clean up resources when done:
ieee802154_transceiver_deinit();
- simple_transceiver
The examples/simple_transceiver directory includes a sample project that demonstrates:
- Initializing the transceiver on channel 11.
- Logging received frames via a callback.
- Periodically transmitting a test frame every 5 seconds.
To build and run the example:
cd examples/simple_transceiver
idf.py set-target esp32c6
idf.py build flash monitor- ieee802154_sniffer
The examples/ieee802154_sniffer directory includes another project that demonstrates:
- Initializing the rx transceiver on channel 11.
- Tracing the binary dump of received frames
To build and run the example:
cd examples/ieee802154_sniffer
idf.py set-target esp32c6
idf.py build flash monitor- ieee802154_bridge
The examples/ieee802154_bridge directory includes another project that demonstrates:
- Initializing the rx transceiver on channel 11.
- Once received a frame, transmitting the same frame to another channel 13.
- Measuring performance and trace average time from receiving to transmitting.
To build and run the example:
cd examples/ieee802154_bridge
idf.py set-target esp32c6
idf.py build flash monitorThe test directory contains Unity-based unit tests to verify the component's functionality, including:
- Transceiver initialization with valid and invalid channels.
- Channel switching.
- Receive callback registration.
Each test case explicitly initializes and deinitializes the transceiver to ensure resource cleanup. To run the tests:
cd test_runner
idf.py set-target esp32c6
idf.py build flash monitorshoderico/ieee802154_frame: Handles IEEE 802.15.4 frame parsing and building.- ESP-IDF's
esp_ieee802154: Provides low-level radio control. - FreeRTOS: Manages tasks and message buffers.
- NVS: Stores radio configuration.
Licensed under the MIT.
Contributions are welcome! Submit issues or pull requests to the repository at [your repository URL].
- Initialization Fails: Ensure NVS is initialized and the channel is between 11 and 26.
- No Frames Received: Verify the radio is in promiscuous mode and the channel matches the sender.
- Resource Errors: Call
ieee802154_transceiver_deinitafter use to free resources.