Skip to content

Commit

Permalink
Added OTA update
Browse files Browse the repository at this point in the history
Both via web interface at settings and via Arduino IDE when connected to the same nentwork
  • Loading branch information
Spacehuhn committed Oct 18, 2019
1 parent e7f7632 commit a13739e
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 16 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Also available: <a href="https://www.tindie.com/products/Spacehuhn/spacehuhn-sti
- [Usage](#usage)
- [CLI](#cli)
- [Ducky Script](#ducky-script)
- [Debug](#debug)
- [FAQ](#faq)
- [Development](#development)
- [Edit Web Files](#edit-web-files)
Expand Down Expand Up @@ -285,6 +286,20 @@ ENTER
STRING Hello World!
```

### Debug

To properly debug, you need to have both the Atmega32u4
and the ESP82xx connected via USB to your computer.

That can be tricky when you only have a all in one board, so it might be useful
you built one yourself. You don't need to solder it, for example you can use an
Arduino Leonardo and a NodeMCU and connect them with jumper cables.

Now open 2 instances of Arduino (so they run as separate processes!),
select the COM port and open the serial monitor for each device.
You might need to reset the Atmega32u4 to see serial output.
If that causes problems with the i2c connection, try to reset the ESP82xx too.

### FAQ

If you have a question, you can check out the [issue section](../../issues).
Expand Down
3 changes: 2 additions & 1 deletion esp_duck/esp_duck.ino
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ void setup() {

webserver::begin();

debugln("\nESP Duck Started");
debugln("\nESP Duck Started!");
}

void loop() {
i2c::update();
webserver::update();

if (Serial.available()) {
String input = Serial.readStringUntil('\n');
Expand Down
20 changes: 10 additions & 10 deletions esp_duck/webfiles.h

Large diffs are not rendered by default.

81 changes: 77 additions & 4 deletions esp_duck/webserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
#include "webserver.h"

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>


#include "config.h"
#include "debug.h"
#include "cli.h"
Expand All @@ -29,16 +32,19 @@ void reply(AsyncWebServerRequest* request, int code, const char* type, const uin

namespace webserver {
// ===== PRIVATE ===== //
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");
AsyncEventSource events("/events");

const char* host_name = "wifiduck";

AsyncWebSocketClient* currentClient { nullptr };

bool reboot = false;

void wsEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len) {
if (type == WS_EVT_CONNECT) {
debugf("WS Client connected %u\n", client->id());

// client->printf("%u", client->id());
}

else if (type == WS_EVT_DISCONNECT) {
Expand Down Expand Up @@ -83,6 +89,8 @@ namespace webserver {
// ===== PUBLIC ===== //
void begin() {
// Access Point
WiFi.hostname(host_name);
// WiFi.mode(WIFI_AP_STA);
WiFi.softAP(settings::getSSID(), settings::getPassword(), settings::getChannelNum());
debugf("Started Access Point \"%s\":\"%s\"\n", settings::getSSID(), settings::getPassword());

Expand All @@ -97,6 +105,66 @@ namespace webserver {

WEBSERVER_CALLBACK;

// Arduino OTA Update
ArduinoOTA.onStart([]() {
events.send("Update Start", "ota");
});
ArduinoOTA.onEnd([]() {
events.send("Update End", "ota");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
char p[32];
sprintf(p, "Progress: %u%%\n", (progress/(total/100)));
events.send(p, "ota");
});
ArduinoOTA.onError([](ota_error_t error) {
if (error == OTA_AUTH_ERROR) events.send("Auth Failed", "ota");
else if (error == OTA_BEGIN_ERROR) events.send("Begin Failed", "ota");
else if (error == OTA_CONNECT_ERROR) events.send("Connect Failed", "ota");
else if (error == OTA_RECEIVE_ERROR) events.send("Recieve Failed", "ota");
else if (error == OTA_END_ERROR) events.send("End Failed", "ota");
});
ArduinoOTA.setHostname(host_name);
ArduinoOTA.begin();

events.onConnect([](AsyncEventSourceClient* client) {
client->send("hello!", NULL, millis(), 1000);
});
server.addHandler(&events);

// Web OTA
server.on("/update", HTTP_POST, [](AsyncWebServerRequest* request) {
reboot = !Update.hasError();

AsyncWebServerResponse* response;
response = request->beginResponse(200, "text/plain", reboot ? "OK" : "FAIL");
response->addHeader("Connection", "close");

request->send(response);
}, [](AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final) {
if (!index) {
Serial.printf("Update Start: %s\n", filename.c_str());
Update.runAsync(true);
if (!Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000)) {
Update.printError(Serial);
}
}
if (!Update.hasError()) {
if (Update.write(data, len) != len) {
Update.printError(Serial);
}
}
if (final) {
if (Update.end(true)) {
Serial.printf("Update Success: %uB\n", index+len);
} else {
Update.printError(Serial);
}
}
});

MDNS.addService("http", "tcp", 80);

// Websocket
ws.onEvent(wsEvent);
server.addHandler(&ws);
Expand All @@ -106,6 +174,11 @@ namespace webserver {
debugln("Started Webserver");
}

void update() {
ArduinoOTA.handle();
if (reboot) ESP.restart();
}

void send(const char* str) {
if (currentClient) currentClient->text(str);
}
Expand Down
1 change: 1 addition & 0 deletions esp_duck/webserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@

namespace webserver {
void begin();
void update();
void send(const char* str);
}
Binary file added img/ota.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions web/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ <h2>WiFi</h2>

<p>Restart the device to apply new settings.</p>

<h2>Update</h2>

<p>
Go to <a href="https://github.com/spacehuhn/WiFiDuck/releases" target="_blank">wifiduck.com/releases</a>
to check for updates.<br>
Select a .bin file and press upload to flash the device.<br>
</p>

<form method='POST' action='/update' enctype='multipart/form-data'>
<input type='file' name='update'>
<input type='submit' class="warn" value='Upload'>
</form>

<footer>
<a href="settings.html">Settings</a> |
<a href="terminal.html">Terminal</a> |
Expand Down
2 changes: 1 addition & 1 deletion web/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ input[type="text"] {
}

input[type="file"] {
display: none;
padding: 1em 0;
}

/* ==== GRID SYSTEM ==== */
Expand Down

0 comments on commit a13739e

Please sign in to comment.