Compiling and Uploading to Arduino R4 WIFI using Arduino CLI + Arduino Create Agent

Hi Arduino Team,

I have a pipeline set up within (Cirkit Designer) to compile Sketch code in the cloud (running the Arduino CLI on a server) and uploading the code to Arduino boards using the Arduino Create Agent.

Overall, this setup is running smoothly for Arduino boards such as the Uno R3 and ESP-32.

The problem I'm facing currently is that I'm unable to successfully compile and upload code to the new Arduino Uno R4 WIFI with my setup.

The code appears to compiling successfully, and it uploads to the board, but I don't think the code is running correctly and I've noticed that the internal D13 LED fades on and off, regardless of the code I upload (empty code, code to blink the LED every second, code to blink every 2 seconds).

To try and isolate the issue, I have tried to compile and upload to the R4 using the Arduino CLI directly on my deskop computer. The following commands work perfectly:

Compile
./arduino-cli.exe compile --fqbn arduino:renesas_uno:unor4wifi sketch --output-dir output
Upload
./arduino-cli.exe upload --fqbn arduino:renesas_uno:unor4wifi --port COM3 sketch

Next, I have tried copying the hex output from the previous compile step, base-64 encoding that hex with an online tool, and then passing the base-64 encoded hex string into the Arduino Create Agent JS Client:

const target = {
      board: 'arduino:renesas_uno:unor4wifi',
      port: 'COM3',
      network: false
    };

    const code = 'base64 encoded hex string';

    this.daemon.uploadSerial(target, 'sketch', { bin: code , files: [] });

The code uploads with the following output, but I get the faded LED blink again.

Upload started
Programming with: Serial
Restarting in bootloader mode
Flashing with command:C:/Users/Vince/.arduino-create/arduino/bossac/1.9.1-arduino5/bossac.exe -d --port=COM3 -U -e -w C:/Users/Vince/AppData/Local/Temp/arduino-create-agent2326052685/sketch.ino.bin -R
Set binary mode
version()=Arduino Bootloader (SAM-BA extended) 2.0 [Arduino:IKXYZ]
Connected at 921600 baud
identifyChip()=nRF52840-QIAA
write(addr=0,size=0x34)
writeWord(addr=0x30,value=0x400)
writeWord(addr=0x20,value=0)
Erase flash
chipErase(addr=0)
Done in 0.001 seconds
Write 143528 bytes to flash (36 pages)

[                              ] 0% (0/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0, size=0x1000)
write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x1000, size=0x1000)

[=                             ] 5% (2/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x2000, size=0x1000)

[==                            ] 8% (3/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x3000, size=0x1000)

[===                           ] 11% (4/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x4000, size=0x1000)

[====                          ] 13% (5/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x5000, size=0x1000)

[=====                         ] 16% (6/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x6000, size=0x1000)

[=====                         ] 19% (7/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x7000, size=0x1000)

[======                        ] 22% (8/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x8000, size=0x1000)

[=======                       ] 25% (9/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x9000, size=0x1000)

[========                      ] 27% (10/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0xa000, size=0x1000)

[=========                     ] 30% (11/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0xb000, size=0x1000)

[==========                    ] 33% (12/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0xc000, size=0x1000)

[==========                    ] 36% (13/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0xd000, size=0x1000)

[===========                   ] 38% (14/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0xe000, size=0x1000)

[============                  ] 41% (15/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0xf000, size=0x1000)

[=============                 ] 44% (16/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x10000, size=0x1000)

[==============                ] 47% (17/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x11000, size=0x1000)

[===============               ] 50% (18/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x12000, size=0x1000)

[===============               ] 52% (19/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x13000, size=0x1000)

[================              ] 55% (20/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x14000, size=0x1000)

[=================             ] 58% (21/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x15000, size=0x1000)

[==================            ] 61% (22/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x16000, size=0x1000)

[===================           ] 63% (23/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x17000, size=0x1000)

[====================          ] 66% (24/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x18000, size=0x1000)

[====================          ] 69% (25/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x19000, size=0x1000)

[=====================         ] 72% (26/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x1a000, size=0x1000)

[======================        ] 75% (27/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x1b000, size=0x1000)

[=======================       ] 77% (28/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x1c000, size=0x1000)

[========================      ] 80% (29/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x1d000, size=0x1000)

[=========================     ] 83% (30/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x1e000, size=0x1000)

[=========================     ] 86% (31/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x1f000, size=0x1000)

[==========================    ] 88% (32/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x20000, size=0x1000)

[===========================   ] 91% (33/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x21000, size=0x1000)

[============================  ] 94% (34/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x22000, size=0x1000)

[============================= ] 97% (35/36 pages)write(addr=0x34,size=0x1000)
writeBuffer(scr_addr=0x34, dst_addr=0x23000, size=0x1000)

[==============================] 100% (36/36 pages)
Done in 9.255 seconds
reset()
Ok

So it appears that at least one issue is how I'm using the Arduino Create Agent / Client library to upload code.

For some additional context, I remember that to get code uploading successfully to the ESP-32, I had to pass in the .bin file, as well as .bootloader.bin file and .partitions.bin file, so I'm wondering if I would need to upload some additional files for this board?

Thanks in advanced for your help!

Also I'm happy to provide any additional details, such as the .hex file I'm using, but I wanted to avoid making this post unnecessarily long.

Best,
Austin

After trying out passing in different file types, I discovered that passing the base64 encoded .bin file to uploadSerial works!

Currently I've hardcoded to use the .bin file when the fqbn matches the Arduino R4 (since .hex and .bin are produced from compilation).

// This is an API to perform server-side compilation. The response
// includes a .hex file (if available), a .bin file (if available), and
// additional files produced in the compilation step.
const response = await firstValueFrom(this.cloudCompilationService.compile(data));

// Determining whether to pass the .bin or .hex file to uploadSerial of the
// create agent JS client library.
let compiledCode = '';

      if (this.selectedBoard.fqbn === 'arduino:renesas_uno:unor4wifi') {
        compiledCode = response.compilationResponseRecord.bin;
      } else if (response.compilationResponseRecord.hex !== '') {
        compiledCode = response.compilationResponseRecord.hex;
      } else if (response.compilationResponseRecord.bin !== '') {
        compiledCode = response.compilationResponseRecord.bin;
      } else {
        console.error(`Server respone missing compiled code`);
        return;
      }

const target = {
      board: 'arduino:renesas_uno:unor4wifi',
      port: 'COM3',
      network: false
    };

    this.daemon.uploadSerial(target, /* sketchName= */ 'sketch', /* compilationResult= */ { bin: compiledCode, files: [] });

I'm wondering now, what is the best approach for determing what files (.hex or .bin) to pass to the uploadSerial function of the Arduino Create Agent JS client library to populate the compilationResult?

uploadSerial(target, sketchName, compilationResult, verbose = true, dialogCustomizations) {

More specifically, since the Arduino CLI can produce .hex and/or .bin output files, what is the best way across all of the supported boards to determine whether I should be passing .hex or .bin?

Thanks again for your time helping out!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.