Change board name, multiple boards of the same type

I am making a load of controllers for a train simulator, all of them contain either an arduino beetle or a pro-micro, which are seen as (and programmed as) Leonardo's by the arduino IDE.

right now i have 4 x beetle boards, and 3 x Pro-micros, they can all be plugged in at once, and i am getting fed up of changing something in the code for one controller, and uploading it to the wrong board.

Every now and then i think i have the right board from the COM port number, but it turns out on the last upload the COM port changed.
These board do that thing where they change to another COM port to go into bootloader / programming mode or something like that, and they don't always go back to the original COM port after it seems, i'm upto COM 36 in some cases now due to this, and that's without me plugging them into different USB ports on the laptop.

I've looked for ways to change the boards names, the one where you change the boards.txt file seems to only change the name assigned to all similar boards.

I need each board to have it's own name show up in the arduino IDE and windows device manager, like 'EN57 Door Switches' 'EU07 power controller' and so on.

I'm using windows 11, and arduino IDE v2.2.1.

This hints that unique identifiers are not available for the Leonardo's processor.

If it does work, you'll be modifying the Registry.

For what it's worth, I recall the Teensy bootloader being much better behaved.

registry modding i was expecting... i actually managed to change the boards name in the registry following a tutorial on how to change the name of a usb game controller.

it still showed up as a 'leonardo' to the arduino IDE, then i changed the name for it on the port it was on, it showed then as 'COM 17 EN57 Door Switches, '

I made a small change to the code, uploaded it... it did that thing where it changed to a different COM port to upload, then came back on COM 16 :frowning:

hang on...

i've just realised it had changed the name to 'Pro-Micro' i must have clicked something, i changed it to a Leonardo board, uploaded it again, and it's now showing as :

image

Now to try and remember what i did, and see if it'll do this with another board.

Really wish there was a simple way to assign a name to arduino boards from the IDE.

2 Likes

well that didn't work as planned,
but thinking about it, it kinda did work as it should,

I'd changed the 'Friendly name' and 'Display name' in the registry, and also the name of what i thought was the board description for the com port it was on.

All was all ok until i plugged a different controller into a usb port that had previously had a different one in it, and it shows up as the last controller.

the controller in question has a pro-micro in, i named it 'EN57 door switches'
when i unplugged that and plugged in a brand new arduino beetle, originally it was on COM 37,
but once i sent a sketch to it as a Leonardo, it became 'COM 17, EN57 door switches'

So i'm thinking there's something the arduino IDE is doing to assign the COM port number to anything programmed as a Leonardo?

or is it me messing with the registry names and changing the wrong one.

The problem you face is the lack of unique serial number. Without that the operating system cannot differentiate between boards. It's my understanding the Leonardo lacks a serial number.

You can change the ID and serial number with the tool in this document with this URL. Need to make an account. Not try it yet. Must first download and install.

Notes in advance

  1. I use 3.3V/8MHz Pro Micros; therefore I had to install the SparkFun AVR board package and this post is basically based on that.
  2. This is tested using a portable install of IDE 1.8.19; same principles should apply for a non-portable install of any IDE
  3. I'm not a specialist in the area of board packages; I've just hacked till such a time that I had a workable solution.
  4. I'm no powershell specialist

Naming

There are a few things when it comes to naming; in 'boards.txt' (for Arduino's AVR 'boards.txt' file, replace promicro by leonardo).

  1. promicro.name=SparkFun Pro Micro; this sets the name that the IDE displays in the status bar as well as for the ports.
  2. promicro.build.variant=promicro will be used in the name of a hex file when you use sketch / export compiled binary in the IDE; it has more purposes.
  3. promicro.build.usb_product="SparkFun Pro Micro"; this is the name that is programmed into the board and will show in Control Panel / Devices and Printers.
  4. The name that you see in the Device Manager is, to my knowledge, determined by the driver.

Solution

There are two functionalities regarding this solution. The first one is to program the board with the usb_description so it can be recognised as a specific board; the second one is a dedicated powershell script that can detect that usb_product and determine the upload port based on that.

Modifying 'boards.txt'

Edit 'boards.txt'.
For each specific board, make a copy of the 'leonardo' entry
Edit the entry according to needs so it looks like below; please note that the below is based on sparkfun's AVR board package and the vid/pid and build variant differ

################################################################################
################################## EN57 Door Switches #######################
################################################################################
EN57.name=EN57 Door Switches

# sterretje attempt to add port identification
EN57.vid.0=0x1B4F
EN57.pid.0=0x9204
# sterretje end

EN57.upload.tool=avrdude
EN57.upload.protocol=avr109
EN57.upload.maximum_size=28672
EN57.upload.maximum_data_size=2560
EN57.upload.speed=57600
EN57.upload.disable_flushing=true
EN57.upload.use_1200bps_touch=true
EN57.upload.wait_for_upload_port=true

EN57.bootloader.tool=avrdude
EN57.bootloader.unlock_bits=0x3F
EN57.bootloader.lock_bits=0x2F
EN57.bootloader.low_fuses=0xFF
EN57.bootloader.high_fuses=0xD8

EN57.build.board=AVR_PROMICRO
EN57.build.core=arduino:arduino
EN57.build.variant=promicro
EN57.build.mcu=atmega32u4
EN57.build.usb_product="EN57_Door_Switches"
EN57.build.vid=0x1b4f
EN57.build.extra_flags={build.usb_flags}

######################### Pro Micro 3.3V / 8MHz ################################
EN57.menu.cpu.8MHzatmega32U4=ATmega32U4 (3.3V, 8 MHz)

EN57.menu.cpu.8MHzatmega32U4.build.pid.0=0x9203
EN57.menu.cpu.8MHzatmega32U4.build.pid.1=0x9204
EN57.menu.cpu.8MHzatmega32U4.build.pid=0x9204
EN57.menu.cpu.8MHzatmega32U4.build.f_cpu=8000000L

EN57.menu.cpu.8MHzatmega32U4.bootloader.extended_fuses=0xFE
EN57.menu.cpu.8MHzatmega32U4.bootloader.file=caterina/Caterina-promicro8.hex

############################# Pro Micro 5V / 16MHz #############################
EN57.menu.cpu.16MHzatmega32U4=ATmega32U4 (5V, 16 MHz)

EN57.menu.cpu.16MHzatmega32U4.build.pid.0=0x9205
EN57.menu.cpu.16MHzatmega32U4.build.pid.1=0x9206
EN57.menu.cpu.16MHzatmega32U4.build.pid=0x9206
EN57.menu.cpu.16MHzatmega32U4.build.f_cpu=16000000L

EN57.menu.cpu.16MHzatmega32U4.bootloader.extended_fuses=0xCB
EN57.menu.cpu.16MHzatmega32U4.bootloader.file=caterina/Caterina-promicro16.hex
  1. Each of your boards needs a unique identifier in 'boards.txt'. In the above example, it is EN57; for the power controller I used EU07.
  2. EN57.name=EN57 Door Switches is used by the IDE to show the name of the board in the status bar.
  3. EN57.build.usb_product="EN57_Door_Switches" is used by the verify (compile) process and eventually ends up in the HEX code after a compile. For the powershell upload script to work correktly, this needs to be the name of the sketch.
  4. EN57.build.variant=promicro is (amongs other things) used to create the file name of the hex file.

Restart the IDE.
After restarting the IDE, you should have new entries for your boards; select the correct one based on the needs.

As said, I'm using the SparkFun AVR board package. I have also stripped the board package down to the bare minimum needed for Sparkfun Pro Micro boards (hence only three entries).

Compiling / Exporting compiled binary

You can now work on the correct board and compile as you always do. Before you upload using the provided powershell script, you need to use Sketch / Export Compiled Binary; this will create a hex file in the sketch directory; the reason for using Sketch / Export Compiled Binary is that the hex file that you need to upload ends in a standardised directory instead of in a temp directory. E.g. after compiling for the board 'EN57 Door Switches' you will find 2 hex files.

D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710>tree /F /A
Folder PATH listing for volume Photos
Volume serial number is B246-DA42
D:.
+---EN57_Door_Switches
|       EN57_Door_Switches.ino
|       EN57_Door_Switches.ino.promicro.hex
|       EN57_Door_Switches.ino.with_bootloader.promicro.hex
|
\---EU07_power_controller
        EU07_power_controller.ino

Notes

  1. Because I used a portable installation, the root directory for sketches is 'sketchbook'. In your case the usual directory is 'C:\Users\yourUsername\Documents\Arduino'; I do not know how you have organised your project so it can be different.
  2. In IDE 2.x, (from memory, not checked) your sketch directory will have a new directory called 'Build' and the hex files will be in there.

If you have two or more instances of the IDE open, changing the board in one will also change the board in the other one.
See post #10 for correction

Uploading

Your first upload to any of the boards needs to be done using the IDE; you can use e.g. the BareMinimum example or your code; just make sure that you use the correct port. In this way, the boards will get their usb_product.

Before the upload, 'Devices and Printers' on my system looks like
DevicesAndPrinters_1

After the two uploads from the IDE, 'Devices and Printers' on my system looks like
DevicesAndPrinters_EN57_EU07

You can use the upload script from the command line like powershell -file upload.ps1 EU07_power_controller or powershell -file upload.ps1 EN57_Door_Switches
The script takes one argument which serves two purposes

  1. Determine the full path for the hex file
  2. Know what the usb_product is.

:warning: Therefore the usb_description and the name of your sketch need to be exactly the same. :warning:

The script is written in a linear fashion; reason is that I had to refresh my basic knowledge of powershell and did not feel figuring functions out.

# powershell script to upload hex files to AVR based boards with native USB
# Author: sterretje

# command line argument
param($sketch)
if ($sketch -eq $null -or $sketch -eq "")
{
  Write-Output "Please specify the sketch"
  return
}

# powershell version
Get-Host | Select-Object Version
Write-Output "==="

# configuration
###################################################
#$sketch = "EU07_power_controller"
#$sketch = "EN57_Door_Switches"
$projectDir = "D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710\"
$buildDir = $projectDir + $sketch + "\"
#$buildDir = $projectDir + $sketch + "\Build\"
$avrdudeExe =  "D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\packages\arduino\tools\avrdude\6.3.0-arduino17\bin\avrdude"
$avrdudeConf = "D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\packages\arduino\tools\avrdude\6.3.0-arduino17\etc\avrdude.conf"
$hexFile = $sketch + ".ino.promicro.hex"

# print configuration
###################################################
Write-Output "Configuration"
$txt = "{0,-15} {1}" -f "sketch", $sketch
Write-Output $txt
$txt = "{0,-15} {1}" -f "projectDir", $projectDir
Write-Output $txt
$txt = "{0,-15} {1}" -f "buildDir", $buildDir
Write-Output $txt
$txt = "{0,-15} {1}" -f "avrdudExe", $avrdudeExe
Write-Output $txt
$txt = "{0,-15} {1}" -f "avrdudConf", $avrdudeConf
Write-Output $txt
$txt = "{0,-15} {1}" -f "hexFile", $hexFile
Write-Output $txt
Write-Output "==="

# checking sketch directory

$uploadFile = $buildDir + $hexFile

$x = Test-Path -Path $uploadFile -PathType Leaf
if($x -eq $false)
{
  $txt = "Hex file '{0}' not found" -f $uploadFile
  Write-Output $txt
  return
}

# get ports
Write-Output "Detecting boards"
$mydevices = Get-PnpDevice -PresentOnly -Class 'Ports' | Where-Object { $_.InstanceId -match '^USB' } | Select-Object FriendlyName, instanceID
foreach($device in $mydevices)
{
  Write-Output $device.FriendlyName
}
# loop through the devices
foreach($device in $mydevices)
{
  # parse FriendlyName
  $regexp = "(^.+)\((COM\d+)\)$"
  $result = $device.FriendlyName -match $regexp

  if($result -eq $false)
  {
    $txt = "Parsing of FriendlyName '{0}' failed; skipping" -f $device.FriendlyName
    Write-Output $txt
    continue
  }

  # get the usb_description property
  $name = Get-PnpDeviceProperty -InstanceId $device.InstanceId -KeyName "DEVPKEY_Device_BusReportedDeviceDesc" | Select-Object data
  $txt = "{0,-10}{1,-30}{2}" -f $Matches[2], $Matches[1], $name.data
  Write-Output $txt

  # $matches[2] contains the comport
  $portName = $matches[2]
  # $matches[1] contains board (as in device manager)
  $boardName = $matches[1]
  # $name.data contains the usb_description

  # check if we have the correct board (based on usb_description)
  if ($name.data -ne $null -and $name.data.Equals($sketch))
  {
    $txt = "Reset board on '{0}'" -f $portName
    Write-Output $txt

    # invoke bootloader
    $port= new-Object System.IO.Ports.SerialPort $matches[2],1200,None,8,one
    $port.Open()
    Start-Sleep -Milliseconds 500
    $port.Close()
    # get new list of ports
    $uploadDevices = Get-PnpDevice -PresentOnly -Class 'Ports' | Where-Object { $_.InstanceId -match '^USB' } | Select-Object FriendlyName, instanceID
    # loop through the devices
    foreach($uploadDevice in $uploadDevices)
    {
      # parse FriendlyName to find bootloader
      $regexp = "(^.+)bootloader \((COM\d+)\)$"
      $result = $uploadDevice.FriendlyName -match $regexp

      # if a board in bootloader mode is found
      if($result -eq $true)
      {
        $txt = "Got upload port '{0}'" -f $matches[2]
        $uploadPortname = $matches[2]
        Write-Output $txt
        $flash = "-Uflash:w:{0}:i" -f $uploadFile
        Write-Output $flash
        & "$avrdudeExe" "-v" "-C$avrdudeConf" "-cavr109" "-patmega32u4" "-P$uploadPortname" "-b57600" "-D" "$flash"
      }
    }
  }
  else
  {
    $txt = "No match for '{0}' on '{1}'" -f $sketch, $Matches[2]
    Write-Output $txt
  }
}

The script is also attached for your convenience at the end. The basic steps are outlined below in case you're not familiar with powershell.

Retrieve list of com ports
The script retrieves a list of ports using Get-PnpDevice; this list of ports will not contain serial-to-usb converters but that is not relevant for the intended purpose.
The result (based on the FriendlyName)

SparkFun Pro Micro (COM4)
Arduino Mega 2560 (COM3)
SparkFun Pro Micro (COM12)
Arduino Leonardo (COM8)

Parse com ports and get usb_description
The script loops through the list of com ports and parses them using a regular expression to extract the port. It will use this port later to reset the board.
Next it extracts the usb_description (DEVPKEY_Device_BusReportedDeviceDesc) based on the vid/pid (instanceId) using Get-PnpDeviceProperty.

Upload
If it finds a matching usb_description, it will start the upload; it resets the board using the com port, gets a new list of devices and tried to find one (using a regular expression) that contains the word 'bootloader'.
If found, it starts the upload on the com port that was extracted using the regular expression.

Example output

D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\_batch_files>powershell -file upload.ps1 EU07_power_controller

Version
-------
5.1.19041.3803
===
Configuration
sketch          EU07_power_controller
projectDir      D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710\
buildDir        D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710\EU07_power_controller\
avrdudExe       D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\packages\arduino\tools\avrdude\6.3.0-arduino17\bin\avrdude
avrdudConf      D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\packages\arduino\tools\avrdude\6.3.0-arduino17\etc\avrdude.conf
hexFile         EU07_power_controller.ino.promicro.hex
===
Detecting boards
SparkFun Pro Micro (COM4)
Arduino Mega 2560 (COM3)
SparkFun Pro Micro (COM12)
Arduino Leonardo (COM8)
COM4      SparkFun Pro Micro            EN57_Door_Switches
No match for 'EU07_power_controller' on 'COM4'
COM3      Arduino Mega 2560
No match for 'EU07_power_controller' on 'COM3'
COM12     SparkFun Pro Micro            EU07_power_controller
Reset board on 'COM12'
Got upload port 'COM17'
-Uflash:w:D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710\EU07_power_controller\EU07_power_controller.ino.promicro.hex:i

avrdude.exe: Version 6.3-20190619
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\packages\arduino\tools\avrdude\6.3.0-arduino17\etc\avrdude.conf"

             Using Port                    : COM17
             Using Programmer              : avr109
             Overriding Baud Rate          : 57600
             AVR Part                      : ATmega32U4
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PA0
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom        65    20     4    0 no       1024    4      0  9000  9000 0x00 0x00
               flash         65     6   128    0 yes     32768  128    256  4500  4500 0x00 0x00
               lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
               hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
               efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
               lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
               calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

             Programmer Type : butterfly
             Description     : Atmel AppNote AVR109 Boot Loader

Connecting to programmer: .
Found programmer: Id = "CATERIN"; type = S
    Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
    Device code: 0x44

avrdude.exe: devcode selected: 0x44
avrdude.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude.exe: Device signature = 0x1e9587 (probably m32u4)
avrdude.exe: safemode: lfuse reads as DE
avrdude.exe: safemode: hfuse reads as D8
avrdude.exe: safemode: efuse reads as CB
avrdude.exe: reading input file "D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710\EU07_power_controller\EU07_power_controller.ino.promicro.hex"
avrdude.exe: writing flash (3634 bytes):

Writing | ################################################## | 100% 0.43s

avrdude.exe: 3634 bytes of flash written
avrdude.exe: verifying flash memory against D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710\EU07_power_controller\EU07_power_controller.ino.promicro.hex:
avrdude.exe: load data flash data from input file D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710\EU07_power_controller\EU07_power_controller.ino.promicro.hex:
avrdude.exe: input file D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710\EU07_power_controller\EU07_power_controller.ino.promicro.hex contains 3634 bytes
avrdude.exe: reading on-chip flash data:

Reading | ################################################## | 100% 0.19s

avrdude.exe: verifying ...
avrdude.exe: 3634 bytes of flash verified

avrdude.exe: safemode: lfuse reads as DE
avrdude.exe: safemode: hfuse reads as D8
avrdude.exe: safemode: efuse reads as CB
avrdude.exe: safemode: Fuses OK (E:CB, H:D8, L:DE)

avrdude.exe done.  Thank you.

COM8      Arduino Leonardo              Arduino Leonardo
No match for 'EU07_power_controller' on 'COM8'

Note
There is no indication (!!) that an upload fails; you will have to dig through the avrdude results to find the error.

Final comments

  1. This is not perfect; especially the fact that there is no error check (or change of colour on error) on avrdude is highly annoying. It also doesn't stop iterating once a an upload is done.
  2. Upgrading the boards package will result in the changing being lost.
  3. A possible improvement can be to integrate Arduino-CLI so you do not have to do 'export compiled binary'; I'm not familiar with the Arduino-CLI.
  4. Running the powershell script might result in errors regarding the executions policy (see e.g. about Execution Policies - PowerShell | Microsoft Learn). I can not remember the reasons why mine is set as shown below, I suggest that you play with them if you get the errors.
PS C:\Users\Wim> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser    RemoteSigned
 LocalMachine       AllSigned

:warning: Changing those settings is your own responsibility / risk :warning:

script
upload.zip (1.6 KB)
example boards.txt
project.boards.txt (6.3 KB)

1 Like

A minor and a major improvement to the script; you can search the attached script for V2.

upload2.zip (1.7 KB)

The minor improvement is that the script now stops after an upload and does not continue with other boards.

The major improvement is that the script reports if avrdude failed

D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\_batch_files>powershell -file upload2.ps1 EU07_power_controller

Version
-------
5.1.19041.3803
===
Configuration
sketch          EU07_power_controller
projectDir      D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710\
buildDir        D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710\EU07_power_controller\
avrdudExe       D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\packages\arduino\tools\avrdude\6.3.0-arduino17\bin\avrdude
avrdudConf      D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\packages\arduino\tools\avrdude\6.3.0-arduino17\etc\avrdude.conf
hexFile         EU07_power_controller.ino.promicro.hex
===
Detecting boards
SparkFun Pro Micro (COM4)
Arduino Mega 2560 (COM3)
SparkFun Pro Micro (COM12)
Arduino Leonardo (COM8)
COM4      SparkFun Pro Micro            EN57_Door_Switches
No match for 'EU07_power_controller' on 'COM4'
COM3      Arduino Mega 2560
No match for 'EU07_power_controller' on 'COM3'
COM12     SparkFun Pro Micro            EU07_power_controller
Reset board on 'COM12'
Got upload port 'COM17'
-Uflash:w:D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710\EU07_power_controller\EU07_power_controller.ino.promicro.hex1:i

avrdude.exe: Version 6.3-20190619
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\packages\arduino\tools\avrdude\6.3.0-arduino17\etc\avrdude.conf"

             Using Port                    : COM17
             Using Programmer              : avr109
             Overriding Baud Rate          : 57600
             AVR Part                      : ATmega32U4
             Chip Erase delay              : 9000 us
             PAGEL                         : PD7
             BS2                           : PA0
             RESET disposition             : dedicated
             RETRY pulse                   : SCK
             serial program mode           : yes
             parallel program mode         : yes
             Timeout                       : 200
             StabDelay                     : 100
             CmdexeDelay                   : 25
             SyncLoops                     : 32
             ByteDelay                     : 0
             PollIndex                     : 3
             PollValue                     : 0x53
             Memory Detail                 :

                                      Block Poll               Page                       Polled
               Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
               ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
               eeprom        65    20     4    0 no       1024    4      0  9000  9000 0x00 0x00
               flash         65     6   128    0 yes     32768  128    256  4500  4500 0x00 0x00
               lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
               hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
               efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
               lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
               calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
               signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

             Programmer Type : butterfly
             Description     : Atmel AppNote AVR109 Boot Loader

Connecting to programmer: .
Found programmer: Id = "CATERIN"; type = S
    Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
    Device code: 0x44

avrdude.exe: devcode selected: 0x44
avrdude.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude.exe: Device signature = 0x1e9587 (probably m32u4)
avrdude.exe: safemode: lfuse reads as DE
avrdude.exe: safemode: hfuse reads as D8
avrdude.exe: safemode: efuse reads as CB
avrdude.exe: reading input file "D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710\EU07_power_controller\EU07_power_controller.ino.promicro.hex1"
avrdude.exe: can't open input file D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710\EU07_power_controller\EU07_power_controller.ino.promicro.hex1: No such file or directory
avrdude.exe: read from file 'D:\_ArduinoPortable\arduino-1.8.19-sparkfun-avr.topic1201710\portable\sketchbook\1201710\EU07_power_controller\EU07_power_controller.ino.promicro.hex1' failed

avrdude.exe: safemode: lfuse reads as DE
avrdude.exe: safemode: hfuse reads as D8
avrdude.exe: safemode: efuse reads as CB
avrdude.exe: safemode: Fuses OK (E:CB, H:D8, L:DE)

avrdude.exe done.  Thank you.

======================================
avrdude failed with error code 1
======================================
1 Like

This needs a correction. Opening a second or third sketch within the IDE using file → ... is not an instance; it's just an other window inside the same instance.

If you start a new instance of the IDE by starting the IDE again (e.g. double click the IDE icon), there is no problem.

1 Like

The last step would be to create your own (kind of private) board package based on the existing Arduino AVR board package. This takes away the disadvantage that a library update will overwrite your changes.

Notes:

  1. I knew that it could be done but I initially did not manage to get it right; hence the previous post that hacked the original library.
  2. This post is for the Arduino AVR boards (so matching the information that you provided, not the SparkFun AVR boards.

Preparation

  1. Create a directory 'hardware' (lowercase) in your sketchbook directory if it does not already exist.
  2. In the hardware directory, create a directory with your username (e.g. 'gazz292'). This directory officially indicates who the maintainer is (e.g. Arduino, SparkFun etc) of the board packages in the directories underneath it.
  3. Create a directory with a name that reflects the purpose of the board package. I called it 'MR_AVR_ARDUINO' indicating Model Railroad, avr based boards from Arduino; if you later decide to use other boards, you can create a similar named directory.
  4. Copy the original board package to 'hardware\gazz292\MR_AVR_ARDUINO. For a stabndard IDE installation, the files and directories of interest are in
    'C:\Users\Wim\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6'.

tree

If you now (re)start the IDE, you will have two entries for the Arduino AVR boards in 'Tools / Board'; the original one 'Arduino AVR Boards' and the new one ''Arduino AVR Boards (in Sketchbook)'.

Hacking the board package

  1. Change the name of the board package.
    • Open the file 'hardware\gazz292\MR_AVR_ARDUINO\platform.txt' in a text editor.
    • Change the name of the package by changing name=Arduino AVR Boards to e.g. name=Model Railroad; this will reflect in the IDE
    • Change the version in a similar way if desired.
    • Save the file.
  2. Add / remove boards.
    • Open the file 'hardware\gazz292\MR_AVR_ARDUINO\boards.txt' in a text editor.
    • In the attached file, I have removed all boards except for the Leonardo as that is what you were using.
    • Changeleonardo.name=Arduino Leonardo to e.g. leonardo.name=Arduino Leonardo (MR);this is not strictly necessary.
    • Change leonardo.build.usb_product="Arduino Leonardo" to e.g. leonardo.build.usb_product="Arduino Leonardo (MR)"; again not strictlu necessary.
    • Add new boards as already described in earlier post.
    • Save the file.

Attached the board package; you can extract it and copy the full 'MR_AVR_ARDUINO' directory to 'hardware\gazz292'.

MR_AVR_Arduino.zip (7.8 MB)

1 Like

I recommend using the established architecture identifier for this architecture folder's name (avr in this case). The reason is that the name of this folder has special significance in the platform framework:


The build.arch platform property is set to the folder name, and that property is used to set an architecture indicator macro:

(note the -DARDUINO_ARCH_{build.arch} flag in the compilation command patterns)


The architectures field in the library metadata is compared against the name of the architecture folder and the match is used to:

  • Determine priority during sketch compilation when multiple installed libraries match an #include directive.
  • Determine whether the library's examples should be listed under the File > Examples > INCOMPATIBLE menu of Arduino IDE 1.x when a board of the platform is selected.
  • Determine whether to display an incompatibility warning during sketch compilation.

It is only possible to reference resources from other platforms with the same architecture identifier.


Differentiation of the platform from other platforms of the architecture should be done exclusively via the "vendor" folder's name.

1 Like

@ptillisch, thanks

I will adjust. It will mean a vendor name like Arduino (MR) instead of gazz292 and renaming the MR_AVR_ARDUINO back to avr. And a vendor like SparkFun (MR).

And while you're here (:wink:), it might be clear that there is a need to be able to identify a board (with native USB) in the ports menu based on some unique parameter. I understand that this will require an update (feature request) of the serial-discovery tool; will it also require an update (feature request) for the IDE / CLI?

@gazz292 attached updated version. Only tested by compiling. I've made a small change in platform.txt (name=Model Railroad (Arduino))

  1. Delete 'hardware/gazz292'.
  2. Unzip attached file and place it in 'hardware/'.

MR_Arduino.zip (7.8 MB)

The hardware tree should now look like
image

It seem to me that the serialNumber port property reported by the serial-discovery tool is already sufficient for the purpose. As already pointed out by @Coding_Badly, unfortunately the ATmega32U4-based boards don't produce CDC serial port with a serial number (apparently because the chip itself doesn't provide one, unlike other AVRs). So what is needed is to be able to set the serial number to an arbitrary value. The same capability would be needed for any other arbitrary new property you might propose adding to serial-discovery so I don't see that a new property is needed when we already have one.

I was able to set an arbitrary serial number by modifying the core as described here:

--- a/MR_AVR_Arduino/avr/boards.txt
+++ b/MR_AVR_Arduino/avr/boards.txt
@@ -60,22 +60,7 @@ leonardo.build.extra_flags={build.usb_flags}
 ##############################################################
 
 EU07_power_controller.name=EU07 power controller
-EU07_power_controller.vid.0=0x2341
-EU07_power_controller.pid.0=0x0036
-EU07_power_controller.vid.1=0x2341
-EU07_power_controller.pid.1=0x8036
-EU07_power_controller.vid.2=0x2A03
-EU07_power_controller.pid.2=0x0036
-EU07_power_controller.vid.3=0x2A03
-EU07_power_controller.pid.3=0x8036
-EU07_power_controller.upload_port.0.vid=0x2341
-EU07_power_controller.upload_port.0.pid=0x0036
-EU07_power_controller.upload_port.1.vid=0x2341
-EU07_power_controller.upload_port.1.pid=0x8036
-EU07_power_controller.upload_port.2.vid=0x2A03
-EU07_power_controller.upload_port.2.pid=0x0036
-EU07_power_controller.upload_port.3.vid=0x2A03
-EU07_power_controller.upload_port.3.pid=0x8036
+EU07_power_controller.upload_port.0.serialNumber=FOO
 EU07_power_controller.upload_port.4.board=leonardo
 
 EU07_power_controller.upload.tool=avrdude
@@ -101,8 +86,9 @@ EU07_power_controller.bootloader.lock_bits=0x2F
 EU07_power_controller.build.mcu=atmega32u4
 EU07_power_controller.build.f_cpu=16000000L
 EU07_power_controller.build.vid=0x2341
-EU07_power_controller.build.pid=0x8036
+EU07_power_controller.build.pid=0xCAFE
 EU07_power_controller.build.usb_product="EU07 power controller (MR)"
+EU07_power_controller.build.usb_serial_number="FOO"
 EU07_power_controller.build.board=AVR_LEONARDO
 EU07_power_controller.build.core=arduino
 EU07_power_controller.build.variant=leonardo

--- a/MR_AVR_Arduino/avr/cores/arduino/USBCore.cpp
+++ b/MR_AVR_Arduino/avr/cores/arduino/USBCore.cpp
@@ -542,9 +542,13 @@ bool SendDescriptor(USBSetup& setup)
 		}
 		else if (setup.wValueL == ISERIAL) {
 #ifdef PLUGGABLE_USB_ENABLED
+#ifdef USB_SERIAL_NUMBER
+			return USB_SendStringDescriptor((uint8_t*)USB_SERIAL_NUMBER, strlen(USB_SERIAL_qNUMBER) + 1, 0);
+#else	// #ifdef USB_SERIAL_NUMBER
 			char name[ISERIAL_MAX_LEN];
 			PluggableUSB().getShortName(name);
 			return USB_SendStringDescriptor((uint8_t*)name, strlen(name), 0);
+#endif	// #ifdef USB_SERIAL_NUMBER
 #endif
 		}
 		else

