Arduino UNO configured for lower speed issue

Hi,
I did read several topics about this subject without finding a solution, so I hope that somebody will help me with this issue.

I am trying to use a boot loader for Arduinio Uno using other clock speed than the default 16MHz.
(MAC OSX 10.9.5 and Arduino IDE 1.6.8)

To keep it simple, this is one of the problem I am facing:

With an Arduino Uno loaded with the standard optiboot file I am using a standard boards.txt (see Original boards.txt) file ( this is a copy of the Uno one but renamed for my environment).
The boot loader file (optiboot_atmega328.hex) is created for a 16MHz speed and a baud rate of 115200 bps.
Burning an Arduino (with ArduinoISP) with this configuration works fine, and I am able to load and use a standard sketch such as the ASCIItable from the example without problem.

Now the I expect to start the Arduino with a lower speed; for that purpose I am just changing the low_fuse from 0xFE to 0x7E, which correspond to divides the clock by 8.
Burning the arduino is not a problem and I can crosscheck the fuse bits using the Nick Gammon utility Arduino fuse calculator (see below).

However I am UNABLE to load a script in the newly burned Arduino, I have already tried to change the cocomand.upload.speed=115200 to 14400bps (115200/8) as the upload speed without success (without burning the boot loader).
The error message is:
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding

So I believe there is an problem with the USB speed, but I don't know which one to use

I have same issue using a new boot file made for a 2MHz frequency (cocomand: AVR_FREQ = 2000000L)

So does someone have an explanation for this, or how can I solve this issue.

Thanks in advance
Robert

Original boards.txt

cocomand.name=CoComand
cocomand.vid.0=0x2341
cocomand.pid.0=0x0043
cocomand.vid.1=0x2341
cocomand.pid.1=0x0001
cocomand.vid.2=0x2A03
cocomand.pid.2=0x0043
cocomand.vid.3=0x2341
cocomand.pid.3=0x0243

cocomand.upload.tool=arduino:avrdude
cocomand.upload.protocol=arduino
cocomand.upload.maximum_size=32256
cocomand.upload.maximum_data_size=2048
cocomand.upload.speed=115200

cocomand.bootloader.tool=arduino:avrdude
cocomand.bootloader.low_fuses=0xFE
cocomand.bootloader.high_fuses=0xDE
cocomand.bootloader.extended_fuses=0x05
cocomand.bootloader.unlock_bits=0x3F
cocomand.bootloader.lock_bits=0x0F
cocomand.bootloader.file=optiboot_atmega328.hex

cocomand.build.mcu=atmega328p
cocomand.build.f_cpu=16000000L
cocomand.build.board=AVR_UNO
cocomand.build.core=arduino:arduino
cocomand.build.variant=arduino:standard

16MHz Makefile example

cocomand: TARGET = atmega328
cocomand: MCU_TARGET = atmega328p
cocomand: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
cocomand: AVR_FREQ = 16000000L
cocomand: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
cocomand: $(PROGRAM)_atmega328.hex
cocomand: $(PROGRAM)_atmega328.lst

2MHz Makefile example

cocomand: TARGET = atmega328
cocomand: MCU_TARGET = atmega328p
cocomand: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=19200'
cocomand: AVR_FREQ = 2000000L
cocomand: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
cocomand: $(PROGRAM)_atmega328_2MHz_19Kbps.hex
cocomand: $(PROGRAM)_atmega328_2MHz_19Kbps.lst

Fuse calculator

Atmega fuse calculator.
Written by Nick Gammon.
Version 1.11
Compiled on Apr 10 2016 at 18:18:24 with Arduino IDE 10608.
Attempting to enter programming mode ...
Entered programming mode OK.
Signature = 0x1E 0x95 0x0F
Processor = ATmega328P
Flash memory size = 32768
LFuse = 0x7E
HFuse = 0xDE
EFuse = 0xFD
Lock byte = 0xCF
Clock calibration = 0x99
External Reset Disable.................. [ ]
Debug Wire Enable....................... [ ]
Enable Serial (ICSP) Programming........ [X]
Watchdog Timer Always On................ [ ]
Preserve EEPROM through chip erase...... [ ]
Boot into bootloader.................... [X]
Divide clock by 8....................... [X]
Clock output............................ [ ]
Bootloader size: 512 bytes.
Start-up time: SUT0: [ ] SUT1: [ ] (see datasheet)
Clock source: low-power crystal.
Brownout detection at: 2.7V.

