Skip to content

Binary Data Output Support for Wi-Fi CSI to prevent packet loss at 256 subcarriers/100+Hz (AEGHB-1434) #249

Open

Description

@khanhdew

Checklist

  • Checked the issue tracker for similar issues to ensure this is not a duplicate.
  • Described the feature in detail and justified the reason for the request.
  • Provided specific use cases and examples.

Feature description

I am requesting an official implementation or a standardized example for Binary Data Streaming of Wi-Fi CSI (Channel State Information). Currently, most examples use printf or ets_printf to output CSI data as ASCII strings. While this works for low subcarrier counts, it fails at 256 subcarriers and 100Hz sampling rates because:

  1. The string conversion (ASCII) significantly inflates the data size (from ~512 bytes raw to ~2000+ characters).
    CPU overhead for string formatting inside the CSI callback causes the system to drop packets (rx_id skipping).
  2. The feature should provide a way to stream the wifi_csi_info_t->buf directly in a raw binary frame (e.g., [Header][Metadata][Raw Payload]) via UART/USB-Serial.

Use cases

  • High-Fidelity Human Activity Recognition (HAR): Capturing fine-grained movements that require the high subcarrier and high sampling rates without data gaps.
  • Real-time CSI Monitoring: Streaming large-scale CSI data to a PC for Machine Learning inference where low latency and zero packet loss are critical.
  • Resource-Constrained Logging: Efficiently saving CSI data to SD cards or external storage by minimizing write overhead.

Alternatives

No response

Additional context

In my testing with an ESP32 at 2,000,000 baud, using 128 subcarriers works fine, but 256 subcarriers causes immediate packet loss (skipping rx_id). This confirms that the bottleneck is the UART throughput and CPU string processing. Moving to a binary-only output would reduce the bandwidth requirement by ~75% and eliminate the formatting overhead, allowing the ESP32 to handle CSI reliably at 100Hz or higher.

Hardware/Software Environment:

Chip: ESP32 C6
CSI Configuration: 256 subcarriers (20MHz bandwidth).
Desired Sample Rate: 100Hz - 200Hz.

#if (CONFIG_IDF_TARGET_ESP32C6 && ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 4, 0))
#define CONFIG_WIFI_BAND_MODE               WIFI_BAND_MODE_2G_ONLY
#define CONFIG_WIFI_2G_BANDWIDTHS           WIFI_BW_HT20
#define CONFIG_WIFI_2G_PROTOCOL             WIFI_PROTOCOL_11AX
#define CONFIG_ESP_NOW_PHYMODE           WIFI_PHY_MODE_HE20
#define CONFIG_ESP_NOW_RATE             WIFI_PHY_RATE_MCS0_LGI
#define CONFIG_FORCE_GAIN                   1
#endif

Activity

  1. changed the title [-]Binary Data Output Support for Wi-Fi CSI to prevent packet loss at 256 subcarriers/100+Hz[/-] [+]Binary Data Output Support for Wi-Fi CSI to prevent packet loss at 256 subcarriers/100+Hz (AEGHB-1434)[/+] on Mar 4, 2026
  2. NingYuxiang commented on Mar 4, 2026

    @NingYuxiang
    Contributor

    Thank you for your detailed feedback and thorough test results.
    The performance limitations you mentioned (i.e., the bandwidth and CPU overhead introduced by ASCII output) are valid and expected. These issues typically become noticeable when using a higher number of subcarriers and higher sampling rates.It is important to note that data transmission methods can vary significantly depending on the application scenario. Therefore, in the current examples, we chose a human-readable ASCII format to facilitate debugging and quick validation.

    For use cases requiring higher throughput or lower latency (such as 256 subcarriers at 100Hz+), we recommend implementing a more efficient data path based on your specific requirements. For example:

    • Avoid performing string formatting inside the CSI callback
    • Use a queue or ring buffer to offload data from the callback context
    • Pack and transmit the data in binary format
    • Select a more suitable interface based on bandwidth requirements (e.g., UART, USB, SPI, or Wi-Fi)

    Additionally, the esp-csi repository primarily focuses on CSI data acquisition and sensing capabilities. Data encoding and transmission are considered application-layer design choices. Therefore, the repository currently only provides ASCII-based output examples.

    Thank you for your understanding and feedback.

  3. khanhdew commented on Mar 4, 2026

    @khanhdew
    Author

    @NingYuxiang
    Thank you for response,

    I tried the first 2 options that you gave but not really solve the problems. I think the only way is to send with binary format.

    Let me try this option and give you feedback, if it works fine I'll create a PR.

  4. Karimkh31 commented on Mar 9, 2026

    @Karimkh31

    Hi @khanhdew ,

    I'm also working on a similar problem. Could you share what you have tried? For example, the ring buffer size? Using USB CDC combined with a ring buffer and binary CSI data should produce better results.

  5. NingYuxiang commented on Mar 9, 2026

    @NingYuxiang
    Contributor

    Actually, the repository already provides an example for binary output, which you can refer to:

    esp-csi/examples/esp-radar/console_test/main/app_main.c#L381

    This example demonstrates how to directly output in binary format.

    You can use this template for your development and testing. If you have any further questions, feel free to continue the discussion.

  6. khanhdew commented on Mar 11, 2026

    @khanhdew
    Author

    I changed my test scenario. ESP32C6 as RX to receive csi data from router with rate 100pps, 128 subcarriers and it working well but when receive from another ESP32C6, there is still packet loss.

    I have no idea what's going rn.

    @Karimkh31 have you experienced this situation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions