Flashing Atmega328PB only works once


Maybe someone has a clue to this rather complicated problem:

I have a board using the Atmega328PB.
I can burn a bootloader. There is no issue with that.

I can flash the board via FTDI multiple times if - and this is the tricky part - I do NOT disable the ADC.
If I use the statement
to disable the ADC before entering power down mode for 8 seconds, I cannot flash the board anymore.

If I don't use the upper statement, and just enter power down mode for 8 seconds, all subsequent flashes work.

In both cases resetting the chip via DTR seems to work since the sketch signals entering the setup() method by blinking in a specific way. And when I try to upload with avrdude the blinking is fine. It just hangs and avrdude gives a sync error.

Fuse Settings:

Tried different voltages: 3.3V and 5V. Both with the same result.

Which hardware package are you using to add support for your ATmega328PB?

I am using atmega328pb-testing (1.1.2) from watterott with a custom board.
Furthermore I've installed Arduino AVR Boards 1.6.207

the board makes use of a 100nF cap and a 10k resistor for handling reset functionality.
everything is 3.3V - the atmega328pb board as well as the FTDI programmer.

There is one other strange thing...

When I do a

I get 135 as output. This is equal to 10000111 afaik
So: ADEN is 1 and ADPS (Prescaler) is 111 (=Factor 128)

On a reset everything should be 0 in ADCSRA.

I wonder which code is messing with this register...

Just noticed that the same output is displayed for atmega328p devices...

Are you still having this problem? If so, please provide a complete sketch and exact set of steps to reproduce the problem.

I have an ATmega328PB board and was going to see if the problem still occurs when using MiniCore, which also uses the optiboot bootloader but perhaps a different version.

This is the test sketch:

#include <LowPower.h>

#define LED_PIN 9

// the setup function runs once when you press reset or power the board
void setup() {
 // initialize digital led PIN as an output.
 pinMode(LED_PIN, OUTPUT);
 for (byte i=0; i<30; i++)
   digitalWrite(LED_PIN, HIGH);   // turn the LED on (HIGH is the voltage level)
   digitalWrite(LED_PIN, LOW);    // turn the LED off by making the voltage LOW

// the loop function runs over and over again forever
void loop() {
 LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

Steps to reproduce:

  1. Burn Bootloader using Atmega328PB-Testing Board package. (Board with "Crystal Clock" and "16MHz" selected in menu). Fuses are also set here.
    I've changed the boards.txt of the atmega328pb package to contain:
    but even if you don't change this, the results should be the same.

I had to edit avrdude.conf too to include:

part parent "m328"
    id			= "m328pb";
    desc		= "ATmega328PB";
    signature		= 0x1e 0x95 0x16;

    ocdrev              = 1;
  1. Upload the sketch above via USB/FTDI. Upload works. Running of setup() routine can be observed by fast LED blinking.

  2. Try to upload the above sketch once again. The board resets (since LED blinking of setup() routine can be observed) but Avrdude gives a sync error.

If you change the sketch, so that ADC_OFF is replaced by ADC_ON, and burn the bootloader again, and upload the new sketch, there are no problems with subsequent uploads.

P.S.: For this to compile you need the attached (modified) Lowpower Lib. It's just a quick hack to make the Lowpower lib work....

LowPower.cpp (33.6 KB)

LowPower.h (2.88 KB)

Thanks for the instructions! That's very helpful.

I can reproduce the issue when using the bootloader from watterott/ATmega328PB-Testing.

When I use the MiniCore bootloader the problem does not occur.

I isolated the problem to the bootloader by using the MiniCore board definition with the watterott bootloader and vice versa. The problem relates to the bootloader used rather than the hardware package. Note that when doing this you need to adjust the upload.speed value in boards.txt since MiniCore's bootloader communicates at 115200 and watterott's at 57600.

So the workaround I can provide is to use MiniCore. But I'm sure we're both curious as to how this code could break the upload. I'm not qualified to answer that question.

I'm not sure whether you noticed, but the watterott bootloader can be uploaded to again after unplugging the board and then plugging back in, even after waiting for the sketch to run and put the board back to sleep. This makes me think the problem is related to the MCUSR register since as far as I know that is the only thing that would be changed by a power on.

Unfortunately watterott did not provide the source code for their bootloader, makefile, or any other information so that makes it difficult to investigate further.

I've changed the boards.txt of the atmega328pb package to contain:

What was the reason for that?

I had to edit avrdude.conf too to include:

part parent "m328"

id = "m328pb";
   desc = "ATmega328PB";
   signature = 0x1e 0x95 0x16;

ocdrev              = 1;

That's not necessary if you install Arduino AVR Boards 1.6.206 (actually latest is now 1.6.207), as instructed:

First off, thanks for the fast reply!
I have tried MiniCore a couple of days ago (manual installation) and could not upload any sketch at all, but at that time I was also messing around with caps and resistors on the board. So... I will try it again, with my current configuration.

It's very good news that you can reproduce the problem!
The probability is high that I can fix it now.
I will check this later today and let you know.

I strongly assume that Watterott is using this bootloader source code:

I changed the bootloader fuses just because I don't want eeprom to get wiped all the time and because I wanted to make sure that it is no startup timing issue that has to do with the external crystal. (I changed the oscillator settings...)

Actually I installed AVR boards 1.6.207 but the board definition in avrdude was missing. (Maybe I looked at the wrong avrdude.conf, or I'm mixing things up. I can just as well uninstall it, and install it again, to be sure.)

OK, just checked with MiniCore release 2.0.1, and, indeed, the upload issues are resolved now!
Thanks a lot for your support!

Glad to hear MiniCore is working for you!

I did a comparison between the MiniCore bootloader source and the watterott source you pointed out. There are some differences in the handling of MCUSR but also watterott's has so auto baud rate detection code added:


I believe the purpose of the added code in the MiniCore version was to preserve the contents of the MCUSR register so that information can be used in the application.

Another significant difference I notice is that the watterott bootloader has auto baudrate detection: