HaleDesign / TorchHeightController

Arduino based THC that read plasma cutter voltage and send Up and Down signals to Plasma Torch Actuator to adjust voltage to target value.
GNU General Public License v3.0
39 stars 17 forks source link

Current position not working #2

Open mikeyd2673 opened 3 years ago

mikeyd2673 commented 3 years ago

Hello I've been watching your videos and want to say thank you I am learning alot. I'm right now trying to build your torch height control for my home made cnc plasma cutter. I cant get it to work I have tried the uno and the mega The screen is there and it is talking to the arduino it reads the plasma voltage simulated by a potentiometer the set point reads 119.14 But my current position stays at zero no matter if I turn the potentiometer all the way up or down. The current position never moves Can you please help me to figure out were im going wrong please Thank you for your time

LinuxEverywhere commented 9 months ago

I am forking this to work on an ESP32 with BT. It seems the error is in calculating targetInput in the main process() block:

  if (SetPoint > Input)
  {
    targetInput = Input - SetPoint + SetPoint;
    output = THCPID.step(SetPoint, targetInput);
    pos = pos + output;
  }
  else
  {
    targetInput = SetPoint - Input + SetPoint;
    output = THCPID.step(SetPoint, targetInput);
    pos = pos - output;
  }

This makes more sense: ... targetInput = Input - SetPoint ... targetInput = SetPoint - Input ...

brennan4 commented 2 months ago

i have the same issue with no movement did any figure what issue is?

LinuxEverywhere commented 2 months ago

I completely refactored it and dropped the pid methodology and made a custom variable acceleration one, using non-blocking loops. The esp32 will loop through this 4X per clock. I haven't finished it as the HF start circuit is blowing out the esp32 remote detector circuit - with HF Voltages in the >1KV range. The remote esp32 has a sim mode to simulate sudden voltage jumps to test the controller response. I was happy with the contollers response in simulator mode.

main loop snippet: (with debug code) ...

void setup() { debug = true; pinMode(TORCH_ON_PIN, INPUT); if (debug) { Serial.begin(115200); Serial.println("Starting THC Controller");

Saved.clear();

} pinMode(TORCH_ON_PIN, INPUT_PULLUP); pinMode(OUTPUT_SWITCH_PIN, OUTPUT);

ifdef _TB6600

stepper.setPinsInverted(true, true);

endif

Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2); SetPoint = 9000; startDisplay(); startBLE(); newPos = 0; Accel = (96 * steps_per_mm / 60);

stepper.setMaxSpeed(6 * Accel); //adjust to cnc table limits stepper.setAcceleration(Accel); //adjust to cnc table limits stepper.setMinPulseWidth(15000000 / Accel / steps_per_mm); //~117 microseconds a = l_accel; b = 0; isEnabled = false; sim = false; delayStart = true; write_bof(); digitalWrite(OUTPUT_SWITCH_PIN, LOW); if (pSim && pSim->canWrite()) { THCNex.writeNum("db0.val", (int)sim); pSim->writeValue((bool)sim); } if (debug) { Serial.println(String(SetPoint) + "\t" + String(HighLow) + "\t" + String(AccelFactor) + "\t" + String(steps_per_mm) + "\t" + String(maxZ) + "\t" + String(threshold)) + "\t" + String(sim); } }

// This is the Arduino main loop function. void loop() {

while (Input >= threshold && isEnabled) { THCNex.NextionListen(); checkBLE();

if (digitalRead(TORCH_ON_PIN) == LOW) {
  if (delayStart) {
    md = millis();
    delayStart = false;

  }
  if (md -millis()>= 1000 ) {digitalWrite(OUTPUT_SWITCH_PIN, HIGH);}
  if (newVolt && md -millis()>= 1100) {

    newVolt = false;

    voltDiff = SetPoint - Input;

    if (voltDiff < 0) {

      voltDiff *= -1;
    }

    newPos = (long)(map(voltDiff, 0, threshold, 0, maxZ));  //hockey stick mapping of values
    if (newPos > maxZ) { newPos = maxZ; }

    //detect high-low acceleration regime
    if (newPos > maxZ / HighLow) {

      //short delay trigger to high accelleration & to ignore spikes
      if (a <= l_accel) {
        a = 0;
        b = 1;
      }
      a += 1 * b;
      if (a >= h_acel) {
        stepper.setAcceleration(Accel * AccelFactor);
        hSpeed = true;
        a = h_acel;
        b = 0;
      }
    } else {

      //long trigger delay to low accelleration
      if (a >= h_acel) {
        b = 1;
      }
      a -= 1 * b;
      if (a <= l_accel) {
        stepper.setAcceleration(Accel);
        hSpeed = false;
        a = l_accel;
        b = 0;
      }
    }

    if (SetPoint < Input) {

      newPos *= -1;
    }
    cPos = stepper.currentPosition();
    sSpeed = stepper.speed();
    if (reset0 && abs(newPos) < steps_per_mm) {

      zPos += newPos;

      stepper.setCurrentPosition(cPos + newPos);
      stepper.setSpeed(sSpeed);
      reset0 = false;
      if (debug) { message2 += "\tzPos is: " + String(zPos); }
    }
    if (oldPos * sSpeed < 0 && hSpeed) {
      stepper.setAcceleration(Accel * AccelFactor * 1.5);
      if (debug) { Serial.print(String("High") + "\t"); }
    } else {
      if (debug) { Serial.print(" \t"); }
    }
    oldPos = newPos;

    //update stepper every t slice of time
    stepper.moveTo(newPos);
    if (debug) {
      Serial.println(String(m - ml) + "\t" + String(Input) + "\t" + String(newPos) + "\t" + String(cPos) + "\t" + String(float(stepper.speed() * 60 / steps_per_mm)) + "\t" + String(a) + message2);
      message2 = "";
      ml = m;
    }
    if (millis() - mll > t) {
      report();
      THCNex.NextionListen();
      mll = millis();
    }
  }
  stepper.run();

} else {
  mz = millis();
  if ((cPos + zPos) != 0) {
    stepper.setCurrentPosition(stepper.currentPosition() + zPos);
    zPos = 0;
    stepper.setAcceleration(Accel);
    stepper.runToNewPosition(0);
    cPos = stepper.currentPosition();

    report();
    message2 += "\tz return to 0 time: " + String((millis() - mz) / 1000) + " secs";
  } else {

    if (millis() - mll > t) {
      if (debug) {
        Serial.println(String(m - ml) + "\t" + String(Input) + "\t" + String(newPos) + "\t" + String(cPos) + "\t" + String(float(stepper.speed() * 60 / steps_per_mm)) + "\t" + String(a) + message2);
        message2 = "";
        ml = m;
      }
      report();
      THCNex.NextionListen();
      mll = millis();
    }
  }
  if (digitalRead(OUTPUT_SWITCH_PIN) == HIGH) {
    digitalWrite(OUTPUT_SWITCH_PIN, LOW);
  }
}

} while (Input < threshold && isEnabled) {

checkBLE();
if (debug && newVolt) {
  newVolt = false;
  Serial.println("LowThsld\t" + String(m - ml) + "\t" + String(Input) + "\t" + String(newPos) + "\t" + String(cPos) + "\t" + String(float(stepper.speed() * 60 / steps_per_mm)) + "\t" + String(a) + message2);
  message2 = "";
  ml = m;
}
if (millis() - mll > t) {
  report();
  THCNex.NextionListen();
  mll = millis();
}
stepper.run();

}

while (isEnabled == false) {

checkBLE();
if (newVolt && debug) {
  newVolt = false;
  Serial.println(" \t" + String(millis() - mll) + "\t" + String(Input) + "\t\t" + String(stepper.currentPosition()) + "\t" + String(isEnabled) + "\t" + message2);
  message2 = "";
}
if (millis() - mll > t) {
  report();
  THCNex.NextionListen();
  mll = millis();
}
stepper.run();

} } ...

brennan4 commented 2 months ago

I have tried to update the code and bring in a start function in order to run at every new job and give the plasma controller a feed back to show the home here is the code but still not getting the position on the HMI screen.

*/

// Check hardware

if !defined(__AVR_ATmega2560__)

#error Not a Mega2560!

endif

include // Include PID Library

include // Include EasyNextionLibrary

include

include

// Pin definitions const int startSignalPin = 5; // Start signal from Plasma controller const int limitSwitchPin = 6; // Limit switch for Z-axis const int statusSignalPin = 12; // Status signal to Plasma controller

const int dirPin = 2; // Direction pin for Z-axis motor (assumed direction pin for motor control) const int stepPin = 3; // Step pin for Z-axis motor (assumed step pin for motor control)

// Constants const int stepsPerRevolution = 200; // Number of steps per revolution for the motor

// The variables to be using be the code below EasyNex THCNex(Serial1); // Create an object of EasyNex class with the name < TCHNex > // Set as parameter the Serial1 for Mega2560 you are going to use // Default baudrate 9600

define PLASMA_INPUT_PIN A1

define STEP_PIN 3 // Step

define DIR_PIN 4 // Direction

// MKS Drive board enable pin in 13 // No need to define because it uses the onboard LED on the Arduino Uno R3

// Define a stepper driver and the pins it will use AccelStepper stepper = AccelStepper(stepper.DRIVER, STEP_PIN, DIR_PIN);

// Define Variables double Input = 0; float targetInput; float gap; float scale; long threshold; long currentGap; uint32_t oldDelay; uint32_t arcStabilizeDelay; long SetPoint = 0; long CalibrationOffset = 0;

// Specify the links and initial tuning parameters float aggKp = 0.175, aggKi = 0.1, aggKd = 0.1; float Kp = 0.075, Ki = 0.01, Kd = 0.01; float Hz = 8; int output_bits = 16; bool output_signed = true; bool alreadySetColor = false;

FastPID THCPID(Kp, Ki, Kd, Hz, output_bits, output_signed);

// Set EEPROM Addresses for Setpoint saving int addressPage1 = 10; int addressPage2 = 20; int addressPage3 = 30; int addressPage4 = 40; int addressPage5 = 50; int addressPage6 = 60; int addressGap = 70; int addressThreshold = 80; int addressDelay = 90; int addressSteps = 100; int addressCalibrate = 110; int addressMaxpos = 120; int addressMinpos = 130; int addressAP = 200; int addressAI = 300; int addressAD = 400; int addressCP = 500; int addressCI = 600; int addressCD = 700; int addressScale = 800;

long defaultSetpoint = 10900;

long SetpointPage1 = 0; long SetpointPage2 = 0; long SetpointPage3 = 0; long SetpointPage4 = 0; long SetpointPage5 = 0; long SetpointPage6 = 0;

long CurrentPageNumber = 0; long SavedPage = 0;

// Movement Variables long steps_per_mm = 200; float pos = 0; float adjpos = 0; long minPos = -(40 steps_per_mm); long maxPos = (40 steps_per_mm); long moveAmt = 0; uint8_t output = 0;

// State Management bool homingDone = false; // State flag to manage homing process

