OTA on the Mega +WiFi R3 ATmega2560+ESP8266 (32Mb memory)

TroelsDK:
@Juraj

I have another Board of same type at the post office, waiting to be picked up.

I can get it within the next days and try a fresh start if you think that could make a difference

Out of curiosity
Have you by any chance worked with a Board like this before?
Or are you helping blindfolded?

I have a Mega and I have an esp8266 module. I tested WiFiLink with ArduinoOTA on Mega with esp8266 on Serial3.
Right now I have it here, but with AT firmware in esp8266. I develop a new WiFiEsp library. It runs at 500000 baud.

Any progress on this. I am stuck with similar problems on Mega +WiFi R3 ATmega2560+ESP8266 (32Mb memory).

So when I upload this code using Arduino Mega 2560 (Optiboot):

#include <WiFiEspAT.h>
#include <ArduinoOTA.h>

#if !defined(ESP_CH_SPI) && !defined(HAVE_HWSERIAL3)
#endif

void setup() {

  Serial.begin(115200);
  while (!Serial);
  Serial.println("Program 2");
  // initialize Serial1 for communication with the WiFi module
  #if !defined(ESP_CH_SPI)
    Serial3.begin(115200); // speed must match with BAUDRATE_COMMUNICATION setting in firmware config.h
    WiFi.init(&Serial3);
  #endif
  
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println();
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  // waiting for connection to Wifi network with settings in the WiFi module
  Serial.println("Waiting for connection to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print('.');
  }
  Serial.println();
  Serial.println("Connected to WiFi network.");

  // start the WiFi OTA library with internal (flash) based storage
  ArduinoOTA.begin(WiFi.localIP(), "arduino", "password", InternalStorage);

  // you're connected now, so print out the status:
  printWifiStatus();
}

void loop() {
  // check for WiFi OTA updates
  ArduinoOTA.poll();

  // add your normal loop code below ...
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

It gives me this:

Using library WiFiEspAT at version 1.1.0 in folder: C:\Users\Sanket\Documents\Arduino\libraries\WiFiEspAT 
Using library ArduinoOTA-master at version 1.0.3 in folder: C:\Users\Sanket\Documents\Arduino\libraries\ArduinoOTA-master 
"C:\\Users\\Sanket\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino5/bin/avr-size" -A "C:\\Users\\Sanket\\AppData\\Local\\Temp\\arduino_build_9743/SerialWiFiOTA.ino.elf"
Sketch uses 16276 bytes (6%) of program storage space. Maximum is 261120 bytes.
Global variables use 1135 bytes (13%) of dynamic memory, leaving 7057 bytes for local variables. Maximum is 8192 bytes.
C:\Users\Sanket\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -CC:\Users\Sanket\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega2560 -carduino -PCOM8 -b115200 -D -Uflash:w:C:\Users\Sanket\AppData\Local\Temp\arduino_build_9743/SerialWiFiOTA.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 "C:\Users\Sanket\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf"

         Using Port                    : COM8
         Using Programmer              : arduino
         Overriding Baud Rate          : 115200
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x50
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x72
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x6f
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x67
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x72
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x61
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x6d
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x20
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x31
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x0d

avrdude done.  Thank you.

An error occurred while uploading the sketch

But I can upload the code with “Arduino Mega or Mega 2560” board. Please Help!

what progress? everything works.
you didn't burn the Optiboot bootloader, if you can upload as normal Mega

Hey Juraj.. Thanks for your reply..

Can you please guide me how to burn the Optiboot bootloader. I am new to this.

Thanks!

sanketpatel87:
Hey Juraj.. Thanks for your reply..

Can you please guide me how to burn the Optiboot bootloader. I am new to this.

Thanks!

setup the programmer hardware and selection in Tools menu as for any ATmega bootloader flashing.
if you don't have an AVR programmer, you can use a second Arduino https://www.arduino.cc/en/Tutorial/ArduinoISP

then, if you copied my_boards, which includes the modified Optiboot for ArduinoOTA, select the "Mega 2560 (Optiboot)" and use Burn bootloader command in Tools menu.

So I have burned the bootloader with another Arduino and upload to the device with the Arduino Mega 2560 (Optiboot) and COM port is successfully uploaded.

Now I want to upload it with network port which gives me following error

C:\Users\Sanket\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0/bin/arduinoOTA -address 192.168.1.104 -port 65280 -username arduino -password password -sketch C:\Users\Sanket\AppData\Local\Temp\arduino_build_343131/SerialWiFiOTA.ino.bin -upload /sketch -b 
Connecting to board ... failed!
Error flashing the sketch
Error flashing the sketch

If I change the port from 65280 to port 80 in platform.local.txt it connects and uploads to the board but gives me this error

C:\Users\Sanket\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0/bin/arduinoOTA -address 192.168.1.104 -port 80 -username arduino -password password -sketch C:\Users\Sanket\AppData\Local\Temp\arduino_build_749734/SerialWiFiOTA.ino.bin -upload /sketch -b 
Connecting to board ...  done
Uploading sketch ...  done
Flashing sketch ...  done
Error flashing the sketch:FileNotFound
Error flashing the sketch:FileNotFound

Please help!

don't change the port.
what firmware is in esp8266?
what networking library do you use for ArduinoOTA library example in Mega?
did you read this?

Juraj:
don't change the port.
Ok. Noted.

what firmware is in esp8266?
I have flashed with WifiLink firmware.

what networking library do you use for ArduinoOTA library example in Mega?
I have tried with both WiFiEspAT and WifiLink libraries

did you read this?
ArduinoOTA/README.md at master · jandrassy/ArduinoOTA · GitHub
Yes I have gone through this but it seems something is missing which i cannot figure out.

So I have an update. I first uploaded this code with Arduino Mega 2560 (Optiboot)

#include <WiFiLink.h>
#if !defined(ESP_CH_SPI) && !defined(HAVE_HWSERIAL3)
#endif


#include <ArduinoOTA.h>

char ssid[] = "LCC";     //  your network SSID (name)
char pass[] = "Laxmiconstco@44";  // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status
  
void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(115200);
  Serial.println("Hello 1");
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
 
  #if !defined(ESP_CH_SPI)
    Serial3.begin(115200); // speed must match with BAUDRATE_COMMUNICATION setting in firmware config.h
    WiFi.init(&Serial3);
  #endif
  
  if (WiFi.checkFirmwareVersion("1.1.0")) {
    WiFi.resetESP(); // to clear 'sockets' after sketch upload
    delay(500); // let firmware initialize
  }

  //Check if communication with the wifi module has been established
  if (WiFi.status() == WL_NO_WIFI_MODULE_COMM) {
    Serial.println("Communication with WiFi module not established.");
    while (true);// don't continue:
  }

  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.print("You're connected to the network");
  ArduinoOTA.begin(WiFi.localIP(), "Arduino", "password", InternalStorage);
}

