Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /********* Pleasedontcode.com **********
- Pleasedontcode thanks you for automatic code generation! Enjoy your code!
- - Terms and Conditions:
- You have a non-exclusive, revocable, worldwide, royalty-free license
- for personal and commercial use. Attribution is optional; modifications
- are allowed, but you're responsible for code maintenance. We're not
- liable for any loss or damage. For full terms,
- please visit pleasedontcode.com/termsandconditions.
- - Project: # Plasma Height Controller
- - Source Code NOT compiled for: ESP32 DevKit V1
- - Source Code created on: 2026-01-23 15:15:44
- ********* Pleasedontcode.com **********/
- /****** SYSTEM REQUIREMENTS *****/
- /****** SYSTEM REQUIREMENT 1 *****/
- /* Integrasikan web server HTTP pada ESP32 dengan */
- /* JSON API untuk memantau tegangan busur 0-250V */
- /* secara real-time, menampilkan status obor */
- /* (UP/DOWN) pada LCD I2C, dan mengontrol program 3 */
- /* parameter melalui encoder KY-040 lokal atau */
- /* endpoint web. */
- /****** END SYSTEM REQUIREMENTS *****/
- #include <WiFi.h>
- #include <WebServer.h>
- #include <ArduinoJson.h>
- #include <EEPROM.h>
- #include <LiquidCrystal_I2C.h>
- // ===== WiFi Configuration =====
- const char* ssid = "ANLOG";
- const char* password = "serversatu1";
- WebServer server(80);
- // ===== LCD Configuration =====
- LiquidCrystal_I2C lcd(0x27, 16, 2);
- // ===== Hardware Pin Configuration =====
- const int pinCLK = 12; // Encoder CLK pin
- const int pinDT = 14; // Encoder DT pin
- const int pinSW = 27; // Encoder Switch pin
- const int adcPin = 35; // ADC pin for arc voltage (0-250V)
- const int outputUpPin = 25; // Output: Torch UP control
- const int outputDnPin = 26; // Output: Torch DOWN control
- const int outputOkPin = 33; // Output: Arc OK signal
- // ===== System Timing Variables =====
- esp_timer_handle_t timer_handle = NULL;
- volatile bool Do = false;
- unsigned long LCDtime = 0;
- unsigned long defaultLCDtime = 500; // 5 seconds auto-return (500 * 10ms)
- // ===== Encoder Variables =====
- volatile int encoderCount = 0;
- volatile int encoderVal = 0;
- int oldValue = 0;
- int lastClkState = 0;
- unsigned long lastButtonPress = 0;
- // ===== LCD Display State Variables =====
- byte menu = 0;
- byte pos = 0;
- byte show = 0;
- // ===== Arc Voltage Monitoring =====
- unsigned long ArcV = 0; // Arc voltage in 0.1V units (0-2500 = 0-250V)
- unsigned long voltageSum = 0;
- int sampleCount = 0;
- // ===== Program and Parameter Management =====
- int program = 1; // Current program (1-3)
- int Param[12] = {0}; // Parameter array for 3 programs (4 params each)
- int SetVa = 0, DTa = 1, HySa = 2, StVa = 3; // Current param addresses
- int SetV = 100, DT = 5, HyS = 80, StV = 100; // Current parameter values
- int SetV_old = 0; // For change detection
- const int ParamItem = 4; // 4 parameters per program
- // ===== THC Control Variables =====
- unsigned int delayTime = 0;
- unsigned int SetVx10 = 0;
- // ===== Custom LCD Characters =====
- byte armsUpDn[8] = {
- B00000,
- B00100,
- B01110,
- B00100,
- B00000,
- B01110,
- B00000,
- B00000
- };
- byte customUp[8] = {
- B00100,
- B01110,
- B10101,
- B00100,
- B00100,
- B00100,
- B00100,
- B00000
- };
- byte customDown[8] = {
- B00100,
- B00100,
- B00100,
- B00100,
- B10101,
- B01110,
- B00100,
- B00000
- };
- // ===== Forward Declarations =====
- void Setup_WiFi();
- void Setup_LCD();
- void Setup_Encoder();
- void Setup_ADC();
- void Setup_THC();
- void Setup_Timer();
- void doLCD();
- void doTHC();
- void readArcVoltage();
- void SaveData(int add, int value);
- void ReadProg();
- void ReadDataProg_1();
- void ReadDataProg_2();
- void ReadDataProg_3();
- void Default();
- void doProgramSet(int prg);
- void doLCDDefault();
- void doLCDMenu();
- void doLCDProgramSellect();
- void doLCDMenuSetup();
- void doLCDTest();
- void doTestUp();
- void doTestDown();
- void doLCDDelayTime();
- void doLCDHysreresis();
- void doLCDStartVoltage();
- void doLCDLoadDefault();
- void IRAM_ATTR isrEncoder();
- void IRAM_ATTR isrButton();
- // ===== Web Server Handlers =====
- void handleRoot();
- void handleGetStatus();
- void handleSetParameter();
- void handleControl();
- void handleNotFound();
- void setup() {
- Serial.begin(115200);
- delay(1000);
- Serial.println("\n\nStarting THC Rotary Control System...");
- // Initialize EEPROM for persistent storage
- EEPROM.begin(64);
- // Initialize all subsystems
- Setup_LCD();
- Setup_Encoder();
- Setup_ADC();
- Setup_THC();
- Setup_Timer();
- Setup_WiFi();
- // Initialize web server routes
- server.on("/", HTTP_GET, handleRoot);
- server.on("/api/status", HTTP_GET, handleGetStatus);
- server.on("/api/param", HTTP_POST, handleSetParameter);
- server.on("/api/control", HTTP_POST, handleControl);
- server.onNotFound(handleNotFound);
- server.begin();
- Serial.println("HTTP Server started");
- // Load program data from EEPROM
- ReadProg();
- if (program < 1 || program > 3) program = 1;
- doProgramSet(program);
- Serial.println("System initialization complete");
- }
- void loop() {
- // Handle WiFi and HTTP requests
- server.handleClient();
- // Process LCD display updates
- doLCD();
- // Process THC (Torch Height Control) logic
- doTHC();
- // Handle button press (encoder switch)
- if (digitalRead(pinSW) == LOW) {
- if (millis() - lastButtonPress > 200) {
- Serial.println("Button pressed");
- if (menu == 0) {
- menu = 1;
- encoderVal = 0;
- } else {
- // Navigate menus
- if (menu == 1) {
- // Main menu selection
- if (pos == 0) menu = 0; // Exit
- else if (pos == 1) menu = 13; // Program
- else if (pos == 2) menu = 11; // Setup
- else if (pos == 3) menu = 12; // Test
- } else if (menu == 13) {
- // Program selection
- if (pos == 0) menu = 1; // Exit
- else if (pos == 1) menu = 121; // Program 1
- else if (pos == 2) menu = 122; // Program 2
- else if (pos == 3) menu = 123; // Program 3
- } else if (menu == 11) {
- // Setup menu selection
- if (pos == 0) menu = 1; // Exit
- else if (pos == 1) menu = 111; // Delay Time
- else if (pos == 2) menu = 112; // Hysteresis
- else if (pos == 3) menu = 113; // Start Voltage
- else if (pos == 4) menu = 114; // Load Default
- } else if (menu == 12) {
- // Test mode selection
- if (pos == 0) menu = 1; // Exit
- else if (pos == 1) menu = 115; // Torch Up
- else if (pos == 2) menu = 116; // Torch Down
- } else if (menu >= 111 && menu <= 116) {
- menu = 11; // Return to setup/test menu
- }
- }
- lastButtonPress = millis();
- }
- }
- }
- // ===== Timer Callback (runs every 10ms) =====
- void onTimerCallback(void* arg) {
- Do = true;
- }
- // ===== Setup Functions =====
- void Setup_WiFi() {
- Serial.print("Connecting to WiFi: ");
- Serial.println(ssid);
- WiFi.mode(WIFI_STA);
- WiFi.begin(ssid, password);
- int attempts = 0;
- while (WiFi.status() != WL_CONNECTED && attempts < 40) {
- delay(500);
- Serial.print(".");
- attempts++;
- }
- Serial.println();
- if (WiFi.status() == WL_CONNECTED) {
- Serial.println("WiFi connected!");
- Serial.print("IP address: ");
- Serial.println(WiFi.localIP());
- } else {
- Serial.println("WiFi connection failed!");
- }
- }
- void Setup_LCD() {
- lcd.init();
- lcd.backlight();
- // Create custom characters
- lcd.createChar(0, armsUpDn);
- lcd.createChar(1, customUp);
- lcd.createChar(2, customDown);
- // Display splash screen
- lcd.setCursor(1, 0);
- lcd.print("MEHMET IBRAHIM");
- lcd.setCursor(3, 1);
- lcd.print("Plasma THC");
- delay(1500);
- lcd.clear();
- }
- void Setup_Encoder() {
- pinMode(pinCLK, INPUT_PULLUP);
- pinMode(pinDT, INPUT_PULLUP);
- pinMode(pinSW, INPUT_PULLUP);
- lastClkState = digitalRead(pinCLK);
- attachInterrupt(digitalPinToInterrupt(pinCLK), isrEncoder, CHANGE);
- Serial.println("Encoder initialized");
- }
- void Setup_ADC() {
- analogReadResolution(12); // 12-bit resolution
- // Configure ADC calibration for more accurate readings
- analogSetPinAttenuation(adcPin, ADC_11db); // Full range 0-3.3V
- Serial.println("ADC initialized");
- }
- void Setup_THC() {
- pinMode(outputUpPin, OUTPUT);
- pinMode(outputDnPin, OUTPUT);
- pinMode(outputOkPin, OUTPUT);
- // Set initial state: all outputs LOW
- digitalWrite(outputUpPin, LOW);
- digitalWrite(outputDnPin, LOW);
- digitalWrite(outputOkPin, LOW);
- Serial.println("THC control outputs initialized");
- }
- void Setup_Timer() {
- esp_timer_create_args_t timer_args = {
- .callback = &onTimerCallback,
- .name = "thc_periodic_timer"
- };
- ESP_ERROR_CHECK(esp_timer_create(&timer_args, &timer_handle));
- ESP_ERROR_CHECK(esp_timer_start_periodic(timer_handle, 10000)); // 10ms period
- Serial.println("Timer initialized");
- }
- // ===== Encoder Interrupt Service Routine =====
- void IRAM_ATTR isrEncoder() {
- int currentClkState = digitalRead(pinCLK);
- if (currentClkState != lastClkState && currentClkState == LOW) {
- if (digitalRead(pinDT) != currentClkState) {
- encoderVal++;
- } else {
- encoderVal--;
- }
- }
- lastClkState = currentClkState;
- }
- // ===== ADC Reading Function =====
- void readArcVoltage() {
- // Read ADC value (12-bit: 0-4095)
- int rawValue = analogRead(adcPin);
- // Convert to voltage (3.3V reference, divided by voltage divider)
- // Voltage divider: 250V -> 3.3V requires 75:1 ratio
- // ADC reading * 3.3V / 4095 * divider_ratio = arc voltage
- // For 250V max: divider = 250V / 3.3V ≈ 75.76
- // Convert to 0-250V range and store in 0.1V units
- // ADC 0-4095 maps to 0-250V = 0-2500 in 0.1V units
- ArcV = (rawValue * 2500UL) / 4095UL;
- }
- // ===== LCD Display Functions =====
- void doLCD() {
- if (show >= 2) {
- show = 0;
- switch (menu) {
- case 0:
- doLCDDefault();
- break;
- case 1:
- doLCDMenu();
- break;
- case 11:
- doLCDMenuSetup();
- break;
- case 111:
- doLCDDelayTime();
- break;
- case 112:
- doLCDHysreresis();
- break;
- case 113:
- doLCDStartVoltage();
- break;
- case 114:
- doLCDLoadDefault();
- break;
- case 12:
- doLCDTest();
- break;
- case 115:
- doTestUp();
- break;
- case 116:
- doTestDown();
- break;
- case 13:
- doLCDProgramSellect();
- break;
- case 121:
- doProgramSet(1);
- break;
- case 122:
- doProgramSet(2);
- break;
- case 123:
- doProgramSet(3);
- break;
- default:
- doLCDDefault();
- }
- }
- }
- void doLCDDefault() {
- // Constrain encoder value to valid voltage range
- if (encoderVal < 0) encoderVal = 0;
- else if (encoderVal > 250) encoderVal = 250;
- SetV = encoderVal;
- // Save to EEPROM if value changed
- if (SetV != oldValue) {
- SaveData(SetVa, SetV);
- oldValue = SetV;
- }
- // Display: [P] [UP/space] [SetV] on line 0
- lcd.setCursor(0, 0);
- lcd.print("P ");
- if (digitalRead(outputUpPin) == HIGH) {
- lcd.write(1); // UP arrow
- } else {
- lcd.print(" ");
- }
- lcd.print(" ");
- lcd.setCursor(4, 0);
- lcd.print("Set.V: ");
- lcd.print(SetV);
- lcd.print(" ");
- // Display: [prog] [DOWN/space] [ArcV] on line 1
- lcd.setCursor(0, 1);
- lcd.print(program);
- lcd.print(" ");
- if (digitalRead(outputDnPin) == HIGH) {
- lcd.write(2); // DOWN arrow
- } else {
- lcd.print(" ");
- }
- lcd.print(" ");
- lcd.setCursor(4, 1);
- lcd.print("Arc.V: ");
- lcd.print(ArcV / 10);
- lcd.print(" ");
- }
- void doLCDMenu() {
- // Menu: Exit, Program, Setup, Test
- if (encoderVal < 0) encoderVal = 3;
- pos = encoderVal % 4;
- switch (pos) {
- case 0:
- lcd.setCursor(0, 0);
- lcd.print("> Exit ");
- lcd.setCursor(0, 1);
- lcd.print(" Program ");
- break;
- case 1:
- lcd.setCursor(0, 0);
- lcd.print("> Program ");
- lcd.setCursor(0, 1);
- lcd.print(" Setup ");
- break;
- case 2:
- lcd.setCursor(0, 0);
- lcd.print("> Setup ");
- lcd.setCursor(0, 1);
- lcd.print(" Test ");
- break;
- case 3:
- lcd.setCursor(0, 0);
- lcd.print("> Test ");
- lcd.setCursor(0, 1);
- lcd.print(" Exit ");
- break;
- }
- }
- void doLCDProgramSellect() {
- // Program selection: Exit, Program 1, Program 2, Program 3
- if (encoderVal < 0) encoderVal = 3;
- pos = abs(encoderVal % 4);
- switch (pos) {
- case 0:
- lcd.setCursor(0, 0);
- lcd.print(">> Exit ");
- lcd.setCursor(0, 1);
- lcd.print(" Load Prog: 1 ");
- break;
- case 1:
- lcd.setCursor(0, 0);
- lcd.print(">> Load Prog: 1 ");
- lcd.setCursor(0, 1);
- lcd.print(" Load Prog: 2 ");
- break;
- case 2:
- lcd.setCursor(0, 0);
- lcd.print(">> Load Prog: 2 ");
- lcd.setCursor(0, 1);
- lcd.print(" Load Prog: 3 ");
- break;
- case 3:
- lcd.setCursor(0, 0);
- lcd.print(">> Load Prog: 3 ");
- lcd.setCursor(0, 1);
- lcd.print(" Exit ");
- break;
- }
- }
- void doLCDMenuSetup() {
- // Setup menu: Exit, Delay Time, Hysteresis, Start Voltage, Load Default
- if (encoderVal < 0) encoderVal = 4;
- pos = abs(encoderVal % 5);
- switch (pos) {
- case 0:
- lcd.setCursor(0, 0);
- lcd.print(">> Exit ");
- lcd.setCursor(0, 1);
- lcd.print(" Delay Time ");
- break;
- case 1:
- lcd.setCursor(0, 0);
- lcd.print(">> Delay Time ");
- lcd.setCursor(0, 1);
- lcd.print(" Hysteresis ");
- break;
- case 2:
- lcd.setCursor(0, 0);
- lcd.print(">> Hysteresis ");
- lcd.setCursor(0, 1);
- lcd.print(" Start Voltage");
- break;
- case 3:
- lcd.setCursor(0, 0);
- lcd.print(">> Start Voltage");
- lcd.setCursor(0, 1);
- lcd.print(" Load Default ");
- break;
- case 4:
- lcd.setCursor(0, 0);
- lcd.print(">> Load Default ");
- lcd.setCursor(0, 1);
- lcd.print(" Exit ");
- break;
- }
- }
- void doLCDTest() {
- // Test mode: Exit, Torch Up, Torch Down
- if (encoderVal < 0) encoderVal = 2;
- pos = abs(encoderVal % 3);
- switch (pos) {
- case 0:
- lcd.setCursor(0, 0);
- lcd.print("Test > Exit ");
- lcd.setCursor(0, 1);
- lcd.print(" Torch Up ");
- digitalWrite(outputDnPin, LOW);
- digitalWrite(outputUpPin, LOW);
- digitalWrite(outputOkPin, LOW);
- break;
- case 1:
- lcd.setCursor(0, 0);
- lcd.print("Test > Torch Up ");
- lcd.setCursor(0, 1);
- lcd.print(" Torch Dn ");
- if (digitalRead(outputOkPin) == LOW) LCDtime = 0;
- if (LCDtime >= 200) { // 2 seconds (200 * 10ms)
- digitalWrite(outputDnPin, LOW);
- digitalWrite(outputUpPin, LOW);
- digitalWrite(outputOkPin, LOW);
- }
- break;
- case 2:
- lcd.setCursor(0, 0);
- lcd.print("Test > Torch Dn ");
- lcd.setCursor(0, 1);
- lcd.print(" Exit ");
- if (digitalRead(outputOkPin) == LOW) LCDtime = 0;
- if (LCDtime >= 200) {
- digitalWrite(outputDnPin, LOW);
- digitalWrite(outputUpPin, LOW);
- digitalWrite(outputOkPin, LOW);
- }
- break;
- }
- }
- void doTestUp() {
- // Execute torch up command
- digitalWrite(outputDnPin, LOW);
- digitalWrite(outputUpPin, HIGH);
- digitalWrite(outputOkPin, HIGH);
- LCDtime = 0;
- menu = 12;
- encoderVal = 1;
- }
- void doTestDown() {
- // Execute torch down command
- digitalWrite(outputDnPin, HIGH);
- digitalWrite(outputUpPin, LOW);
- digitalWrite(outputOkPin, HIGH);
- LCDtime = 0;
- menu = 12;
- encoderVal = 2;
- }
- void doLCDDelayTime() {
- // Delay Time adjustment: 1-200 units (0.1s to 20.0s)
- if (encoderVal < 1) encoderVal = 1;
- else if (encoderVal > 200) encoderVal = 200;
- DT = encoderVal;
- if (DT != oldValue) {
- SaveData(DTa, DT);
- oldValue = DT;
- LCDtime = 0;
- }
- double x = DT / 10.00;
- lcd.setCursor(0, 0);
- lcd.print("Set > Delay Time");
- lcd.setCursor(0, 1);
- lcd.print(" : ");
- lcd.print(x, 1);
- lcd.print(" s ");
- }
- void doLCDHysreresis() {
- // Hysteresis adjustment: 1-99 units (±0.1V to ±9.9V)
- if (encoderVal < 1) encoderVal = 1;
- else if (encoderVal > 99) encoderVal = 99;
- HyS = encoderVal;
- if (HyS != oldValue) {
- SaveData(HySa, HyS);
- oldValue = HyS;
- LCDtime = 0;
- }
- double x = HyS / 10.00;
- lcd.setCursor(0, 0);
- lcd.print("Set > Hysteresis");
- lcd.setCursor(0, 1);
- lcd.print(" :");
- lcd.write(0);
- lcd.print(x, 1);
- lcd.print(" V ");
- }
- void doLCDStartVoltage() {
- // Start Voltage adjustment: 50-250V
- if (encoderVal < 50) encoderVal = 50;
- else if (encoderVal > 250) encoderVal = 250;
- StV = encoderVal;
- if (StV != oldValue) {
- SaveData(StVa, StV);
- oldValue = StV;
- LCDtime = 0;
- }
- lcd.setCursor(0, 0);
- lcd.print("Set > Start Volt");
- lcd.setCursor(0, 1);
- lcd.print(" : ");
- lcd.print(StV);
- lcd.print(" V ");
- }
- void doLCDLoadDefault() {
- // Load default parameters
- Default();
- for (byte i = 0; i < 100; i++) {
- lcd.setCursor(0, 0);
- lcd.print(" Default ");
- lcd.setCursor(0, 1);
- lcd.print("Load ");
- lcd.print(i);
- lcd.print(" % ");
- delay(5);
- }
- lcd.setCursor(0, 0);
- lcd.print("Default: DONE ");
- lcd.setCursor(0, 1);
- lcd.print("Please Restart ");
- exit(0);
- }
- void doProgramSet(int prg) {
- // Set program and load its parameters
- if (prg == 1) {
- SetVa = 0;
- DTa = 1;
- HySa = 2;
- StVa = 3;
- ReadDataProg_1();
- } else if (prg == 2) {
- SetVa = 4;
- DTa = 5;
- HySa = 6;
- StVa = 7;
- ReadDataProg_2();
- } else {
- SetVa = 8;
- DTa = 9;
- HySa = 10;
- StVa = 11;
- ReadDataProg_3();
- }
- SaveData(12, prg);
- program = prg;
- SetV = Param[0];
- DT = Param[1];
- HyS = Param[2];
- StV = Param[3];
- encoderVal = SetV;
- menu = 0;
- }
- // ===== THC Logic =====
- void doTHC() {
- if (Do) {
- Do = false;
- LCDtime++;
- show++;
- // Read arc voltage from ADC
- readArcVoltage();
- // Auto-return to default menu after timeout
- if (LCDtime > defaultLCDtime) {
- menu = 0;
- pos = 0;
- LCDtime = 0;
- encoderVal = SetV;
- }
- // Arc voltage validation: 50V < ArcV < 250V (500 < value < 2500 in 0.1V units)
- if ((500 < ArcV) && (ArcV < 2500)) {
- // Wait for arc to stabilize above start voltage
- if (ArcV > StV * 10) {
- delayTime++;
- }
- // After stabilization delay, enable arc control
- if (delayTime >= DT * 10) {
- SetVx10 = SetV * 10;
- delayTime = DT * 10;
- digitalWrite(outputOkPin, HIGH); // Arc OK signal
- // Torch height control hysteresis logic
- if (ArcV >= SetVx10 + HyS) {
- // Arc voltage too high, move torch down
- digitalWrite(outputUpPin, LOW);
- digitalWrite(outputDnPin, HIGH);
- } else if (ArcV <= SetVx10 - HyS) {
- // Arc voltage too low, move torch up
- digitalWrite(outputDnPin, LOW);
- digitalWrite(outputUpPin, HIGH);
- } else {
- // Arc voltage within target range, hold position
- digitalWrite(outputUpPin, LOW);
- digitalWrite(outputDnPin, LOW);
- }
- }
- } else if (menu != 12) {
- // Arc lost or invalid, disable all outputs
- delayTime = 0;
- digitalWrite(outputUpPin, LOW);
- digitalWrite(outputOkPin, LOW);
- digitalWrite(outputDnPin, LOW);
- }
- }
- }
- // ===== EEPROM Functions =====
- void Default() {
- // Initialize EEPROM with default values for all 3 programs
- // Program 1: SetV=100V, DT=0.5s, HyS=8.0V, StV=100V
- EEPROM.write(0, 100); // SetV
- EEPROM.write(1, 5); // DT (0.5s = 5 * 0.1s)
- EEPROM.write(2, 80); // HyS (8.0V = 80 * 0.1V)
- EEPROM.write(3, 100); // StV
- // Program 2: SetV=120V, DT=0.5s, HyS=8.0V, StV=110V
- EEPROM.write(4, 120); // SetV
- EEPROM.write(5, 5); // DT
- EEPROM.write(6, 80); // HyS
- EEPROM.write(7, 110); // StV
- // Program 3: SetV=140V, DT=0.5s, HyS=8.0V, StV=120V
- EEPROM.write(8, 140); // SetV
- EEPROM.write(9, 5); // DT
- EEPROM.write(10, 80); // HyS
- EEPROM.write(11, 120); // StV
- // Default program selection
- EEPROM.write(12, 1);
- EEPROM.commit();
- }
- void ReadProg() {
- // Read current program selection from EEPROM
- int prog = EEPROM.read(12);
- if (prog >= 1 && prog <= 3) {
- program = prog;
- } else {
- program = 1;
- }
- }
- void ReadDataProg_1() {
- // Read Program 1 parameters (addresses 0-3)
- for (int j = 0; j < ParamItem; j++) {
- Param[j] = EEPROM.read(j);
- }
- }
- void ReadDataProg_2() {
- // Read Program 2 parameters (addresses 4-7)
- for (int j = 0; j < ParamItem; j++) {
- Param[j] = EEPROM.read(j + 4);
- }
- }
- void ReadDataProg_3() {
- // Read Program 3 parameters (addresses 8-11)
- for (int j = 0; j < ParamItem; j++) {
- Param[j] = EEPROM.read(j + 8);
- }
- }
- void SaveData(int add, int value) {
- // Save a single value to EEPROM and commit
- EEPROM.write(add, value);
- EEPROM.commit();
- }
- // ===== Web Server Handlers =====
- void handleRoot() {
- // Serve HTML control interface
- String html = R"(<!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>THC Control System</title>
- <style>
- body {
- font-family: Arial, sans-serif;
- max-width: 800px;
- margin: 50px auto;
- padding: 20px;
- background-color: #f5f5f5;
- }
- h1 {
- color: #333;
- text-align: center;
- }
- .container {
- background: white;
- padding: 20px;
- border-radius: 8px;
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
- margin-bottom: 20px;
- }
- .status-box {
- background-color: #f9f9f9;
- padding: 15px;
- border-left: 4px solid #4CAF50;
- margin-bottom: 15px;
- }
- .status-item {
- margin: 8px 0;
- font-size: 16px;
- }
- .status-value {
- font-weight: bold;
- color: #4CAF50;
- }
- .control-section {
- margin: 20px 0;
- }
- .control-section h3 {
- color: #333;
- border-bottom: 2px solid #4CAF50;
- padding-bottom: 10px;
- }
- label {
- display: inline-block;
- width: 150px;
- font-weight: bold;
- color: #555;
- }
- input[type="number"] {
- width: 100px;
- padding: 8px;
- margin: 5px;
- border: 1px solid #ddd;
- border-radius: 4px;
- }
- button {
- background-color: #4CAF50;
- color: white;
- padding: 10px 20px;
- margin: 5px;
- border: none;
- border-radius: 4px;
- cursor: pointer;
- font-size: 16px;
- font-weight: bold;
- }
- button:hover {
- background-color: #45a049;
- }
- button.danger {
- background-color: #f44336;
- }
- button.danger:hover {
- background-color: #da190b;
- }
- .select-program {
- margin: 10px 0;
- }
- .response {
- background-color: #e8f5e9;
- border: 1px solid #4CAF50;
- padding: 10px;
- border-radius: 4px;
- margin-top: 10px;
- display: none;
- }
- .error {
- background-color: #ffebee;
- border: 1px solid #f44336;
- color: #c62828;
- }
- </style>
- </head>
- <body>
- <h1>THC (Torch Height Control) System</h1>
- <div class="container">
- <h2>Current Status</h2>
- <div class="status-box">
- <div class="status-item">Arc Voltage: <span class="status-value" id="arcVoltage">0</span> V</div>
- <div class="status-item">Set Voltage: <span class="status-value" id="setVoltage">0</span> V</div>
- <div class="status-item">Program: <span class="status-value" id="program">1</span></div>
- <div class="status-item">Torch Status: <span class="status-value" id="torchStatus">IDLE</span></div>
- <div class="status-item">Delay Time: <span class="status-value" id="delayTime">0</span> s</div>
- <div class="status-item">Hysteresis: <span class="status-value" id="hysteresis">0</span> V</div>
- <div class="status-item">Start Voltage: <span class="status-value" id="startVoltage">0</span> V</div>
- </div>
- </div>
- <div class="container">
- <h2>Program Selection</h2>
- <div class="select-program">
- <label>Select Program:</label>
- <select id="programSelect">
- <option value="1">Program 1</option>
- <option value="2">Program 2</option>
- <option value="3">Program 3</option>
- </select>
- <button onclick="loadProgram()">Load Program</button>
- </div>
- </div>
- <div class="container">
- <h2>Parameter Control</h2>
- <div class="control-section">
- <h3>Set Voltage (0-250V)</h3>
- <label>Value:</label>
- <input type="number" id="setVoltageSetting" min="0" max="250" value="100">
- <button onclick="setParameter('SetV')">Set</button>
- </div>
- <div class="control-section">
- <h3>Delay Time (0.1-20.0s)</h3>
- <label>Value:</label>
- <input type="number" id="delayTimeSetting" min="1" max="200" value="5" step="1">
- <span> (×0.1s)</span>
- <button onclick="setParameter('DT')">Set</button>
- </div>
- <div class="control-section">
- <h3>Hysteresis (±0.1-9.9V)</h3>
- <label>Value:</label>
- <input type="number" id="hysteresisSetting" min="1" max="99" value="80" step="1">
- <span> (×0.1V)</span>
- <button onclick="setParameter('HyS')">Set</button>
- </div>
- <div class="control-section">
- <h3>Start Voltage (50-250V)</h3>
- <label>Value:</label>
- <input type="number" id="startVoltageSetting" min="50" max="250" value="100">
- <button onclick="setParameter('StV')">Set</button>
- </div>
- </div>
- <div class="container">
- <h2>Torch Control</h2>
- <div class="control-section">
- <button onclick="torchUp()">Torch UP</button>
- <button onclick="torchDown()" class="danger">Torch DOWN</button>
- <button onclick="torchStop()" class="danger">STOP</button>
- </div>
- </div>
- <div id="response" class="response"></div>
- <script>
- const API_BASE = '/api';
- function updateStatus() {
- fetch(API_BASE + '/status')
- .then(response => response.json())
- .then(data => {
- document.getElementById('arcVoltage').textContent = (data.arc_voltage / 10).toFixed(1);
- document.getElementById('setVoltage').textContent = data.set_voltage;
- document.getElementById('program').textContent = data.program;
- document.getElementById('torchStatus').textContent = data.torch_status;
- document.getElementById('delayTime').textContent = (data.delay_time / 10).toFixed(1);
- document.getElementById('hysteresis').textContent = (data.hysteresis / 10).toFixed(1);
- document.getElementById('startVoltage').textContent = data.start_voltage;
- document.getElementById('programSelect').value = data.program;
- })
- .catch(error => showResponse('Error fetching status: ' + error, true));
- }
- function setParameter(param) {
- let value = 0;
- if (param === 'SetV') {
- value = document.getElementById('setVoltageSetting').value;
- } else if (param === 'DT') {
- value = document.getElementById('delayTimeSetting').value;
- } else if (param === 'HyS') {
- value = document.getElementById('hysteresisSetting').value;
- } else if (param === 'StV') {
- value = document.getElementById('startVoltageSetting').value;
- }
- fetch(API_BASE + '/param', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- param: param,
- value: parseInt(value),
- program: parseInt(document.getElementById('programSelect').value)
- })
- })
- .then(response => response.json())
- .then(data => {
- if (data.success) {
- showResponse(param + ' set to ' + value);
- updateStatus();
- } else {
- showResponse('Error: ' + data.message, true);
- }
- })
- .catch(error => showResponse('Error: ' + error, true));
- }
- function loadProgram() {
- const program = document.getElementById('programSelect').value;
- fetch(API_BASE + '/param', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- param: 'PROGRAM',
- value: parseInt(program)
- })
- })
- .then(response => response.json())
- .then(data => {
- if (data.success) {
- showResponse('Program ' + program + ' loaded');
- updateStatus();
- } else {
- showResponse('Error: ' + data.message, true);
- }
- })
- .catch(error => showResponse('Error: ' + error, true));
- }
- function torchUp() {
- fetch(API_BASE + '/control', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- action: 'UP'
- })
- })
- .then(response => response.json())
- .then(data => {
- showResponse('Torch moving UP');
- updateStatus();
- })
- .catch(error => showResponse('Error: ' + error, true));
- }
- function torchDown() {
- fetch(API_BASE + '/control', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- action: 'DOWN'
- })
- })
- .then(response => response.json())
- .then(data => {
- showResponse('Torch moving DOWN');
- updateStatus();
- })
- .catch(error => showResponse('Error: ' + error, true));
- }
- function torchStop() {
- fetch(API_BASE + '/control', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- action: 'STOP'
- })
- })
- .then(response => response.json())
- .then(data => {
- showResponse('Torch STOPPED');
- updateStatus();
- })
- .catch(error => showResponse('Error: ' + error, true));
- }
- function showResponse(message, isError = false) {
- const response = document.getElementById('response');
- response.textContent = message;
- response.style.display = 'block';
- if (isError) {
- response.classList.add('error');
- } else {
- response.classList.remove('error');
- }
- }
- // Update status every 500ms
- updateStatus();
- setInterval(updateStatus, 500);
- </script>
- </body>
- </html>
- )";
- server.send(200, "text/html", html);
- }
- void handleGetStatus() {
- // Return current system status as JSON
- DynamicJsonDocument doc(512);
- doc["arc_voltage"] = (int)ArcV; // in 0.1V units
- doc["set_voltage"] = SetV; // in V
- doc["program"] = program;
- doc["delay_time"] = DT; // in 0.1s units
- doc["hysteresis"] = HyS; // in 0.1V units
- doc["start_voltage"] = StV; // in V
- // Determine torch status
- if (digitalRead(outputOkPin) == HIGH) {
- if (digitalRead(outputUpPin) == HIGH) {
- doc["torch_status"] = "UP";
- } else if (digitalRead(outputDnPin) == HIGH) {
- doc["torch_status"] = "DOWN";
- } else {
- doc["torch_status"] = "HOLD";
- }
- } else {
- doc["torch_status"] = "IDLE";
- }
- String json;
- serializeJson(doc, json);
- server.send(200, "application/json", json);
- }
- void handleSetParameter() {
- // Parse JSON request to set parameters
- if (!server.hasArg("plain")) {
- server.send(400, "application/json", "{\"success\": false, \"message\": \"No data\"}");
- return;
- }
- String body = server.arg("plain");
- DynamicJsonDocument doc(256);
- DeserializationError error = deserializeJson(doc, body);
- if (error) {
- server.send(400, "application/json", "{\"success\": false, \"message\": \"Invalid JSON\"}");
- return;
- }
- String param = doc["param"];
- int value = doc["value"];
- int prog = doc["program"] | program; // Default to current program
- DynamicJsonDocument response(256);
- if (param == "SetV") {
- if (value >= 0 && value <= 250) {
- SetV = value;
- encoderVal = value;
- SaveData(SetVa, value);
- Param[0] = value;
- response["success"] = true;
- } else {
- response["success"] = false;
- response["message"] = "SetV must be 0-250";
- }
- } else if (param == "DT") {
- if (value >= 1 && value <= 200) {
- DT = value;
- encoderVal = value;
- SaveData(DTa, value);
- Param[1] = value;
- response["success"] = true;
- } else {
- response["success"] = false;
- response["message"] = "DT must be 1-200 (0.1-20.0s)";
- }
- } else if (param == "HyS") {
- if (value >= 1 && value <= 99) {
- HyS = value;
- encoderVal = value;
- SaveData(HySa, value);
- Param[2] = value;
- response["success"] = true;
- } else {
- response["success"] = false;
- response["message"] = "HyS must be 1-99 (±0.1-9.9V)";
- }
- } else if (param == "StV") {
- if (value >= 50 && value <= 250) {
- StV = value;
- encoderVal = value;
- SaveData(StVa, value);
- Param[3] = value;
- response["success"] = true;
- } else {
- response["success"] = false;
- response["message"] = "StV must be 50-250V";
- }
- } else if (param == "PROGRAM") {
- if (value >= 1 && value <= 3) {
- doProgramSet(value);
- response["success"] = true;
- } else {
- response["success"] = false;
- response["message"] = "Program must be 1-3";
- }
- } else {
- response["success"] = false;
- response["message"] = "Unknown parameter";
- }
- String json;
- serializeJson(response, json);
- server.send(200, "application/json", json);
- }
- void handleControl() {
- // Handle torch control commands
- if (!server.hasArg("plain")) {
- server.send(400, "application/json", "{\"success\": false, \"message\": \"No data\"}");
- return;
- }
- String body = server.arg("plain");
- DynamicJsonDocument doc(256);
- DeserializationError error = deserializeJson(doc, body);
- if (error) {
- server.send(400, "application/json", "{\"success\": false, \"message\": \"Invalid JSON\"}");
- return;
- }
- String action = doc["action"];
- DynamicJsonDocument response(256);
- if (action == "UP") {
- digitalWrite(outputDnPin, LOW);
- digitalWrite(outputUpPin, HIGH);
- digitalWrite(outputOkPin, HIGH);
- response["success"] = true;
- response["message"] = "Torch moving UP";
- } else if (action == "DOWN") {
- digitalWrite(outputDnPin, HIGH);
- digitalWrite(outputUpPin, LOW);
- digitalWrite(outputOkPin, HIGH);
- response["success"] = true;
- response["message"] = "Torch moving DOWN";
- } else if (action == "STOP") {
- digitalWrite(outputUpPin, LOW);
- digitalWrite(outputDnPin, LOW);
- digitalWrite(outputOkPin, LOW);
- response["success"] = true;
- response["message"] = "Torch STOPPED";
- } else {
- response["success"] = false;
- response["message"] = "Unknown action";
- }
- String json;
- serializeJson(response, json);
- server.send(200, "application/json", json);
- }
- void handleNotFound() {
- // Handle 404 errors
- DynamicJsonDocument doc(256);
- doc["error"] = "Endpoint not found";
- doc["path"] = server.uri();
- String json;
- serializeJson(doc, json);
- server.send(404, "application/json", json);
- }
- /* END CODE */
Advertisement
Add Comment
Please, Sign In to add comment