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:
+1
-1
@@ -48,7 +48,7 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<p class="card-title">
|
<p class="card-title">
|
||||||
Target temperature</p>
|
Target temperature</p>
|
||||||
<p class="reading"><input type="number" min="0" max="600" placeholder="350" id="target_temperature">
|
<p class="reading"><input type="number" min="0" max="600" placeholder="300" id="target_temperature">
|
||||||
</input> <label for="target_temperature">
|
</input> <label for="target_temperature">
|
||||||
°C
|
°C
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
+17
-12
@@ -9,10 +9,7 @@
|
|||||||
|
|
||||||
#include "secrets.h"
|
#include "secrets.h"
|
||||||
|
|
||||||
// Create AsyncWebServer object on port 80
|
|
||||||
AsyncWebServer server(80);
|
AsyncWebServer server(80);
|
||||||
|
|
||||||
// Create a WebSocket object
|
|
||||||
AsyncWebSocket ws("/ws");
|
AsyncWebSocket ws("/ws");
|
||||||
|
|
||||||
// Json Variable to Hold Sensor Readings
|
// Json Variable to Hold Sensor Readings
|
||||||
@@ -30,19 +27,23 @@ int thermoCLK = 5;
|
|||||||
|
|
||||||
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
|
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
|
||||||
|
|
||||||
|
float temperature = 0;
|
||||||
int targetTemp = 300;
|
int targetTemp = 300;
|
||||||
float setOverShoot = 15;
|
float setOverShoot = 20;
|
||||||
float setUnderShoot = 10;
|
float setUnderShoot = 20;
|
||||||
float derivedOverShoot = targetTemp;
|
float derivedOverShoot = targetTemp;
|
||||||
float derivedUnderShoot = targetTemp;
|
float derivedUnderShoot = targetTemp;
|
||||||
unsigned long lastSwitch = 0;
|
unsigned long lastSwitch = 0;
|
||||||
unsigned long switchDelay = 30000; // 30s
|
unsigned long switchDelay = 30000; // 15s
|
||||||
bool autoSwitch = true;
|
bool autoSwitch = true;
|
||||||
|
|
||||||
// Get Sensor Readings and return JSON object
|
// Get Sensor Readings and return JSON object
|
||||||
String getSensorReadings()
|
String getSensorReadings()
|
||||||
{
|
{
|
||||||
readings["temperature"] = thermocouple.readCelsius();
|
temperature = thermocouple.readCelsius();
|
||||||
|
|
||||||
|
readings["temperature"] = temperature;
|
||||||
|
|
||||||
if (digitalRead(relay) == HIGH)
|
if (digitalRead(relay) == HIGH)
|
||||||
{
|
{
|
||||||
readings["relais"] = 1;
|
readings["relais"] = 1;
|
||||||
@@ -51,6 +52,7 @@ String getSensorReadings()
|
|||||||
{
|
{
|
||||||
readings["relais"] = 0;
|
readings["relais"] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
readings["target_temp"] = targetTemp;
|
readings["target_temp"] = targetTemp;
|
||||||
readings["derived_overshoot"] = derivedOverShoot;
|
readings["derived_overshoot"] = derivedOverShoot;
|
||||||
readings["derived_undershoot"] = derivedUnderShoot;
|
readings["derived_undershoot"] = derivedUnderShoot;
|
||||||
@@ -161,9 +163,6 @@ void regulateRelais()
|
|||||||
{
|
{
|
||||||
if (autoSwitch)
|
if (autoSwitch)
|
||||||
{
|
{
|
||||||
if ((millis() - lastSwitch) > switchDelay)
|
|
||||||
{
|
|
||||||
float temperature = thermocouple.readCelsius();
|
|
||||||
float sinceLastSwitch = millis() - lastSwitch;
|
float sinceLastSwitch = millis() - lastSwitch;
|
||||||
float fiveMinutesInMillis = 5 * 60 * 1000;
|
float fiveMinutesInMillis = 5 * 60 * 1000;
|
||||||
float shootFactor = sinceLastSwitch / fiveMinutesInMillis;
|
float shootFactor = sinceLastSwitch / fiveMinutesInMillis;
|
||||||
@@ -177,7 +176,10 @@ void regulateRelais()
|
|||||||
float overShootCorrectedTarget = derivedOverShoot = targetTemp - dirivedOvershoot;
|
float overShootCorrectedTarget = derivedOverShoot = targetTemp - dirivedOvershoot;
|
||||||
float underShootCorrectedTarget = derivedUnderShoot = targetTemp + dirivedUndershoot;
|
float underShootCorrectedTarget = derivedUnderShoot = targetTemp + dirivedUndershoot;
|
||||||
|
|
||||||
if (temperature > overShootCorrectedTarget) // > 285°C
|
if ((millis() - lastSwitch) > switchDelay)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (temperature > overShootCorrectedTarget) // > 280°C
|
||||||
{
|
{
|
||||||
if (digitalRead(relay) == HIGH)
|
if (digitalRead(relay) == HIGH)
|
||||||
{
|
{
|
||||||
@@ -186,7 +188,10 @@ void regulateRelais()
|
|||||||
resetDerivedValues();
|
resetDerivedValues();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (temperature < underShootCorrectedTarget) // < 310°C
|
}
|
||||||
|
if ((millis() - lastSwitch) > switchDelay)
|
||||||
|
{
|
||||||
|
if (temperature < underShootCorrectedTarget) // < 320°C
|
||||||
{
|
{
|
||||||
if (digitalRead(relay) == LOW)
|
if (digitalRead(relay) == LOW)
|
||||||
{
|
{
|
||||||
|
|||||||
+93
-21
@@ -28,15 +28,23 @@ let relaisData = [
|
|||||||
|
|
||||||
let temp = 300;
|
let temp = 300;
|
||||||
let targetTemp = 300
|
let targetTemp = 300
|
||||||
|
let setOverShoot = 30
|
||||||
|
let setUnderShoot = 30
|
||||||
let targetTempOverShoot = 300
|
let targetTempOverShoot = 300
|
||||||
let targetTempUnderShoot = 300
|
let targetTempUnderShoot = 300
|
||||||
|
|
||||||
|
let lastSwitch = new Date()
|
||||||
|
let lastSwitchDuration = 0
|
||||||
const oven = document.querySelector('#oven')
|
const oven = document.querySelector('#oven')
|
||||||
const temperature = document.querySelector('#temperature')
|
const temperature = document.querySelector('#temperature')
|
||||||
const relaisSwitch = document.querySelector('#relais_switch')
|
const relaisSwitch = document.querySelector('#relais_switch')
|
||||||
const relaisSwitchInput: HTMLInputElement | null = document.querySelector('#relais_switch_input')
|
const relaisSwitchInput: HTMLInputElement | null = document.querySelector('#relais_switch_input')
|
||||||
const targetTempInput: HTMLInputElement | null = document.querySelector('#target_temperature')
|
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 maxValues = 4 * 60 * 60 // 60 minutes (4 values/sec)
|
||||||
|
|
||||||
let hs: Highcharts.StockChart;
|
let hs: Highcharts.StockChart;
|
||||||
@@ -91,10 +99,10 @@ const createChart = () => {
|
|||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
|
|
||||||
title: {
|
// title: {
|
||||||
text: 'Temperature',
|
// text: 'Temperature',
|
||||||
align: 'left',
|
// align: 'left',
|
||||||
},
|
// },
|
||||||
|
|
||||||
rangeSelector: {
|
rangeSelector: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
@@ -218,36 +226,95 @@ const onLoad = () => {
|
|||||||
}
|
}
|
||||||
let d = new Date()
|
let d = new Date()
|
||||||
|
|
||||||
if (temp < 150) {
|
if (temp < (targetTemp / 2)) {
|
||||||
temp = temp + Math.random() * 4 - 1
|
temp = temp + Math.random() * 0.5 - 0.125
|
||||||
} else if (temp < 20) {
|
} else if (temp < (targetTemp / (3 / 2))) {
|
||||||
temp = temp + Math.random() * 4 - 1.3
|
temp = temp + Math.random() * 0.5 - 0.15
|
||||||
} 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
|
|
||||||
} else {
|
} 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)
|
if (temperature)
|
||||||
temperature.innerHTML = temp.toFixed(2);
|
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.xAxis[0].update({ plotBands: getRelaisBands() })
|
||||||
hs.yAxis[0].update({ plotLines: getTargetLines() })
|
hs.yAxis[0].update({ plotLines: getTargetLines() })
|
||||||
hs.series[0].setData(temperatureData, true)
|
hs.series[0].setData(temperatureData, true)
|
||||||
}, 250)
|
}, spoofInterval)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
window.addEventListener('load', onLoad);
|
window.addEventListener('load', onLoad);
|
||||||
|
|
||||||
const getReadings = () => {
|
const getReadings = () => {
|
||||||
@@ -329,6 +396,9 @@ const switchRelais = () => {
|
|||||||
ws.send("switchRelais");
|
ws.send("switchRelais");
|
||||||
} else {
|
} else {
|
||||||
// spoof some test data
|
// spoof some test data
|
||||||
|
let d = new Date()
|
||||||
|
lastSwitchDuration = d.getTime() - lastSwitch.getTime()
|
||||||
|
lastSwitch = new Date()
|
||||||
if (!relais) {
|
if (!relais) {
|
||||||
relais = 1
|
relais = 1
|
||||||
oven?.classList.add('on')
|
oven?.classList.add('on')
|
||||||
@@ -338,7 +408,6 @@ const switchRelais = () => {
|
|||||||
} else {
|
} else {
|
||||||
relais = 0
|
relais = 0
|
||||||
oven?.classList.remove('on')
|
oven?.classList.remove('on')
|
||||||
|
|
||||||
relaisSwitch?.classList.remove('on')
|
relaisSwitch?.classList.remove('on')
|
||||||
if (relaisSwitchInput)
|
if (relaisSwitchInput)
|
||||||
relaisSwitchInput.checked = false
|
relaisSwitchInput.checked = false
|
||||||
@@ -349,10 +418,13 @@ const switchRelais = () => {
|
|||||||
const changeTargetTemp = (e: Event) => {
|
const changeTargetTemp = (e: Event) => {
|
||||||
const target = e.target as HTMLTextAreaElement;
|
const target = e.target as HTMLTextAreaElement;
|
||||||
let value = Number(target?.value)
|
let value = Number(target?.value)
|
||||||
// targetTemp = value
|
|
||||||
console.log('Changed target temp to ' + value)
|
console.log('Changed target temp to ' + value)
|
||||||
if (!import.meta.env.DEV) {
|
if (!import.meta.env.DEV) {
|
||||||
ws.send("setTargetTemp: " + pad(value, 3));
|
ws.send("setTargetTemp: " + pad(value, 3));
|
||||||
|
} else {
|
||||||
|
targetTemp = value
|
||||||
|
targetTempOverShoot = value
|
||||||
|
targetTempUnderShoot = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user