Use SD card to automatically flash a sketch to a MEGA2560

Hello everyone,

so far I have read about the possibility to use an SD card for transfering a sketch to an Arduino board. One was the use of avr_boot. However, there seem to be some issues refering to the MEGA2560. It would be
convenient to have the option to transfer a sketch in the following way:
You put in a SD card into a SD shield
the MCU recognizes that a SD card is inserted
a sketch with a fixed name is searched
if it is found a digital output is set to 1, a LED turns on and the bootloader starts to transfer it to the storage of the MCU
after transfer is completed the digital output is set to 0 again and LED turns off
the MCU is reset and starts again with the new sketch.

Are there any existing solutions regarding the MEGA2560?

Nick Gammon's Atmega chip stand-alone programmer to upload .hex files.

I believe that the forum member Crossroads sells a version.
and here it is

If this programmer could be modified such that it could be plugged on the MEGA2560 as a shield it would be great.

You could definitely make a custom shield by soldering the necessary components onto a Mega prototyping shield:


You would want to use one of the small form Arduinos such as the Nano so that it could be soldered onto the shield.

Hmmm, an ESP8266 version might be do-able, for the whim :slight_smile: $3 board with 3M flash, I once did a sketch to reflash Nextion displays via wi-fi. Back later....

Considering a Nano as programmer. Would it be possible to change the connections from Nano to SD card and Nano to MEGA2560 as to directly connect the ICSP headers of Nano and MEGA2560? The Nano could be directly plugged upside down on top of the MEGA2560. Then the Nano would be connected with the SD card.

The hardware SPI pins on the programmer board are connected to the SD module. The target boards is connected to pins 4-7 and is programmed over software SPI. So you would need to make some changes to the sketch to swap the two and I have no idea how difficult/feasible that is.

You wouldn't connect the Nano upside down because that would cause the ICSP header pins to be mismatched. Instead you would solder a female ICSP header to the bottom of the Nano.

Hello Nick Gammon,

I tried your sketch for a programmer uploading a single hex file. Instead of using a UNO I took a Nano because of limited space. Now I get the error of 5x blinking red led which means that the signature of the chip cannot be read. In the case of the UNO I have no error. Both Uno and Nano are using the ATMEGA328. What could be the reason that the Nano is not recognized?

When I tried to find out the signature of the target MEGA2560 which should be flashed and chose the tool
to get the board info it showed "BN: unknown board". Is BN the chip signature? Do I need to get another MEGA2560 from Arduino to get it running?

Finally I could solve the issue and found a faulty SD card as reason for the error shown by 5x blinking of the red LED. So if one observes the same error it does not need to be the unidentifiable signature of the target chip of the MCU. The green LED is continually on and flashing could be started by grounding D2.
Now, I am not sure if flashing by using USB and Arduino IDE is still possible after the MCU was once flashed via SD card. Could someone till me if this is still possible?

If you do Sketch > Export Compiled Binary you will find two .hex files in the sketch folder. One filename has "with_bootloader". If you upload that file I believe you will still be able to do USB uploads.

Hello pert,

I have done it the way you recommended. The flashing was successful. I can see the parameters of the flashed sketch in the serial monitor at set baud rate of 9600. However, if I try to program the Mega target chip via USB port and Arduino IDE I get the following message from the compiler:
avrdude: Version 6.3, compiled on Jan 17 2017 at 12:00:53
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch

System wide configuration file is "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"

Using Port : COM5
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
An error occurred while uploading
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer

avrdude done. Thank you.

What could be the reason for the timeout?
The baudrate or the wiring as programmer maybe?

I don't have any experience using this Nick Gammon sketch or the with_bootloader .hex files. My suspicion is that you need to set the fuses for the appropriate boot section size and also to enable BOOTRST. So make sure the sketch is using the fuse settings as defined in the boards.txt entry for the Mega 2560:

and see if that solves the issue.

