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: # Automated Torchwork
- - Source Code compiled for: ESP32 DevKit V1
- - Source Code created on: 2026-01-23 16:17:56
- ********* 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 *****/
- /* START CODE */
- #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 approx 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 (plusminus 0.1V to plusminus 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 with proper character encoding
- String html = "<!DOCTYPE html>\n<html>\n<head>\n";
- html += " <meta charset=\"UTF-8\">\n";
- html += " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n";
- html += " <title>THC Control System</title>\n";
- html += " <style>\n";
- html += " body {\n";
- html += " font-family: Arial, sans-serif;\n";
- html += " max-width: 800px;\n";
- html += " margin: 50px auto;\n";
- html += " padding: 20px;\n";
- html += " background-color: #f5f5f5;\n";
- html += " }\n";
- html += " h1 {\n";
- html += " color: #333;\n";
- html += " text-align: center;\n";
- html += " }\n";
- html += " .container {\n";
- html += " background: white;\n";
- html += " padding: 20px;\n";
- html += " border-radius: 8px;\n";
- html += " box-shadow: 0 2px 4px rgba(0,0,0,0.1);\n";
- html += " margin-bottom: 20px;\n";
- html += " }\n";
- html += " .status-box {\n";
- html += " background-color: #f9f9f9;\n";
- html += " padding: 15px;\n";
- html += " border-left: 4px solid #4CAF50;\n";
- html += " margin-bottom: 15px;\n";
- html += " }\n";
- html += " .status-item {\n";
- html += " margin: 8px 0;\n";
- html += " font-size: 16px;\n";
- html += " }\n";
- html += " .status-value {\n";
- html += " font-weight: bold;\n";
- html += " color: #4CAF50;\n";
- html += " }\n";
- html += " .control-section {\n";
- html += " margin: 20px 0;\n";
- html += " }\n";
- html += " .control-section h3 {\n";
- html += " color: #333;\n";
- html += " border-bottom: 2px solid #4CAF50;\n";
- html += " padding-bottom: 10px;\n";
- html += " }\n";
- html += " label {\n";
- html += " display: inline-block;\n";
- html += " width: 150px;\n";
- html += " font-weight: bold;\n";
- html += " color: #555;\n";
- html += " }\n";
- html += " input[type=\"number\"] {\n";
- html += " width: 100px;\n";
- html += " padding: 8px;\n";
- html += " margin: 5px;\n";
- html += " border: 1px solid #ddd;\n";
- html += " border-radius: 4px;\n";
- html += " }\n";
- html += " button {\n";
- html += " background-color: #4CAF50;\n";
- html += " color: white;\n";
- html += " padding: 10px 20px;\n";
- html += " margin: 5px;\n";
- html += " border: none;\n";
- html += " border-radius: 4px;\n";
- html += " cursor: pointer;\n";
- html += " font-size: 16px;\n";
- html += " font-weight: bold;\n";
- html += " }\n";
- html += " button:hover {\n";
- html += " background-color: #45a049;\n";
- html += " }\n";
- html += " button.danger {\n";
- html += " background-color: #f44336;\n";
- html += " }\n";
- html += " button.danger:hover {\n";
- html += " background-color: #da190b;\n";
- html += " }\n";
- html += " .select-program {\n";
- html += " margin: 10px 0;\n";
- html += " }\n";
- html += " .response {\n";
- html += " background-color: #e8f5e9;\n";
- html += " border: 1px solid #4CAF50;\n";
- html += " padding: 10px;\n";
- html += " border-radius: 4px;\n";
- html += " margin-top: 10px;\n";
- html += " display: none;\n";
- html += " }\n";
- html += " .error {\n";
- html += " background-color: #ffebee;\n";
- html += " border: 1px solid #f44336;\n";
- html += " color: #c62828;\n";
- html += " }\n";
- html += " </style>\n";
- html += "</head>\n<body>\n";
- html += " <h1>THC (Torch Height Control) System</h1>\n";
- html += " \n";
- html += " <div class=\"container\">\n";
- html += " <h2>Current Status</h2>\n";
- html += " <div class=\"status-box\">\n";
- html += " <div class=\"status-item\">Arc Voltage: <span class=\"status-value\" id=\"arcVoltage\">0</span> V</div>\n";
- html += " <div class=\"status-item\">Set Voltage: <span class=\"status-value\" id=\"setVoltage\">0</span> V</div>\n";
- html += " <div class=\"status-item\">Program: <span class=\"status-value\" id=\"program\">1</span></div>\n";
- html += " <div class=\"status-item\">Torch Status: <span class=\"status-value\" id=\"torchStatus\">IDLE</span></div>\n";
- html += " <div class=\"status-item\">Delay Time: <span class=\"status-value\" id=\"delayTime\">0</span> s</div>\n";
- html += " <div class=\"status-item\">Hysteresis: <span class=\"status-value\" id=\"hysteresis\">0</span> V</div>\n";
- html += " <div class=\"status-item\">Start Voltage: <span class=\"status-value\" id=\"startVoltage\">0</span> V</div>\n";
- html += " </div>\n";
- html += " </div>\n";
- html += " \n";
- html += " <div class=\"container\">\n";
- html += " <h2>Program Selection</h2>\n";
- html += " <div class=\"select-program\">\n";
- html += " <label>Select Program:</label>\n";
- html += " <select id=\"programSelect\">\n";
- html += " <option value=\"1\">Program 1</option>\n";
- html += " <option value=\"2\">Program 2</option>\n";
- html += " <option value=\"3\">Program 3</option>\n";
- html += " </select>\n";
- html += " <button onclick=\"loadProgram()\">Load Program</button>\n";
- html += " </div>\n";
- html += " </div>\n";
- html += " \n";
- html += " <div class=\"container\">\n";
- html += " <h2>Parameter Control</h2>\n";
- html += " <div class=\"control-section\">\n";
- html += " <h3>Set Voltage (0-250V)</h3>\n";
- html += " <label>Value:</label>\n";
- html += " <input type=\"number\" id=\"setVoltageSetting\" min=\"0\" max=\"250\" value=\"100\">\n";
- html += " <button onclick=\"setParameter('SetV')\">Set</button>\n";
- html += " </div>\n";
- html += " \n";
- html += " <div class=\"control-section\">\n";
- html += " <h3>Delay Time (0.1-20.0s)</h3>\n";
- html += " <label>Value:</label>\n";
- html += " <input type=\"number\" id=\"delayTimeSetting\" min=\"1\" max=\"200\" value=\"5\" step=\"1\">\n";
- html += " <span> (x 0.1s)</span>\n";
- html += " <button onclick=\"setParameter('DT')\">Set</button>\n";
- html += " </div>\n";
- html += " \n";
- html += " <div class=\"control-section\">\n";
- html += " <h3>Hysteresis (Range 0.1-9.9V)</h3>\n";
- html += " <label>Value:</label>\n";
- html += " <input type=\"number\" id=\"hysteresisSetting\" min=\"1\" max=\"99\" value=\"80\" step=\"1\">\n";
- html += " <span> (x 0.1V)</span>\n";
- html += " <button onclick=\"setParameter('HyS')\">Set</button>\n";
- html += " </div>\n";
- html += " \n";
- html += " <div class=\"control-section\">\n";
- html += " <h3>Start Voltage (50-250V)</h3>\n";
- html += " <label>Value:</label>\n";
- html += " <input type=\"number\" id=\"startVoltageSetting\" min=\"50\" max=\"250\" value=\"100\">\n";
- html += " <button onclick=\"setParameter('StV')\">Set</button>\n";
- html += " </div>\n";
- html += " </div>\n";
- html += " \n";
- html += " <div class=\"container\">\n";
- html += " <h2>Torch Control</h2>\n";
- html += " <div class=\"control-section\">\n";
- html += " <button onclick=\"torchUp()\">Torch UP</button>\n";
- html += " <button onclick=\"torchDown()\" class=\"danger\">Torch DOWN</button>\n";
- html += " <button onclick=\"torchStop()\" class=\"danger\">STOP</button>\n";
- html += " </div>\n";
- html += " </div>\n";
- html += " \n";
- html += " <div id=\"response\" class=\"response\"></div>\n";
- html += " \n";
- html += " <script>\n";
- html += " const API_BASE = '/api';\n";
- html += " \n";
- html += " function updateStatus() {\n";
- html += " fetch(API_BASE + '/status')\n";
- html += " .then(response => response.json())\n";
- html += " .then(data => {\n";
- html += " document.getElementById('arcVoltage').textContent = (data.arc_voltage / 10).toFixed(1);\n";
- html += " document.getElementById('setVoltage').textContent = data.set_voltage;\n";
- html += " document.getElementById('program').textContent = data.program;\n";
- html += " document.getElementById('torchStatus').textContent = data.torch_status;\n";
- html += " document.getElementById('delayTime').textContent = (data.delay_time / 10).toFixed(1);\n";
- html += " document.getElementById('hysteresis').textContent = (data.hysteresis / 10).toFixed(1);\n";
- html += " document.getElementById('startVoltage').textContent = data.start_voltage;\n";
- html += " document.getElementById('programSelect').value = data.program;\n";
- html += " })\n";
- html += " .catch(error => showResponse('Error fetching status: ' + error, true));\n";
- html += " }\n";
- html += " \n";
- html += " function setParameter(param) {\n";
- html += " let value = 0;\n";
- html += " if (param === 'SetV') {\n";
- html += " value = document.getElementById('setVoltageSetting').value;\n";
- html += " } else if (param === 'DT') {\n";
- html += " value = document.getElementById('delayTimeSetting').value;\n";
- html += " } else if (param === 'HyS') {\n";
- html += " value = document.getElementById('hysteresisSetting').value;\n";
- html += " } else if (param === 'StV') {\n";
- html += " value = document.getElementById('startVoltageSetting').value;\n";
- html += " }\n";
- html += " \n";
- html += " fetch(API_BASE + '/param', {\n";
- html += " method: 'POST',\n";
- html += " headers: {\n";
- html += " 'Content-Type': 'application/json',\n";
- html += " },\n";
- html += " body: JSON.stringify({\n";
- html += " param: param,\n";
- html += " value: parseInt(value),\n";
- html += " program: parseInt(document.getElementById('programSelect').value)\n";
- html += " })\n";
- html += " })\n";
- html += " .then(response => response.json())\n";
- html += " .then(data => {\n";
- html += " if (data.success) {\n";
- html += " showResponse(param + ' set to ' + value);\n";
- html += " updateStatus();\n";
- html += " } else {\n";
- html += " showResponse('Error: ' + data.message, true);\n";
- html += " }\n";
- html += " })\n";
- html += " .catch(error => showResponse('Error: ' + error, true));\n";
- html += " }\n";
- html += " \n";
- html += " function loadProgram() {\n";
- html += " const program = document.getElementById('programSelect').value;\n";
- html += " fetch(API_BASE + '/param', {\n";
- html += " method: 'POST',\n";
- html += " headers: {\n";
- html += " 'Content-Type': 'application/json',\n";
- html += " },\n";
- html += " body: JSON.stringify({\n";
- html += " param: 'PROGRAM',\n";
- html += " value: parseInt(program)\n";
- html += " })\n";
- html += " })\n";
- html += " .then(response => response.json())\n";
- html += " .then(data => {\n";
- html += " if (data.success) {\n";
- html += " showResponse('Program ' + program + ' loaded');\n";
- html += " updateStatus();\n";
- html += " } else {\n";
- html += " showResponse('Error: ' + data.message, true);\n";
- html += " }\n";
- html += " })\n";
- html += " .catch(error => showResponse('Error: ' + error, true));\n";
- html += " }\n";
- html += " \n";
- html += " function torchUp() {\n";
- html += " fetch(API_BASE + '/control', {\n";
- html += " method: 'POST',\n";
- html += " headers: {\n";
- html += " 'Content-Type': 'application/json',\n";
- html += " },\n";
- html += " body: JSON.stringify({\n";
- html += " action: 'UP'\n";
- html += " })\n";
- html += " })\n";
- html += " .then(response => response.json())\n";
- html += " .then(data => {\n";
- html += " showResponse('Torch moving UP');\n";
- html += " updateStatus();\n";
- html += " })\n";
- html += " .catch(error => showResponse('Error: ' + error, true));\n";
- html += " }\n";
- html += " \n";
- html += " function torchDown() {\n";
- html += " fetch(API_BASE + '/control', {\n";
- html += " method: 'POST',\n";
- html += " headers: {\n";
- html += " 'Content-Type': 'application/json',\n";
- html += " },\n";
- html += " body: JSON.stringify({\n";
- html += " action: 'DOWN'\n";
- html += " })\n";
- html += " })\n";
- html += " .then(response => response.json())\n";
- html += " .then(data => {\n";
- html += " showResponse('Torch moving DOWN');\n";
- html += " updateStatus();\n";
- html += " })\n";
- html += " .catch(error => showResponse('Error: ' + error, true));\n";
- html += " }\n";
- html += " \n";
- html += " function torchStop() {\n";
- html += " fetch(API_BASE + '/control', {\n";
- html += " method: 'POST',\n";
- html += " headers: {\n";
- html += " 'Content-Type': 'application/json',\n";
- html += " },\n";
- html += " body: JSON.stringify({\n";
- html += " action: 'STOP'\n";
- html += " })\n";
- html += " })\n";
- html += " .then(response => response.json())\n";
- html += " .then(data => {\n";
- html += " showResponse('Torch STOPPED');\n";
- html += " updateStatus();\n";
- html += " })\n";
- html += " .catch(error => showResponse('Error: ' + error, true));\n";
- html += " }\n";
- html += " \n";
- html += " function showResponse(message, isError = false) {\n";
- html += " const response = document.getElementById('response');\n";
- html += " response.textContent = message;\n";
- html += " response.style.display = 'block';\n";
- html += " if (isError) {\n";
- html += " response.classList.add('error');\n";
- html += " } else {\n";
- html += " response.classList.remove('error');\n";
- html += " }\n";
- html += " }\n";
- html += " \n";
- html += " // Update status every 500ms\n";
- html += " updateStatus();\n";
- html += " setInterval(updateStatus, 500);\n";
- html += " </script>\n";
- html += "</body>\n";
- html += "</html>\n";
- 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 (Range 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