How to change the f_cpu value in arduino-cli ?

Hi, I use the 8MHz internal oscillator of my atmega328p-pu, but after compiling using arduino-cli, such as:

arduino-cli compile --build-property "build.f_cpu=8000000UL" --fqbn arduino:avr:uno mySketch.ino --output-dir .

it can't change the frequency from 16MHz to 8MHz.
I trid many times, but failed.

How to change the frequency value of mcu from the default 16MHz to 8MHz in arduino-cli ?
Best regards.

Try it (I don't know if it will work)
Configure Arduino IDE for Atmega 328P to Use 8MHz Internal Clock : 8 Steps - Instructables

Regards

Hi, @MaximoEsfuerzo
Thank you.
The link is about arduino 1.x, but ... I want to use the arduino-cli, namely, the command line, to set the frequency of mcu.
Best regards.

Oops! :man_facepalming:t2:

How do you know? The f_cpu is used for the compile.

Hi @wanggaoteng. My recommendation is to use the excellent "MiniCore" boards platform:

This 3rd party boards platform provides a board definition for the ATmega328P microcontroller with custom board options that allow you to set various configurations, including the clock source (internal or external) and speed. This means you can use a convenient user interface to configure the clock speed instead of having to adjust the F_CPU macro value using a lower level internal interface that was never intended to be used by the user.

The Arduino boards platform framework allows the platform developer to include "custom board options" in a board definition. These "custom board options" can be used by the user to adjust the configuration of that board definition (e.g., choosing the clock speed).

When using Arduino CLI, the custom board options are set via --board-options flags added to the arduino-cli commands.

The format of the flag is like this:

--board-options "<menu ID>=<option ID>"

(where <menu ID> and <option ID> are placeholders for the custom board options menu and menu option you are setting)

You can learn all the available menu IDs and option IDs for a given board by running the following arduino-cli command:

arduino-cli board details --fqbn <FQBN>

(where <FQBN> is replaced by the fully qualified board name of the board you are using)

For example:

arduino-cli board details --fqbn MiniCore:avr:328

Board name:            ATmega328
FQBN:                  MiniCore:avr:328
Board version:         2.2.1

Package name:          MiniCore
Package maintainer:    MCUdude
Package URL:           https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json
Package website:       https://github.com/MCUdude/MiniCore
Package online help:   https://forum.arduino.cc/index.php?topic=412070

Platform name:         MiniCore
Platform category:     Contributed
Platform architecture: avr
Platform URL:          https://MCUdude.github.io/MiniCore/MiniCore-2.2.1.tar.bz2
Platform file name:    MiniCore-2.2.1.tar.bz2
Platform size (bytes): 602320
Platform checksum:     SHA-256:1da6b88b191d7d804acd982ebc15dd35d227d123791805024abda6dd5ec690b9

Required tool: MiniCore:avrdude         7.1-arduino.1
Required tool: arduino:arduinoOTA       1.3.0
Required tool: arduino:avr-gcc          7.3.0-atmel3.6.1-arduino7

Option:        Clock                                              clock
               External 16 MHz          ✔                         clock=16MHz_external     
               External 20 MHz                                    clock=20MHz_external     
               External 18.432 MHz                                clock=18_432MHz_external 
               External 14.7456 MHz                               clock=14_7456MHz_external
               External 12 MHz                                    clock=12MHz_external     
               External 11.0592 MHz                               clock=11_0592MHz_external
               External 8 MHz                                     clock=8MHz_external      
               External 7.3728 MHz                                clock=7_3728MHz_external 
               External 4 MHz                                     clock=4MHz_external      
               External 3.6864 MHz                                clock=3_6864MHz_external 
               External 2 MHz                                     clock=2MHz_external      
               External 1.8432 MHz                                clock=1_8432MHz_external 
               External 1 MHz                                     clock=1MHz_external      
               Internal 8 MHz                                     clock=8MHz_internal      
               Internal 4 MHz                                     clock=4MHz_internal      
               Internal 2 MHz                                     clock=2MHz_internal      
               Internal 1 MHz                                     clock=1MHz_internal      
Option:        BOD                                                BOD
               BOD 2.7V                 ✔                         BOD=2v7
               BOD 4.3V                                           BOD=4v3
               BOD 1.8V                                           BOD=1v8
               BOD  disabled                                      BOD=disabled
Option:        EEPROM                                             eeprom
               EEPROM retained          ✔                         eeprom=keep
               EEPROM not retained                                eeprom=erase
Option:        Compiler LTO                                       LTO
               LTO disabled             ✔                         LTO=Os
               LTO enabled                                        LTO=Os_flto
Option:        Variant                                            variant
               328P / 328PA             ✔                         variant=modelP
               328 / 328A                                         variant=modelNonP
               328PB                                              variant=modelPB
Option:        Bootloader                                         bootloader
               Yes (UART0)              ✔                         bootloader=uart0
               Yes (UART1 328PB only)                             bootloader=uart1
               No bootloader                                      bootloader=no_bootloader
Programmers:   ID                       Name
               atmel_ice                Atmel-ICE ISP
               snap_isp                 MPLAB SNAP ISP
               usbtinyisp               USBtinyISP
               xplainedmini             Xplained Mini
               avrispmkii               AVRISP mkII
               usbasp                   USBasp
               usbtinyisp_slow          USBtinyISP slow
               stk500                   STK500 as ISP (MiniCore)
               usbasp_slow              USBasp slow
               arduinoasisp             Arduino as ISP
               pickit4_isp              PICkit4 ISP

Here we can see that the ID for the "Clock" menu is clock and the ID for the "Internal 8 MH" option is 8MHz_internal.

So, if you wanted to compile a sketch with this custom board option, you would use the following command:

arduino-cli compile --fqbn MiniCore:avr:328 --board-options "clock=8MHz_internal"

You can add multiple --board-options flags to an arduino-cli command if you want to set multiple custom board options menus.


Just to verify, you have properly set the fuses in the atmega328p-pu for 8MHz internal oscillator?

Hi, @sterretje
I have test using:

arduino-cli compile --build-property "build.f_cpu=8000000UL" --fqbn arduino:avr:uno mySketch.ino --output-dir .

the frequency remains 16MHz, not 8MHz.
Maybe the above command is not the correct usage of arduino-cli.

How are you determining that?

The value of the F_CPU macro you are modifying is only used by code that needs to know the clock frequency. It does not affect the clock source. That is done by the configuration fuses. So if your board has an external 16 MHz clock and the fuses are set to use that clock, then it will continue to do so even after you change the value of the F_CPU macro.

You can easily change the configuration fuses by running an arduino-cli burn-bootloader command with the MiniCore:avr:328 board and clock=8MHz_internal custom board option. In addition to flashing the bootloader, this command also sets the configuration fuses according to the board definition. The clock=8MHz_internal custom board option does three things:

  • Selects the configuration fuses for using the microcontroller's internal RC oscillator
  • Selects the bootloader that is compiled for an 8 MHz clock
  • Sets the F_CPU macro for an 8 MHz clock

Hi, @ptillisch
Thanks a lot for providing many informations.
I try to understand the information and use
arduino-cli compile --fqbn MiniCore:avr:328 --board-options "clock=8MHz_internal"
But it returns that "can not find MiniCore:avr platform, the platform is not installed", I searched in the document of arduino-cli, but ... failed, how to solve it?
P.S. my computer os is win10.

In order to install a 3rd party boards platform like MiniCore, you must first add its package index URL to your Arduino CLI configuration file.

If you don't already have a configuration file, generate one by running the following command:

arduino-cli config init

You can learn the package index URL by checking the platform's installation instructions. In this case, they are here.

Now run the arduino-cli config add command to add that package index URL to your configuration file:

arduino-cli config add board_manager.additional_urls https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json

After adding the URL to your configuration, you can run the arduino-cli core update-index command to download the package index:

arduino-cli core update-index

In order to install the platform, you will need to know its ID. You can learn it by running the arduino-cli core list --all command:

$ arduino-cli core list --all
ID                      Installed Latest    Name
arduino:avr             1.8.6     1.8.6     Arduino AVR Boards
arduino:mbed_edge                 4.0.2     Arduino Mbed OS Edge Boards
arduino:mbed_giga                 4.0.2     Arduino Mbed OS Giga Boards
arduino:mbed_nano                 4.0.2     Arduino Mbed OS Nano Boards
arduino:mbed_nicla                4.0.2     Arduino Mbed OS Nicla Boards
arduino:mbed_opta                 4.0.2     Arduino Mbed OS Opta Boards
arduino:mbed_portenta             4.0.2     Arduino Mbed OS Portenta Boards
arduino:mbed_rp2040               4.0.2     Arduino Mbed OS RP2040 Boards
arduino:megaavr                   1.8.8     Arduino megaAVR Boards
arduino:nrf52                     1.0.2     Arduino nRF52 Boards
arduino:sam                       1.6.12    Arduino SAM Boards (32-bits ARM Cortex-M3)
arduino:samd                      1.8.13    Arduino SAMD Boards (32-bits ARM Cortex-M0+)
Arrow:samd                        2.1.0     Arrow Boards
atmel-avr-xminis:avr              0.6.0     Atmel AVR Xplained-minis
emoro:avr                         3.2.2     EMORO 2560
industruino:samd                  1.0.1     Industruino SAMD Boards (32-bits ARM Cortex-M0+)
Intel:arc32                       2.0.6     Intel Curie Boards
Intel:i586                        1.6.7+1.0 Intel i586 Boards
Intel:i686                        1.6.7+1.0 Intel i686 Boards
littleBits:avr                    1.0.0     littleBits Arduino AVR Modules
MiniCore:avr                      2.2.2     MiniCore
renesas:rl78g22_fpb               2.0.0     RL78/G22 Fast Prototyping Board
renesas:rl78g23_fpb_p64           2.0.0     RL78/G23-64p Fast Prototyping Board
Microsoft:win10                   1.1.2     Windows 10 Iot Core
arduino:mbed                      3.3.0     [DEPRECATED] [DEPRECATED - Please install standalone packages] Arduino Mbed OS Boards

You now know the ID is MiniCore:avr so you can run the arduino-cli core install command, specifying the platform ID:

arduino-cli core install MiniCore:avr

Hi, @ptillisch
The information you provided is very clear and easy to understand, according to the instructions you provided, I solve all the problems and my board works very well.

By the way, I want to shield the information generated by the command:

arduino-cli compile --fqbn MiniCore:avr:328 --board-options "clock=8MHz_internal"

namely, make all the information which generated after compiling, such as :
xxx byte (xx%) used, the max rom is xxx byte. xxx byte (xx%) used, the max ram is xxx byte.
don't display in the command window.

How to disappear it?

P.S.
I can use:

avr-objdump -Pmem-usage sketch_name.elf

to get the usage information.

Best regards.

I'm glad it is working now!

Which shell are you using to run the command? I ask because the answer can be different from one shell to another.

Examples of common shells:

  • PowerShell
  • Windows cmd
  • Bash
  • zsh

I use a simple Makefile:

PRG             = sketch
ArduinoC        = arduino-cli
SIZE            = avr-objdump -Pmem-usage

all:
	@$(ArduinoC) compile --fqbn MiniCore:avr:328 --board-options "clock=8MHz_internal" $(PRG).ino --output-dir .
	@$(SIZE) $(PRG).ino.elf
clean:
	@del *.elf *.eep *.hex *.bin *.lst {$(PRG)_path}

and open the folder which contains sketch.ino and Makefile in vscode:


The output of
$(ArduinoC) compile --fqbn MiniCore:avr:328 --board-options "clock=8MHz_internal" $(PRG).ino --output-dir .
and
$(SIZE) $(PRG).ino.elf
are duplicated, I want to sheild the output come from arduino-cli if .

The shell is PowerShell.

It's too long ago that I played with makefiles. From memory, if you invoke make without an argument it executes the first target (all in your case).

If you want to suppress the reporting of the size, don't add it to the all target in the makefile.

You can add a different target (e.g. called size) to report the size.

To suppress the output of a command invoked in PowerShell, pipe it to Out-Null.

So try this:

@$(ArduinoC) compile --fqbn MiniCore:avr:328 --board-options "clock=8MHz_internal" $(PRG).ino --output-dir . | Out-Null

I haven't tested it in a Makefile, but it does work if I use it with an arduino-cli command run directly from PowerShell.

It works in my PowerShell too, but I test it in the Makefile, it failed.
Best regards.

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