Atmega328pb incompatibility with PlatformIO running on Windows 11: The problem, and the eventual solution

Introduction:

It began as a frustration so grand that I inevitably table flipped, bought an Win11 OEM pro license, and a new drive, reinstalling everything from the ground up, all because stuff wasn’t working and I had no clue where to begin. So I began fresh.

Brief background:

Tinkering with some atmega328pb boards, with usb and ftdi interface, I could not get them to behave at all. At least one was a hardware failure which I proved by removing the CH340/FTDI chip and instead used another arduino uno to program. Desperately wanting the convenience returned, I took another fresh board out from the AliExpress and set to work getting it ready. This time I installed Arduino IDE 2. I noticed that I needed to also install additional platforms just to get it to work. A few searches quickly led to variant 328PB, minicore, these two package sources

  1. https:// mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json
  2. https:// github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json

for installing board requirements, possibly updating a CH340 driver file. Sparing you those details, Arduino IDE2 was successfully uploading to my board. Great. Now I wanted to switch to VScode and platform IO, and this is where it becomes relevant to this forum:

It didn’t work, but I got it working.

It was a pain the bum which took days to solve, and I want to detail it here so that people much more clever than I can maybe use this to implement a fix for PlatformIO, or at least others who are also experiencing pain may find some joy with my journey.

I have an avr 328pb microprocessor. I am able to flash to it using the Arduino IDE 2.3.6, but I am unable to using VSCode & PlatformIO. The final error message from vscode is: avrdude error: unable to open programmer urclock on port COM6

The output from Arduino IDE mentions:

  • FQBN: MiniCore:avr:328:variant=modelPB

while VScode mentions:

  • PLATFORM: Atmel AVR (5.1.0) > ATmega328PB

  • HARDWARE: ATMEGA328PB 16MHz, 2KB RAM, 32KB Flash

along with …

Using port : COM6

Using programmer : urclock

Setting baud rate : 115200

AVR part : ATmega328PB

Programming modes : SPM, ISP, HVPP, debugWIRE

Programmer type : Urclock

Description : Urboot bootloaders using urprotocol

Protocol : Urprotocol

AVR device initialized and ready to accept instructions

Device signature = 1E 95 16 (ATmega328PB)

By contrast, the VScode output mentions this:

PLATFORM: Atmel AVR (5.1.0) > ATmega328PB

HARDWARE: ATMEGA328PB 16MHz, 2KB RAM, 32KB Flash

PACKAGES:

  • framework-arduino-avr-minicore @ 3.0.2

  • tool-avrdude @ 1.70200.0 (7.2.0)

  • toolchain-atmelavr @ 1.60300.200527 (6.3.0)

[….]

avrdude warning: attempt 1 of 10: not in sync

avrdude warning: attempt 2 of 10: not in sync

[…]

avrdude warning: attempt 10 of 10: not in sync

avrdude warning: programmer is not responding; try -xstrict and/or vary -xdelay=100

avrdude error: unable to open programmer urclock on port COM6

The core issue, and the verbose dump confirms the problem is a synchronization failure between the specific version of avrdude PlatformIO is using and the Urboot bootloader on the ATmega328PB.

The error avrdude error: unable to open programmer urclock on port COM6 is misleading; the full output shows that PlatformIO is trying to use the correct protocol (CURRENT: upload_protocol = urclock), but the subsequent errors (not in sync) indicate a timing/version mismatch.

  • VScode/PlatformIO vs Arduino IDE2

  • MiniCore\hardware\avr\3.1.1 vs framework-arduino-avr-minicore @ 3.0.2

  • tool-avrdude @ 1.60300 vs tool-avrdude@^1.80.1

Things I investigated.

Incorrect Baud Rate: both were running at 115200

Timing/Reset Issues: The specific version of avrdude (7.2.0) has slightly different timing or reset sequence logic conflicting with the Urboot bootloader version flashed by MiniCore 3.1.1.

Upload delay: inserting a pause before the flashing via argument in platformio.ini “-xdelay=200”

Ensuring board model was set correctly, matching what worked in Arduino IDE2

board_build.core = minicore board_build.variant = modelPB


No change.

The “urclock” programmer definition is a custom entry created by MiniCore. The reason the PlatformIO upload fails while attempting to use urclock is often that PlatformIO’s bundled avrdude (v7.2.0) is either:
a) Missing the custom urclock definition in its avrdude.conf.
b) Has a different urclock definition than the one the Arduino IDE2 uses.

Since PlatformIO is successfully finding the urclock protocol (we see CURRENT: upload_protocol = urclock), it means the entry is there, but it’s possible PlatformIO’s version of avrdude.conf is subtly wrong.

To fix this, i tried injecting the path to a known working configuration file, namely the same one used by Arduino IDE2. The platformIO.ini was changed to this:

upload_flags = -C C:/Users/myName/AppData/Local/Arduino15/packages/MiniCore/hardware/avr/3.1.1/tools/avr/etc/avrdude.conf -P$UPLOAD_PORT -b$UPLOAD_SPEED -c$UPLOAD_PROTOCOL -Uflash:w:$SOURCE:i -xdelay=200

No change.

The AVRDUDE Version Conflict

The core issue is a version mismatch between the core, MiniCore, and the upload tool, AVRDUDE, provided by PlatformIO.