// The Setup function runs once when you press reset or power the board void setup() { // Initialize digital pin LED_BUILTIN as an output. // This is used to enable the MKS driver board. Plus it flashes and flashes are cool. pinMode(LED_BUILTIN, OUTPUT);

// Initialize pins
pinMode(startSignalPin, INPUT);
pinMode(limitSwitchPin, INPUT_PULLUP); // Assuming the limit switch is normally open
pinMode(statusSignalPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(stepPin, OUTPUT);

// Set initial state of the status signal
digitalWrite(statusSignalPin, LOW);

// Set the direction for moving the Z-axis down
digitalWrite(dirPin, LOW); // LOW might represent down, depending on your setup

// Begin serial communication for debugging
Serial.begin(9600);

// Begin the object with a baud rate of 9600
THCNex.begin(); // If no parameter was given in the begin(), the default baud rate of 9600 will be used
while (!Serial) {
    ; // Wait for serial port to connect. Needed for native USB port only
}

// Initialize the variables we're linked to
// Load EEPROM Addresses for Setpoints or set defaults
SetpointPage1 = readLongFromEEPROM(addressPage1);
if (SetpointPage1 == 0) {
    SetpointPage1 = defaultSetpoint;
}
SetpointPage2 = readLongFromEEPROM(addressPage2);
if (SetpointPage2 == 0) {
    SetpointPage2 = defaultSetpoint;
}
SetpointPage3 = readLongFromEEPROM(addressPage3);
if (SetpointPage3 == 0) {
    SetpointPage3 = defaultSetpoint;
}
SetpointPage4 = readLongFromEEPROM(addressPage4);
if (SetpointPage4 == 0) {
    SetpointPage4 = defaultSetpoint;
}
SetpointPage5 = readLongFromEEPROM(addressPage5);
if (SetpointPage5 == 0) {
    SetpointPage5 = defaultSetpoint;
}
SetpointPage6 = readLongFromEEPROM(addressPage6);
if (SetpointPage6 == 0) {
    SetpointPage6 = defaultSetpoint;
}

scale = readFloatFromEEPROM(addressScale); // float
if (scale == 0) {
    scale = 1;
}
gap = readLongFromEEPROM(addressGap);
if (gap == 0) {
    gap = 500;
}
threshold = readLongFromEEPROM(addressThreshold);
if (threshold == 0) {
    threshold = 4000;
}
arcStabilizeDelay = readLongFromEEPROM(addressDelay);
if (arcStabilizeDelay == 0) {
    arcStabilizeDelay = 150;
}
steps_per_mm = readLongFromEEPROM(addressSteps);
if (steps_per_mm == 0) {
    steps_per_mm = 200;
}
maxPos = readLongFromEEPROM(addressMaxpos);
if (maxPos == 0) {
    maxPos = 40 * steps_per_mm;
}
minPos = readLongFromEEPROM(addressMinpos);
if (minPos == 0) {
    minPos = -(40 * steps_per_mm);
}
aggKp = readFloatFromEEPROM(addressAP); // float
if (aggKp == 0) {
    aggKp = 0.175;
}
aggKi = readFloatFromEEPROM(addressAI); // float
if (aggKi == 0) {
    aggKi = 0.1;
}
aggKd = readFloatFromEEPROM(addressAD); // float
if (aggKd == 0) {
    aggKd = 0.1;
}
Kp = readFloatFromEEPROM(addressCP); // float
if (Kp == 0) {
    Kp = 0.075;
}
Ki = readFloatFromEEPROM(addressCI); // float
if (Ki == 0) {
    Ki = 0.01;
}
Kd = readFloatFromEEPROM(addressCD); // float
if (Kd == 0) {
    Kd = 0.01;
}
CalibrationOffset = readLongFromEEPROM(addressCalibrate);
if (CalibrationOffset == 0) {
    CalibrationOffset = 0;
}

// Wait for Nextion Screen to bootup
delay(2500);
THCNex.writeNum("CustomSetPoint.val", SetpointPage1);
THCNex.writeNum("CustomSetPoint.val", SetpointPage1); // Make sure it set
THCNex.writeNum("CustomSetPoint.val", SetpointPage1); // One more time
SetPoint = SetpointPage1;

// Setup Stepper Driver
stepper.setMaxSpeed(150000); // Through experimentation I found these values to work... Change for your setup.
stepper.setAcceleration(20000);
// Enable MKS Driver Board
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);

}

// The Loop function runs over and over again forever void loop() { // Check if start signal is received if (digitalRead(startSignalPin) == HIGH) { homingDone = false; // Reset homingDone flag to re-run homing sequence runHomeSequence(); homingDone = true; }

if (homingDone) {
    while (CurrentPageNumber <= 6 || CurrentPageNumber == 11) {
        Input = map(analogRead(PLASMA_INPUT_PIN), 0, 1023, 0, 25000) + CalibrationOffset;
        process(); // This is the main method of the application, it calculates position and move steps if Input Voltage is over threshold.
        report();
        THCNex.NextionListen();
    }
} else {
    THCNex.NextionListen();
}

}

void runHomeSequence() { Serial.println("Start signal received. Moving Z-axis down...");

// Move the Z-axis down until the limit switch is activated
while (digitalRead(limitSwitchPin) == HIGH) {
    moveZAxisDown();
}

// Send status signal back to the Plasma controller
digitalWrite(statusSignalPin, HIGH);
Serial.println("Limit switch hit. Status signal sent to Plasma controller.");

// Stop the motor (if necessary)
stopZAxis();

// Wait for the next start signal (you can add a delay or other logic here)
delay(1000); // Optional delay for debouncing or other reasons
digitalWrite(statusSignalPin, LOW);

}

