Hi, I have been experiencing issues with a simple arduino sketch on PIO where my chip is running 8 times slower than expected even after I tried setting the fuses accordingly.
Then, the led changes states every 2 sec (0.25 * 8 = 2).
I have tried numerous fuse combinations with the clock divider disabled and enabled and the timing is still the same… Why is that?? current platformio.ini config:
WARNING Fuse bits are 0 when enabled/set, and 1 when disabled/clear - this will fry your brain.
Your fuses are set to use the internal 8MHz oscillator and not the external 16 MHz crystal. This is where your problem arises I rather suspect.
In addition, you are probably setting the bootloader address and size too big (at least for an Uno) as you are reserving 2048 bytes where the Uno needs only 512. The Nano and Duemilanove both need 2048 bytes though – at least, with the default bootloader.
You have also turned off brown out detection (BOD) which is not necessarily a bad thing, but might cause problems if the supply fluctuates.
Gory Details.
What board are you running please? I’m assuming an Uno, as those are the most popular, however, those fuse settings don’t match up with anything the Arduino (boards.txt) configures.
Your Fuses
Low Fuse: 0xE2
0xE2 gives you SUT0, CKSEL3, CKSEL2 and CKSEL0 only. The CKSEL bits mean Use the calibrated internal oscillator. This is most likely your problem as that runs at 8 MHz. You should have CKSEL3|2|1|0 to use the external oscillator and the 16 MHz crystal.
High Fuse: 0xD9
0xD9 gives you SPIEN, BOOTSZ1 and BOOTSZ0. This is reserving 2048 words of bootloader space starting at address $3800. This is the Atmel/Microchip default fuse setting and is wrong for an Arduino board.
UNO uses 0xDE giving SPIEN and BOOTRST only. This reserves 512 bytes at address $3F00 for the bootloader. A RESET starts executing at the bootloader address. The Uno bootloaders all hard code address $0000 into themselves - at least the ones I’ve looked at, which is where the jump to if they don’t see a programming command coming in at startup.
Nano/Duemilanove uses 0xDA giving SPIEN, BOOTSZ1 and BOOTRST. This reserves 2048 bytes at address $3C00 for the bootloader. A RESET starts executing at the bootloader address.
Ext Fuse: 0xFF
Nothing is active here, you are turning off Brown Out Detection. This can lead to problems if the supply voltage fluctuates too much.
The Uno, Nano and Duemilanove use 0xFD here giving BODLEVEL1 which is actually a bug! This sets the Brown Out Level detector to reset the device at 2.7 V but at 16 MHz, the setting should be 4.3 V, which is a fuse setting of 0xFC.
@maxgerhardt Indeed I had forgotten to burn the fuses… I was rusty and forgot this instruction, I though it did it at every upload… sorry! Now it works.
@normandunbar
I am using an Atmega328pau on a custom PCB. I wanted to run it at internal 8mhz since it will run at 4v max
The device will run at 4 to 3v so if I activate BOD, it will be at 2.7V or even 1.8. And also, since I am using a programmer, I will be using the smallest flash section size (256)
That being said, following your advice I made sure I fully understood all of the fuse bits instead of just making sure my settings will not brick my device. I changed my settings for what I believe is better suited for a semi low power app
board_fuses.hfuse = 0xDF ;smallest flash section size 256 since not using a bootloader with ICE programmer
board_fuses.lfuse = 0xE2 ;int 8MHz crystal (16MHz not working with less than 5V PSU)
board_fuses.efuse = 0xFE ;BOD at 1.8V, perfect for low power