Newer MiniCore: MiniCore version 3.0.0 and later replaced the older Optiboot with the Urboot bootloader. Urboot is superior but requires a different configuration and, crucially, a newer AVRDUDE version that supports its specific settings (like the "urclock" programmer ID which is often missing in older AVRDUDE versions).

Since PlatformIO was not auto updating avrdude to latest (?) let’s force it by mentioning the same version which Arduino IDE2 is using. Asking PlatformIO nicely to grab version @ ^ 1.80000.1 did not result in a download, only an error. However asking for 1.80.1 did grab that version.

platform_packages = tool-avrdude@^1.80.1 ;

The TX light now blinks during the attempt to upload however it’s still not working. This leaves me with knowing that Arduino IDE2 can accomplish this, but PlatformIO cannot, with everything pointing towards subtle differences in avrdude. Despite identifying this, and forcing PlatformIO to grab the same version, it wasn’t going to play. Let’s use actual avrdude.exe from the Arduino IDE, and the actual arvdude.conf file from the same.

Specifying a different avrdude.exe, one that is known to work.

upload_command =
C:/Users/myName/AppData/Local/Arduino15/packages/MiniCore/tools/avrdude/8.0-arduino.1/bin/avrdude
-C
C:/Users/myName/AppData/Local/Arduino15/packages/MiniCore/tools/avrdude/8.0-arduino.1/etc/avrdude.conf
-p atmega328pb
-c urclock
-b 115200
-P $UPLOAD_PORT
-D
-U flash:w:$SOURCE:i
-xdelay=200

This came back with:

‘C’ is not recognized as an internal or external command,
‘p’ is not recognized as an internal or external command,
‘c’ is not recognized as an internal or external command,

okay, so we need to fix the syntax:

upload_command = "C:/Users/myName/AppData/Local/Arduino15/packages/MiniCore/tools/avrdude/8.0-arduino.1/bin/avrdude -C C:/Users/myName/AppData/Local/Arduino15/packages/MiniCore/tools/avrdude/8.0-arduino.1/etc/avrdude.conf -p atmega328pb -c urclock -b 115200 -P $UPLOAD_PORT -D -U flash:w:$SOURCE:i -xdelay=1000 -xstrict"

Result:

Uploading .pio\build\atmega328pb_urclock\firmware.hex
The filename, directory name, or volume label syntax is incorrect.

Trying a variation on that theme, expecting that one set of quotes is being lost

upload_command = "\"C:/Users/myName/AppData/Local/Arduino15/packages/MiniCore/tools/avrdude/8.0-arduino.1/bin/avrdude\" -C \"C:/Users/myName/AppData/Local/Arduino15/packages/MiniCore/tools/avrdude/8.0-arduino.1/etc/avrdude.conf\" -p atmega328pb -c urclock -b 115200 -P $UPLOAD_PORT -D -U flash:w:\"$SOURCE\":i -xdelay=1000 -xstrict"

Same response. The filename, directory name, or volume label syntax is incorrect**. Lets do away with the paths completely and put the** two files (.exe and .conf) inside the project folder. So I copied those two over, and changed the ini entry to this:

upload_command = ““avrdude.exe” -C “avrdude.conf” -p atmega328pb -c urclock -b 115200 -P $UPLOAD_PORT -D -U flash:w:“$SOURCE”:i -xdelay=1000 -xstrict”

Nope.The upload_command is still being executed by the shell, causing the path error .

upload_command = “"avrdude.exe" -C "avrdude.conf" -p atmega328pb -c urclock -b 115200 -P $UPLOAD_PORT -D -U flash:w:"$SOURCE":i -xdelay=1000 -xstrict”

That’s an improvement! “The filename, directory name, or volume label syntax is incorrect.” That leaves the “$SOURCE” part.

upload_command = avrdude.exe -C avrdude.conf -p atmega328pb -c urclock -b 115200 -P $UPLOAD_PORT -D -U flash:w:"$SOURCE":i -xdelay=1000 -xstrict

And it worked!

Why I think this is an issue with PlatformIO

As a hobbyist, I should expect that clicking on update, ensuring that versions are high, etc., is enough to make things work. I never would have gone through this trouble had I not known that Arduino IDE2 was able to flash to the chip. I would have simply assumed that it was a hardware failure on the programmer chip, and rightly so. Despite the effort and helpfulness of PlatformIO, it led me on a wild journey chasing higher version of avrdude, which still didn’t fix the issue. Again, anyone would take this to mean a general hardware failure and leave it at that. For some reason which is beyond my understanding, Arduino IDE2 was, with some help, able to surmount this inconsistency and give reliable results. Yet despite my best efforts with PlatformIO I was unable to accomplish this without a great deal of help from Google’s Gemini, and a lot of patience from myself.

While I don’t know why this all occurred in the first place, it is still an issue that exists beyond the user interface but before the nuts and bolts of it all. That’s developer territory. I would love to be able to fix it myself, but I wouldn’t know where to start.

I am happy to provide any further information about this. Thanks for reading it all. Thanks for supporting PlatformIO. Thanks for this opportunity to give my feedback.

Seems to have been tracked in

for some time.

The platform is also where this bug report belongs. The issue should be pushed.