Files
Analog_System_Monitor/analog_system_monitor_arduino/Ui.cpp

383 lines
10 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <Arduino.h>
#include "UI.h"
// Local UI control
static uint16_t portInput;
// -------------------------------
// Calibration UI helpers & callbacks
// -------------------------------
void refreshCalibrationUI() {
for (int i = 0; i < 5; i++) {
ESPUI.updateControlValue(calInputs[i], String(calibratedPoints[selectedCalChannel][i], 2));
}
}
void calChannelCallback(Control *sender, int type) {
// Turn override OFF when switching channels
for (int ch = 0; ch < NUM_CHANNELS; ch++) {
overrideActive[ch] = false;
}
ESPUI.updateControlValue(calOverrideSwitch, "0");
selectedCalChannel = sender->value.toInt();
Serial.print("Calibration channel changed to ");
Serial.println(selectedCalChannel);
refreshCalibrationUI();
}
void calPointCallback(Control *sender, int type) {
int index = sender->id - calInputs[0];
if (index >= 0 && index < 5) {
float val = sender->value.toFloat();
calibratedPoints[selectedCalChannel][index] = val;
Serial.printf("Cal[%d][%d] = %.2f\n", selectedCalChannel, index, val);
}
}
void calTestCallback(Control *sender, int type) {
if (!overrideActive[selectedCalChannel]) return;
float logical = sender->value.toFloat(); // 0100 integer
if (logical < 0) logical = 0;
if (logical > 100) logical = 100;
float calibrated = applyCalibration(selectedCalChannel, logical);
int duty = (int)((calibrated / 100.0f) * ((1 << pwmResolution) - 1));
ledcWrite(pwmPins[selectedCalChannel], duty);
Serial.printf("Override update CH%d: logical=%.2f calibrated=%.2f duty=%d\n",
selectedCalChannel, logical, calibrated, duty);
}
void calSaveCallback(Control *sender, int type) {
Serial.printf("Saving calibration for CH%d...\n", selectedCalChannel);
for (int i = 0; i < 5; i++) {
String key = "cal_" + String(selectedCalChannel) + "_" + String(i);
prefs.putFloat(key.c_str(), calibratedPoints[selectedCalChannel][i]);
}
Serial.println("Calibration saved.");
}
void calOverrideSwitchCallback(Control *sender, int type) {
bool enabled = sender->value.toInt() == 1;
if (enabled) {
Serial.println("Override enabled.");
// Enable override only for the selected channel
for (int ch = 0; ch < NUM_CHANNELS; ch++) {
overrideActive[ch] = (ch == selectedCalChannel);
}
// Immediately apply the test value
float logical = ESPUI.getControl(calTestValueInput)->value.toFloat();
if (logical < 0) logical = 0;
if (logical > 100) logical = 100;
float calibrated = applyCalibration(selectedCalChannel, logical);
int duty = (int)((calibrated / 100.0f) * ((1 << pwmResolution) - 1));
ledcWrite(pwmPins[selectedCalChannel], duty);
Serial.printf("Override driving CH%d: logical=%.2f calibrated=%.2f duty=%d\n",
selectedCalChannel, logical, calibrated, duty);
} else {
Serial.println("Override disabled. Returning to UDP control.");
// Disable all overrides
for (int ch = 0; ch < NUM_CHANNELS; ch++) {
overrideActive[ch] = false;
}
}
}
void lightingSaveCallback(Control *sender, int type) {
if (type != B_UP) return; // avoid double-trigger
prefs.putUChar("light_hue", lightingHue);
prefs.putUChar("light_sat", lightingSaturation);
prefs.putUChar("light_bright", lightingBrightness);
Serial.printf("Lighting saved (0255): H=%d S=%d B=%d\n",
lightingHue, lightingSaturation, lightingBrightness);
}
static int toSlider(uint8_t v) {
return (int)((v / 255.0f) * 100.0f);
}
static uint8_t fromSlider(int v) {
return (uint8_t)((v / 100.0f) * 255.0f);
}
// -------------------------------
// UI init
// -------------------------------
void uiInit(uint16_t& tabSettings, uint16_t& tabLighting, uint16_t& tabCalibration) {
// Create tabs
tabSettings = ESPUI.addControl(ControlType::Tab, "Settings", "Settings");
tabLighting = ESPUI.addControl(ControlType::Tab, "Lighting", "Lighting");
tabCalibration= ESPUI.addControl(ControlType::Tab, "Calibration", "Calibration");
// Restart button callback
auto restartCallback = [](Control *sender, int type) {
ESP.restart();
};
// Port input callback
auto portInputCallback = [](Control *sender, int type) {
Serial.print("Port input changed to: ");
Serial.println(sender->value);
};
// Save & Apply callback
auto savePortCallback = [](Control *sender, int type) {
if (type != B_UP) return; // Prevent double-trigger
Control* c = ESPUI.getControl(portInput);
int newPort = c->value.toInt();
if (newPort < 1024 || newPort > 65535) {
Serial.println("Invalid port (102465535)");
return;
}
prefs.putInt("udpPort", newPort);
udpPort = newPort;
udp.stop();
udp.begin(udpPort);
Serial.print("New UDP port applied: ");
Serial.println(udpPort);
ESPUI.updateControlValue(portInput, String(newPort));
};
// -------------------------------------------
// Connection Status section
// -------------------------------------------
ESPUI.addControl(
ControlType::Separator,
"Connection Status",
"",
ControlColor::None,
tabSettings
);
// Live-updating connection status label
connectionStatusLabel = ESPUI.addControl(
ControlType::Label,
"Status",
"Disconnected",
ControlColor::Wetasphalt,
tabSettings
);
// -------------------------------------------
// UDP Telemetry Connection Settings section
// -------------------------------------------
ESPUI.addControl(
ControlType::Separator,
"UDP Telemetry Connection Settings",
"",
ControlColor::None,
tabSettings
);
// UDP Port Number input
portInput = ESPUI.addControl(
ControlType::Number,
"UDP Port",
String(udpPort),
ControlColor::Peterriver,
tabSettings,
portInputCallback
);
// Save & Apply button
ESPUI.addControl(
ControlType::Button,
"UDP Port",
"Save & Apply",
ControlColor::Emerald,
tabSettings,
savePortCallback
);
// Existing separator (leave as-is)
ESPUI.addControl(
ControlType::Separator,
"",
"",
ControlColor::None,
tabSettings
);
// Restart button (unchanged)
ESPUI.addControl(
ControlType::Button,
"Restart ESP32",
"Restart",
ControlColor::Alizarin,
tabSettings,
restartCallback
);
// -------------------------------
// Lighting Controls
// -------------------------------
// Hue slider (0360)
ESPUI.addControl(
ControlType::Slider,
"Hue",
String(toSlider(lightingHue)),
ControlColor::Sunflower,
tabLighting,
[](Control *sender, int type) {
int sliderVal = sender->value.toInt(); // 0100
lightingHue = fromSlider(sliderVal); // convert to 0255
Serial.printf("Lighting Hue changed (RAM only): %d\n", lightingHue);
}
);
// Saturation slider (0100)
ESPUI.addControl(
ControlType::Slider,
"Saturation",
String(toSlider(lightingSaturation)),
ControlColor::Carrot,
tabLighting,
[](Control *sender, int type) {
int sliderVal = sender->value.toInt(); // 0100
lightingSaturation = fromSlider(sliderVal);
Serial.printf("Lighting Saturation updated (RAM only): %d\n", lightingSaturation);
}
);
// Brightness slider (0100)
ESPUI.addControl(
ControlType::Slider,
"Brightness",
String(toSlider(lightingBrightness)),
ControlColor::Emerald,
tabLighting,
[](Control *sender, int type) {
int sliderVal = sender->value.toInt(); // 0100
lightingBrightness = fromSlider(sliderVal);
Serial.printf("Lighting Brightness updated (RAM only): %d\n", lightingBrightness);
}
);
ESPUI.addControl(
ControlType::Button,
"Save Lighting Settings",
"Save",
ControlColor::Emerald,
tabLighting,
lightingSaveCallback
);
// -------------------------------
// Calibration tab UI
// -------------------------------
// Channel selector
calChannelDropdown = ESPUI.addControl(
ControlType::Select,
"Selected Channel",
"0",
ControlColor::Peterriver,
tabCalibration,
calChannelCallback
);
// Add options 07
for (int i = 0; i < NUM_CHANNELS; i++) {
char value[8];
snprintf(value, sizeof(value), "%d", i);
ESPUI.addControl(
ControlType::Option,
channelDropdownLabels[i], // static label
value, // static-ish value (OK)
ControlColor::None,
calChannelDropdown
);
}
ESPUI.addControl(
ControlType::Separator,
"",
"",
ControlColor::None,
tabCalibration
);
// Calibration inputs
const char* calNames[5] = {"0%", "25%", "50%", "75%", "100%"};
for (int i = 0; i < 5; i++) {
calInputs[i] = ESPUI.addControl(
ControlType::Number,
calNames[i],
String(calibratedPoints[0][i], 2),
ControlColor::Wetasphalt,
tabCalibration,
calPointCallback
);
}
ESPUI.addControl(
ControlType::Separator,
"",
"",
ControlColor::None,
tabCalibration
);
// Test value input
calTestValueInput = ESPUI.addControl(
ControlType::Slider,
"Test Value",
"50",
ControlColor::Carrot,
tabCalibration,
calTestCallback
);
calOverrideSwitch = ESPUI.addControl(
ControlType::Switcher,
"Override",
"0", // default OFF
ControlColor::Alizarin,
tabCalibration,
calOverrideSwitchCallback
);
ESPUI.addControl(
ControlType::Separator,
"",
"",
ControlColor::None,
tabCalibration
);
// Save button
calSaveButton = ESPUI.addControl(
ControlType::Button,
"Save Calibration",
"Save",
ControlColor::Emerald,
tabCalibration,
calSaveCallback
);
}