void moveZAxisDown() { // Function to move the Z-axis down by one step digitalWrite(stepPin, HIGH); delayMicroseconds(500); // Adjust the delay as needed for your motor speed digitalWrite(stepPin, LOW); delayMicroseconds(500); // Adjust the delay as needed for your motor speed }

void stopZAxis() { // Function to stop the Z-axis movement // If using a stepper motor driver, you may not need additional code here // Just ensure that the step and direction signals are not changing // You might want to disable the motor driver or set it to an idle state

}

void process() { oldDelay = micros(); while (Input > (threshold + CalibrationOffset)) { // Only move if cutting by checking for voltage above a threshold level if (micros() - oldDelay >= arcStabilizeDelay) { // Wait for arc to stabilize typically 100-300ms Input = map(analogRead(PLASMA_INPUT_PIN), 0, 1023, 0, 25000) + CalibrationOffset; // Get new plasma arc voltage and convert to millivolts

        currentGap = abs(SetPoint - Input); // Distance away from setpoint
        if (currentGap < gap) {
            THCPID.setCoefficients(Kp, Ki, Kd, Hz); // We're close to setpoint, use conservative tuning parameters
        } else {
            THCPID.setCoefficients(aggKp, aggKi, aggKd, Hz); // We're far from setpoint, use aggressive tuning parameters
        }

        if (SetPoint > Input) {
            targetInput = Input - SetPoint + SetPoint;
            output = THCPID.step(SetPoint, targetInput);
            pos = pos + output;
        } else {
            targetInput = SetPoint - Input + SetPoint;
            output = THCPID.step(SetPoint, targetInput);
            pos = pos - output;
        }

        // Validate move is within range
        if (pos >= maxPos) {
            pos = maxPos;
        }
        if (pos <= minPos) {
            pos = minPos;
        }

        // Do move
        stepper.moveTo(pos);
        while (stepper.distanceToGo() != 0) {
            stepper.run();
        }

        report(); // Report plasma voltage and position
        // format();
    }
}
// After cut reset height
pos = 0;
// Do move
stepper.moveTo(pos);
while (stepper.distanceToGo() != 0) {
    stepper.run();
}

}

void trigger0() { // Not used because bug with Nextion screen not updating screen loaded event. // THCNex.writeNum("dp", SavedPage);

}

void trigger1() { CurrentPageNumber = THCNex.readNumber("dp"); SetPoint = THCNex.readNumber("CustomSetPoint.val"); if (CurrentPageNumber != 777777 && SetPoint != 777777) { switch (CurrentPageNumber) { case 1: SetPoint = SetpointPage1; // Write a few times to make sure... Nextion screen has a nasty habit of ignoring update commands on boot. THCNex.writeNum("CustomSetPoint.val", SetpointPage1); THCNex.writeNum("CustomSlide.val", SetpointPage1); THCNex.writeNum("CustomSetPoint.val", SetpointPage1); THCNex.writeNum("CustomSlide.val", SetpointPage1); THCNex.writeNum("CustomSetPoint.val", SetpointPage1); THCNex.writeNum("CustomSlide.val", SetpointPage1); break; case 2:

            SetPoint = SetpointPage2;
            THCNex.writeNum("CustomSetPoint.val", SetpointPage2);
            THCNex.writeNum("CustomSlide.val", SetpointPage2);
            break;
        case 3:
            SetPoint = SetpointPage3;
            THCNex.writeNum("CustomSetPoint.val", SetpointPage3);
            THCNex.writeNum("CustomSlide.val", SetpointPage3);
            break;
        case 4:

            SetPoint = SetpointPage4;
            THCNex.writeNum("CustomSetPoint.val", SetpointPage4);
            THCNex.writeNum("CustomSlide.val", SetpointPage4);
            break;
        case 5:
            SetPoint = SetpointPage5;
            THCNex.writeNum("CustomSetPoint.val", SetpointPage5);
            THCNex.writeNum("CustomSlide.val", SetpointPage5);
            break;
        case 6:
            SetPoint = SetpointPage6;
            THCNex.writeNum("CustomSetPoint.val", SetpointPage6);
            THCNex.writeNum("CustomSlide.val", SetpointPage6);
            break;
        default:
            break;

    }

}

}

void trigger2() { CurrentPageNumber = THCNex.readNumber("dp"); SetPoint = THCNex.readNumber("CustomSetPoint.val"); if (CurrentPageNumber != 777777 && SetPoint != 777777) { switch (CurrentPageNumber) { case 1: SetpointPage1 = SetPoint; writeLongIntoEEPROM(addressPage1, SetpointPage1); break; case 2: SetpointPage2 = SetPoint; writeLongIntoEEPROM(addressPage2, SetpointPage2); break; case 3: SetpointPage3 = SetPoint; writeLongIntoEEPROM(addressPage3, SetpointPage3); break; case 4: SetpointPage4 = SetPoint; writeLongIntoEEPROM(addressPage4, SetpointPage4); break; case 5: SetpointPage5 = SetPoint; writeLongIntoEEPROM(addressPage5, SetpointPage5); break; case 6: SetpointPage6 = SetPoint; writeLongIntoEEPROM(addressPage6, SetpointPage6); break; default: break; } } }

void trigger3() { pos = pos + (scale * steps_per_mm); stepper.moveTo(pos); while (stepper.distanceToGo() != 0) { stepper.run();

}
THCNex.writeNum("x2.val", (int)(pos / 2));

}