Keep the fuse settings at the standard Uno settings.
Create a copy of the boards.txt entry for the standard Uno with everything the same except build.f_cpu=2000000L
Burn the standard Uno bootloader onto the Uno
At top of your sketch do:

#include <avr/power.h>

In your sketch in the setup function do:

// if boards.txt Arduino selected with (board).build.f_cpu=2000000L
// underclock to that speed
#if F_CPU == 2000000
clock_prescale_set(clock_div_8);
#endif

Upload as usual. If you upload using the regular Uno board selection, the sketch will run at 16MHz; if you upload using the custom Uno board selection, the sketch will run at 2MHz. Upload will happen at 16MHz using the standard bootloader.

The problem is that once I use another speed than 16MHz, I can’t load any script anymore
Example 4MHz 57600Kbps (115200 not possible because of the baud tolerance), see make file and boards.txt below :

  1. Arduino UNO used as ISP loaded as Arduino UNO + ArduinoISP sketch
  2. Select as board Cocomand from the Tool Board manager menu (defined in the hardware directory)
  3. Burn the Cocomand connected as required (see attached Burn log.txt) No problem
  4. Disconnect the Arduinio ISP and connect the USB port to the burned one
  5. Board selected is Cocomand
  6. Load the sketch ASCII table for instance
  7. Error message:
    Using Port : /dev/cu.usbmodem26411
    Using Programmer : arduino
    Overriding Baud Rate : 57600
    avrdude: stk500_recv(): programmer is not responding

Make:
cocomand: TARGET = atmega328
cocomand: MCU_TARGET = atmega328p
cocomand: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=57600'
cocomand: AVR_FREQ = 4000000L
cocomand: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
cocomand: $(PROGRAM)_atmega328_4MHz_57Kbps.hex
cocomand: $(PROGRAM)_atmega328_4MHz_57Kbps.lst

boards.txt:
##############################################################

cocomand.name=CoComand
cocomand.vid.0=0x2341
cocomand.pid.0=0x0043
cocomand.vid.1=0x2341
cocomand.pid.1=0x0001
cocomand.vid.2=0x2A03
cocomand.pid.2=0x0043
cocomand.vid.3=0x2341
cocomand.pid.3=0x0243

cocomand.upload.tool=arduino:avrdude
cocomand.upload.protocol=arduino
cocomand.upload.maximum_size=32256
cocomand.upload.maximum_data_size=2048
cocomand.upload.speed=57600

cocomand.bootloader.tool=arduino:avrdude
cocomand.bootloader.low_fuses=0xEE
cocomand.bootloader.high_fuses=0xDE
cocomand.bootloader.extended_fuses=0x05
cocomand.bootloader.unlock_bits=0x3F
cocomand.bootloader.lock_bits=0x0F
cocomand.bootloader.file=optiboot_atmega328_4MHz_57Kbps.hex

cocomand.build.mcu=atmega328p
cocomand.build.f_cpu=4000000L
cocomand.build.board=AVR_UNO
cocomand.build.core=arduino:arduino
cocomand.build.variant=arduino:standard

Burn log.txt (9.88 KB)

Error Log.txt (1.88 KB)

Yes, that is why I recommend my method of reducing clock speed in the sketch. Standard Uno bootloader and fuses burned onto the Uno, and standard Uno settings in boards.txt except for the build.f_cpu setting. Then you won't have to do anything special for uploading and it will just work.

OK thanks for the tip, I have used the same method for the BOD (modifying the Arduino UNO fuse) and it looks also to work.

Now this is really confusing me with all I read about the fuse, etc…