void loop() {
  // check for WiFi OTA updates
  ArduinoOTA.poll();
}

Then I upload the same code with different debug Serial.println(“Hello 2”);
It uploads successfully

C:\Users\Sanket\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.3.0/bin/arduinoOTA -address 192.168.1.104 -port 65280 -username arduino -password password -sketch C:\Users\Sanket\AppData\Local\Temp\arduino_build_802417/ArduinoOTAMegaWifiShield.ino.bin -upload /sketch -b 
Connecting to board ...  done
Uploading sketch ...  done
Flashing sketch ...  done

Sketch uploaded successfully

But shows the same message “Hello 1” when connected back to COM port and viewed in Serial Monitor. It is not running the new Sketch.

Finally got it working! Thanks for your help.

I was using a different bootloader.

1 Like

sanketpatel87:
Finally got it working! Thanks for your help.

I was using a different bootloader.

so it was not easy, but doable :slight_smile:

Hey Juraj!

I have another problem to submit to you!

I want to update OTA both sketches on my ATmega2560+ESP8266 via urls.


I got the ESP side implemented with <ESP8266httpUpdate.h>


For the MEGA side, here is the scheme I followed:

  • Upload the Mega 2560 (optiboot) bootloader on the ATmega2560 (I confirmed that it was installed, as I can now only upload using this board configuration from Arduino IDE).

  • Compiled the sketch binary using Mega 2560 (optiboot) board profile.

  • Download the binary update from URL onto the SPIFFS of ESP.

  • Transfer data from ESP to MEGA using the serial connection.

  • Use the functions InternalStorage.open(), InternalStorage.write(), InternalStorage.close(), InternalStorage.apply() to write and apply the binary update.

Now, my problem is that the Mega does not apply the update correctly. I tried both HEX and BIN files, and got the following behavior: the RED LED above GREEN flashes continuously (error?), and the arduino has lost the initial sketch.

The Arduino does not work until I re-upload the sketch from Arduino IDE. I wonder if there is something wrong with the binary files I am uploading. There are 4 files in the build folder, 2 HEX (with/without bootloader) and 2 BIN (with/without bootloader).

Thanks in advance for the feedback!
Tony

In case you have time to take a look, the code is here:

https://github.com/8bit-Dude/8bit-Hub/tree/master/Firmware

In summary, the HTTP fetching to SPIFFS and transfer via serial is done by:

File httpFile; 

