mirror of
https://github.com/vincentvdwal/crust-craft.git
synced 2026-08-18 17:26:39 +02:00
fix overshoot
This commit is contained in:
+27
-22
@@ -9,10 +9,7 @@
|
||||
|
||||
#include "secrets.h"
|
||||
|
||||
// Create AsyncWebServer object on port 80
|
||||
AsyncWebServer server(80);
|
||||
|
||||
// Create a WebSocket object
|
||||
AsyncWebSocket ws("/ws");
|
||||
|
||||
// Json Variable to Hold Sensor Readings
|
||||
@@ -30,19 +27,23 @@ int thermoCLK = 5;
|
||||
|
||||
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
|
||||
|
||||
float temperature = 0;
|
||||
int targetTemp = 300;
|
||||
float setOverShoot = 15;
|
||||
float setUnderShoot = 10;
|
||||
float setOverShoot = 20;
|
||||
float setUnderShoot = 20;
|
||||
float derivedOverShoot = targetTemp;
|
||||
float derivedUnderShoot = targetTemp;
|
||||
unsigned long lastSwitch = 0;
|
||||
unsigned long switchDelay = 30000; // 30s
|
||||
unsigned long switchDelay = 30000; // 15s
|
||||
bool autoSwitch = true;
|
||||
|
||||
// Get Sensor Readings and return JSON object
|
||||
String getSensorReadings()
|
||||
{
|
||||
readings["temperature"] = thermocouple.readCelsius();
|
||||
temperature = thermocouple.readCelsius();
|
||||
|
||||
readings["temperature"] = temperature;
|
||||
|
||||
if (digitalRead(relay) == HIGH)
|
||||
{
|
||||
readings["relais"] = 1;
|
||||
@@ -51,6 +52,7 @@ String getSensorReadings()
|
||||
{
|
||||
readings["relais"] = 0;
|
||||
}
|
||||
|
||||
readings["target_temp"] = targetTemp;
|
||||
readings["derived_overshoot"] = derivedOverShoot;
|
||||
readings["derived_undershoot"] = derivedUnderShoot;
|
||||
@@ -161,23 +163,23 @@ void regulateRelais()
|
||||
{
|
||||
if (autoSwitch)
|
||||
{
|
||||
float sinceLastSwitch = millis() - lastSwitch;
|
||||
float fiveMinutesInMillis = 5 * 60 * 1000;
|
||||
float shootFactor = sinceLastSwitch / fiveMinutesInMillis;
|
||||
|
||||
float overshoot = setOverShoot * shootFactor; // derive over 5 mins -> 1 min eq. 3°C, 5mins eq. 15°C
|
||||
float dirivedOvershoot = min(overshoot, setOverShoot);
|
||||
|
||||
float undershoot = setUnderShoot * shootFactor; // derive over 5 min -> 1 min eq. 3°C, 5mins eq. 15°C
|
||||
float dirivedUndershoot = min(undershoot, setUnderShoot);
|
||||
|
||||
float overShootCorrectedTarget = derivedOverShoot = targetTemp - dirivedOvershoot;
|
||||
float underShootCorrectedTarget = derivedUnderShoot = targetTemp + dirivedUndershoot;
|
||||
|
||||
if ((millis() - lastSwitch) > switchDelay)
|
||||
{
|
||||
float temperature = thermocouple.readCelsius();
|
||||
float sinceLastSwitch = millis() - lastSwitch;
|
||||
float fiveMinutesInMillis = 5 * 60 * 1000;
|
||||
float shootFactor = sinceLastSwitch / fiveMinutesInMillis;
|
||||
|
||||
float overshoot = setOverShoot * shootFactor; // derive over 5 mins -> 1 min eq. 3°C, 5mins eq. 15°C
|
||||
float dirivedOvershoot = min(overshoot, setOverShoot);
|
||||
|
||||
float undershoot = setUnderShoot * shootFactor; // derive over 5 min -> 1 min eq. 3°C, 5mins eq. 15°C
|
||||
float dirivedUndershoot = min(undershoot, setUnderShoot);
|
||||
|
||||
float overShootCorrectedTarget = derivedOverShoot = targetTemp - dirivedOvershoot;
|
||||
float underShootCorrectedTarget = derivedUnderShoot = targetTemp + dirivedUndershoot;
|
||||
|
||||
if (temperature > overShootCorrectedTarget) // > 285°C
|
||||
if (temperature > overShootCorrectedTarget) // > 280°C
|
||||
{
|
||||
if (digitalRead(relay) == HIGH)
|
||||
{
|
||||
@@ -186,7 +188,10 @@ void regulateRelais()
|
||||
resetDerivedValues();
|
||||
}
|
||||
}
|
||||
else if (temperature < underShootCorrectedTarget) // < 310°C
|
||||
}
|
||||
if ((millis() - lastSwitch) > switchDelay)
|
||||
{
|
||||
if (temperature < underShootCorrectedTarget) // < 320°C
|
||||
{
|
||||
if (digitalRead(relay) == LOW)
|
||||
{
|
||||
|
||||
+93
-21
@@ -28,15 +28,23 @@ let relaisData = [
|
||||
|
||||
let temp = 300;
|
||||
let targetTemp = 300
|
||||
let setOverShoot = 30
|
||||
let setUnderShoot = 30
|
||||
let targetTempOverShoot = 300
|
||||
let targetTempUnderShoot = 300
|
||||
|
||||
let lastSwitch = new Date()
|
||||
let lastSwitchDuration = 0
|
||||
const oven = document.querySelector('#oven')
|
||||
const temperature = document.querySelector('#temperature')
|
||||
const relaisSwitch = document.querySelector('#relais_switch')
|
||||
const relaisSwitchInput: HTMLInputElement | null = document.querySelector('#relais_switch_input')
|
||||
const targetTempInput: HTMLInputElement | null = document.querySelector('#target_temperature')
|
||||
|
||||
let spoofInterval = 10
|
||||
let speedFactor = 250 / spoofInterval
|
||||
const switchDelay = 60 / speedFactor * 1000
|
||||
|
||||
let maxValues = 4 * 60 * 60 // 60 minutes (4 values/sec)
|
||||
|
||||
let hs: Highcharts.StockChart;
|
||||
@@ -91,10 +99,10 @@ const createChart = () => {
|
||||
enabled: false
|
||||
},
|
||||
|
||||
title: {
|
||||
text: 'Temperature',
|
||||
align: 'left',
|
||||
},
|
||||
// title: {
|
||||
// text: 'Temperature',
|
||||
// align: 'left',
|
||||
// },
|
||||
|
||||
rangeSelector: {
|
||||
enabled: false,
|
||||
@@ -218,36 +226,95 @@ const onLoad = () => {
|
||||
}
|
||||
let d = new Date()
|
||||
|
||||
if (temp < 150) {
|
||||
temp = temp + Math.random() * 4 - 1
|
||||
} else if (temp < 20) {
|
||||
temp = temp + Math.random() * 4 - 1.3
|
||||
} else if (temp < targetTemp) {
|
||||
temp = temp + Math.random() * 4 - 1.5
|
||||
} else if (temp >= targetTemp) {
|
||||
temp = temp + Math.random() * 3 - 1.6
|
||||
}
|
||||
if (relais) {
|
||||
temp = temp + 0.2
|
||||
if (temp < (targetTemp / 2)) {
|
||||
temp = temp + Math.random() * 0.5 - 0.125
|
||||
} else if (temp < (targetTemp / (3 / 2))) {
|
||||
temp = temp + Math.random() * 0.5 - 0.15
|
||||
} else {
|
||||
temp = temp - 0.1
|
||||
temp = temp + Math.random() * 0.5 - 0.25
|
||||
}
|
||||
|
||||
let shootFactor = Math.min(((((d.getTime() - lastSwitch.getTime()) / speedFactor) - ((lastSwitchDuration * 0.5) / speedFactor))) / ((3 * 60 * 1000) / speedFactor), 1) // 5mins
|
||||
shootFactor = shootFactor
|
||||
|
||||
if (relais == 0) {
|
||||
temp = temp - 0.8 * shootFactor
|
||||
} else {
|
||||
temp = temp + 1 * shootFactor
|
||||
}
|
||||
|
||||
let mod = temp % 0.25
|
||||
if (mod > 0.125) {
|
||||
temp = temp - mod + 0.25
|
||||
} else {
|
||||
temp = temp - mod
|
||||
}
|
||||
|
||||
if (temperature)
|
||||
temperature.innerHTML = temp.toFixed(2);
|
||||
temperatureData.push([d.getTime(), temp])
|
||||
relaisData.push([d.getTime(), relais])
|
||||
|
||||
temperatureData.push([d.getTime(), temp])
|
||||
|
||||
let derivedShootFactor = Math.min(((d.getTime() - lastSwitch.getTime()) / speedFactor) / ((3 * 60 * 1000) / speedFactor), 1) // 5mins
|
||||
|
||||
let overshoot = setOverShoot * derivedShootFactor; // derive over 5 mins -> 1 min eq. 3°C, 5mins eq. 15°C
|
||||
let dirivedOvershoot = Math.min(overshoot, setOverShoot);
|
||||
|
||||
let undershoot = setUnderShoot * derivedShootFactor; // derive over 5 min -> 1 min eq. 3°C, 5mins eq. 15°C
|
||||
let dirivedUndershoot = Math.min(undershoot, setUnderShoot);
|
||||
|
||||
targetTempOverShoot = targetTemp - dirivedOvershoot;
|
||||
targetTempUnderShoot = targetTemp + dirivedUndershoot;
|
||||
|
||||
if ((d.getTime() - lastSwitch.getTime()) > switchDelay) {
|
||||
if (temp > targetTempOverShoot) // > 270 °C
|
||||
{
|
||||
if (relais == 1) {
|
||||
relais = 0;
|
||||
oven?.classList.remove('on')
|
||||
relaisSwitch?.classList.remove('on')
|
||||
if (relaisSwitchInput)
|
||||
relaisSwitchInput.checked = false
|
||||
|
||||
targetTempOverShoot = targetTemp
|
||||
targetTempUnderShoot = targetTemp
|
||||
lastSwitchDuration = d.getTime() - lastSwitch.getTime()
|
||||
lastSwitch = new Date()
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((d.getTime() - lastSwitch.getTime()) > switchDelay) {
|
||||
if (temp < targetTempUnderShoot) // < 310°C
|
||||
{
|
||||
if (relais == 0) {
|
||||
relais = 1;
|
||||
oven?.classList.add('on')
|
||||
relaisSwitch?.classList.add('on')
|
||||
if (relaisSwitchInput)
|
||||
relaisSwitchInput.checked = true
|
||||
|
||||
targetTempOverShoot = targetTemp
|
||||
targetTempUnderShoot = targetTemp
|
||||
lastSwitchDuration = d.getTime() - lastSwitch.getTime()
|
||||
lastSwitch = new Date()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
relaisData.push([d.getTime(), relais])
|
||||
|
||||
hs.xAxis[0].update({ plotBands: getRelaisBands() })
|
||||
hs.yAxis[0].update({ plotLines: getTargetLines() })
|
||||
hs.series[0].setData(temperatureData, true)
|
||||
}, 250)
|
||||
}, spoofInterval)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
window.addEventListener('load', onLoad);
|
||||
|
||||
const getReadings = () => {
|
||||
@@ -329,6 +396,9 @@ const switchRelais = () => {
|
||||
ws.send("switchRelais");
|
||||
} else {
|
||||
// spoof some test data
|
||||
let d = new Date()
|
||||
lastSwitchDuration = d.getTime() - lastSwitch.getTime()
|
||||
lastSwitch = new Date()
|
||||
if (!relais) {
|
||||
relais = 1
|
||||
oven?.classList.add('on')
|
||||
@@ -338,7 +408,6 @@ const switchRelais = () => {
|
||||
} else {
|
||||
relais = 0
|
||||
oven?.classList.remove('on')
|
||||
|
||||
relaisSwitch?.classList.remove('on')
|
||||
if (relaisSwitchInput)
|
||||
relaisSwitchInput.checked = false
|
||||
@@ -349,10 +418,13 @@ const switchRelais = () => {
|
||||
const changeTargetTemp = (e: Event) => {
|
||||
const target = e.target as HTMLTextAreaElement;
|
||||
let value = Number(target?.value)
|
||||
// targetTemp = value
|
||||
console.log('Changed target temp to ' + value)
|
||||
if (!import.meta.env.DEV) {
|
||||
ws.send("setTargetTemp: " + pad(value, 3));
|
||||
} else {
|
||||
targetTemp = value
|
||||
targetTempOverShoot = value
|
||||
targetTempUnderShoot = value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user