void trigger4() { pos = pos - (scale * steps_per_mm); stepper.moveTo(pos); while (stepper.distanceToGo() != 0) { stepper.run();

}
THCNex.writeNum("x2.val", (int)(pos / 2));

}

void trigger5() {

minPos = minPos + (scale * steps_per_mm);

THCNex.writeNum("x1.val", (int)(minPos / 2));
writeLongIntoEEPROM(addressMinpos, minPos);

}

void trigger6() {

minPos = minPos - (scale * steps_per_mm);

THCNex.writeNum("x1.val", (int)(minPos / 2));
writeLongIntoEEPROM(addressMinpos, minPos);

}

void trigger7() {

maxPos = maxPos + (scale * steps_per_mm);
THCNex.writeNum("x0.val", (int)(maxPos / 2));
writeLongIntoEEPROM(addressMaxpos, maxPos);

}

void trigger8() { maxPos = maxPos - (scale * steps_per_mm); THCNex.writeNum("x0.val", (int)(maxPos / 2)); writeLongIntoEEPROM(addressMaxpos, maxPos); }

void trigger9() { gap = gap + (scale * 100); THCNex.writeNum("x2.val", (int)(gap)); writeLongIntoEEPROM(addressGap, gap); }

void trigger10() {

gap = gap - (scale * 100);
THCNex.writeNum("x2.val", (int)(gap));
writeLongIntoEEPROM(addressGap, gap);

}

void trigger11() {

threshold = threshold + (scale * 100);
THCNex.writeNum("x1.val", (int)(threshold));
writeLongIntoEEPROM(addressThreshold, threshold);

}

void trigger12() {

threshold = threshold - (scale * 100);
THCNex.writeNum("x1.val", (int)(threshold));
writeLongIntoEEPROM(addressThreshold, threshold);

}

void trigger13() { arcStabilizeDelay = arcStabilizeDelay + (scale * 100);

THCNex.writeNum("x0.val", (int)(arcStabilizeDelay / 10));
writeLongIntoEEPROM(addressDelay, arcStabilizeDelay);

}

void trigger14() { arcStabilizeDelay = arcStabilizeDelay - (scale * 100);

THCNex.writeNum("x0.val", (int)(arcStabilizeDelay / 10));
writeLongIntoEEPROM(addressDelay, arcStabilizeDelay);

}

void trigger15() { steps_per_mm = steps_per_mm + scale;

THCNex.writeNum("x3.val", (int)(100 * steps_per_mm));
writeLongIntoEEPROM(addressSteps, steps_per_mm);

}

void trigger16() { steps_per_mm = steps_per_mm - scale;

THCNex.writeNum("x3.val", (int)(100 * steps_per_mm));
writeLongIntoEEPROM(addressSteps, steps_per_mm);

}

void trigger17() {

aggKp = aggKp + scale * 0.01;
THCNex.writeNum("x2.val", (int)(1000 * aggKp));
writeFloatIntoEEPROM(addressAP, aggKp);

}

void trigger18() {

aggKp = aggKp - scale * 0.01;
THCNex.writeNum("x2.val", (int)(1000 * aggKp));
writeFloatIntoEEPROM(addressAP, aggKp);

}

void trigger19() {

aggKi = aggKi + scale * 0.01;
THCNex.writeNum("x1.val", (int)(1000 * aggKi));
writeFloatIntoEEPROM(addressAI, aggKi);

}

void trigger20() {

aggKi = aggKi - scale * 0.01;
THCNex.writeNum("x1.val", (int)(1000 * aggKi));
writeFloatIntoEEPROM(addressAI, aggKi);

}

void trigger21() {

aggKd = aggKd + scale * 0.01;
THCNex.writeNum("x0.val", (int)(1000 * aggKd));
writeFloatIntoEEPROM(addressAD, aggKd);

}

void trigger22() {

aggKd = aggKd - scale * 0.01;
THCNex.writeNum("x0.val", (int)(1000 * aggKd));
writeFloatIntoEEPROM(addressAD, aggKd);

}

void trigger23() {

Kp = Kp + scale * 0.01;
THCNex.writeNum("x2.val", (int)(1000 * Kp));
writeFloatIntoEEPROM(addressCP, Kp);

}

void trigger24() {

Kp = Kp - scale * 0.01;
THCNex.writeNum("x2.val", (int)(1000 * Kp));
writeFloatIntoEEPROM(addressCP, Kp);

}

void trigger25() {

Ki = Ki + scale * 0.01;
THCNex.writeNum("x1.val", (int)(1000 * Ki));
writeFloatIntoEEPROM(addressCI, Ki);

}

void trigger26() {

Ki = Ki - scale * 0.01;
THCNex.writeNum("x1.val", (int)(1000 * Ki));
writeFloatIntoEEPROM(addressCI, Ki);

}

void trigger27() {

Kd = Kd + scale * 0.01;
THCNex.writeNum("x0.val", (int)(1000 * Kd));
writeFloatIntoEEPROM(addressCD, Kd);

}

void trigger28() {

Kd = Kd - scale * 0.01;
THCNex.writeNum("x0.val", (int)(1000 * Kd));
writeFloatIntoEEPROM(addressCD, Kd);

}

void trigger29() { if (scale == 0.1) { THCNex.writeNum("bt0.val", 1); THCNex.writeNum("bt1.val", 0); THCNex.writeNum("bt2.val", 0); } if (scale == 1.0) { THCNex.writeNum("bt0.val", 0); THCNex.writeNum("bt1.val", 1); THCNex.writeNum("bt2.val", 0); } if (scale == 10.0) { THCNex.writeNum("bt0.val", 0); THCNex.writeNum("bt1.val", 0); THCNex.writeNum("bt2.val", 1); } THCNex.writeNum("x2.val", (int)(pos / 2)); THCNex.writeNum("x0.val", (int)(maxPos / 2)); THCNex.writeNum("x1.val", (int)(minPos / 2)); }