I will continue my investigations for a better understanding, but anyway you did solve my problem

Thanks again,
Robert

darvade:

Quote from: darvadeNow this is really confusing me with all I read about the fuse, etc…

The CKDIV8 fuse just sets the startup value for CLKPR - Clock Prescale Register.
**10.13.2 **CLKPR – Clock Prescale Register
The CKDIV8 Fuse determines the initial value of the CLKPS bits. If CKDIV8 is unprogrammed, the CLKPS bits will be reset to “0000”. If CKDIV8 is programmed, CLKPS bits are reset to “0011”, giving a division factor of 8 at start up. This feature should be used if the selected clock source has a higher frequency than the maximum frequency of the device at the present operating conditions. Note that any value can be written to the CLKPS bits regardless of the CKDIV8 Fuse setting. The Application software must ensure that a sufficient division factor is chosen if the selected clock source has a higher frequency than the maximum frequency of the device at the present operating conditions. The device is shipped with the CKDIV8 Fuse programmed.

Just for me to understand ....

Arduino Uno is working with a low power crystal of 16 MHz.
Standard fuse is:
uno.bootloader.low_fuses=0xFE << means NO Divide clock by 8 internally; [CKDIV8=0])
uno.bootloader.high_fuses=0xDE
uno.bootloader.extended_fuses=0x05
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F

So if I set the low_fuse to 0x7E and burn the Arduino UNO with this configuration the divider should be used and the clock should be 2MHz.

Now what I don't understand is that I can't load a sketch with this configuration (even using a build.f_cpu = 2000000L)
Another possibility is that the upload speed of 115200 bps is to high for a chip running at 2MHz, so I did use 19200 bps for the boot loader and the build, without success.
Until now the only think which is working is the trick proposed by dmjlambert.

But I don't want to monopolise this topic with newbies questions. Is there some topics that I should read that explains the correct settings between the boot loader configuration and the build settings (using the boards.txt)?

Thanks Robert

See this section of the datasheet so you can use an external 16 MHz xtal or resonator, and then control the clock speed of your sketch in software:

9.11 System Clock Prescaler
The ATmega48A/PA/88A/PA/168A/PA/328/P has a system clock prescaler, and the system clock can be
divided by setting the ”CLKPR – Clock Prescale Register” on page 37. This feature can be used to decrease
the system clock frequency and the power consumption when the requirement for processing power is low. This
can be used with all clock source options, and it will affect the clock frequency of the CPU and all synchronous
peripherals. clkI/O, clkADC, clkCPU, and clkFLASH are divided by a factor as shown in Table 29-11 on page 305.

Why are you trying to run at 2 MHz? Are you trying to save power? Sometimes that backfires because even though everything takes 8 times as long you are using more than 1/8th the power so your power consumption goes UP.

The Arduino timer functions (millis, micros, delay, delayMicroseconds) are designed to only work correctly at 16 MHz and 8 MHz. Most features also work at 20 MHz. You can't expect those functions to work with FCPU set to 2,000,000.

