Skip to content

OTA support encapsulated to ArduinoOTA class #883

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 18, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions hardware/esp8266com/esp8266/libraries/ArduinoOTA/ArduinoOTA.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include "ArduinoOTA.h"

ArduinoOTA::ArduinoOTA(const char *mdns_host_prefix, int port, bool serial_debug)
{
_port = port;
_mdns_host = new String(mdns_host_prefix);
*_mdns_host += String(ESP.getChipId(), HEX);
_udp_ota = new WiFiUDP();
_serial_debug = serial_debug;

_start_callback = NULL;
_end_callback = NULL;
_progress_callback = NULL;
_error_callback = NULL;
}

void ArduinoOTA::onStart(OTA_CALLBACK(fn)){
_start_callback = fn;
}

void ArduinoOTA::onEnd(OTA_CALLBACK(fn)){
_end_callback = fn;
}

void ArduinoOTA::onProgress(OTA_CALLBACK_PROGRESS(fn)){
_progress_callback = fn;
}

void ArduinoOTA::onError(OTA_CALLBACK(fn)){
_error_callback = fn;
}

ArduinoOTA::~ArduinoOTA(){
delete _udp_ota;
delete _mdns_host;
}

void ArduinoOTA::setup() {
_udp_ota->begin(_port);
if (_mdns_host) {
if (_serial_debug)
Serial.printf("OTA server at: %s:%u\n",
_mdns_host->c_str(),
_port);
MDNS.begin(_mdns_host->c_str());
MDNS.addService("arduino", "tcp", _port);
}
}

void ArduinoOTA::handle() {

if (!_udp_ota->parsePacket()) return;

IPAddress remote = _udp_ota->remoteIP();
int cmd = _udp_ota->parseInt();
int port = _udp_ota->parseInt();
int size = _udp_ota->parseInt();

if (_serial_debug){
Serial.print("Update Start: ip:");
Serial.print(remote);
Serial.printf(", port:%d, size:%d\n", port, size);
}

WiFiUDP::stopAll();

if(!Update.begin(size)){
if (_serial_debug)
Serial.println("Update Begin Error");
if (_error_callback) _error_callback();
_udp_ota->begin(_port);
return;
}
if (_start_callback) _start_callback();
if (_progress_callback) _progress_callback(0, size);

WiFiClient client;
if (!client.connect(remote, port)) {
if (_serial_debug)
Serial.printf("Connect Failed\n");
_udp_ota->begin(_port);
if (_error_callback) _error_callback();
}

uint32_t written;
while(!Update.isFinished() && client.connected()){
// TODO(mangelajo): enhance the Update.write(client) to
// accept a progress callback
written = Update.write(client);
if(written > 0) client.print(written, DEC);
if(_progress_callback) _progress_callback(written, size);
}

Serial.setDebugOutput(false);

if(Update.end()){
client.println("OK");
if (_serial_debug)
Serial.printf("Update Success\nRebooting...\n");
if(_end_callback) _end_callback();
ESP.restart();
} else {
// Update failed: listen UDP again, callback and print
_udp_ota->begin(_port);
if (_error_callback) _error_callback();
Update.printError(client);
if (_serial_debug)
Update.printError(Serial);
}
}
35 changes: 35 additions & 0 deletions hardware/esp8266com/esp8266/libraries/ArduinoOTA/ArduinoOTA.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef __ARDUINO_OTA_H
#define __ARDUINO_OTA_H

class WiFiUDP;

#define OTA_CALLBACK(callback) void (*callback)()
#define OTA_CALLBACK_PROGRESS(callback) void (*callback)(unsigned int, unsigned int)

class ArduinoOTA
{
int _port;
String* _mdns_host;
WiFiUDP* _udp_ota;
bool _serial_debug;

OTA_CALLBACK(_start_callback);
OTA_CALLBACK(_end_callback);
OTA_CALLBACK(_error_callback);

OTA_CALLBACK_PROGRESS(_progress_callback);

public:
ArduinoOTA(const char *mdns_host="ESP8266-OTA-",
int port=8266,
bool serial_debug=true);
~ArduinoOTA();
void setup();
void handle();
void onStart(OTA_CALLBACK(fn));
void onEnd(OTA_CALLBACK(fn));
void onProgress(OTA_CALLBACK_PROGRESS(fn));
void onError(OTA_CALLBACK (fn));
};

#endif /* __ARDUINO_OTA_H */
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

const char* ssid = "...";
const char* password = "...";

ArduinoOTA ota_server;

void setup() {
Serial.begin(115200);

Serial.println("Booting");
WiFi.mode(WIFI_STA);

/* try the flash stored password first */
WiFi.begin();

while (WiFi.waitForConnectResult() != WL_CONNECTED){
WiFi.begin(ssid, password);
Serial.println("Retrying connection...");
}
ota_server.setup();
Serial.println("Ready");
}

void loop() {
ota_server.handle();
yield();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

const char* ssid = "...";
const char* password = "...";
const char* host_prefix = "OTA-LEDS-";

ArduinoOTA ota_server(host_prefix, 8266, /* debug_serial= */ true);

int led_pin = 13;
#define N_DIMMERS 3
int dimmer_pin[] = {14, 5, 15};

void setup() {
Serial.begin(115200);

/* switch on led */
pinMode(led_pin, OUTPUT);
digitalWrite(led_pin, LOW);

Serial.println("Booting");
WiFi.mode(WIFI_STA);

/* try the flash stored password first */
WiFi.begin();

while (WiFi.waitForConnectResult() != WL_CONNECTED){
WiFi.begin(ssid, password);
Serial.println("Retrying connection...");
}
/* switch off led */
digitalWrite(led_pin, HIGH);

/* setup the OTA server */
ota_server.setup();
Serial.println("Ready");

/* configure dimmers, and OTA server events */
analogWriteRange(1000);
analogWrite(led_pin,990);

for (int i=0; i<N_DIMMERS; i++)
{
pinMode(dimmer_pin[i], OUTPUT);
analogWrite(dimmer_pin[i],50);
}

ota_server.onStart([]() { // switch off all the PWMs during upgrade
for(int i=0; i<N_DIMMERS;i++)
analogWrite(dimmer_pin[i], 0);
analogWrite(led_pin,0);
});

ota_server.onEnd([]() { // do a fancy thing with our board led at end
for (int i=0;i<30;i++)
{
analogWrite(led_pin,(i*100) % 1001);
delay(50);
}
});

ota_server.onError([]() { ESP.restart(); });

}

void loop() {
ota_server.handle();
yield();
}
26 changes: 26 additions & 0 deletions hardware/esp8266com/esp8266/libraries/ArduinoOTA/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#######################################
# Syntax Coloring Map For Ultrasound
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

ArduinoOTA KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

begin KEYWORD2
setup KEYWORD2
handle KEYWORD2
onStart KEYWORD2
onEnd KEYWORD2
onError KEYWORD2
onProgress KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=ArduinoOTA
version=1.0
author=Ivan Grokhotkov and Miguel Angel Ajo
maintainer=Ivan Grokhtkov <[email protected]>
sentence=Enables Over The Air upgrades, via wifi and espota.py UDP request/TCP download.
paragraph=With this library you can enable your sketch to be upgraded over network. Includes mdns anounces to get discovered by the arduino IDE.
category=Communication
url=
architectures=esp8266