Cannot upload code to esp32 on my Mac

Hi, I have been using Platformio on my Mac for quite some time with no problems.
Now, with one esp32 devkit1 I am facing a strange issue I cannot solve and I am looking for some help.

Using terminal and esptool.py I can connect to the device, detect the chip, program it, verify the code, etc. etc. No problems.
Same using a usb-serial app. Same with Arduino IDE. This esp32 connects and works absolutely fine.
Then I open Platformio.
The usb interface of the esp32 is visible (/dev/cu.usbserial-0001) but if I try and connect I get this error:
UserSideException: [Errno 16] could not open port /dev/cu.usbserial-0001: [Errno 16] Resource busy: ‘/dev/cu.usbserial-0001’
Clearly all previous programs are closed.
Even more strange, after I get this error I can no longer access the usb interface, neither with terminal nor with the serial app.
I need to close platformio and only then can I access the interface again, as if Platfomio was “grabbing” the interface.
So far, using other esp32 devkit’s I have had no problems.
I tried including this in .ini
upload_port = /dev/cu.usbserial-0001
upload_speed = 460800
no change, also modifying the speed.
I also tried to add an elco on the EN pin, which used to solve similar problems long ago, but that also does not help.

Has anyone got any suggestion?
…I could clearly throw away this very device… but I would just like to understand why it is not working with Platformio.
Regards.

Do you also have a /dev/tty.usbserial-0001 device? I think there’s a difference between a callup and a teletypewrite device.

Yes, /dev/tty.usbserial-0001 does exist, though this is not listed by Platformio as an available device.
If I try and use /dev/tty.usbserial-0001 either as an upload port or as a monitor port I just get basically the same error with a different code. See here below:
(when trying to uplod)

A fatal error occurred: Could not open /dev/tty.usbserial-0001, the port is busy or doesn't exist.
([Errno 35] Could not exclusively lock port /dev/tty.usbserial-0001: [Errno 35] Resource temporarily unavailable)

*** [upload] Error 2

(when trying to connect to the esp32 serial)

UserSideException: [Errno 35] Could not exclusively lock port /dev/tty.usbserial-0001: [Errno 35] Resource temporarily unavailable

 *  The terminal process "platformio 'device', 'monitor'" terminated with exit code: 1. 
 *  Terminal will be reused by tasks, press any key to close it. 

If I remove the upload_port & monitor_port definitions in .ini, and use “auto” selection, Platformio does select automatically /dev/cu.usbserial-0001 but the error is again the same:

Uploading .pio/build/esp32/firmware.bin
esptool.py v4.7.5
Serial port /dev/cu.usbserial-0001

A fatal error occurred: Could not open /dev/cu.usbserial-0001, the port is busy or doesn't exist.
([Errno 16] could not open port /dev/cu.usbserial-0001: [Errno 16] Resource busy: '/dev/cu.usbserial-0001')

*** [upload] Error 2

And you 100% have all other programs closed? If any serial monitor is open, it might have a lock on the device.

Indeed. All other programs are closed.

I’ve never seen such a thing.

In the Arduino IDE, where it works, go to File → Preferences → tick “Verbose Upload”. Do a upload and copy paste the log here or to pastebin.com.

It is indeed weird. I start to believe that this very device is somehow defective, though I cannot understand why it is just not working with Platformio on the Mac.
FYI I installed Platformio for windows running on Parallels on the same Mac.
I can connect with this esp32 with no problems. Yet, to upload the code I must keep the boot button pressed. Still it works.
Here is the verbose log with Arduino 2.3.4:

