Alternative to built-in OTA library please?

Hi All,

Not exactly a newbie but definitely no expert. I want to try out Arduino OTA programming but even the basic example doesn't work.

The problem seems to be that although the code partially runs for the first time after an IDE upload, it does not run properly after that. The WiFi connects and I can ping the board but the contents of loop() does not execute. If I disconnect the USB and power the board from a powersupply then it is worse, the WiFi doesn't even connect and I cannot ping it any more.

It doesn't matter whether the serial monitor is enabled or not. Behaviour is the same either way.

It seems to get stuck in setup(). So I assume that library calls to 'OTAUpdate.h' are not completing and I would like to try an alternative. Especially since the bundled version of 'OTAUpdate.h' makes silly space invaders images appear on the LED matrix which I could do without. Maybe it's that graphics loop that is hanging the process? In any case I want to use the LED matrix for my own display.

Is there an alternative OTA library header file that I could use for the R4 WiFi? I've lloked but the others all seem specific to other hardware.

Thanks in advance,

Moo

Using IDE 2.3.2
BN: Ardiono UNO R4 WiFi
VID: 0x2341
PID: 0x1002
SN: F412FA70A064
Windows 11 Desktop

(I can't get Arduino cloud to do anything useful!)

/*
  OTA

  This sketch demonstrates how to make an OTA Update on the UNO R4 WiFi.
  Upload the sketch and wait for the invasion!

*/


#include "WiFiS3.h"
#include "OTAUpdate.h"
#include "root_ca.h"
#include "arduino_secrets.h"

char ssid[] = SECRET_SSID;    // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)

int status = WL_IDLE_STATUS;

OTAUpdate ota;
static char const OTA_FILE_LOCATION[] = "https://downloads.arduino.cc/ota/UNOR4WIFI_Animation.ota";

/* -------------------------------------------------------------------------- */
void setup() {
/* -------------------------------------------------------------------------- */
  //Initialize serial and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the Wi-Fi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with Wi-Fi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to Wi-Fi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 1 seconds for connection:
    delay(1000);
  }

  printWiFiStatus();

  int ret = ota.begin("/update.bin");
  if(ret != OTAUpdate::OTA_ERROR_NONE) {
    Serial.println("ota.begin() error: ");
    Serial.println((int)ret);
    return;
  }
  ret = ota.setCACert(root_ca);
  if(ret != OTAUpdate::OTA_ERROR_NONE) {
    Serial.println("ota.setCACert() error: ");
    Serial.println((int)ret);
    return;
  }
  int ota_size = ota.download(OTA_FILE_LOCATION, "/update.bin");
  if(ota_size <= 0) {
    Serial.println("ota.download() error: ");
    Serial.println(ota_size);
    return;
  }
  ret = ota.verify();
  if(ret != OTAUpdate::OTA_ERROR_NONE) {
    Serial.println("ota.verify() error: ");
    Serial.println((int)ret);
    return;
  }

  ret = ota.update("/update.bin");
  if(ret != OTAUpdate::OTA_ERROR_NONE) {
    Serial.println("ota.update() error: ");
    Serial.println((int)ret);
    return;
  }
}

/* -------------------------------------------------------------------------- */
void loop() {
/* -------------------------------------------------------------------------- */


//   delay(1000);
}

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

  // print your board'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");
}

my ArduinoOTA library

1 Like

why not modify the existing one to suite your wants?

Well you know I said I wasn't a newbie...

I actually can't find 'OTAUpdate.h' I've done a complete search of my desktop PC and also Googled for it and no results!! Modifying it or at least looking at it to try to understand it and fix the problem is all I have been doing this week.

It appears to be bundled with the arduino IDE but I can't find it so I can't do anything with it.

Yes this is definitely the next step. I'll see how I get on.

Any idea what could be going on with the IDE built in library? Is it why you went to the huge effort of writing a new one?

Many thanks.

Hi @moomelon

Try this:

  1. Open a sketch that contains an #include directive for OTAUpdate.h in Arduino IDE.
  2. Select File > Preferences... (or Arduino IDE > Settings... for macOS users) from the Arduino IDE menus.
    The "Preferences" dialog will open.
  3. Check the box next to "Show verbose output during: > ☐ compile" in the "Preferences" dialog.
  4. Click the "OK" button.
    The "Preferences" dialog will close.
  5. Select Sketch > Verify/Compile from the Arduino IDE menus.
  6. Wait for the compilation to finish.

