From 119b4e6398ee292ff0991fc09ad10cdacd9e770c Mon Sep 17 00:00:00 2001 From: Waterloo Hacker Fab Date: Mon, 8 Sep 2025 12:46:58 -0400 Subject: [PATCH 1/6] delete arduino stuff --- TubeFurnace/Makefile | 0 TubeFurnace/TubeFurnace.cpp | 489 ------------------ TubeFurnace/TubeFurnace.h | 76 --- TubeFurnace/TubeFurnace.ino | 33 -- TubeFurnace/libraries/RampSoakPID/.DS_Store | Bin 6148 -> 0 bytes .../libraries/RampSoakPID/.gitattributes | 2 - TubeFurnace/libraries/RampSoakPID/LICENSE | 21 - TubeFurnace/libraries/RampSoakPID/README.md | 3 - .../libraries/RampSoakPID/RampSoakPID.cpp | 205 -------- .../libraries/RampSoakPID/RampSoakPID.h | 52 -- .../libraries/RampSoakPID/RampSoakPID.ino | 0 .../TemperatureController.ino | 36 -- .../libraries/RampSoakPID/library.properties | 10 - TubeFurnace/log.txt | 26 - TubeFurnace/readme.md | 3 - {python => src}/main.py | 0 {python => src}/mpy_main.py | 0 {python => src}/pid.py | 0 {python => src}/profile.py | 0 {python => src}/running_average.py | 0 {python => src}/sim.py | 0 {python => src}/test/test_running_average.py | 0 {python => src}/test/test_sim.py | 0 23 files changed, 956 deletions(-) delete mode 100644 TubeFurnace/Makefile delete mode 100644 TubeFurnace/TubeFurnace.cpp delete mode 100644 TubeFurnace/TubeFurnace.h delete mode 100644 TubeFurnace/TubeFurnace.ino delete mode 100644 TubeFurnace/libraries/RampSoakPID/.DS_Store delete mode 100644 TubeFurnace/libraries/RampSoakPID/.gitattributes delete mode 100644 TubeFurnace/libraries/RampSoakPID/LICENSE delete mode 100644 TubeFurnace/libraries/RampSoakPID/README.md delete mode 100644 TubeFurnace/libraries/RampSoakPID/RampSoakPID.cpp delete mode 100644 TubeFurnace/libraries/RampSoakPID/RampSoakPID.h delete mode 100644 TubeFurnace/libraries/RampSoakPID/RampSoakPID.ino delete mode 100644 TubeFurnace/libraries/RampSoakPID/examples/TemperatureController/TemperatureController.ino delete mode 100644 TubeFurnace/libraries/RampSoakPID/library.properties delete mode 100644 TubeFurnace/log.txt delete mode 100644 TubeFurnace/readme.md rename {python => src}/main.py (100%) rename {python => src}/mpy_main.py (100%) rename {python => src}/pid.py (100%) rename {python => src}/profile.py (100%) rename {python => src}/running_average.py (100%) rename {python => src}/sim.py (100%) rename {python => src}/test/test_running_average.py (100%) rename {python => src}/test/test_sim.py (100%) diff --git a/TubeFurnace/Makefile b/TubeFurnace/Makefile deleted file mode 100644 index e69de29b..00000000 diff --git a/TubeFurnace/TubeFurnace.cpp b/TubeFurnace/TubeFurnace.cpp deleted file mode 100644 index 8a84e1e2..00000000 --- a/TubeFurnace/TubeFurnace.cpp +++ /dev/null @@ -1,489 +0,0 @@ - -/*************************** INCLUDES ******************************/ -#include "TubeFurnace.h" -#include -#include // Library for LCD -#include -#include -#include - -/*************************** GLOBALS *******************************/ -Adafruit_MAX31856 maxthermo = Adafruit_MAX31856(CS_PIN); - -// system control -int systemMode = STOP_MODE; // current system mode for furnace -char strbuf[BUFSIZE] = ""; // command buffer -float pwmPercent = 0.0; - -// timers -unsigned long currentTime = 0; // keeps track of current time -unsigned long nextTempTime = 0; // keeps track of when to measure temp val -unsigned long lcdUpdateTime = 0; // when to update the LCD -unsigned long pidUpdateTime = 0; // keeps track of when to update PID -unsigned long nextLogTime = 0; // keeps track of when to log data -unsigned long clockStart = 0; // - -// temperature values -float desiredTemp = 0.0; // temperature we want the furnace to reach -float currentTemp = 0.0; // whatever the current temperature is -float prevTemp = 0.0; // previous temperature value -float rampRateF = 0.0; // difference between current and previous temp -bool rampInitialized = false; // whether or not we've calculated the ramp yet (prevent prevTemp == 0 problem) -float rampLimit = 0; - -// lcd -LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27, 16 column and 2 rows -int column_index = 0; -int row_index = 0; -#define NUM_LCD_CHARS 16 -#define NUM_LCD_ROWS 2 -char lcdBuffer[NUM_LCD_ROWS][NUM_LCD_CHARS] = {"tube furnace"}; - -// Values to keep a running average of -RunningAverage tempAvg(N_TEMP_AVG); -RunningAverage rampAvg(N_TEMP_RAMP_AVG); - -// rotary encoder -int counter = 0; -int currentStateCLK; -int lastStateCLK; -String currentDir = ""; -unsigned long lastButtonPress = 0; -unsigned long lastISR = 0; - -/*************************** FUNCTIONS *****************************/ -// init serial -void initSerial() { - // initialize serial - Serial.begin(115200); - while (!Serial) - delay(10); -} - -// init clock -void resetClock() { clockStart = millis(); } - -// init lcd -void initLcd() { - lcd.init(); // initialize the lcd - lcd.backlight(); // open the backlight - row_index = 0; - column_index = 0; - lcd.setCursor(column_index, row_index); -} - -// init status LEDs -void initLED() { - pinMode(RED_LED, OUTPUT); - pinMode(YELLOW_LED, OUTPUT); - pinMode(GREEN_LED, OUTPUT); - digitalWrite(RED_LED, HIGH); - digitalWrite(YELLOW_LED, HIGH); - digitalWrite(GREEN_LED, HIGH); - delay(1000); - digitalWrite(RED_LED, LOW); - digitalWrite(YELLOW_LED, LOW); - digitalWrite(GREEN_LED, LOW); -} - -// init rotary encoder -void initEncoder() { - // Set encoder pins as inputs - pinMode(CLK, INPUT); - pinMode(DT, INPUT); - pinMode(SW, INPUT_PULLUP); - pinMode(DEBUGPIN, OUTPUT); - digitalWrite(DEBUGPIN, LOW); - attachInterrupt(digitalPinToInterrupt(CLK), updateEncoder, CHANGE); -} - -// init Time -void initTime() { currentTime = millis(); } - -// init thermocouple -void initThermocouple() { - - tempAvg.clear(); - rampAvg.clear(); - - pinMode(DRDY_PIN, INPUT); - if (!maxthermo.begin()) { - Serial.println("Could not initialize thermocouple."); - while (1) - delay(10); - } - maxthermo.setThermocoupleType(MAX31856_TCTYPE_K); - maxthermo.setConversionMode(MAX31856_CONTINUOUS); -} - -// init pwm -void initPwm() { - pinMode(RELAY_PIN, OUTPUT); - TCCR1A = _BV(COM1A1) | _BV(WGM11); // Enable the PWM output OC1A on digital pins 9 - TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS12); // Set fast PWM and prescaler of 256 on timer 1 - ICR1 = ICR1_VAL; // Set the PWM frequency to 4Hz: 16MHz/(256 * 4Hz) - 1 = 15624 - OCR1A = 0; // Set PWM output to 0 for now -} - -// init pid -void initPID() { - pidUpdateTime = currentTime; - setPidCoefficients(0.5, 0.05, 1.0); - setIntegratorWindupLimit(100); - setRampLimit(-30, 30); - setCrossoverDistance(10); - setDebugOnOff(true); -} - -// init logging -void initLog() { - // update log timers - nextLogTime = currentTime; -} - -// gets the current Time -void getTime() { currentTime = millis(); } - -// measure the temperature and update running avg -void measureTemp() { - if (currentTime < nextTempTime) { - return; - } - nextTempTime += TEMP_PERIOD; - while (digitalRead(DRDY_PIN)) - ; - tempAvg.addValue(maxthermo.readThermocoupleTemperature()); - prevTemp = currentTemp; - currentTemp = tempAvg.getAverage(); - - // if we don't have a prev temp, rampRate = 0 - if (!rampInitialized) { - prevTemp = currentTemp; - rampInitialized = true; - } - - // now add ramp rate to averager - rampRateF = 60 * (1000.0 / TEMP_PERIOD) * (currentTemp - prevTemp); - rampAvg.addValue(rampRateF); -} - -// lcd display -// ROW1: Current temp, Ramp rate "1234°C00°C/min" -// ROW2: Elapsed Time -void displayData() { - - if (currentTime < lcdUpdateTime) { - return; - } - lcdUpdateTime = currentTime + LCD_PERIOD; - - char row1[17] = ""; - char row2[17] = ""; - char tmp1[7] = ""; - char tmp2[10] = ""; - char tmp3[9] = ""; - char tmp4[8] = ""; - int t = (int)tempAvg.getAverage(); - if (systemMode == STOP_MODE) { - t = (counter * DEGREES_PER_COUNT) + DEGREES_START; - } - int r = (int)rampAvg.getAverage(); - int total_sec = (currentTime - clockStart) / 1000; - int m = total_sec / 60; - int s = total_sec % 60; - - // check bounds - if (r > 99) { - r = 99; - } else if (r < -99) { - r = -99; - } - - if (m > 999) { - m = 999; - } - - // create row strings - sprintf(tmp1, "%d%cC", t, DEGREE_SYMBOL); - sprintf(tmp2, "%+2d%cC/min", r, DEGREE_SYMBOL); - sprintf(tmp3, "%dm:%02ds", m, s); - switch (systemMode) { - case STOP_MODE: - sprintf(tmp4, "OFF"); - break; - case MANUAL_MODE: - sprintf(tmp4, "%d%%", pwmPercent); - break; - case AUTO_MODE: - sprintf(tmp4, "H%d%cC", (int)desiredTemp, DEGREE_SYMBOL); - break; - } - - // finalize row strings - sprintf(row1, "%-6s %9s", tmp1, tmp2); - sprintf(row2, "%-8s %7s", tmp3, tmp4); - - // output to LCD - lcd.setCursor(0, 0); - lcd.print(row1); - lcd.setCursor(0, 1); - lcd.print(row2); -} - -// updates status LEDs -void updateLEDs() { - if ((desiredTemp > 100) || (currentTemp > 100)) { - digitalWrite(YELLOW_LED, HIGH); - } else { - digitalWrite(YELLOW_LED, LOW); - } -} - -// keep track of position of rotary encoder -void updateEncoder() { - - // primitive debounce: ignore stuff that happened recently - if ((millis() - lastISR) < 10) { - return; - } - - if (digitalRead(CLK) == HIGH) { - if (digitalRead(DT) == LOW) { - counter++; - currentDir = "CW"; - desiredTemp = (counter * DEGREES_PER_COUNT) + DEGREES_START; - if (desiredTemp > 1200) { - counter--; - desiredTemp = 1200; - } - } else { - counter--; - currentDir = "CCW"; - desiredTemp = (counter * DEGREES_PER_COUNT) + DEGREES_START; - if (desiredTemp < 10) { - counter++; - desiredTemp = 10; - } - } - if (systemMode == AUTO_MODE) { - setTargetValue(desiredTemp); - } - } -} - -void updateButton() { - // Read the button state - int btnState = digitalRead(SW); - - // If we detect LOW signal, button is pressed - if (btnState == LOW) { - // if 100ms have passed since last LOW pulse, it means that the - // button has been pressed, released and pressed again - if (millis() - lastButtonPress > 100) { - // desiredTemp = (counter * DEGREES_PER_COUNT) + DEGREES_START; - // systemMode = AUTO_MODE; - resetClock(); - if (systemMode == STOP_MODE) { - setTargetValue(desiredTemp); - systemMode = AUTO_MODE; - } - } - - // Remember last button press event - lastButtonPress = millis(); - } -} - -// Read data from serial line if available -void recvSerial() { - char c; - int i = 0; - bool newData = false; - - while (Serial.available()) { - newData = true; - c = Serial.read(); - strbuf[i] = c; - delay(1); // not sure why this is needed but it breaks without it :( - i++; - if (i >= BUFSIZE) { - i = BUFSIZE - 1; - } - } - strbuf[i] = '\0'; // terminate string - - if (newData) { - // Serial.print("strbuf: "); - // Serial.print(strbuf); - ; - } - newData = false; -} - -// execute new command if available -void evaluateCommand() { - int newTemp = 0; - int newPwm = 0; - float val = 0.0; - - // no command available - if (strbuf[0] == '\0') { - return; - - // set pwm percentage - } else if (strbuf[0] == 'S') { - newPwm = atoi(strbuf + 1); - if ((newPwm <= MAXPWM) && (newPwm >= 0)) { - updatePwm(newPwm); - if (newPwm == 0) { - systemMode = STOP_MODE; - } else { - systemMode = MANUAL_MODE; - } - resetPid(); - Serial.print("Set PWM to "); - Serial.print(newPwm); - Serial.println("%"); - } else { - Serial.print("Cannot set PWM to "); - Serial.print(newPwm); - Serial.println("%"); - } - - // set target temperature - } else if (strbuf[0] == 'T') { - newTemp = atoi(strbuf + 1); - if ((newTemp <= MAXTEMP) && (newTemp >= MINTEMP)) { - desiredTemp = newTemp; - setTargetValue(desiredTemp); - systemMode = AUTO_MODE; - resetPid(); - Serial.print("Set temp to "); - Serial.print(desiredTemp); - Serial.println("C"); - } else { - Serial.print("Cannot set temp to "); - Serial.print(newTemp); - Serial.println("C"); - } - - // set PID values - } else if (strbuf[0] == 'P') { - val = atof(strbuf + 1); - setKp(val); - // resetPid(); - Serial.print("Set P value to "); - Serial.println(val); - } else if (strbuf[0] == 'I') { - val = atof(strbuf + 1); - setKi(val); - // resetPid(); - Serial.print("Set I value to "); - Serial.println(val); - } else if (strbuf[0] == 'D') { - val = atof(strbuf + 1); - setKd(val); - // resetPid(); - Serial.print("Set D value to "); - Serial.println(val); - } else if (strbuf[0] == 'W') { - val = atof(strbuf + 1); - setIntegratorWindupLimit(val); - // resetPid(); - Serial.print("Set W value to "); - Serial.println(val); - - // Emergency Stop - } else if (strbuf[0] == 'E') { - Serial.println("EMERGENCY STOP"); // probably need to make this more foolproof like a hard shutdown - systemMode = STOP_MODE; - - // Reset Clock - } else if (strbuf[0] == 'C') { - Serial.println("Reset Clock"); // - resetClock(); - - // command not recognized - } else { - Serial.print("Unknown Command: "); - Serial.println(strbuf); - } - - strbuf[0] = '\0'; // clear command -} - -// check if we need to change heater setting based on PID -void updateHeater() { - if (pidUpdateTime < currentTime) { - pidUpdateTime += PID_PERIOD; - switch (systemMode) { - case STOP_MODE: - updatePwm(0); - break; - case MANUAL_MODE: - // keep constant PWM, dont run PID - break; - case AUTO_MODE: - float pidVal = pidStep(currentTemp); - updatePwm(mapPidToPwm(pidVal)); - break; - } - } -} - -// log new data -void logData() { - - if (nextLogTime < currentTime) { - nextLogTime += LOG_PERIOD; - // print logs - Serial.print("temp:"); - Serial.print(currentTemp); - Serial.print(","); - Serial.print("tempAvg:"); - Serial.print(tempAvg.getAverage()); - Serial.print(","); - Serial.print("ramp:"); - Serial.print(rampRateF); - Serial.print(","); - Serial.print("rampAvg:"); - Serial.print(rampAvg.getAverage()); - Serial.print(","); - Serial.print("pwmPercent:"); - Serial.print(pwmPercent); - Serial.print(","); - Serial.print("pwmPercent:"); - Serial.print(pwmPercent); - Serial.print(","); - Serial.print("currentTemp:"); - Serial.print(currentTemp); - Serial.print(","); - Serial.print("desiredTemp:"); - Serial.print(desiredTemp); - Serial.print(","); - } -} - -// control the OCR1A register directly to set PWM value -void updatePwm(float percent) { - // check and enforce bounds - if (percent > MAXPWM) { - percent = MAXPWM; - } else if (percent < 0) { - percent = 0; - } - pwmPercent = percent; - OCR1A = (percent * ICR1_VAL) / 100; -} - -float mapPidToPwm(float pid) { - float val = 0.0; - if (pid < 0.0) { - val = 0.0; - } else if (pid > MAXPWM) { - val = MAXPWM; - } else { - val = pid; - } - return val; -} diff --git a/TubeFurnace/TubeFurnace.h b/TubeFurnace/TubeFurnace.h deleted file mode 100644 index 29680932..00000000 --- a/TubeFurnace/TubeFurnace.h +++ /dev/null @@ -1,76 +0,0 @@ - - -/*************************** DEFINES *******************************/ - -// Arduino Pins -#define DRDY_PIN 5 -#define SCK_PIN 13 -#define MISO_PIN 12 -#define MOSI_PIN 11 -#define CS_PIN 10 - -#define RELAY_PIN 9 - -#define CLK 2 -#define DT 3 -#define SW 4 - -#define DEBUGPIN 5 -#define RED_LED A0 -#define YELLOW_LED A1 -#define GREEN_LED A2 - -// registers -#define ICR1_VAL 15624 // Set the PWM frequency to 4Hz: 16MHz/(256 * 4Hz) - 1 = 15624 - -// system mode -#define STOP_MODE 0 // mode where the heater is off completely -#define MANUAL_MODE 1 // system mode for controlling pwm manually -#define AUTO_MODE 2 // system mode for holding upward ramp rate steady -#define NUM_MODES 3 // - -// limits -#define MAXPWM 60 // max allowable PWM percentage for tube furnace -#define MINPWM 0 // min allowable PWM percentage for tube -#define MAXTEMP 1200 // max allowable temperature for tube furnace -#define MINTEMP 0 // min allowable temperature for tube furnace - -// time periods -#define TEMP_PERIOD 100 // interval to measure temp value -#define LCD_PERIOD 100 // interval to update LCD -#define PID_PERIOD 100 // interval of time to update PID loop -#define LOG_PERIOD 100 // log interval in milliseconds - -// other -#define BUFSIZE 64 -#define N_TEMP_RAMP_AVG 10 // number of values to average to smooth ramp values -#define N_TEMP_AVG 10 -#define DEGREE_SYMBOL ((char)223) -#define DEGREES_PER_COUNT 10 -#define DEGREES_START 1000 - -/*************************** FUNCTION PROTOTYPES *******************/ -void initSerial(); -void resetClock(); -void initLcd(); -void initLED(); -void initEncoder(); -void initTime(); -void initThermocouple(); -void initPwm(); -void initPID(); -void initLog(); -void getTime(); -void measureTemp(); -void displayData(); -void updateLEDs(); -void updateEncoder(); -void updateButton(); -void recvSerial(); -void evaluateCommand(); -void updateHeater(); -void logData(); -float mapPidToPwm(float pid); -void calculateRampRate(); -void updatePwm(float percent); -void isrCLK(); diff --git a/TubeFurnace/TubeFurnace.ino b/TubeFurnace/TubeFurnace.ino deleted file mode 100644 index aabe7441..00000000 --- a/TubeFurnace/TubeFurnace.ino +++ /dev/null @@ -1,33 +0,0 @@ -#include - -/*************************** INCLUDES ******************************/ -#include "TubeFurnace.h" - -/*************************** SETUP *********************************/ -void setup() { - - initSerial(); - resetClock(); - initLcd(); - initLED(); - initEncoder(); - initTime(); - initThermocouple(); - initPwm(); - initPID(); - initLog(); -} - -/*************************** MAIN **********************************/ -void loop() { - - getTime(); - measureTemp(); - displayData(); - updateLEDs(); - updateButton(); - recvSerial(); - evaluateCommand(); - updateHeater(); - // logData(); -} \ No newline at end of file diff --git a/TubeFurnace/libraries/RampSoakPID/.DS_Store b/TubeFurnace/libraries/RampSoakPID/.DS_Store deleted file mode 100644 index cf4165f03b3f1c1a9a3796a1b4025ec659c086bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKy-veG47N)^saQHPMq*d-w@;R(7jKq+dG5)uiJV9UrW^o5vtBtD<5kW)%W zgeqI|eHZ`SUA{}=91-#Sbu}fL5K#&h9F5WJ5b=u+WMmd`vW!u#r;Gc#Y6g*R_^%Ae z-X(NNYkH)Yc>g}OeP2}<#j>oIu%+kQi<{Zg=T+=q?e#aC-m}49NX0|-KyP$M6*W|% z{~XVM^1dskzmDTgw~oPBRsFM`eR0vc!h0Y~b8!Zo0cYT#89>bzNlz8Mbq1UPXP{$1 zz7H8xFgI)!!>0pHI066@n1i4%X9>y440FR)5grI@Do|6|ju>peV65rz=N8{8YC3V4 z8ROW@Y$p^Bv%{W+aN=CiTW7!-h#5H2%Zb$g>)+4+agtv-1J1xfF~CW&DCW2&tF42Z ulUkcWZ=oU**D7`?=!8;?SSiJ4&>*m9(gEg%ts*QC{}Bi@c;gKGDFfdY8b -#include - -/*************************** Variables ***************************************/ -float Kp = KP_DEFAULT; -float Ki = KI_DEFAULT; -float Kd = KD_DEFAULT; -float IMax = IMAX_DEFAULT; -float rampUpLimit = RAMP_UP_LIMIT_DEFAULT; -float rampDownLimit = RAMP_DOWN_LIMIT_DEFAULT; -float crossoverDistance = CROSSOVER_DISTANCE_DEFAULT; -float error = 0.0; -float PVal = 0.0; -float IVal = 0.0; -float DVal = 0.0; -float currentVal = 0.0; -float targetVal = 0.0; -unsigned long int currentStepTime; -bool currentStepTimeInitialized = false; -float previousVal = 0.0; -bool previousValInitialized = false; -float previousError = 0.0; -bool previousErrorInitialized = false; -unsigned long int previousStepTime = 0; -float rampRate = 0.0; -float desiredRampRate = 0.0; -RunningAverage rampRateAvg(N_RAMP_AVG); -bool debugPIDOn = false; -RunningAverage DValAvg(N_DVAL_AVG); - -/*************************** Functions ***************************************/ - -// sets the coefficients of the PID controller -void setPidCoefficients(float P, float I, float D) { - Kp = P; - Ki = I; - Kd = D; -} - -// sets the P coefficient of the PID controller -void setKp(float P) { - Kp = P; -} - -// sets the I coefficient of the PID controller -void setKi(float I) { - Ki = I; -} - -// sets the D coefficient of the PID controller -void setKd(float D) { - Kd = D; -} - -// sets the integrator windup limit (max value the integrator can reach) -void setIntegratorWindupLimit(float val) { - IMax = val; -} - -// sets the maximum ramp rate (both ramp up and ramp down) -void setRampLimit(float rampDown, float rampUp) { - rampDownLimit = rampDown; - rampUpLimit = rampUp; -} - -// sets how far from the set point that the controller will transition -// from holding a constant ramp to holding a constant value -void setCrossoverDistance(float val) { - crossoverDistance = val; -} - -// set the target value for the controller to reach -void setTargetValue(float val) { - targetVal = val; -} - -// resets the PID loop -void resetPid() -{ - previousStepTime = 0; - currentStepTime = 0; - currentStepTimeInitialized = false; - previousError = 0; - previousErrorInitialized = false; - previousVal = 0; - previousValInitialized = false; - if (IVal < 0) { - IVal = 0; // this will make the system recover faster if I is negative - } - rampRate = 0.0; -} - -// set debug on/off -void setDebugOnOff(bool onOff) { - debugPIDOn = onOff; -} - -// computes the next PID value (call this function every 100ms or so) -float pidStep(float val) { - - currentVal = val; - float dt; // in seconds - - // compute the time since last PID step - if (currentStepTimeInitialized == false) { - dt = 0.0; - rampRate = 0; - currentStepTime = millis(); - currentStepTimeInitialized = true; - } else { - previousStepTime = currentStepTime; - currentStepTime = millis(); - dt = (currentStepTime - previousStepTime) / 1000.0; - } - - // compute the current rampRate - if (previousValInitialized == false) { - previousVal = currentVal; - rampRate = 0.0; - previousValInitialized = true; - } else if (dt != 0.0) {; - rampRateAvg.addValue(S_PER_MIN * (currentVal - previousVal) / dt); - rampRate = rampRateAvg.getAverage(); - previousVal = currentVal; - } - - // compute previousError - previousError = error; - - // Adjust Ramp Limits if we are close to the set point - - if (currentVal < (targetVal - 0)) { - // ramping up - desiredRampRate = min(rampUpLimit, (rampUpLimit * abs(targetVal - currentVal) / crossoverDistance)); - error = desiredRampRate - rampRate; - - } else if (currentVal > (targetVal + 0)) { - // ramping down - desiredRampRate = max(rampDownLimit, (rampDownLimit * abs(targetVal - currentVal) / crossoverDistance)); - error = desiredRampRate - rampRate; - - } else { - // holding steady - error = targetVal - currentVal; - } - - // Compute PID Values and PID Output - - PVal = Kp * error; - IVal += Ki * error * dt; - if (dt != 0) { - DVal = Kd * (error - previousError) / dt; - } else { - DVal = 0; - } - - // integrator windup prevention - if (IVal > IMax) { - IVal = IMax; - } - if (IVal < (-1 * IMax)) { - IVal = -1 * IMax; - } - - if (debugPIDOn) { - debugPID(); - } - - DValAvg.addValue(DVal); - return PVal + IVal + DValAvg.getAverage(); - -} - -// prints PID values to terminal -void debugPID() { - - Serial.print("currentVal:"); Serial.print(currentVal); Serial.print(","); - Serial.print("targetVal:"); Serial.print(targetVal); Serial.print(","); - Serial.print("rampRate:"); Serial.print(rampRateAvg.getAverage()); Serial.print(","); - Serial.print("desiredRampRate:"); Serial.print(desiredRampRate); Serial.print(","); - Serial.print("error:"); Serial.print(error); Serial.print(","); - Serial.print("P:"); Serial.print(PVal); Serial.print(","); - Serial.print("I:"); Serial.print(IVal); Serial.print(","); - Serial.print("D:"); Serial.print(DValAvg.getAverage()); Serial.print(","); - Serial.print("Kp:"); Serial.print(Kp); Serial.print(","); - Serial.print("Ki:"); Serial.print(Ki); Serial.print(","); - Serial.print("Kd:"); Serial.print(Kd); Serial.print(","); - Serial.println(""); -} - - diff --git a/TubeFurnace/libraries/RampSoakPID/RampSoakPID.h b/TubeFurnace/libraries/RampSoakPID/RampSoakPID.h deleted file mode 100644 index bba5a3a4..00000000 --- a/TubeFurnace/libraries/RampSoakPID/RampSoakPID.h +++ /dev/null @@ -1,52 +0,0 @@ - -/*! - * @file RampSoakPID.h - * - * - */ - -#ifndef RAMPSOAKPID_H -#define RAMPSOAKPIDH - -// default values - -#define KP_DEFAULT 1.0 -#define KI_DEFAULT 0.1 -#define KD_DEFAULT 1.0 -#define IMAX_DEFAULT 1000 -#define RAMP_UP_LIMIT_DEFAULT 10 -#define RAMP_DOWN_LIMIT_DEFAULT -10 -#define CROSSOVER_DISTANCE_DEFAULT 10 -#define N_RAMP_AVG 50 -#define N_DVAL_AVG 10 -#define S_PER_MIN 60 - -// function prototypes - -// sets the coefficients of the PID controller -void setPidCoefficients(float P, float I, float D); -// sets the P coefficient of the PID controller -void setKp(float P); -// sets the I coefficient of the PID controller -void setKi(float I); -// sets the D coefficient of the PID controller -void setKd(float D); -// sets the integrator windup limit (max value the integrator can reach) -void setIntegratorWindupLimit(float val); -// sets the maximum ramp rate (both ramp up and ramp down) -void setRampLimit(float rampDown, float rampUp); -// sets how far from the set point that the controller will transition -// from holding a constant ramp to holding a constant value -void setCrossoverDistance(float val); -// set the target value for the controller to reach -void setTargetValue(float val); -// resets the PID loop -void resetPid(); -// set debug on/off -void setDebugOnOff(bool onOff); -// computes the next PID value (call this function every 100ms or so) -float pidStep(float currentVal); -// prints PID values to terminal -void debugPID(); - -#endif diff --git a/TubeFurnace/libraries/RampSoakPID/RampSoakPID.ino b/TubeFurnace/libraries/RampSoakPID/RampSoakPID.ino deleted file mode 100644 index e69de29b..00000000 diff --git a/TubeFurnace/libraries/RampSoakPID/examples/TemperatureController/TemperatureController.ino b/TubeFurnace/libraries/RampSoakPID/examples/TemperatureController/TemperatureController.ino deleted file mode 100644 index c0b7af22..00000000 --- a/TubeFurnace/libraries/RampSoakPID/examples/TemperatureController/TemperatureController.ino +++ /dev/null @@ -1,36 +0,0 @@ -// -// This file is an example of how to use the RampSoakPID controller to control an oven. - -// You simply need to create two functions: -// float measureTemp(): measures a temperature value -// setHeaterPWM(float pwmPercent): sets PWM for heating element -// -// You can change the values in the setup function to better suit your needs. -// Use the serial monitor and serial plotter to see the data in real time. - -#include - -float currentTemp; // the thing we are trying to control (temperature in Celcius) -float pidOutput; // the output of the PID controller - -void setup() { - Serial.begin(115200); - setPidCoefficients(1.0, 0.1, 1.0); // P, I, D - setIntegratorWindupLimit(100); // Maximum value the integral term can reach (+/- 100) - setRampLimit(-10, 10); // Min, Max values for ramp rate (+/- 10 degrees Celcius per minute) - setCrossoverDistance(10); // How far from the setpoint before we start lowering the ramp rate to zero - // So if our setpoint is 100C we will start lowering the ramp rate at 90C - setDebugOnOff(true); // Debugging logs are printed to the Serial port -} - -void loop() { - setTarget(100); // set a new value for the PID controller to reach (100 Celcius) - - while (true) { - delay(100); // Update PID (once every 100ms recommended) - // currentTemp = measureTemp(); // measure the temperature - pidOutput = pidStep(currentTemp); // compute next PID step - // setHeaterPWM(pidOutput); // apply output of PID controller to heater - } - -} \ No newline at end of file diff --git a/TubeFurnace/libraries/RampSoakPID/library.properties b/TubeFurnace/libraries/RampSoakPID/library.properties deleted file mode 100644 index a5655df5..00000000 --- a/TubeFurnace/libraries/RampSoakPID/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=RampSoakPID -version=1.0.0 -author=ProjectsInFlight -maintainer=ProjectsInFlight -sentence=PID Controller with Ramp-Rate Control -paragraph=PID Controller with Ramp-Rate Control -category=Sensors -url=https://github.com/ProjectsInFlight/RampSoakPID -architectures=* -depends=RunningAverage diff --git a/TubeFurnace/log.txt b/TubeFurnace/log.txt deleted file mode 100644 index 5fad0069..00000000 --- a/TubeFurnace/log.txt +++ /dev/null @@ -1,26 +0,0 @@ -. -├── Makefile -├── TubeFurnace.cpp -├── TubeFurnace.h -├── TubeFurnace.ino -├── libraries -│   └── RampSoakPID -│   ├── LICENSE -│   ├── README.md -│   ├── RampSoakPID.cpp -│   ├── RampSoakPID.h -│   ├── RampSoakPID.ino -│   ├── examples -│   │   └── TemperatureController -│   │   └── TemperatureController.ino -│   └── library.properties -├── log.txt -├── readme.md -└── tests - ├── README.md - ├── test_lcd.ino - ├── test_rotary_encoder.ino - ├── test_ssr.ino - └── test_thermocouple.ino - -6 directories, 18 files diff --git a/TubeFurnace/readme.md b/TubeFurnace/readme.md deleted file mode 100644 index 7816f6a3..00000000 --- a/TubeFurnace/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -Source code taken/modified from: https://github.com/projectsinflight/TubeFurnace/ - -Move ./libraries into the /Arduino/Libraries on the machine (os dependant) diff --git a/python/main.py b/src/main.py similarity index 100% rename from python/main.py rename to src/main.py diff --git a/python/mpy_main.py b/src/mpy_main.py similarity index 100% rename from python/mpy_main.py rename to src/mpy_main.py diff --git a/python/pid.py b/src/pid.py similarity index 100% rename from python/pid.py rename to src/pid.py diff --git a/python/profile.py b/src/profile.py similarity index 100% rename from python/profile.py rename to src/profile.py diff --git a/python/running_average.py b/src/running_average.py similarity index 100% rename from python/running_average.py rename to src/running_average.py diff --git a/python/sim.py b/src/sim.py similarity index 100% rename from python/sim.py rename to src/sim.py diff --git a/python/test/test_running_average.py b/src/test/test_running_average.py similarity index 100% rename from python/test/test_running_average.py rename to src/test/test_running_average.py diff --git a/python/test/test_sim.py b/src/test/test_sim.py similarity index 100% rename from python/test/test_sim.py rename to src/test/test_sim.py From 47c301b7a2cf1f413759e743d19110ad29083c19 Mon Sep 17 00:00:00 2001 From: Waterloo Hacker Fab Date: Mon, 8 Sep 2025 12:53:55 -0400 Subject: [PATCH 2/6] update workflows --- .github/workflows/build.yaml | 46 ------------------- .github/workflows/{test-py.yaml => test.yaml} | 0 2 files changed, 46 deletions(-) delete mode 100644 .github/workflows/build.yaml rename .github/workflows/{test-py.yaml => test.yaml} (100%) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml deleted file mode 100644 index 23c3110c..00000000 --- a/.github/workflows/build.yaml +++ /dev/null @@ -1,46 +0,0 @@ -name: Build Firmware - -on: - push: - branches: ["main"] - pull_request: - branches: ["main"] - -jobs: - lint: - name: Lint - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Lint - run: clang-format --dry-run -Werror TubeFurnace/*.cpp TubeFurnace/*.h TubeFurnace/*.ino - - build-arduino: - name: Arduino CLI - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest] - steps: - - uses: actions/checkout@v4 - - - name: Set up Arduino CLI - uses: arduino/setup-arduino-cli@v2 - with: - version: 0.32.2 - - - name: Install Library Dependencies - run: | - arduino-cli core install arduino:avr - arduino-cli lib update-index - arduino-cli lib install "Adafruit MAX31856 Library" - arduino-cli lib install "LiquidCrystal I2C" - arduino-cli lib install "RunningAverage" - - - name: Build TubeFurnace - run: | - # Use the --libraries flag to include the local libraries folder - arduino-cli compile \ - --fqbn arduino:avr:uno \ - --libraries TubeFurnace/libraries \ - TubeFurnace diff --git a/.github/workflows/test-py.yaml b/.github/workflows/test.yaml similarity index 100% rename from .github/workflows/test-py.yaml rename to .github/workflows/test.yaml From ede85aab4c1b1a675999a50493c9ce1740e471e3 Mon Sep 17 00:00:00 2001 From: Waterloo Hacker Fab Date: Mon, 8 Sep 2025 12:57:25 -0400 Subject: [PATCH 3/6] fix paths --- .github/workflows/test.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 9985d039..eae307b3 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -19,7 +19,9 @@ jobs: - name: Install deps run: pip install -r requirements.txt - name: Lint - run: ruff check python/ python/test/ + run: ruff check src/ src/test/ + - name: Format + run: ruff check src/ src/test/ unit: name: Unit Tests @@ -33,4 +35,4 @@ jobs: - name: Install deps run: pip install -r requirements.txt - name: Pytest - run: PYTHONPATH=python pytest python/test/*.py + run: PYTHONPATH=python pytest src/test/ From e434fc5fec52541c47e82593aefb38d56489c7a8 Mon Sep 17 00:00:00 2001 From: Waterloo Hacker Fab Date: Mon, 8 Sep 2025 12:58:19 -0400 Subject: [PATCH 4/6] fix paths 2 --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index eae307b3..4af27858 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -35,4 +35,4 @@ jobs: - name: Install deps run: pip install -r requirements.txt - name: Pytest - run: PYTHONPATH=python pytest src/test/ + run: PYTHONPATH=src pytest src/test/ From d4d5dbac73295de523689f2831bbbd8414ab1482 Mon Sep 17 00:00:00 2001 From: Waterloo Hacker Fab Date: Mon, 8 Sep 2025 13:00:24 -0400 Subject: [PATCH 5/6] move ino scripts to scripts/examples/ --- {tests => scripts/examples}/README.md | 0 {tests => scripts/examples}/test_lcd/test_lcd.ino | 0 .../examples}/test_rotary_encoder/test_rotary_encoder.ino | 0 {tests => scripts/examples}/test_ssr/test_ssr.ino | 0 .../examples}/test_thermocouple/test_thermocouple.ino | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename {tests => scripts/examples}/README.md (100%) rename {tests => scripts/examples}/test_lcd/test_lcd.ino (100%) rename {tests => scripts/examples}/test_rotary_encoder/test_rotary_encoder.ino (100%) rename {tests => scripts/examples}/test_ssr/test_ssr.ino (100%) rename {tests => scripts/examples}/test_thermocouple/test_thermocouple.ino (100%) diff --git a/tests/README.md b/scripts/examples/README.md similarity index 100% rename from tests/README.md rename to scripts/examples/README.md diff --git a/tests/test_lcd/test_lcd.ino b/scripts/examples/test_lcd/test_lcd.ino similarity index 100% rename from tests/test_lcd/test_lcd.ino rename to scripts/examples/test_lcd/test_lcd.ino diff --git a/tests/test_rotary_encoder/test_rotary_encoder.ino b/scripts/examples/test_rotary_encoder/test_rotary_encoder.ino similarity index 100% rename from tests/test_rotary_encoder/test_rotary_encoder.ino rename to scripts/examples/test_rotary_encoder/test_rotary_encoder.ino diff --git a/tests/test_ssr/test_ssr.ino b/scripts/examples/test_ssr/test_ssr.ino similarity index 100% rename from tests/test_ssr/test_ssr.ino rename to scripts/examples/test_ssr/test_ssr.ino diff --git a/tests/test_thermocouple/test_thermocouple.ino b/scripts/examples/test_thermocouple/test_thermocouple.ino similarity index 100% rename from tests/test_thermocouple/test_thermocouple.ino rename to scripts/examples/test_thermocouple/test_thermocouple.ino From cd0b119e737a751df7e1e59bcbce1fee21502499 Mon Sep 17 00:00:00 2001 From: Waterloo Hacker Fab Date: Mon, 8 Sep 2025 13:00:36 -0400 Subject: [PATCH 6/6] only test when real files have changed --- .github/workflows/test.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4af27858..9389273e 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -3,8 +3,14 @@ name: Test Python on: push: branches: ["main"] + paths: + - "src/**" + - ".github/workflows/test.yml" pull_request: branches: ["main"] + paths: + - "src/**" + - ".github/workflows/test.yml" jobs: lint: