Skip to content

Commit

Permalink
Merge pull request #883 from mangelajo/esp8266-ArduinoOTA
Browse files Browse the repository at this point in the history
OTA support encapsulated to ArduinoOTA class
  • Loading branch information
igrr committed Oct 18, 2015
2 parents e5a5456 + a3beaa6 commit 2aa4bba
Show file tree
Hide file tree
Showing 6 changed files with 285 additions and 0 deletions.
113 changes: 113 additions & 0 deletions hardware/esp8266com/esp8266/libraries/ArduinoOTA/ArduinoOTA.cpp
@@ -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
@@ -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 */
@@ -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();
}
@@ -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
@@ -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)
#######################################

@@ -0,0 +1,9 @@
name=ArduinoOTA
version=1.0
author=Ivan Grokhotkov and Miguel Angel Ajo
maintainer=Ivan Grokhtkov <ivan@esp8266.com>
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

0 comments on commit 2aa4bba

Please sign in to comment.