void trigger30() { if (scale == 0.1) { THCNex.writeNum("bt0.val", 1); THCNex.writeNum("bt1.val", 0); THCNex.writeNum("bt2.val", 0); } if (scale == 1.0) { THCNex.writeNum("bt0.val", 0); THCNex.writeNum("bt1.val", 1); THCNex.writeNum("bt2.val", 0); } if (scale == 10.0) { THCNex.writeNum("bt0.val", 0); THCNex.writeNum("bt1.val", 0); THCNex.writeNum("bt2.val", 1); } THCNex.writeNum("x2.val", (int)(gap)); THCNex.writeNum("x1.val", (int)(threshold)); THCNex.writeNum("x0.val", (int)(arcStabilizeDelay / 10)); THCNex.writeNum("x3.val", (int)(100 * steps_per_mm)); }

void trigger31() {

if (THCNex.readNumber("bt0.val") == 1) {
    scale = 0.1;
}

if (THCNex.readNumber("bt1.val") == 1) {
    scale = 1;

}

if (THCNex.readNumber("bt2.val") == 1) {
    scale = 10;
}

}

void trigger32() {

if (scale == 0.1) {

    THCNex.writeNum("bt0.val", 1);
    THCNex.writeNum("bt1.val", 0);
    THCNex.writeNum("bt2.val", 0);
}
if (scale == 1.0) {

    THCNex.writeNum("bt0.val", 0);
    THCNex.writeNum("bt1.val", 1);
    THCNex.writeNum("bt2.val", 0);
}
if (scale == 10.0) {

    THCNex.writeNum("bt0.val", 0);
    THCNex.writeNum("bt1.val", 0);
    THCNex.writeNum("bt2.val", 1);
}
THCNex.writeNum("x2.val", (int)(1000 * aggKp));
THCNex.writeNum("x1.val", (int)(1000 * aggKi));

THCNex.writeNum("x0.val", (int)(1000 * aggKd));

}

void trigger33() { if (scale == 0.1) { THCNex.writeNum("bt0.val", 1); THCNex.writeNum("bt1.val", 0); THCNex.writeNum("bt2.val", 0); } if (scale == 1.0) { THCNex.writeNum("bt0.val", 0); THCNex.writeNum("bt1.val", 1); THCNex.writeNum("bt2.val", 0); } if (scale == 10.0) { THCNex.writeNum("bt0.val", 0); THCNex.writeNum("bt1.val", 0); THCNex.writeNum("bt2.val", 1); } THCNex.writeNum("x2.val", (int)(1000 Kp)); THCNex.writeNum("x1.val", (int)(1000 Ki)); THCNex.writeNum("x0.val", (int)(1000 * Kd));

}

void trigger34() {

THCNex.writeNum("CustomSetPoint.val", CalibrationOffset);

}

void trigger35() { int cali = THCNex.readNumber("CustomSetPoint.val"); if (cali != 77777) { CalibrationOffset = cali; writeLongIntoEEPROM(addressCalibrate, CalibrationOffset);

}

}

void report() { THCNex.writeNum("PV.val", (int)Input); THCNex.writeNum("POS.val", (int)(pos / 2)); }

void format() { if (pos > 1 && pos < 1000) { THCNex.writeNum("POS.pco", 4065); } if (pos < -1 && pos > -1000) { THCNex.writeNum("POS.pco", 63488); } }

// +++++++++++++ Helpers ++++++++++++++++ void writeStringIntoEEPROM(char add, String data) {

int _size = data.length();
int i;
for (i = 0; i < _size; i++) {

    EEPROM.write(add + i, data[i]);
}
EEPROM.write(add + _size, '\0'); // Add termination null character for String Data

}

String read_StringFromEEPROM(char add) {

int i;
char data[100]; // Max 100 Bytes
int len = 0;
unsigned char k;
k = EEPROM.read(add);
while (k != '\0' && len < 500) { // Read until null character

    k = EEPROM.read(add + len);
    data[len] = k;
    len++;
}
data[len] = '\0';
return String(data);

}

void writeIntIntoEEPROM(int address, int number) {

EEPROM.write(address, number >> 8);
EEPROM.write(address + 1, number & 0xFF);

}

int readIntFromEEPROM(int address) {

return (EEPROM.read(address) << 8) + EEPROM.read(address + 1);

}

void writeLongIntoEEPROM(int address, long number) {

EEPROM.write(address, (number >> 24) & 0xFF);
EEPROM.write(address + 1, (number >> 16) & 0xFF);
EEPROM.write(address + 2, (number >> 8) & 0xFF);
EEPROM.write(address + 3, number & 0xFF);

}

long readLongFromEEPROM(int address) {

return ((long)EEPROM.read(address) << 24) + ((long)EEPROM.read(address + 1) << 16) + ((long)EEPROM.read(address + 2) << 8) + ((long)EEPROM.read(address + 3));

}

void writeFloatIntoEEPROM(int address, float num) {

byte* f = (byte*)(void*)&num;
for (int x = 0; x < 4; x++) {

    EEPROM.write(address + (x * 4), *f++);
}

}

float readFloatFromEEPROM(int address) {

float eevalue;
for (int x = 0; x < 4; x++) {

    eevalue = eevalue + (float)EEPROM.read(address + (x * 4));       
}
return eevalue;

}