OK,
I want to configure a Atmega 328P for low power (see for instance: Implementing Bootloader for Ultra Low Power Arduino Wireless Sensor Node : Part 2 – Charles's Blog and 2), typically running at 4 MHz with a cell battery of 1.8V, from the time the micro controller starts. The explanation looks straight forward to me, however following the instructions doesn't work.

I have read the Atmel® AVR® 8-Bit Microcontroller Advanced RISC Architecture more than once, specifically regarding the fuse bits.

I have read several articles regarding boot loader and fuse configurations, typically the one of Gammon Forum : Electronics : Microprocessors : Atmega bootloader programmer (and plenty of others), so I know how to create a .hex file from a make file, configure a boards.txt file and how to configure Arduino IDE with these ones and activate them from the menu.

No, I don't have a standalone programer to configure the fuse and to load the .hex file, so I only have the Arduino IDE to do it.

I understand that changing the CPU speed will affect timers and the USB speed.

I understand the impact of the clock pre-scaler and I have experiment several scripts that are use it.

However I still doesn't understand why changing the fuse clock (or to compile a boot loader file with a clock different than 16MHz) impact the Arduino IDE sketch loader, blocking me to do further tests.

This is currently the issue I am facing, I can't load a script because the IDE can't synchronise regarding what value I give for the USB speed.

So I wonder if this issue is a pure Arduino ISP one or more than probably because there something that I do not fully understand, so I am looking for a rational explanation.

Robert

My guess is that the baud rate calculation is going wrong. Check the bootloader's baud rate calculation to make sure nothing overflows or underflows when dividing into 2 MHz instead of 8, 16, or 20 MHz. If the actual baud rate comes out more than 5% away from the desired baud rate the communications could get garbled.

These things can be tough to figure out, and you're getting away from the stuff a lot of people have done with their Arduinos. But yes, to running it at 2MHz and 1.8V ought to be OK.

Here is something to try just for the heck of it:
Create a custom Uno boards.txt entry with all the same settings as the standard Uno entry.
In that custom entry change the fuse settings to have CKDIV8=0 (programmed), and BODLEVEL=111 (disabled)
Low:7F High:DE Ext:07 or FF
Leave the standard Uno bootloader hex file that runs at 115200 baud and 16MHz in the custom boards.txt entry
Set the upload baud rate to 14400 in the custom boards.txt entry

When the bootloader that normally listens at 115200 baud is operating on a chip that has its clock divided by 8, it will be listening at 14400 baud (115200/8).

Burn the bootloader. Try an upload.

I would program the board while powered at the usual 5V, and just run it at 1.8V when disconnected from the computer after uploading.

If you can't get uploading to work, you can use ISP programming to load sketches, instead of using USB and the bootloader. When you upload a sketch using a programmer, it overwrites the bootloader.

[EDIT: whoops, I guess you already know this] You can use another Arduino as a programmer by loading the ArduinoISP sketch on it and selecting on the Tools, Programmer menu "Arduino as ISP". There are pretty good comments inside the sketch that describe how to connect programmer to target.

Thanks for your replies, unfortunately I did test your proposals already.

For my first post in order to simplify my issue, I have described an example corresponding to the test proposed by dmjlambert, the simple fact that the CLKDIV8 is used on a standard Arduino profile (16MHz, 115200 bps) gives synchronisation issue while trying to load a sketch, changing the speed in the boards.txt to 1/8 of the configured one doesn't help.

Regarding the selected USB speed at 2MHz, baud settings giving more than 5% of tolerance generates a compilation error while making the boot loader file. This is the reason I have tried it with 19200 bps which doesn't generates an error. But even so I can't load script (note that boot loader using 16MHz at 19200 bps works).

I am convinced that there is a 'problem' with the actual baud rate the processor is using when configured with a boot loader having a different clock than 16MHz (or when the CLKDIV8 fuse is set).

Using the workaround prosed by dmjlambert ; boot loader at 16MHz / 115200bps and then change the F_CPU to 2MHz, I can load a script at 115200 bps. This script is supposed to dump the ASCII table to a terminal at 9600 bps, however without specifying in the sketch clock_prescale_set(clock_div_8), only rubbish is printed, I couldn't fine the correct speed for the terminal emulator, 9600, 4800, 2400, 1200, .... bps doesn't work.
Changing the clock_prescale solves the problem, the actual speed to use is 9600.

I believe I have a problem to understand the difference of changing the CPU clock in the boot loader (AVR_FREQ or the CLKDIV8 fuse) and the boards.txt (build.f_cpu).
The first one looks to greatly impact the UART speed (but now simply divide it) disregarding the upload.speed value used after.

The values in hardware/arduino/avr/bootloaders/optiboot/Makefile control the behavior of the bootloader and should reflect the conditions when the bootloader is running. AVR_FREQ is used to set the F_CPU for the bootloader compile and BAUD_RATE is used to force a specific baud rate rather than using the default:

/* set the UART baud rate defaults */
#ifndef BAUD_RATE
#if F_CPU >= 8000000L
#define BAUD_RATE   115200L // Highest rate Avrdude win32 will support
#elsif F_CPU >= 1000000L
#define BAUD_RATE   9600L   // 19200 also supported, but with significant error
#elsif F_CPU >= 128000L
#define BAUD_RATE   4800L   // Good for 128kHz internal RC
#else
#define BAUD_RATE 1200L     // Good even at 32768Hz
#endif
#endif

Note that the default for a 2 MHz clock is 9600L.

If you use a 16 MHz crystal clock and set the CKDIV8 fuse you should compile a special bootloader with AVR_FREQ=2000000L and BAUD_RATE=9600L.

If you use a 16 MHz crystal and intend to change the clock divider in your sketch you should use the standard UNO bootloader (AVR_FREQ=16000000L, BAUD_RATE=115200).

The values in hardware/arduino/avr/boards.txt control the compilation of your sketch and the behavior of the uploader.

uno.name=Arduino/Genuino Uno
uno.upload.speed=115200
uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L

upload.speed is the baud rate the uploader uses to talk to your bootloader. Set it to match the baud rate of your bootloader.
build.f_cpu is the system clock rate when your sketch is running. Set it to 2000000L if you are setting the clock prescale to 8 either by fuse or in your sketch. It will adjust the timing functions and baud rate calculations so that they should work (at least fairly close to correct) at the specified clock rate.

Another option is to just leave all the settings unchanged and modify your code to take into account that the clock is running at 1/8th speed:

#define MyMillis() (millis()*8)
#define MyDelay(value) delay((value)/8)
#define MySerialBegin(baud) Serial.begin((baud)*8L)

NO it doesn't work ....
I still have while loading a script:
avrdude: Version 6.0.1, compiled on Apr 14 2015 at 16:30:25
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2009 Joerg Wunsch

System wide configuration file is "/Applications/Arduino 1.6.7.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf"
User configuration file is "/Users/Robert/.avrduderc"
User configuration file does not exist or is not a regular file, skipping

Using Port : /dev/cu.usbmodem26411
Using Programmer : arduino
Overriding Baud Rate : 9600
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
.....

Make file is:
cocomand: TARGET = atmega328
cocomand: MCU_TARGET = atmega328p
cocomand: CFLAGS += '-DLED_START_FLASHES=1' '-DBAUD_RATE=9600'
cocomand: AVR_FREQ = 2000000L
cocomand: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
cocomand: $(PROGRAM)_atmega328_2Mhz_9Kbps_cocomand.hex
cocomand: $(PROGRAM)_atmega328_2Mhz_9Kbps_cocomand.lst

Boards.txt is:
##############################################################
cocomand.name=Cocomand
cocomand.upload.tool=arduino:avrdude
cocomand.upload.protocol=arduino
cocomand.upload.maximum_size=32256
cocomand.upload.maximum_data_size=512
cocomand.upload.speed=9600

cocomand.bootloader.tool=arduino:avrdude
cocomand.bootloader.low_fuses=0xEE
cocomand.bootloader.high_fuses=0xDE
cocomand.bootloader.extended_fuses=0x06
cocomand.bootloader.unlock_bits=0x3F
cocomand.bootloader.lock_bits=0x0F
cocomand.bootloader.file=optiboot_atmega328_2Mhz_9Kbps_cocomand.hex

cocomand.build.mcu=atmega328p
cocomand.build.f_cpu=2000000L
cocomand.build.board=AVR_UNO
cocomand.build.core=arduino:arduino
cocomand.build.variant=arduino:standard

Are you actually running at 1.8v?

Yes 1.8V in my last example but the fuse BOD level has no impact on the upload synchronisation.
Changing the AVR_FREQ or the CKDIV8 fuse bit is ALWAYS an issue to load a script, I believe this something you should be able to test.

A make file at 16MHz / 115200bps with boards.txt F_cpu of 2 or 4 MHz is the only solution (the one of djlambert), all fuse bits are possible (beside the CKDIV8)

My ultimate working configuration (tanks djlambert) and according to the specs is 4 MHz with a BOD level of 1.8V.
This was my simple and initial objective for my low power command module. Even if I am not satisfied with the theoretical explanation, it works so I can continue to load atmeg328 processor and develop my low power scripts.

Robert

I am thinking you don't want BOD at 1.8V if you are running at 1.8V. But then I have trouble understanding the brown out sections in the data sheet.

I have verified this by johnwasser in reply #13

johnwasser:
If you use a 16 MHz crystal clock and set the CKDIV8 fuse you should compile a special bootloader with AVR_FREQ=2000000L and BAUD_RATE=9600L.

I was curious about this and I compiled Optiboot and burned it on my Uno and it works.

I programmed the CKDIV8 fuse and disabled BOD. I compiled Optiboot for 2MHz and 9600 baud. I can upload to it fine. It is the current Optiboot 6.2 from Github.

Command I used to compile Optiboot on my Mac:

$ make OS=macosx ENV=arduino AVR_FREQ=2000000L BAUD_RATE=9600 LED_START_FLASHES=3 LED=B5 atmega328
$ mv optiboot_atmega328.hex optiboot_atmega328_9600baud_2MHz.hex

My custom boards.txt entry:

uno3.name=Arduino/Genuino Uno 2MHz
uno3.vid.0=0x2341
uno3.pid.0=0x0043
uno3.vid.1=0x2341
uno3.pid.1=0x0001
uno3.vid.2=0x2A03
uno3.pid.2=0x0043
uno3.vid.3=0x2341
uno3.pid.3=0x0243
uno3.upload.tool=arduino:avrdude
uno3.upload.protocol=arduino
uno3.upload.maximum_size=32256
uno3.upload.maximum_data_size=2048
uno3.upload.speed=9600
uno3.bootloader.tool=arduino:avrdude
uno3.bootloader.low_fuses=0x7F
uno3.bootloader.high_fuses=0xDE
uno3.bootloader.extended_fuses=0x07
uno3.bootloader.unlock_bits=0x3F
uno3.bootloader.lock_bits=0x0F
uno3.bootloader.file=optiboot_atmega328_9600baud_2MHz.hex
uno3.build.mcu=atmega328p
uno3.build.f_cpu=2000000L
uno3.build.board=AVR_UNO
uno3.build.core=arduino:arduino
uno3.build.variant=arduino:standard

optiboot_atmega328_9600baud_2MHz.hex.zip (851 Bytes)

Have you tried the fuse/code modifications on a 5V Arduino, separately from changing the running voltage?

  1. I'm concerned that the crystal oscillator may not run at 16MHz/1.8V - I don't recall the datasheet specifically characterizing the oscillator separately from the chip as a whole, but it's pretty common is "overclocking" attempts for the oscillator to be one of the first things that stops working.
  2. What did you do to make sure that the USB/Serial port (or plain serial?) is working at 1.8V? People get complacent about 5V vs 3.3V because usually 3.3V logic levels will work with 5V logic, but the same is probably not true of 1.8V logic.

That made me curious again. I had been uploading at 5V.

I went ahead and:

  • burned this bootloader/fuses on a Pro Mini
  • powered it with 1.8 V through the VCC pin using an adjustable power supply
  • connected the VCC, GND, RST, RX, and TX pins of the Pro Mini to the LV side of a logic level converter
  • included a 0.1uF cap in the RST line
  • connected the VCC, GND, DTR, TX, and RX pins of a 3.3V FTDI basic adapter to the HV side of the converter
  • connected a brighter LED to pin 13 because the built-in LED barely glows

I don't have a whole lot to do with an Arduino running at 1.8V, but I did successfully upload and run the blink sketch at several different blink frequencies and it appears to work well and program consistently. My Pro Mini has one of those very small 16MHz SMD resonators.

ASCIITable also uploads and works well.

The converter is simply 4 ea. BSS138 N-Channel Logic Level Enhancement Mode FETs and resistors on a breakout board.