Mega 2560: bootloader is erased after every update

I came across a couple of Mega 2560 clones. One of them works perfectly fine. The other seems to have the blink sketch burned into it. But I'm not able to upload a new sketch in Arduino IDE. Here's the error message:

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/Users/deling/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf"
         User configuration file is "/Users/deling/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/cu.usbserial-21310
         Using Programmer              : wiring
         Overriding Baud Rate          : 115200
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout

It appears to be a bootloader issue. So... I followed the instructions here and burned the bootloader into the Mega 2560 using an Uno over ICSP. Then I unplugged the Uno (the programmer) and plugged in the Mega 2560 (the target board), and uploaded the blink sketch from Arduino IDE. And it worked this time.

However,

  • It only works once. When I try to upload the same sketch again, I'm getting the same timeout error message again, until I repeat the process and burn the bootloader again.
  • It only works if I keep the Uno (the programmer) connected with the Mega 2560 (the target).

Any idea what's going on? Since I have two supposedly identical boards and one works fine, I tend to believe this is not a hardware issue.

Thanks.

P.S. this is the verbose output when the upload succeeds:

Sketch uses 1544 bytes (0%) of program storage space. Maximum is 253952 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 8183 bytes for local variables. Maximum is 8192 bytes.
"/Users/deling/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude" "-C/Users/deling/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf" -v -V -patmega2560 -cwiring "-P/dev/cu.usbserial-21320" -b115200 -D "-Uflash:w:/private/var/folders/f3/6ysp3l5j4zb5fz9r5zgjqgj400nmsy/T/arduino/sketches/11EBBBCDAE32B5881D6B4DDE9238999E/Blink.ino.hex:i"

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/Users/deling/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf"
         User configuration file is "/Users/deling/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/cu.usbserial-21320
         Using Programmer              : wiring
         Overriding Baud Rate          : 115200
         AVR Part                      : ATmega2560
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PA0
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    10     8    0 no       4096    8      0  9000  9000 0x00 0x00
           flash         65    10   256    0 yes    262144  256   1024  4500  4500 0x00 0x00
           lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : Wiring
         Description     : Wiring
         Programmer Model: AVRISP
         Hardware Version: 15
         Firmware Version Master : 2.10
         Vtarget         : 0.0 V
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9801 (probably m2560)
avrdude: reading input file "/private/var/folders/f3/6ysp3l5j4zb5fz9r5zgjqgj400nmsy/T/arduino/sketches/11EBBBCDAE32B5881D6B4DDE9238999E/Blink.ino.hex"
avrdude: writing flash (1544 bytes):

Writing | ################################################## | 100% 0.29s

avrdude: 1544 bytes of flash written

avrdude done.  Thank you.

Just top of the mind, there are lock bits that protect the bootloader memory section from being written. Check your settings.

this bit will be automatically set while "Burn Bootloader" routine of IDE

1 Like

Usually the "can only upload once after burning bootloader" symptom is caused by your board's auto-reset circuit not working.

Normally you need to do a hardware reset of the microcontroller to activate the bootloader, then start an upload before the bootloader times out and starts the user application. However, after burning bootloader the bootloader is perpetually activated so no reset is necessary, meaning the first upload will work with or without a reset.

The auto reset circuit (for an example, see these "minimal setup" schematics) is the DTR pin of the USB-TTL serial chip connected to the reset pin of the microcontroller via a 0.1 uF capacitor. In combination with the pull-up resistor on that pin, it generates a reset pulse when the serial connection is opened.

To test this, you could see whether uploads work after a manual reset. The tricky thing is that when you press the "Upload" button in Arduino IDE, it first compiles your sketch before starting the actual upload. If you reset the microcontroller immediately after pushing the button, the bootloader will have timed out by the time the upload actually starts. The way to get the timing right is:

  1. If the board is in the "good" state where you can perform one successful upload following a "Burn Bootloader" operation, do an upload to the board to put it in the "bad" state.
  2. Select Sketch > Upload from the Arduino IDE menus to start an upload (or click the upload button or whatever you prefer).
  3. Watch the black "Output" panel at the bottom of the Arduino IDE window until you see something like this:
    Sketch uses 444 bytes (1%) of program storage space. Maximum is 30720 bytes.
    Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. 
    Maximum is 2048 bytes.
    
  4. Immediately press and release the reset button. The upload should now finish successfully.

This is quite strange. It might be that the ATmega2560's reset pin is floating (it should have a "pull-up" resistor to ensure it doesn't float to a LOW state and intermittently reset the board) and the connection between the reset pin and pin 10 on the Uno is keeping the pin's state HIGH.

Thank you for the detailed explanation. You are right about both issues!

It is quite tricky to get the timing of pressing the reset button right. But when I do get the timing right, it works. And it only works if I pull down the reset pin with a 100K resistor.

With the pull-down resistor on the reset pin, it also works when the Mega2560 is in the "good state" (first upload after the bootloader is burned) and disconnected from the programmer, which presumably held the reset pin high.

So, in summary, there are two issues with this board, not sure if they are related.

  1. The reset pin is floating.
  2. The hardware reset circuit is busted.

Issue 1 can be easily fixed by soldering a resistor in place.

Issue 2 is probably quite tricky to fix at the hardware level. But I'm thinking about increasing the timeout in the bootloader before loading the user code, so that I can have a decent chance at pressing the reset button manually.

Some quick search led me to this:
ArduinoCore-avr/bootloaders/stk500v2/stk500boot.c at master · arduino/ArduinoCore-avr · GitHub. Am I looking at the right place?

It'd still be annoying to press the reset button manually for every upload. But if I use a good board for developing and testing and only use this board for production, it isn't so bad.

Thanks.

You are welcome. I'm glad if I was able to be of assistance.

You might check the solder jumper here to see if it is cut:

📷

Arduino Mega 2560 Full Pinout by Arduino - CC BY-SA 4.0 (crop, mark solder jumper, add border)

image

📷

A000067_00.default_1000x750.jpg by Arduino - CC BY-SA 4.0 (crop, rotate, mark solder jumper, add border)

It must be shorted for the auto-reset circuit to work (though I wouldn't expect it to affect the pull-up on the reset pin).

Yes, that is the source code for the bootloader on the Mega 2560 board. There is also a dedicated repository:

I'm not sure whether there has been a divergence in the two code bases, and if so, which of the two is superior.

If you are going to the trouble of jumping into the project of messing with the source code and building from source, I think you will be better off to switch to using the Optiboot bootloader:

This is the bootloader used on the Arduino UNO R3 and other Arduino boards. Optiboot didn't support ATmega2560 at the time the Mega 2560 board was created, but it does now. This bootloader is supported in the excellent 3rd party MegaCore boards platform for the ATmega2560's family:

MegaCore is now using a recently created bootloader named "urboot". I haven't found the time to try out urboot, so I can't personally recommend it as I can Optiboot (which I have extensive experience using, even on ATmega2560), but I'm sure it is a very nice bootloader and worth a look if you are deciding which of the available bootloaders you want to dig into the innards of.

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