Skip to content

ESP32-C2 IDF5 iperf test

Hardware

The ESP32-C2 is an effort by Espressif Systems to have a modernized replacement for the popular ESP8266, and targets the same low price point.

In order to have some hardware to play with I ordered this module from AliExpress.

ESPC2-12 module

It comes with an ESPC2-12 module, which is built around the ESP8684 SoC, which integrates an ESP32-C2 chip together with flash memory in one package. I know, confusing. It seems the amount of flash can vary from 1 MB to 2 MB or 4 MB. The ESPC2-12 module seems to integrate the 2 MB version. Not sure if the amount of flash used in the ESPC2-12 module can vary as well or if it's always 2 MB.

Anyway, for development with the ESP-IDF, you treat this as an ESP32-C2 and you need to be on version 5.0 or higher for this chip to be supported.

Building iperf

I decided to build the ESP-IDF iperf example to get an idea of the chip's performance. After cloning the ESP-IDF Github repo with its submodules, running the install.sh script to get the toolchain set up (see this page for details), and getting the environment ready with source ./export.sh, I was ready to build the example.

I navigated to examples/wifi/iperf, set the target chip with idf.py set-target esp32c2 and then activated the menu config tool with idf.py menuconfig. For the ESPC2-12 module, you need to make a change in Component config → Hardware Settings → Main XTAL Config → Main XTAL frequency and change that setting to 26 MHz since that's the crystal used in this module. After Q → Save, I was ready to do idf.py build followed by idf.py -p /dev/ttyUSB0 flash monitor.

One snag I hit at this point is that the board didn't seem to be receiving any power when its USB Type-C cable was plugged in to my PC's USB Type-C port. Turns out that the problem is that even though the board comes with a Type-C port, it is not implemented correctly. The resistors on CC1 and CC2 are missing, so the PD controller on my PC never turned power on. It seems this board will only work with a USB A to Type-C cable, not a Type-C to Type-C cable. 🙄

iperf results

The iperf example provides a command line interface on the device that can be accessed over the serial console. After connecting to my network using the sta command, I ran the chip through tests as client and server, using both TCP and UDP, connecting to an iperf program running on my PC. The results are below.

iperf client TCP

iperf> iperf -c 192.168.1.131
I (166415) cmd_wifi: mode=tcp-client sip=192.168.1.123:5001, dip=192.168.1.131:5001, interval=3, time=30
I (166488) iperf: Successfully connected

        Interval Bandwidth
iperf>    0-   3 sec       11.84 Mbits/sec
   3-   6 sec       6.99 Mbits/sec
   6-   9 sec       11.80 Mbits/sec
   9-  12 sec       12.23 Mbits/sec
  12-  15 sec       12.10 Mbits/sec
  15-  18 sec       11.67 Mbits/sec
  18-  21 sec       11.97 Mbits/sec
  21-  24 sec       12.23 Mbits/sec
  24-  27 sec       11.75 Mbits/sec
  27-  30 sec       10.62 Mbits/sec
   0-  30 sec       11.32 Mbits/sec
I (196512) iperf: TCP Socket client is closed.
I (196513) iperf: iperf exit

iperf client UDP

iperf> iperf -u -c 192.168.1.131
I (262102) cmd_wifi: mode=udp-client sip=192.168.1.123:5001, dip=192.168.1.131:5001, interval=3, time=30
I (262104) iperf: Socket created, sending to -2097043264:5001

        Interval Bandwidth
   0-   3 sec       24.38 Mbits/sec
   3-   6 sec       24.91 Mbits/sec
   6-   9 sec       22.76 Mbits/sec
   9-  12 sec       22.29 Mbits/sec
  12-  15 sec       23.11 Mbits/sec
  15-  18 sec       22.96 Mbits/sec
  18-  21 sec       24.30 Mbits/sec
  21-  24 sec       22.75 Mbits/sec
  24-  27 sec       22.94 Mbits/sec
  27-  30 sec       23.07 Mbits/sec
   0-  30 sec       23.35 Mbits/sec
I (292123) iperf: UDP Socket client is closed
I (292124) iperf: iperf exit

iperf server TCP

iperf> iperf -s
I (523951) cmd_wifi: mode=tcp-server sip=192.168.1.123:5001, dip=0.0.0.0:5001, interval=3, time=30
I (523953) iperf: Socket created
iperf> I (529306) iperf: accept: 192.168.1.131,58362


        Interval Bandwidth
   0-   3 sec       8.86 Mbits/sec
   3-   6 sec       10.11 Mbits/sec
   6-   9 sec       6.55 Mbits/sec
W (539471) iperf: tcp server recv error, error code: 128, reason: Socket is not connected
I (539474) iperf: TCP Socket server is closed.
I (539490) iperf: iperf exit
   9-  12 sec       3.48 Mbits/sec

iperf server UDP

iperf> iperf -u -s
I (470205) cmd_wifi: mode=udp-server sip=192.168.1.123:5001, dip=0.0.0.0:5001, interval=3, time=30
I (470206) iperf: Socket created
I (470223) iperf: Socket bound, port 35091
        Interval Bandwidth
   0-   3 sec       1.09 Mbits/sec
   3-   6 sec       1.05 Mbits/sec
   6-   9 sec       1.05 Mbits/sec
   9-  12 sec       1.10 Mbits/sec
  12-  15 sec       0.00 Mbits/sec

iperf>   15-  18 sec       0.00 Mbits/sec
  18-  21 sec       0.00 Mbits/sec
W (494215) iperf: udp server recv error, error code: 11, reason: No more processes
I (494216) iperf: Udp socket server is closed.
I (494233) iperf: iperf exit
  21-  24 sec       0.00 Mbits/sec

Results

I didn't spend much time digging into these results. From a quick Internet search it seems that the ~20+ Mbits/sec for UDP client seems to be in the low but expected range for ESP32s in a normal WiFi environment (not a shielded box). The TCP client result of ~10+ Mbits/sec seems a bit low compared to UDP. Since TCP requires more processing than UDP, maybe this can be blamed on the comparatively slower 120 MHz single core RISC-V processor used in this chip, compared to other ESP32s.

On the other hand, this page seems to indicate the ESP8266 (that the ESP32-C2 intends to replace) only reaches about 2-3 Mbits/sec, so compared to that it's an improvement.

For the server test, something seems to be wrong. The UDP result of ~1 Mbits/sec seems really low compared to the client test, and both the TCP and UDP tests suffered disconnection problems. I don't have time to dig more into this currently.

MicroPython?

I had the initial thought to check how hard it would be to port MicroPython to this module. After a bit of hacking it definitely seemed like too much of a project. The ESP32-C2 is only supported in ESP-IDF version 5.0 and higher, and MicroPython currently supports ESP-IDF up to version 4.4. There seem to be quite a few breaking changes between versions 4.4 and 5.0, and I had to give up my quick effort. It looks like moving to ESP-IDF 5.0 will be a substantial effort for the good folks at MicroPython since it looks like there will be quite a few changes necessary.