LinuxEverywhere commented 2 months ago

here is how I set up the display. The Esp32 libs do not support the eeprom lib so I converted to the Preferences.h to store values to disk

include

include // Include EasyNextionLibrary

include

//#include

include

define TORCH_ON_PIN 27

define OUTPUT_SWITCH_PIN 14

define RXD2 16

define TXD2 17

define _TB6600 /_28BYJ /

ifdef _TB6600

define STEP_PIN 2 // steps

define DIR_PIN 15 //dir

AccelStepper stepper = AccelStepper(stepper.DRIVER, STEP_PIN, DIR_PIN); static unsigned short steps_per_mm = 160;

endif

ifdef _28BYJ

define FULLSTEP 4

define IN1 4 // IN1 on ULN2003 ==> Blue on 28BYJ-48

define IN2 0 // IN2 on ULN2004 ==> Pink on 28BYJ-48

define IN3 2 // IN3 on ULN2003 ==> Yellow on 28BYJ-48

define IN4 15 // IN4 on ULN2003 ==> Orange on 28BYJ-48

AccelStepper stepper(FULLSTEP, IN1, IN3, IN2, IN4); static unsigned short steps_per_mm = 320;

endif

static bool debug, sim, delayStart = true; static bool newVolt, reset0, isEnabled = false; unsigned long m, ml, mll, mz, md = 0; unsigned short t = 500; static unsigned long SetPoint, Input = 11000; //setpoint, measured voltage static String message2; Preferences Saved;

define Setpoint1 10000

define Setpoint2 8000

define Setpoint3 7000

define Setpoint4 6500

define Setpoint5 11000

define Setpoint6 12000

static unsigned short tmp, CurrentPageNumber = 1; //statc unsigned short SavedPage = 1;

EasyNex THCNex(Serial2);

static unsigned short threshold = 4096; //both low voltage lockout & upper control limit to calculate newPos long int voltDiff = 0; //difference of measured voltage and setpoint

static bool hSpeed = false; //high-low accelleration flag static unsigned short Z = 8; static unsigned short maxZ = steps_per_mm Z; // max +- z movement in steps / static float AccelFactor = 2.0; static float HighLow = 2.2; static unsigned short Accel = (96 * steps_per_mm / 60); //medium acceleration steps-per-sec-sec static int newPos, oldPos, cPos, zPos, sSpeed = 0; // caclulated desired stepper movement short int a, b = 0; //logic variables to switch between high/low acceleration modes static short int dir;

define h_acel 4 // logic trigger delay to high accel

define l_accel -6 // logic trigger delay to low accel