--- a/MR_AVR_Arduino/avr/platform.txt
+++ b/MR_AVR_Arduino/avr/platform.txt
@@ -144,4 +144,4 @@ tools.arduino_ota.upload.pattern="{cmd}" -address {upload.port.address} -port {u
 # Default blank usb manufacturer will be filled in at compile time
 # - from numeric vendor ID, set to Unknown otherwise
 build.usb_manufacturer="Unknown"
-build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'
+build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' '-DUSB_SERIAL_NUMBER={build.usb_serial_number}'

The reason I changed the value of build.pid was to avoid the board also being identified as "Arduino Leonardo". The multiple identifications don't actually cause any problem, so that change is not required, but I thought they might make the demonstration more confusing.

I don't know if there is a better way of configuring an arbitrary serial number.

No, I think the pluggable discovery and port identification systems are flexible enough to accommodate use cases like this without any changes to the development tools.

Thanks again,

Maybe I was not clear enough but I did not necessarily imply an additional field in this output

    {
      "address": "COM8",
      "label": "COM8",
      "protocol": "serial",
      "protocolLabel": "Serial Port (USB)",
      "properties": {
        "pid": "0x8036",
        "serialNumber": "",
        "vid": "0x2341"
      }
    },

It's lacking the hardwareId because the the serialNumber is ampty (at least I assume that that is the reason).

The idea was to insert the usb_description (from 'boards.txt') in the serialNumber (and create the hardwareId based on that) if the serialNumber is empty.

I can follow the approach that you took, I will however have to study the changes that you made. I've already gone a few times (in the last week) through the Platform specification - Arduino CLI and will have to do it again to try to figure out what upload.port and build.pid are exactly used for. This will take some time; I can see part of it in the diff output of 'platform.txt'.

I think it would be unexpected behavior. These are two distinctly different things. It would be better to add a new property to the serial-discovery output for this information.

You could use the build.usb_product property instead of build.usb_serial_number in the platform modification I described in my previous reply if you want to set the serial number to that value. I don't know whether the USB framework imposes any restrictions on the serial number value. I notice this:

But I don't know what that number is based on.

This one is especially confusing.

The most important thing to understand is that some properties have special significance within the Arduino boards platform framework:

  • Some properties (e.g., build.arch) are automatically defined by the framework internally.
  • The values of some properties set within the platform configuration files (e.g., upload_port.<port property ID>) are used internally by the framework.

Other properties are simply arbitrary data containers used by the platform developer exclusively within the platform configuration files, without any special significance in the framework.

The upload.port and build.pid are the latter type of properties. They would work just the same if the properties had any other name (e.g., foobar and bazqux).

The properties are defined in boards.txt:

Then referenced in the definition of the build.usb_flags property (another arbitrary property) in platform.txt:

The build.usb_flags property is in turn referenced in the definition of the build.extra_flags property (an arbitrary property) back in boards.txt (this is the part I found tricky when I was trying to figure out the system):

The build.extra_flags property is referenced in the "pattern" properties from which the platform framework generates the compilation commands:

So the final result is to add -D flags to the compilation commands that set the USB_VID, USB_PID, USB_MANUFACTURER, USB_PRODUCT (and USB_SERIAL_NUMBER as well after my modifications) macros to the values of the properties set in the board definition. Those macros are then used by the core:

wow, lots of options it seems, thankyou everyone for helping me with this.

i guessed there'd be nothing as simple as pressing a virtual button to assign a board name that stays with the board even if it is plugged into a different computer,

I will try and work through the solutions offered,
i keep adding more controllers as i make them for the different trains i like to drive, and even using my old method of unplugging all controllers but the one i want to change code on no longer works as i managed to miss one that was still plugged in a port i'd forgotten about, and sent it the wrong code the other night.

1 Like

I'm reasonably sure that that is the 20 nibbles (10 bytes) of the serial number in the 16U2; they call this an educated guess :slight_smile:

I had a very frustrating time with that. I have a portable install of 1.8.19 and developed using that for the SparkFun AVR boards; I could not get it working. serial-discovery showed the serial number, Windows device manager showed it and after connecting a board to my Linux laptop, dmesg also showed it but IDE 1.8.19 did not.

I did also test it in IDE 2.2.0 at occasion (thinking that maybe there is a difference) but still had problems. I eventually brewed a version that again failed in IDE 1.8.19 portable but after moving the hardware directory to the sketchbook directory of the permanent IDE installs (IDE 2.2.0 as well as IDE 1.8.5) it suddenly showed in IDE 2.2.0. In IDE 1.8.5 it however does not shown.

So the given approach does not seem to work in the older IDE.

Note:
I did also create a stripped copy of the Arduino AVR boards in the same hardware folder; it does not contain the required changes for the more extended board detection. Because I did not want to modify two USBCore.cpp files, I changed the core for the SparkFun boards to use the core MR_arduino platform.

Below two files to be extracted to the hardware directory in the sketchbook directory if so desired; you need both (see note above) for boards that identify themselves as Pro Micros.
MR_arduino.zip (7.8 MB)
MR_SparkFun.zip (1.6 MB)

1 Like

Board identification by arbitrary port properties via the upload_port.<port property ID> system is not supported in Arduino IDE 1.x (unfortunately the developers weren't kind enough to add a note to the platform and pluggable discovery specifications about the tool versions that support the feature). Arduino IDE 1.x uses a short-sighted design that only supports identification via the VID/PID pair (and a completely different but even more limited undocumented system for identifying "network" ports). So it is expected that the port will not be labeled as "EU07 power controller" in the Arduino IDE 1.x Tools > Port menu and in the "BN" field of the Arduino IDE 1.x "Board Info" dialog (Tools > Get Board Info).

What is not expected to me is that the serial number is not shown in the "SN" field of the Arduino IDE 1.x "Board Info" dialog:

image

I don't have any idea of why it can't recognize it. It works as expected in Arduino IDE 2.x:

image

An important thing to note is that Arduino IDE (both 1.x and 2.x) does not recognize changes made to the platform configuration files (e.g., boards.txt, platform.txt) while running. So you should restart the IDE after each change to the files to cause it to reload the configurations.