Arduino MEGA2560 update sketch downloaded via WIFI-FTP to SD

Hi everyone,

I want to be able to update an Arduino Mega 2560 with a new sketch in two ways:

  1. inserting an SD card with the updated precompiled sketch.hex file, then loading the sketch to the Mega.

  2. Downloading the sketch from an FTP server to the SD card and than loading the sketch to the Mega.

The hardware Im using is the Arduino Mega an ESP8266 NodeMCU 1.0 version and an SD card.

The way Im connecting the hardware is connecting the SD card to the ESP8266 NodeMCU 1.0. and the ESP8266 NodeMCU 1.0. to the Arduino Mega2560 via SPI.

I want the ESP8266 NodeMCU 1.0. take care of downloading the sketch.hex via ftp to the SD, and then load it to the Arduino MEGA2560 via SPI

I found that Nick Gammon has written a sketch that does something very similar to this but using an Arduino UNO as a source instead of the ESP8266 NodeMCU. See it here:

The problems I have found for now are:

A) I don´t know if the Atmega_Hex_Uploader_Fixed_Filename file will run on the ESP8266 NodeMCU ? I have uploaded several sketches to the ESP8266 NodeMCU with the arduino IDE and worked perfectly. I think the ESP8266 NodeMCU has an Tensilica Xtensa LX106 core processor but don´t know if this is compatible with the Arduino UNO, but I suppose it is.

B) The Arduino Mega is 5v and the ESP8266 is 3v so SPI connections have to be level shifted. I have done this with a 10k an 20k resistor voltage divider. I think I have done this correctly?

C) The Atmega_Hex_Uploader_Fixed_Filename needs:

A "start programming" switch on D2, normally open, which is connected to Ground when closed. I changed this to pin D3.
A red "error" LED connected (via a 220 ohm resistor) to A0. I changed this to D0
A green "ready" LED connected (via a 220 ohm resistor) to A1. I changed this to D1
A yellow "working" LED connected (via a 220 ohm resistor) to A2. I changed this to D2

After these changes in the sketch I tried to compile but I get the following error:

"PORTD was not declared in this scope"

Need some help here, I don´t know why I get this error ???

"PORTD was not declared in this scope"

PORTD won't apply to the ESP8266 because it is a different processor.

You would need to adapt the way it does the setting of the pins to match what that processor supports, perhaps just using digitalWrite instead.

Hi again,

I have been reading the code threw slowly and think only the PORTH, PINH and PORTG have to be changed.

// for fast port access
#ifdef AVR_ATmega2560
// Atmega2560
#define BB_MISO_PORT PINH >>>Here I need to change PINH
#define BB_MOSI_PORT PORTH >>>Here I need to change PORTH
#define BB_SCK_PORT PORTG >>>Here I need to change PORTG
const byte BB_SCK_BIT = 5;
const byte BB_MISO_BIT = 3;
const byte BB_MOSI_BIT = 4;

The first one #define BB_MISO_PORT PINH I don´t understand what it is doing. I think PINH holds if PORTH is input or output, so I dont understand why this is put into BB_MISO_PORT. Anyhow I dont know the way to get the PINH value from each bit of the port to assign it to the BB_MISO_PORT bit by bit.

The second one #define BB_MOSI_PORT PORTH looks easier to me but still dont know how the syntax would be I suppose something like:
BB_MISO_PORT[0]=PH0
BB_MISO_PORT[1]=PH1
BB_MISO_PORT[2]=PH2
BB_MISO_PORT[3]=PH3
BB_MISO_PORT[4]=PH4
BB_MISO_PORT[5]=PH5
BB_MISO_PORT[6]=PH6
BB_MISO_PORT[7]=PH7
BB_MISO_PORT[8]=PH8

Or maybe something like
DigitalWrite(BB_MISO_PORT[0],PH0)
DigitalWrite(BB_MISO_PORT[1],PH1)
DigitalWrite(BB_MISO_PORT[2],PH2)
DigitalWrite(BB_MISO_PORT[3],PH3)
DigitalWrite(BB_MISO_PORT[4],PH4)
DigitalWrite(BB_MISO_PORT[5],PH5)
DigitalWrite(BB_MISO_PORT[6],PH6)
DigitalWrite(BB_MISO_PORT[7],PH7)
DigitalWrite(BB_MISO_PORT[8],PH8)

The third one #define BB_SCK_PORT PORTG I suppose is the same as the second one but with PORTG

Ive been looking threw the "PORT Registers" Reference page and the "Bit Math Tutorial" but cant find this out !!

Pleas help me :slight_smile:

Please explain what you want to do, not how you want to do it.

Eight digitalWrite() are overkill, to set all bits of a port. A single assignment of the byte value to the port will do that.
Single bits usually are manipulated by |=, &= and ^=, but that depends on the target controller architecture.

If you want to port some low-level code from Mega to ESP8266, you have to look up the ESP8266 declarations, and the port bits used there for SPI. The high-level digitalRead() and digitalWrite() functions should work on any controller, so that you can look up their implementation for the target controller. When you understand what's going on there, and how it's expressed in low-level code, you can start porting the code to that controller. Until then it may be easier to translate the well known instructions for Mega ports into digitalRead and digitalWrite, which are understood by the ESP8266 as well.

Hi DrDiettrich, Thanks for your answer.

I have an Arduino Mega2560 running a sketch controlling a machine. I need to update the sketch in two ways, connecting the Mega2560 to the internet so it can download an updated sketch.hex, or to insert an MicroSD card in the SD Card slot on the arduino2560 containing the updated sketch.hex

For connecting with the internet I want to use a ESP8266 module because it is cheap, powerfull and because I can program it using the Arduino IDE. So my problem is once having the updated sketch.hex file on the SD card (downloaded from the internet or inserted in the SD Slot by hand) I need to program the Arduino Mega with this updated Sketch.

Looking around I found that Nick Gammon has coded a sketch that uses two Arduino UNO and an SD card. What id does is with one of the Arduinos y programs the other (this can also be a Mega2560) with the Sketch.hex thats is on the SD card. This is exactly what I need to do, the difference is that I want to run his sketch on the ESP8266 instead of on the Arduino UNO, and so update my arduino Mega2560.

Nick Gammon´s code is here

The page where this project is explained is here

I tried to upload Nick´s code to the ESP8266 but stops when it reaches this line:

#define BB_SCK_PORT PORTD

the error I get is "PORTD is not defined in this scope"

From what Nick said:

"PORTD won't apply to the ESP8266 because it is a different processor.

You would need to adapt the way it does the setting of the pins to match what that processor supports, perhaps just using digitalWrite instead."

maybe I could change this line using digitalWrite but I don´t know how to do this.

So its not really on the Mega but on the ESP8266 where the code from the UNO does not run. The ESP8266 is a processor from Espressif

Please Help :confused:

If you cannot help yourself, hire somebody familiar with both controllers. Such low level code doesn't translate easily.

I'm not familiar with low-level code on the ESP8266 myself, so I can't offer a solution easily. There must be some way of doing SPI with it, which is all that you have to solve.