tatic bool doConnect = false; static uint32_t scanTime = 0; /* 0 = scan forever /

void OpenSaved(bool open = true) { if (open) { Saved.begin("Saved", false); } else { Saved.end(); } }

... ble code not included ...

void startDisplay() {

OpenSaved(true);

HighLow = Saved.getFloat("HighLow", 2.2); if (HighLow < 1) { HighLow = 1; } if (HighLow > 3) { HighLow = 3; } AccelFactor = Saved.getFloat("AccelFactor", 2.0); if (AccelFactor <= 1) { AccelFactor = 1; } if (AccelFactor > 2.5) { AccelFactor = 2.5; }

steps_per_mm = Saved.getUShort("Steps", 160);

Z = Saved.getUShort("Z", 8);

maxZ = steps_per_mm * Z;

threshold = Saved.getUShort("Threshold", 4096);

CurrentPageNumber = Saved.getUShort("dp", 1);

OpenSaved(false);

THCNex.begin(9600);

THCNex.writeStr("page " + String(CurrentPageNumber)); // For synchronizing Nextion page in case of reset to Arduino }

void write_bof() { if (isEnabled) { THCNex.writeStr("bof.txt", "On"); } else { THCNex.writeStr("bof.txt", "Off"); } }

... void setup and main loops here ....

the display routines:

void report() //report plasma voltage and position { THCNex.writeNum("PV.val", Input); THCNex.writeNum("cPos.val", (long int)(100 * cPos / steps_per_mm)); }

void trigger0() //Set last page used on startup loaded event { //not used because bug with Nextion screen not updating screen loaded event. //THCNex.writeNum("dp", SavedPage); }

void trigger1() //update page and slider to stored values { CurrentPageNumber = THCNex.readNumber("dp");

if (CurrentPageNumber <= 8) {

OpenSaved(true);

switch (CurrentPageNumber) {
  case 1:
    SetPoint = Saved.getULong("SetPoint1", Setpoint1);
    THCNex.writeNum("SP1.val", SetPoint);
    break;
  case 2:
    SetPoint = Saved.getULong("SetPoint2", Setpoint2);
    THCNex.writeNum("SP2.val", SetPoint);
    break;
  case 3:
    SetPoint = Saved.getULong("SetPoint3", Setpoint3);
    THCNex.writeNum("SP3.val", SetPoint);

    break;
  case 4:
    SetPoint = Saved.getULong("SetPoint4", Setpoint4);
    THCNex.writeNum("SP4.val", SetPoint);
    break;
  case 5:
    SetPoint = Saved.getULong("SetPoint5", Setpoint5);
    THCNex.writeNum("SP5.val", SetPoint);
    break;
  case 6:
    SetPoint = Saved.getULong("SetPoint6", Setpoint6);
    THCNex.writeNum("SP6.val", SetPoint);
    break;
  case 7:
    THCNex.writeNum("dth0.val", threshold / 10);
    THCNex.writeNum("dzm.val", Z);
    break;
  case 8:
    tmp = 10 * AccelFactor;
    THCNex.writeNum("daf.val", tmp);
    tmp = 10 * HighLow;
    THCNex.writeNum("dhl.val", tmp);
    THCNex.writeNum("db0.val", (int)sim);
    break;
  default:
    break;
}
write_bof();

if (pChr && pChr->canWrite() && SetPoint >= threshold && SetPoint <= 18000 && CurrentPageNumber <= 6) {
  pChr->writeValue(SetPoint);
  Saved.putUShort("dp", CurrentPageNumber);
}
OpenSaved(false);
if (debug) { message2 += ("\tt1:" + String(SetPoint)); }

} } void trigger2() //Save customsetpoints on end touch event { CurrentPageNumber = THCNex.readNumber("dp");

if (CurrentPageNumber <= 6 && SetPoint >= threshold && SetPoint <= 18000) {

OpenSaved(true);
reset0 = true;

switch (CurrentPageNumber) {
  case 1:
    SetPoint = THCNex.readNumber("SP1.val");
    Saved.putULong("SetPointSteel", SetPoint);
    break;
  case 2:
    SetPoint = THCNex.readNumber("SP2.val");
    Saved.putULong("SetPoint2", SetPoint);
    break;
  case 3:
    SetPoint = THCNex.readNumber("SP3.val");
    Saved.putULong("SetPoint3", SetPoint);
    break;
  case 4:
    SetPoint = THCNex.readNumber("SP4.val");
    Saved.putULong("SetPoint4", SetPoint);
    break;
  case 5:
    SetPoint = THCNex.readNumber("SP5.val");
    Saved.putULong("SetPoint5", SetPoint);
    break;
  case 6:
    SetPoint = THCNex.readNumber("SP6.val");
    Saved.putULong("SetPoint6", SetPoint);
    break;
  default:
    break;
}
Saved.putUShort("dp", CurrentPageNumber);
OpenSaved(false);

if (pChr && pChr->canWrite()) {
  pChr->writeValue(SetPoint);
}
if (debug) { message2 += ("\tt2:" + String(SetPoint)); }

} }

void trigger4() //Move Z Up/Down { CurrentPageNumber = THCNex.readNumber("dp"); }

void trigger5() //Adjust maxZ Up/Down { dir = THCNex.readNumber("va0.val"); if (dir == 1 || dir == -1) { Z += dir 1; if (Z > 20) { Z = 20; } if (Z < 4) { Z = 4; } maxZ = steps_per_mm Z; THCNex.writeNum("dzm.val", Z); OpenSaved(true); Saved.putUShort("Z", Z); OpenSaved(false); } } void trigger6() //Adjust AccelFactor Up/Down { dir = THCNex.readNumber("va0.val"); if (dir == 1 || dir == -1) { AccelFactor += (dir 0.1); if (AccelFactor > 3) { AccelFactor = 3; } if (AccelFactor < .5) { AccelFactor = 0.5; } tmp = 10 AccelFactor; THCNex.writeNum("daf.val", tmp); OpenSaved(true); Saved.putFloat("AccelFactor", AccelFactor); OpenSaved(false); if (debug) { message2 += "\tAF: " + String(tmp); } } }

void trigger7() //Adjust HighLow Up/Down { dir = THCNex.readNumber("va0.val"); if (dir == 1 || dir == -1) { HighLow += (dir 0.1); if (HighLow > 3) { HighLow = 3; } if (HighLow < .5) { HighLow = 0.5; } tmp = 10 HighLow; THCNex.writeNum("dhl.val", tmp); OpenSaved(true); Saved.putFloat("HighLow ", HighLow); OpenSaved(false); if (debug) { message2 += "\tHL: " + String(tmp); } } } void trigger8() //Adjust threshold Up/Down { threshold = THCNex.readNumber("th0.val"); if (threshold >= 3000 && threshold <= 12000) { OpenSaved(true); Saved.putUShort("Threshold", threshold); OpenSaved(false); } else { threshold = Saved.getUShort("Threshold", 4096); THCNex.writeNum("dth0.val", (int)threshold / 10); } }

void trigger10() { //Adjust Steps per mm steps_per_mm = THCNex.readNumber("s0.val"); if (steps_per_mm >= 80 && steps_per_mm <= 320) { OpenSaved(true); Saved.putUShort("steps_per_mm", steps_per_mm); OpenSaved(false); } else { steps_per_mm = Saved.getUShort("Steps", 160); THCNex.writeNum("s0.val", steps_per_mm); } } void trigger11() { //toggle torch on/off from screen, with automatic z return to zero if (sim) { sim = false; } else { sim = true; } if (pSim && pSim->canWrite()) { THCNex.writeNum("db0.val", (int)sim); pSim->writeValue((uint8_t)sim); if (debug) { message2 += "\tsim: " + String(sim); } } } void trigger12() { //toggle torch on/off from screen, with automatic z return to zero if (isEnabled) { THCNex.writeStr("bof.txt", "Off"); THCNex.writeStr("bof.txt", "Off"); isEnabled = false; message2 += "bof: Off"; digitalWrite(OUTPUT_SWITCH_PIN, LOW); } else { THCNex.writeStr("\tbof.txt", "On"); THCNex.writeStr("bof.txt", "On"); isEnabled = true; message2 += "\tbof: On"; digitalWrite(OUTPUT_SWITCH_PIN, HIGH); } }

the code is 750 lines in length, so I'm only posting snipets. I both simplified and added some reporting and debug inputs to the page displays. The 3 main while loops in the main code, control updating and reading the touch screen.