Skip to content
Open
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
213 changes: 115 additions & 98 deletions README.md

Large diffs are not rendered by default.

19 changes: 14 additions & 5 deletions esp_duck/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,21 @@
#define BOOT_MAGIC_NUM 1234567890

/*! ===== WiFi Settings ===== */
#define WIFI_SSID "wifiduck"
#define WIFI_PASSWORD "wifiduck"
#define WIFI_CHANNEL "1"

#define HOSTNAME "wifiduck"
#define URL "wifi.duck"
/*
Mode can be "STA" or "AP"
STA is for connecting to an existing access point
AP is for creating a new access point
*/
#define MODE "STA"

#define WIFI_SSID "wifiduck" // wifi name for AP or STA
#define WIFI_PASSWORD "wifiduck" // wifi password for AP or STA

#define WIFI_CHANNEL "1" // wifi channel for AP

#define HOSTNAME "wifiduck" // hostname
#define URL "wifi.duck" // url to access web interface

/*! ========== Safty checks ========== */
#if !defined(ENABLE_I2C) && !defined(ENABLE_SERIAL)
Expand Down
23 changes: 22 additions & 1 deletion esp_duck/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace settings {
typedef struct settings_t {
uint32_t magic_num;

char mode[11];
char ssid[33];
char password[65];
char channel[5];
Expand All @@ -36,6 +37,7 @@ namespace settings {
eeprom::getObject(SETTINGS_ADDRES, data);
if (data.magic_num != SETTINGS_MAGIC_NUM) reset();

if (data.mode[10] != 0) setMODE(MODE);
if (data.ssid[32] != 0) setSSID(WIFI_SSID);
if (data.password[64] != 0) setPassword(WIFI_PASSWORD);
if (data.channel[4] != 0) setChannel(WIFI_CHANNEL);
Expand All @@ -45,6 +47,7 @@ namespace settings {
void reset() {
debugln("Resetting Settings");
data.magic_num = SETTINGS_MAGIC_NUM;
setMODE(MODE);
setSSID(WIFI_SSID);
setPassword(WIFI_PASSWORD);
setChannel(WIFI_CHANNEL);
Expand All @@ -58,6 +61,9 @@ namespace settings {
String toString() {
String s;

s += "mode=";
s += getMODE();
s += "\n";
s += "ssid=";
s += getSSID();
s += "\n";
Expand All @@ -74,6 +80,10 @@ namespace settings {
return s;
}

const char* getMODE() {
return data.mode;
}

const char* getSSID() {
return data.ssid;
}
Expand All @@ -96,7 +106,9 @@ namespace settings {
}

void set(const char* name, const char* value) {
if (strcmp(name, "ssid") == 0) {
if (strcmp(name, "mode") == 0) {
setMODE(value);
} else if (strcmp(name, "ssid") == 0) {
setSSID(value);
} else if (strcmp(name, "password") == 0) {
setPassword(value);
Expand All @@ -107,6 +119,15 @@ namespace settings {
}
}

void setMODE(const char* mode) {
if (mode) {
memset(data.mode, 0, sizeof(data.mode)); // Clear the buffer to ensure no leftover data
strncpy(data.mode, mode, sizeof(data.mode) - 1); // Copy up to 10 characters, leave room for null terminator
data.mode[sizeof(data.mode) - 1] = '\0'; // Explicitly set the last character to null terminator
save();
}
}

void setSSID(const char* ssid) {
if (ssid) {
memset(data.ssid, 0, 33);
Expand Down
2 changes: 2 additions & 0 deletions esp_duck/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace settings {

String toString();

const char* getMODE();
const char* getSSID();
const char* getPassword();
const char* getChannel();
Expand All @@ -25,6 +26,7 @@ namespace settings {

void set(const char* name, const char* value);

void setMODE(const char* mode);
void setSSID(const char* ssid);
void setPassword(const char* password);
void setChannel(const char* channel);
Expand Down
20 changes: 10 additions & 10 deletions esp_duck/webfiles.h

Large diffs are not rendered by default.

47 changes: 41 additions & 6 deletions esp_duck/webserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,50 @@ namespace webserver {

// ===== PUBLIC ===== //
void begin() {
// Access Point
// Set hostname for the device
WiFi.hostname(HOSTNAME);

// WiFi.mode(WIFI_AP_STA);
WiFi.softAP(settings::getSSID(), settings::getPassword(), settings::getChannelNum());
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
debugf("Started Access Point \"%s\":\"%s\"\n", settings::getSSID(), settings::getPassword());
// Determine mode based on channel setting or another configuration parameter
if (strcmp(settings::getMODE(), "STA") == 0) {
WiFi.mode(WIFI_STA); // Set WiFi to station mode
debugf("Attempting to connect to WiFi...");

int connectionAttempts = 0;
while (connectionAttempts < 10) {
WiFi.begin(settings::getSSID(), settings::getPassword()); // Attempt to connect

// Wait for the connection to establish
if (WiFi.waitForConnectResult() == WL_CONNECTED) {
debugf("Connected to WiFi successfully!");
IPAddress ip = WiFi.localIP(); // Get the local IP address
debugf("IP Address: %s\n", ip.toString().c_str()); // Print the IP address
break; // Exit loop if connected
} else {
connectionAttempts++;
debugf("Connection attempt %d failed, retrying...\n", connectionAttempts);

// Delay before the next connection attempt
delay(10000); // 10 seconds
}
}

// If connection failed after all attempts
if (connectionAttempts >= 10) {
debugf("Failed to connect after 10 attempts. Starting AP...");
WiFi.softAP(settings::getSSID(), settings::getPassword());
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
}
} else {
// Default to AP mode
debugf("Mode is set to AP (Access Point Mode). Setting up AP...");
WiFi.mode(WIFI_AP);
WiFi.softAP(settings::getSSID(), settings::getPassword());
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
}

debugf("\"%s\" Mode SSID \"%s\":\"%s\"\n", settings::getMODE(), settings::getSSID(), settings::getPassword());

// Webserver
// Continue with the Web server initialization...
server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) {
request->redirect("/index.html");
});
Expand Down
3 changes: 1 addition & 2 deletions web/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@ function ws_update_status() {
function ws_init() {
status("connecting...");

ws = new WebSocket("ws://192.168.4.1/ws");

ws = new WebSocket("ws://" + location.host + "/ws");
ws.onopen = function(event) {
log_ws("connected");
status("connected");
Expand Down
5 changes: 5 additions & 0 deletions web/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
<h1>WiFi</h1>
<p>Restart the device to apply new settings.</p>
<table>
<tr>
<td>MODE:</td>
<td id="mode"></td>
<td><button class="primary" id="edit_mode">edit</button></td>
</tr>
<tr>
<td>SSID:</td>
<td id="ssid"></td>
Expand Down
24 changes: 20 additions & 4 deletions web/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ function load_settings() {
ws_send("settings", function(msg) {
var lines = msg.split(/\n/);

var ssid = lines[0].split("=")[1];
var password = lines[1].split("=")[1];
var channel = lines[2].split("=")[1];
var autorun = lines[3].split("=")[1];
var mode = lines[0].split("=")[1];
var ssid = lines[1].split("=")[1];
var password = lines[2].split("=")[1];
var channel = lines[3].split("=")[1];
var autorun = lines[4].split("=")[1];

E("mode").innerHTML = mode;
E("ssid").innerHTML = ssid;
E("password").innerHTML = password;
E("channel").innerHTML = channel;
Expand All @@ -27,6 +29,20 @@ function ws_connected() {
// ===== Startup ===== //
window.addEventListener("load", function() {

E("edit_mode").onclick = function() {
var newssid = prompt("MODE (1-11 chars)", E("mode").innerHTML);

if (newssid) {
if (newssid.length >= 1 && newssid.length <= 11) {
ws_send("set mode \"" + newssid + "\"", function(msg) {
load_settings();
});
} else {
alert("ERROR: Invalid length");
}
}
};

E("edit_ssid").onclick = function() {
var newssid = prompt("SSID (1-32 chars)", E("ssid").innerHTML);

Expand Down