Can I use OTA along with FreeRTOS tasks on ESP32. I ask this because in the following example OTA seems to be enabled if FreeRTOS is disabled. Can for example upload firmware that runs on both cores over OTA? Example taken from OTA template project by Andrea's Speiss
2 Answers
You can't not use FreeRTOS. The whole ESP-IDF is based around it. The Arduino setup()
and loop()
run in their own FreeRTOS thread.
If you "turn off" FreeRTOS then nothing will work.
Whatever that "template" is from it's of no use to you.
I was also believing that it is not possible but I handle it thanks to this post below;
https://github.com/SensorsIot/ESP32-OTA/issues/8
I applied what ever shared and it works like a charm together both FreeRTOS and OTA features.
As summary you need to create 2 custom header which includes your wifi credentials and OTA function. The remaining is same mostly.
credentials.h
#pragma once
const char* mySSID = "SSID of your AP";
const char* myPASSWORD = "Password of your AP";
OTA.h
#ifdef ESP32
#include <WiFi.h>
#include <ESPmDNS.h>
#else
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#endif
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#if defined(ESP32_RTOS) && defined(ESP32)
void ota_handle( void * parameter ) {
for (;;) {
ArduinoOTA.handle();
delay(3500);
}
}
#endif
void setupOTA(const char* nameprefix, const char* ssid, const char* password) {
// Configure the hostname
uint16_t maxlen = strlen(nameprefix) + 7;
char *fullhostname = new char[maxlen];
uint8_t mac[6];
WiFi.macAddress(mac);
snprintf(fullhostname, maxlen, "%s-%02x%02x%02x", nameprefix, mac[3], mac[4], mac[5]);
ArduinoOTA.setHostname(fullhostname);
delete[] fullhostname;
// Configure and start the WiFi station
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
// Wait for connection
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Connection Failed! Rebooting...");
delay(5000);
ESP.restart();
}
// Port defaults to 3232
// ArduinoOTA.setPort(3232);
// No authentication by default
// ArduinoOTA.setPassword("admin");
// Password can be set with it's md5 value as well
// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
ArduinoOTA.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH)
type = "sketch";
else // U_SPIFFS
type = "filesystem";
// NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
Serial.println("Start updating " + type);
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("\nAuth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("\nBegin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("\nConnect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("\nReceive Failed");
else if (error == OTA_END_ERROR) Serial.println("\nEnd Failed");
});
ArduinoOTA.begin();
Serial.println("OTA Initialized");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
#if defined(ESP32_RTOS) && defined(ESP32)
xTaskCreate(
ota_handle, /* Task function. */
"OTA_HANDLE", /* String with name of task. */
10000, /* Stack size in bytes. */
NULL, /* Parameter passed as input of the task */
1, /* Priority of the task. */
NULL); /* Task handle. */
#endif
}
OTA Template sketch.ino
#define ESP32_RTOS // Uncomment this line if you want to use the code with freertos only on the ESP32
// Has to be done before including "OTA.h"
#include "OTA.h"
#include "credentials.h"
void setup() {
Serial.begin(115200);
Serial.println("Booting");
setupOTA("TemplateSketch", mySSID, myPASSWORD);
// Your setup code
/* Example
pinMode(2, OUTPUT);
*/
}
void loop() {
#ifdef defined(ESP32_RTOS) && defined(ESP32)
#else
ArduinoOTA.handle();
#endif
// Your code here
/* Example
digitalWrite(2, HIGH);
delay(500);
digitalWrite(2, LOW);
delay(1000);
*/
}