In the sketch I upload a software reset is included which is executed after new parameters for an automatic mode have been stored in the EEPROM. So after reset the MCU will get those parameters and continue with the auto mode. Now, if I flash via SD card and after parameters have been changed the MEGA stopps and nothing happens anymore. Is this because BOOTRST is inactive? If so I cannot find the sequence for acivating BootRST in the sketch from Nick Gammon.

BOOTRST is enabled or disabled by bit 0 of the high fuse. If you set that fuse to 0xD8, as in boards.txt, then it will be enabled.

First of all. Thank you very much for your answers.

The only sequence in Gammons sketch which considers the highfuse is

// programming commands to send via SPI to the chip
enum {
    progamEnable = 0xAC,
    
      // writes are preceded by progamEnable
      chipErase = 0x80,
      writeLockByte = 0xE0,
      writeLowFuseByte = 0xA0,
      writeHighFuseByte = 0xA8,
      writeExtendedFuseByte = 0xA4,
    
    pollReady = 0xF0,
    
    programAcknowledge = 0x53,
    
    readSignatureByte = 0x30,
    readCalibrationByte = 0x38,
    
    readLowFuseByte = 0x50,       readLowFuseByteArg2 = 0x00,
    readExtendedFuseByte = 0x50,  readExtendedFuseByteArg2 = 0x08,
    readHighFuseByte = 0x58,      readHighFuseByteArg2 = 0x08,  
    readLockByte = 0x58,          readLockByteArg2 = 0x00,  
    
    readProgramMemory = 0x20,  
    writeProgramMemory = 0x4C,
    loadExtendedAddressByte = 0x4D,
    loadProgramMemory = 0x40,
    
};  // end of enum

I am not sure now. Is it writeHighFuseByte = 0xA8 which should be 0xD8 instead? Or
do I need to simply copy mega.menu.cpu.atmega2560.bootloader.high_fuses=0xD8
anywhere into the sketch?

You don't modify the code of the sketch, there is a menu in the Serial Monitor that allows you to configure the fuses. See the "Updated user interface" section of:

Hello Pert,
the sketch you refer to is Atmega_Board_Programmer. I was dealing with Atmega_Hex_Uploader_Fixed_Filename. Thats why I was confused. I uploaded the programmer sketch to the UNO to be able to set the fuse at the MEGA target chip. The wiring is exactly the same as shown by Nick Gammon. The serial monitor shows up the following:

Atmega chip programmer.
Written by Nick Gammon.
Version 1.37
Compiled on Aug 15 2017 at 08:35:27 with Arduino IDE 10802.
Attempting to enter ICSP programming mode ......................................................
Failed to enter programming mode. Double-check wiring!
Type 'C' when ready to continue with another chip ...

The SD card seems to work properly with the programmer board as I could successfully flash the MEGA2560 as target with Atmega_Hex_Uploader_Fixed_Filename.

I tried a UNO as target as well and I have the same message. :confused:

Is there a possibility to set the Reset pin to LOW?
Like digitalwrite(pin,LOW);
When I pull the reset pin to LOW with a wire and release it again the auto mode starts correct again. However, I want to switch from manual to auto with remote control. So it would be nice not to go to the control unit and to press the reset button.
What I used for Software reset is the following which does not work if the sketch was flashed with SD card:

void softwareReset( uint8_t prescaller) {
  // start watchdog with the provided prescaller
  wdt_enable( prescaller);
  // wait for the prescaller time to expire
  // without sending the reset signal by using
  // the wdt_reset() method
  while (1) {}
}

and the function is conditionally called here

  if ((setpointer == 2) && (message != "")) //Transmit message and reset MCU
  {
    HC12Serial.print(message);
    delay(100);
    Serial.println(message);
    softwareReset( WDTO_60MS);
  }

I have seen the following possibility to reset by software:

void(* resetFunc) (void) = 0; //declare reset function @ address 0

and then call it in the if condition loop with
resetFunc();

maybe this works?!