void httpGet() {
   // Check if http file handle still open?
   if (httpFile) httpFile.close();
 
   // Stream file to flash file system
   unsigned long httpSize;
   megaLen = readBuffer(megaBuffer);
   httpFile = SPIFFS.open("/http.tmp", "w");
   if (httpFile) {
       if (httpClient.begin(megaBuffer)) {
           if (httpClient.GET() == HTTP_CODE_OK) {
               httpClient.writeToStream(&httpFile);
           } else {
               reply(HUB_ESP_ERROR, "HTTP: url not found!");
               return;        
           }
           httpClient.end();
       } else {
           reply(HUB_ESP_ERROR, "HTTP: cannot connect!");
           return;
       }
       httpFile.close();
   } else {
       reply(HUB_ESP_ERROR, "HTTP: flash drive error!");
       return;
   }
   
   // Prepare file for reading
   httpFile = SPIFFS.open("/http.tmp", "r");
   httpSize = httpFile.size();

   // Send back file size        
   writeCMD(HUB_HTTP_GET);    
   Serial.write(4);    
   writeLong(httpSize);       
}

void httpRead() {
   // Stream required number of bytes
   megaLen = 0;
   if (httpFile) {
       // Read requested bytes, as long as there are any
       unsigned char requestLen = readChar();
       while (httpFile.available() && megaLen < requestLen) {
           megaBuffer[megaLen++] = httpFile.read();
       }
   }
   
   // Send it to mega        
   writeCMD(HUB_HTTP_READ);    
   writeBuffer(megaBuffer, megaLen);   
}

The update on MEGA is carried out with:

void readHttp() {
    // Store data to Packet/OTA update
    if (readBuffer()) {
            for (unsigned char i=0; i<espLen; i++)
                InternalStorage.write(espBuffer[i]);
            break;
        }
    }
}

void checkUpdate() {
.................
            // Fetch update file on ESP
            Serial.println("Downloading MEGA update...");
            writeCMD(HUB_HTTP_GET);
            writeBuffer(urlMega, strlen(urlMega));
            while (lastCMD != HUB_HTTP_GET)
                if (Serial3.find("CMD")) processCMD();

            // Check update size
            if (!httpSize) {
                Serial.print("Error: update not found.");
                return;
            }

            // Check there is enough storage for update
            if (!InternalStorage.open(httpSize)) {
                Serial.print("Error: not enough space to store the update.");
                return;
            }

            // Transfer update file to MEGA
            unsigned long recvSize = 0;
            while (1) {
                // Request next http packet
                writeCMD(HUB_HTTP_READ);
                writeChar(200);
                delay(10);
        
                // Wait to receive packet
                while (1) {
                    if (Serial3.find("CMD"))
                        processCMD();
                    if (lastCMD == HUB_HTTP_READ) 
                        break;
                }

                // Check if packet was empty
                if (espLen)
                    recvSize += espLen;
                else
                    break;
            }
            
            // Close the internal storage
            InternalStorage.close();
            Serial.print("Received: ");
            Serial.print(recvSize);
            Serial.print("/");
            Serial.print(httpSize);
            Serial.println(" bytes");

            // Apply update
            Serial.println("Updating MEGA firmware...");
            Serial.flush();
            InternalStorage.apply();
.................
}

P.S: The function processCMD invokes readHttp()

One more thing: printing to Serial the HEX values sent to InternalStorage(), they match what I read on my PC when reading the BIN file with an HEX editor...

InternalStorage expects bin file.

Juraj:
InternalStorage expects bin file.

With or without bootloader?
(I suspect without).

I will try tomorrow to load the bin file from a SD card, so i can figure out if InternalStorage actuallt works correctly on my board.

8bit-Dude:
With or without bootloader?
(I suspect without).

I will try tomorrow to load the bin file from a SD card, so i can figure out if InternalStorage actuallt works correctly on my board.

without bootloader. it is written from address 0 as continues data.
a valid bin with bootloader for Mega would have to be 256kB large. (suspicious 65536 bytes has the bin created by the builder)

I was able to update using a binary file stored on the SD card. In turn, this helped me figure out the problem with HTPP download: my code had a bug whereby 1 packet of 160 bytes was missing (towards the bottom of the file). Once I fixed the bug, everything worked fine!

Thanks to this really nifty library, I can now update both ESP and MEGA by OTA download from URL!

1 Like

I have one more question!

After updating the ESP, I want to reset the MEGA.

I googled "optiboot soft reset" and could not find any clear information...

I tried using:

            wdt_enable(WDTO_15MS);
            for(;;) {}

But that did not work out (the board just seem to freeze...)

Could you quickly tell me how I can tell Optiboot to reset the Sketch??

I found some information on this page:

I tried the following, but it still does not work… :frowning:

typedef void (*do_reboot_t)(void);
const do_reboot_t do_reboot = (do_reboot_t)((FLASHEND-511)>>1);

void reboot() {
    MCUSR=0; cli();
    noInterrupts();
    do_reboot();
}