Initial junk to get temp control working.

Totally not working yet, just getting it pushed
to the remote
This commit is contained in:
Chris Giacofei 2022-01-18 19:45:05 -05:00
parent 6a0de023c4
commit 18c43187cb
3 changed files with 141 additions and 9 deletions

View File

@ -3,7 +3,7 @@
#include <SPI.h>
#include <Ethernet.h>
// Additoinal Libraries
// Additional Libraries
#include <ArduinoJson.h>
#include <MQTT.h>
#include <LiquidCrystal_I2C.h>
@ -15,17 +15,28 @@
#include "config.h"
#include "button.h"
#include "slowPWM.h"
#include "thermoControl.h"
// Global variables.
byte KettleDuty = 0;
bool KettleOn = false;
uint8_t KettleDuty = 0;
double KettleTemp;
uint8_t KettleSetpoint;
modes KettleMode = OFF;
/* Defined in config.h for now */
// uint8_t ThreshPWR = 5;
// double Hysteresis = 1;
// User I/O objects.
Button Enter;
slowPWM boilPWM;
MD_REncoder rotary = MD_REncoder(encoderDT, encoderCLK);
LiquidCrystal_I2C lcd(0x27,20,4);
// Internal I/O
Adafruit_MAX31865 KettleThermo = Adafruit_MAX31865(10);
slowPWM boilPWM;
thermoControl KettleController = thermoControl(&KettleTemp, &KettleSetpoint, &KettleDuty, &ThreshPWR, &Hysteresis);
EthernetClient net;
MQTTClient mqtt_client;
@ -34,13 +45,26 @@ unsigned long lastRun = 0;
// Return a character array to represent the
// On/Off state of the kettle.
char* KettleState() {
if (KettleOn) {
return (char*)"On";
if (KettleMode == MANUAL) {
return (char*)"Manual";
} else if (KettleMode == AUTOMATIC) {
return (char*)"Auto";
} else {
return (char*)"Off";
}
}
char* ShowKettleSetting() {
char* LCD_Line;
if (KettleMode == MANUAL) {
return sprintf(LCD_Line, "Kettle Power: %03d%", KettleDuty);
} else if (KettleMode == AUTOMATIC) {
return sprintf(LCD_Line, "Kettle Temp: %03dF", KettleSetpoint);
} else {
return (char[])" Off ";
}
}
// Interrupt function to run when encoder is turned.
//
// Increases/decreases the kettle output to a max
@ -65,7 +89,7 @@ void doEncoder()
// LCD menu setup.
LiquidLine KettleState_line(0, 0, "Boil Kettle ", KettleState);
LiquidLine kettle_power_line(0, 1, "Kettle Power % ", KettleDuty);
LiquidLine kettle_power_line(0, 1, ShowKettleSetting);
LiquidScreen home_screen(KettleState_line, kettle_power_line);
LiquidMenu menu(lcd);
@ -84,6 +108,7 @@ void setup() {
pinMode(encoderDT, INPUT_PULLUP);
Enter.begin(encoderBTN);
boilPWM.begin(kettlePWM, PeriodPWM);
KettleThermo.begin(MAX31865_3WIRE);
// if you get a connection, report back via serial:
if (Ethernet.linkStatus() == LinkON) {
@ -106,7 +131,8 @@ void UpdateBoilKettle(){
static byte last_KettleDuty = 0;
if (Enter.pressed()) {
KettleOn = !KettleOn;
KettleMode = !KettleMode;
menu.update();
}
@ -115,7 +141,8 @@ void UpdateBoilKettle(){
menu.update();
}
if (KettleOn) {
if (KettleMode) {
KettleController.Compute();
digitalWrite(kettlePWM, boilPWM.compute(KettleDuty));
} else {
digitalWrite(kettlePWM, boilPWM.compute(0));
@ -123,6 +150,7 @@ void UpdateBoilKettle(){
}
void loop() {
KettleTemp = KettleThermo.readRTD();
UpdateBoilKettle();
unsigned long elapsedTime = (millis() - lastRun);

View File

@ -0,0 +1,71 @@
#include <Arduino.h>
#include <EEPROM.h>
#include "thermoControl.h"
thermoControl::thermoControl(double* input_temp, uint8_t* setpoint_temp, uint8_t* output_pwm, uint8_t* max_threshold, uint8_t* hysteresis) {
output_pwm = output_pwm;
input_temp = input_temp;
setpoint_temp = setpoint_temp;
outMax = 100;
outMin = 10;
OpMode = OFF;
SampleTime = 100;
lastTime = millis()-SampleTime;
}
bool thermoControl::Compute() {
unsigned long now = millis();
unsigned long timeChange = (now - lastTime);
if(timeChange>=SampleTime && OpMode == AUTOMATIC) {
double output;
double input = *input_temp;
double error = (double)*setpoint_temp - input;
if (error >= (double)*max_threshold) {
output = outMax;
} else if (error > *hysteresis) {
output = 100 * error / *max_threshold;
output = max(output, outMin);
output = min(output, outMax);
} else {
output = 0;
}
*output_pwm = output;
lastTime = now;
return true;
} else {
return false;
}
}
void thermoControl::SetSampleTime(int NewSampleTime) {
if (NewSampleTime > 0) {
SampleTime = (unsigned long)NewSampleTime;
}
}
void thermoControl::SetPowerLimits(uint8_t Max, uint8_t Min) {
if(Min >= Max) return;
outMax = Max;
outMin = Min;
}
void thermoControl::SetMode(modes newMode) {
OpMode = newMode;
}
modes thermoControl::GetMode() {
return OpMode;
}
modes thermoControl::CycleMode() {
OpMode = (modes)(OpMode + 1);
return OpMode;
}

View File

@ -0,0 +1,33 @@
#ifndef THERMOCONTROL_h
#define THERMOCONTROL_h
enum modes : uint8_t {OFF, AUTOMATIC, MANUAL};
class thermoControl {
private:
double *input_temp;
double *output_pwm;
double *setpoint_temp;
double *hysteresis;
double *max_threshold;
double outMax;
double outMin;
modes OpMode;
unsigned long SampleTime;
unsigned long lastTime;
public:
thermoControl(double*, uint8_t*, uint8_t*, uint8_t*, uint8_t*);
bool Compute();
void SetSampleTime(int);
void SetPowerLimits(uint8_t, uint8_t);
void SetHysteresis(double);
void SetThreshPWR(uint8_t);
void SetMode(modes);
modes GetMode();
modes CycleMode();
};
#endif