Initial commit: mata avispas Arduino code and README
This commit is contained in:
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* mata avispas – Flyback high voltage generator controller
|
||||
* ESP32‑C3 as Access Point + Web server to configure PWM driving an XY‑MOS driver
|
||||
*
|
||||
* PWM output: GPIO2 (adjustable via LEDC)
|
||||
* Web page: http://192.168.4.1
|
||||
* AP SSID: MataAvispas_AP
|
||||
* AP Password: avispas123
|
||||
*
|
||||
* The page lets you set:
|
||||
* - Frequency (Hz) : 100 – 20000
|
||||
* - Duty cycle (%) : 0 – 100
|
||||
* - Enable/Disable output
|
||||
*
|
||||
* Uses the ESP32 Arduino core (https://github.com/espressif/arduino-esp32)
|
||||
*/
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <WebServer.h>
|
||||
|
||||
// ==== USER SETTINGS ====
|
||||
const char* AP_SSID = "MataAvispas_AP";
|
||||
const char* AP_PASSWORD = "avispas123";
|
||||
const uint8_t PWM_GPIO = 2; // XY‑MOS INPUT pin
|
||||
const uint8_t PWM_CHANNEL = 0; // LEDC channel 0
|
||||
const uint8_t PWM_RESOLUTION = 10; // 10‑bit resolution => 0‑1023
|
||||
// =======================
|
||||
|
||||
WebServer server(80);
|
||||
|
||||
// Current PWM state
|
||||
uint32_t pwmFrequency = 1000; // default 1 kHz
|
||||
uint32_t pwmDuty = 512; // 50 % of 1023
|
||||
bool pwmEnabled = false;
|
||||
|
||||
// HTML page (stored in PROGMEM to save RAM)
|
||||
const char INDEX_HTML[] PROGMEM = R"rawliteral(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, charset=utf-8">
|
||||
<title>Mata Avispas – PWM Config</title>
|
||||
<style>
|
||||
body { font-family: Arial, Helvetica, sans-serif; margin: 20px; background:#f4f4f4; }
|
||||
.container { max-width: 480px; margin: auto; background:#fff; padding:20px; box-shadow:0 0 10px rgba(0,0,0,.1); border-radius:8px; }
|
||||
h1 { color:#2c3e50; text-align:center; }
|
||||
label { display:block; margin-top:15px; font-weight:bold; }
|
||||
input[type="number"], input[type="range"] { width:100%; padding:8px; margin-top:5px; }
|
||||
.btn { display:inline-block; margin-top:20px; padding:10px 20px; background:#27ae60; color:#fff; border:none; border-radius:4px; cursor:pointer; }
|
||||
.btn.disabled { background:#95a5a6; cursor:not-allowed; }
|
||||
.status { margin-top:15px; padding:10px; background:#ecf0f1; border-radius:4px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Mata Avispas</h1>
|
||||
<div class="status" id="status">PWM: <span id="pwmState">OFF</span></div>
|
||||
|
||||
<label for="freq">Frequency (Hz)</label>
|
||||
<input type="number" id="freq" min="100" max="20000" value="1000">
|
||||
<small>Range: 100 – 20000 Hz</small>
|
||||
|
||||
<label for="duty">Duty cycle (%)</label>
|
||||
<input type="range" id="duty" min="0" max="100" value="50">
|
||||
<span id="dutyVal">50</span>%
|
||||
|
||||
<label for="enable">Output</label>
|
||||
<select id="enable">
|
||||
<option value="0">Disabled</option>
|
||||
<option value="1">Enabled</option>
|
||||
</select>
|
||||
|
||||
<button class="btn" id="sendBtn">Apply Settings</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const freqIn = document.getElementById('freq');
|
||||
const dutyIn = document.getElementById('duty');
|
||||
const dutyVal = document.getElementById('dutyVal');
|
||||
const enableIn = document.getElementById('enable');
|
||||
const btn = document.getElementById('sendBtn');
|
||||
const status = document.getElementById('status');
|
||||
const pwmState = document.getElementById('pwmState');
|
||||
|
||||
dutyIn.addEventListener('input', () => {
|
||||
dutyVal.textContent = dutyIn.value;
|
||||
});
|
||||
|
||||
btn.addEventListener('click', () => {
|
||||
const data = {
|
||||
freq: parseInt(freqIn.value),
|
||||
duty: parseInt(dutyIn.value),
|
||||
en: parseInt(enableIn.value)
|
||||
};
|
||||
fetch('/set', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data)
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(resp => {
|
||||
if (resp.ok) {
|
||||
pwmState.textContent = resp.enabled ? 'ON' : 'OFF';
|
||||
status.innerHTML = `PWM: <strong>${resp.enabled ? 'ON' : 'OFF'}</strong> (freq: ${resp.freq} Hz, duty: ${resp.duty}%)`;
|
||||
status.style.background = resp.enabled ? '#dff0d8' : '#f2dede';
|
||||
} else {
|
||||
alert('Error: ' + resp.msg);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
alert('Network error: ' + err);
|
||||
});
|
||||
});
|
||||
|
||||
// Load current settings on page load
|
||||
window.addEventListener('load', () => {
|
||||
fetch('/get')
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
freqIn.value = data.freq;
|
||||
dutyIn.value = data.duty;
|
||||
dutyVal.textContent = data.duty;
|
||||
enableIn.value = data.enabled ? '1' : '0';
|
||||
pwmState.textContent = data.enabled ? 'ON' : 'OFF';
|
||||
status.innerHTML = `PWM: <strong>${data.enabled ? 'ON' : 'OFF'}</strong> (freq: ${data.freq} Hz, duty: ${data.duty}%)`;
|
||||
status.style.background = data.enabled ? '#dff0d8' : '#f2dede';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
)rawliteral";
|
||||
|
||||
void handleRoot() {
|
||||
server.send_P(200, "text/html", INDEX_HTML, strlen_P(INDEX_HTML));
|
||||
}
|
||||
|
||||
void handleGet() {
|
||||
String json = "{";
|
||||
json += "\"freq\":" + String(pwmFrequency) + ",";
|
||||
json += "\"duty\":" + String(map(pwmDuty, 0, (1<<PWM_RESOLUTION)-1, 0, 100)) + ",";
|
||||
json += "\"enabled\":" + String(pwmEnabled ? "true" : "false");
|
||||
json += "}";
|
||||
server.send(200, "application/json", json);
|
||||
}
|
||||
|
||||
void handleSet() {
|
||||
if (server.method() != HTTP_POST) {
|
||||
server.send(405, "text/plain", "Method Not Allowed");
|
||||
return;
|
||||
}
|
||||
if (!server.hasArg("plain")) {
|
||||
server.send(400, "text/plain", "Missing JSON body");
|
||||
return;
|
||||
}
|
||||
String body = server.arg("plain");
|
||||
// Very simple JSON parsing (expects {"freq":N,"duty":M,"en":0|1})
|
||||
int freq = 1000;
|
||||
int duty = 50;
|
||||
int en = 0;
|
||||
|
||||
int idx = body.indexOf("\"freq\":");
|
||||
if (idx >= 0) {
|
||||
String sub = body.substring(idx + 7);
|
||||
freq = sub.substring(0, sub.indexOf(",")).toInt();
|
||||
}
|
||||
idx = body.indexOf("\"duty\":");
|
||||
if (idx >= 0) {
|
||||
String sub = body.substring(idx + 7);
|
||||
duty = sub.substring(0, sub.indexOf(",")).toInt();
|
||||
}
|
||||
idx = body.indexOf("\"en\":");
|
||||
if (idx >= 0) {
|
||||
String sub = body.substring(idx + 5);
|
||||
en = sub.substring(0, sub.indexOf("}")).toInt();
|
||||
}
|
||||
|
||||
// Clamp values
|
||||
if (freq < 100) freq = 100;
|
||||
if (freq > 20000) freq = 20000;
|
||||
if (duty < 0) duty = 0;
|
||||
if (duty > 100) duty = 100;
|
||||
|
||||
// Update PWM
|
||||
pwmFrequency = freq;
|
||||
pwmDuty = map(duty, 0, 100, 0, (1<<PWM_RESOLUTION)-1);
|
||||
pwmEnabled = (en == 1);
|
||||
|
||||
if (pwmEnabled) {
|
||||
ledcSetup(PWM_CHANNEL, pwmFrequency, PWM_RESOLUTION);
|
||||
ledcAttachPin(PWM_GPIO, PWM_CHANNEL);
|
||||
ledcWrite(PWM_CHANNEL, pwmDuty);
|
||||
} else {
|
||||
ledcDetachPin(PWM_GPIO);
|
||||
}
|
||||
|
||||
String json = "{";
|
||||
json += "\"ok\":true,\"freq\":" + String(pwmFrequency) + ",";
|
||||
json += "\"duty\":" + String(duty) + ",";
|
||||
json += "\"enabled\":" + String(pwmEnabled ? "true" : "false");
|
||||
json += "}";
|
||||
server.send(200, "application/json", json);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
// Set PWM GPIO as output (safe default)
|
||||
pinMode(PWM_GPIO, OUTPUT);
|
||||
digitalWrite(PWM_GPIO, LOW);
|
||||
|
||||
// Start AP
|
||||
WiFi.mode(WIFI_AP);
|
||||
WiFi.softAP(AP_SSID, AP_PASSWORD);
|
||||
IPAddress apIP = WiFi.softAPIP();
|
||||
Serial.print("AP IP address: ");
|
||||
Serial.println(apIP);
|
||||
|
||||
// Web server routes
|
||||
server.on("/", HTTP_GET, handleRoot);
|
||||
server.on("/get", HTTP_GET, handleGet);
|
||||
server.on("/set", HTTP_POST, handleSet);
|
||||
server.begin();
|
||||
Serial.println("HTTP server started");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
server.handleClient();
|
||||
// Nothing else needed; PWM runs in hardware
|
||||
}
|
||||
Reference in New Issue
Block a user