Now examine the contents of the black "Output" panel at the bottom of the Arduino IDE window. There you will see a line that looks something like this:

Using library OTAUpdate at version 0.0.1 in folder: C:\Users\per\AppData\Local\Arduino15\packages\arduino\hardware\renesas_uno\1.2.1\libraries\OTAUpdate 

The library is located at that path.

The library is located under a folder that is typically hidden by the operating system so this is probably why you didn't find it in the search.

2 Likes

Ok, I got OTA working with an Arduino R4 but it wasn't easy!

I'm posting here the steps I took so that others may find it useful. If there is anything inaccurate in my post then please let me know as I don't want to make it worse!

The way I did it involved using ArduinoOTA libray from Juraj here: ArduinoOTA

Firstly the examples given use a WiFi library which I couldn't get working so I changed from #include 'WiFiNINA.h' to #include 'WiFiS3.h'. I only had to change one line in the sketch to get that one working: if (WiFi.status() == WL_NO_SHIELD) becomes if (WiFi.status() == WL_NO_MODULE).

The README.md files contain a lot of good information but there is no working example for OTA using Arduino R4 only for some other boards. When I first got into it I could not establish a network connection from the IDE. This is a known issue and Juraj gives a workaround and says it's the best way to go anyway.

What you are doing is making a 'fake' programmer inside the IDE that points at the network address for your Arduino once it has connected to the WiFi.

The key steps are: 'Copy platform.local.txt next to platform.txt in the hardware package of your board'. On my PC for the R4 it is "C:\Users\paul\AppData\Local\Arduino15\packages\arduino\hardware\renesas_uno\1.2.1". You have to copy 'platform.local.txt' from the ArduinoOTA library download.

You also have to edit programmers text to add the section in the readme given below. You'll have to edit the name and IP address to suit your own device.

arduinoOTA104.name=Arduino OTA (192.168.1.104)
arduinoOTA104.program.tool=arduinoOTA
arduinoOTA104.program.tool.default=arduinoOTA
arduinoOTA104.ip=192.168.1.104

But I still couldnt get an upload working and that turned out to be because the changes you made to programmers.txt are only read once the first time the IDE attempts to find a board. To make it accept the changes you made you have to make the IDE reset by deleting a folder as described here and restarting the IDE: Changes to programmers.txt are not recognized #591

My example code is here. It includes a bit of Blink.ino so you can prove it works for you.:

/*

 This example connects to an WPA encrypted WiFi network.
 Then it prints the  MAC address of the Wifi shield,
 the IP address obtained, and other network details.
 It then polls for sketch updates over WiFi, sketches
 can be updated by selecting a network port from within
 the Arduino IDE: Tools -> Port -> Network Ports ...

 Circuit:
 * WiFi shield attached

 created 13 July 2010
 by dlf (Metodo2 srl)
 modified 31 May 2012
 by Tom Igoe
 modified 16 January 2017
 by Sandeep Mistry
 modified again 16 September 2024 
 by moomelon
 */
 

#include <SPI.h>
// #include <WiFiNINA.h>  // PT
#include "WiFiS3.h"
#include <ArduinoOTA.h>

#include "arduino_secrets.h" 
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
/////// Wifi Settings ///////
char ssid[] = SECRET_SSID;      // your network SSID (name)
char pass[] = SECRET_PASS;   // your network password

int status = WL_IDLE_STATUS;

void setup() {

  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

  //Initialize serial:
  Serial.begin(115200);

    while (!Serial) {

    ; // wait for serial port to connect. Needed for native USB port only

  }

  // check for the presence of the shield:

  // if (WiFi.status() == WL_NO_SHIELD) {                              // Use this for WiFiNINA.h
  //  Serial.println("WiFi shield not present");                      // Use this for WiFiNINA.h

  if (WiFi.status() == WL_NO_MODULE) {                                // Use this for WiFiS3.h
    Serial.println("Communication with WiFi module failed!");         // Use this for WiFiS3.h
    // don't continue:
    while (true);
  }

  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 5 seconds for connection:
    delay(5000);
  }

  // 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 ...

  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay(200);                      // wait for a bit
  digitalWrite(LED_BUILTIN, LOW);   // turn the LED off by making the voltage LOW
  delay(200);                      // wait for a bit



}

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");
}

1 Like