Sketch uses 197340 bytes (15%) of program storage space. Maximum is 1310720 bytes.
Global variables use 13084 bytes (3%) of dynamic memory, leaving 314596 bytes for local variables. Maximum is 327680 bytes.
"/Users/gabriele/Library/Arduino15/packages/esp32/tools/esptool_py/3.0.0/esptool" --chip esp32 --port "/dev/cu.usbserial-0001" --baud 921600  --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size detect 0xe000 "/Users/gabriele/Library/Arduino15/packages/esp32/hardware/esp32/1.0.6/tools/partitions/boot_app0.bin" 0x1000 "/Users/gabriele/Library/Arduino15/packages/esp32/hardware/esp32/1.0.6/tools/sdk/bin/bootloader_dio_80m.bin" 0x10000 "/Users/gabriele/Library/Caches/arduino/sketches/A02387A2454CDF2010EC9A207070C649/sketch_jan24a.ino.bin" 0x8000 "/Users/gabriele/Library/Caches/arduino/sketches/A02387A2454CDF2010EC9A207070C649/sketch_jan24a.ino.partitions.bin"
esptool.py v3.0-dev
Serial port /dev/cu.usbserial-0001
Connecting........_____....._____....._
Chip is ESP32-D0WD-V3 (revision 3)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 08:b6:1f:29:db:cc
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Compressed 8192 bytes to 47...
Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (effective 2585.6 kbit/s)...
Hash of data verified.
Compressed 17120 bytes to 11164...
Writing at 0x00001000... (100 %)
Wrote 17120 bytes (11164 compressed) at 0x00001000 in 0.2 seconds (effective 908.1 kbit/s)...
Hash of data verified.
Compressed 197456 bytes to 105527...
Writing at 0x00010000... (14 %)
Writing at 0x00014000... (28 %)
Writing at 0x00018000... (42 %)
Writing at 0x0001c000... (57 %)
Writing at 0x00020000... (71 %)
Writing at 0x00024000... (85 %)
Writing at 0x00028000... (100 %)
Wrote 197456 bytes (105527 compressed) at 0x00010000 in 2.0 seconds (effective 780.9 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 128...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (128 compressed) at 0x00008000 in 0.0 seconds (effective 1003.8 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

Well it does use an older esptool version in the Arduino IDE compared to what PlatformIO is using

Can you add this to the platformio.ini

platform_packages =
   tool-esptoolpy@1.30300.0

to try and downgrade the version? If that’s not working, try with version 1.30000.201119.

Apparently the version number is not correct.
I get this error:

Resolving esp32 dependencies...

Tool Manager: Installing pioarduino/tool-esptoolpy @ 1.30300.0

UnknownPackageError: Could not find the package with 'pioarduino/tool-esptoolpy @ 1.30300.0' requirements for your system 'darwin_x86_64'

I get the same error using 1.30000.201119
I also tried the opposite, upgrading to esptool 4.8.0 which I had used elsewhere. No improvement.

esptool.py v4.8.0
Serial port /dev/cu.usbserial-0001

A fatal error occurred: Could not open /dev/cu.usbserial-0001, the port is busy or doesn't exist.
([Errno 16] could not open port /dev/cu.usbserial-0001: [Errno 16] Resource busy: '/dev/cu.usbserial-0001')

he Mac is running esptool version 4.8.1
If I use this command from terminal:
esptool.py --chip esp32 --port /dev/cu.usbserial-0001 --baud 460800 write_flash -z 0x1000 bootloader.bin 0x8000 partitions.bin 0x10000 firmware.bin

The code uploads with no problems.

Oh, I thought you were using mainline platform-espressif32, not pioarduino/platform-espressif32. This would be able to use a newer version.

Can you retry with

platform_packages =
   platformio/tool-esptoolpy@1.30300.0

and

platform_packages =
   platformio/tool-esptoolpy@1.30000.201119

respectively?

Otherwise, please use the mainline Espressif platform as a test, not the pioarduino forked one.

[env:esp32dev]
platform = espressif32@6.9.0
framework = arduino
board = esp32dev

I tried one step at a time.
First I moved to the mainline Espressif platform
platform = espressif32@6.9.0
same error as before.
Then, with the espressif platform, I tried

   platformio/tool-esptoolpy@1.30300.0

same error

OSError: [Errno 16] Resource busy: '/dev/cu.usbserial-0001'

During handling of the above exception, another exception occurred:

and another set of warnings.

Then with
platformio/tool-esptoolpy@1.30000.201119
and I get a different error:

esptool.py v3.0

A fatal error occurred: Invalid segment count 31 (max 16). Usually this indicates a linker script problem.
*** [.pio/build/esp32dev/firmware.bin] Error 2

I’m baffled how this doesn’t work. Can you downlaod the very latest version of esptoolpy standalone at

https://github.com/espressif/esptool/releases for MacOS

and then try do a simple

./esptool -p /dev/cu.usbserial-0001 read_mac

If this doesn’t work, then you can get help from Espressif directly at https://github.com/espressif/esptool/issues.

The latest version for Mac is 4.8.1, which is the one I am using as a stand alone tool.
By the way, is there a way to run in Platformio the equivalent of the “verbose upload” in Arduino, so that we can see the actual esptool command being used?

If I try a simple esptool command in terminal it does work as expected (and, as I said, I can also upload the firmware with no problems)

MacBook-Pro-4:/ gabriele$ esptool.py chip_id
esptool.py v4.8.1
Found 1 serial ports
Serial port /dev/cu.usbserial-0001
Connecting......
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting....
Detecting chip type... ESP32
Chip is ESP32-D0WD-V3 (revision v3.0)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 08:b6:1f:29:db:cc
Uploading stub...
Running stub...
Stub running...
Warning: ESP32 has no Chip ID. Reading MAC instead.
MAC: 08:b6:1f:29:db:cc
Hard resetting via RTS pin...

Project tasks → Advanced → Verbose Upload.

Good morning Max!
So, using the “verbose upload” of Platformio I saw that the command being executed is listed as follows:

"/Users/gabriele/.platformio/penv/bin/python" "/Users/gabriele/.platformio/packages/tool-esptoolpy/esptool.py" --chip esp32 --port "/dev/cu.usbserial-0001" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 /Users/gabriele/Dropbox/Documents/PlatformIO/Projects/audio_test/.pio/build/esp32dev/bootloader.bin 0x8000 /Users/gabriele/Dropbox/Documents/PlatformIO/Projects/audio_test/.pio/build/esp32dev/partitions.bin 0xe000 /Users/gabriele/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin 0x10000 .pio/build/esp32dev/firmware.bin

I dont’ understand why I see two calls to python, but so be it.
If I try and run the first part manually in terminal
/Users/gabriele/.platformio/penv/bin/python
I get a normal activation of the python interpreter.
If I try and run the second part
/Users/gabriele/.platformio/packages/tool-esptoolpy/esptool.py"
I get this error:

MacBook-Pro-4:audio_test gabriele$ /Users/gabriele/.platformio/packages/tool-esptoolpy/esptool.py
Pyserial is not installed for /usr/local/opt/python@3.12/bin/python3.12. Check the README for installation instructions.
Traceback (most recent call last):
  File "/Users/gabriele/.platformio/packages/tool-esptoolpy/esptool.py", line 31, in <module>
    import esptool
  File "/Users/gabriele/.platformio/packages/tool-esptoolpy/esptool/__init__.py", line 41, in <module>
    from esptool.cmds import (
  File "/Users/gabriele/.platformio/packages/tool-esptoolpy/esptool/cmds.py", line 14, in <module>
    from .bin_image import ELFFile, ImageSegment, LoadFirmwareImage
  File "/Users/gabriele/.platformio/packages/tool-esptoolpy/esptool/bin_image.py", line 14, in <module>
    from .loader import ESPLoader
  File "/Users/gabriele/.platformio/packages/tool-esptoolpy/esptool/loader.py", line 30, in <module>
    import serial
ModuleNotFoundError: No module named 'serial'

Last byt not least, if I run esptool.py manually, as I would normally do, with the rest of the Platformio command string, the code uploads with no problems!

MacBook-Pro-4:audio_test gabriele$ esptool.py --chip esp32 --port "/dev/cu.usbserial-0001" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 /Users/gabriele/Dropbox/Documents/PlatformIO/Projects/audio_test/.pio/build/esp32dev/bootloader.bin 0x8000 /Users/gabriele/Dropbox/Documents/PlatformIO/Projects/audio_test/.pio/build/esp32dev/partitions.bin 0xe000 /Users/gabriele/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin 0x10000 .pio/build/esp32dev/firmware.bin
esptool.py v4.8.1
Serial port /dev/cu.usbserial-0001
Connecting....
Chip is ESP32-D0WD-V3 (revision v3.0)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 08:b6:1f:29:db:cc
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00001000 to 0x00005fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x0000e000 to 0x0000ffff...
Flash will be erased from 0x00010000 to 0x0013afff...
SHA digest in image updated
Compressed 17536 bytes to 12202...
Wrote 17536 bytes (12202 compressed) at 0x00001000 in 0.7 seconds (effective 206.7 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 175...
Wrote 3072 bytes (175 compressed) at 0x00008000 in 0.1 seconds (effective 241.9 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 47...
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.2 seconds (effective 371.0 kbit/s)...
Hash of data verified.
Compressed 1222560 bytes to 732655...
Wrote 1222560 bytes (732655 compressed) at 0x00010000 in 19.1 seconds (effective 510.9 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

Try this: place everything locally on your MAC. Have seen weird errors when using cloud drives
Do not use the old v3.0.0 esptool.py with actual Arduino core 3.x.x
It will generate faulty firmwares
In other words the bundled esptool.py I provide with pioarduino is working well.
Trying other (older) version will not solve the issue you have

jason2866, thanks for your suggestions. Unfortunately I need to use cloud drives for various reasons, and I have been using this setup for a few years with no problems.

Meanwhile I did some additional tests and eventually found a solution (?!?) which is working.
I tried with various esp32 devkits and discovered that those that are not working are from the same producer (AzDelivery). They all register as /dev/cu.usbserial-0001 VID:PID=10C4:EA60 SER=0001 and share exactly the same problem, i.e. they do not work just with Platformio on the Mac.
One other device which is working is registering as /dev/cu.usbserial-1410 VID:PID=10C4:EA60 SER=ec41bba78ffbeb11b02fb4f7c6d924ec. This device is also using the same Silabs driver and does work with no problems whatsoever.
I tried to change the usb name of the first device using a simlink /Users/gabriele/cu.custom_esp32 but this did not help either.

Apparently, what does work, is connecting the problematic devices to the mac via a (powered) hub which must have another device already connected.
It is not 100% proof but it works 9 out of 10 times.
Very weird.
It also does not explain why Arduino or stand-alone espool do work with no problems, but at least I have a quasi-workaround now.
Thanks for your support.

Hm, SER=0001 would mean that the chip is a fake.

There have been cases in the past where an FTDI driver bricked a fake FTDI chip if it detected it as such, but I’ve never header that of a Silabs or Apple driver.

Very bad surprise.
Max, you are indeed right! The CP210x driver used on these devkit’s is definitely a fake.
Here below the picture of a “good” one, with proper Silabs logo and marking, and then a picture of the fake one!
(timestamps on the pictures are clearly wrong - I did not adjust the camera clock…)
No use to continue any investigation any further.
Thanks for your prompt support!
Best regards, Gabriele


Oh but the CP2102 and CP2102N are two distinct chips, so that can still be correct.