Compare commits
4 Commits
master
...
PID-contro
Author | SHA1 | Date | |
---|---|---|---|
|
23f5c79cf3 | ||
|
455d5cc89f | ||
|
ac157d2acb | ||
|
9be0cabfe3 |
@ -8,23 +8,23 @@
|
|||||||
#include <LiquidMenu.h> // LiquidMenu_config.h needs to be modified to use I2C.
|
#include <LiquidMenu.h> // LiquidMenu_config.h needs to be modified to use I2C.
|
||||||
#include <MD_REncoder.h>
|
#include <MD_REncoder.h>
|
||||||
#include <Adafruit_MAX31865.h>
|
#include <Adafruit_MAX31865.h>
|
||||||
//#include <EEPROM-Storage.h>
|
#include <EEPROM-Storage.h>
|
||||||
|
|
||||||
// My Includes
|
// My Includes
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "src/button/button.h"
|
#include "src/button/button.h"
|
||||||
#include "src/slowPWM/slowPWM.h"
|
#include "src/slowPWM/slowPWM.h"
|
||||||
#include "src/thermoControl/thermoControl.h"
|
//#include "src/thermoControl/thermoControl.h"
|
||||||
//#include "src/Arduino-PID-Library/PID_v1.h"
|
#include "src/Arduino-PID-Library/PID_v1.h"
|
||||||
|
|
||||||
double KettleDuty = 0;
|
double KettleDuty = 0;
|
||||||
double KettleSetpoint = 70;
|
double KettleSetpoint = 70;
|
||||||
double CurrentTemp;
|
double CurrentTemp;
|
||||||
bool tuning = false;
|
bool tuning = false;
|
||||||
|
|
||||||
//EEPROMStorage<double> eepromKp(0, 2.0); // 9 bytes for doubles 8 + 1 for checksum
|
EEPROMStorage<double> kettleKp(0, 2.0); // 9 bytes for doubles 8 + 1 for checksum
|
||||||
//EEPROMStorage<double> eepromKi(9, 5.0); // Initialize at zero.
|
EEPROMStorage<double> kettleKi(9, 5.0);
|
||||||
//EEPROMStorage<double> eepromKd(18, 1.0);
|
EEPROMStorage<double> kettleKd(18, 1.0);
|
||||||
|
|
||||||
// User I/O objects.
|
// User I/O objects.
|
||||||
Button Enter;
|
Button Enter;
|
||||||
@ -32,11 +32,7 @@ slowPWM boilPWM;
|
|||||||
MD_REncoder rotary = MD_REncoder(encoderDT, encoderCLK);
|
MD_REncoder rotary = MD_REncoder(encoderDT, encoderCLK);
|
||||||
LiquidCrystal_I2C lcd(0x27, 20, 4);
|
LiquidCrystal_I2C lcd(0x27, 20, 4);
|
||||||
Adafruit_MAX31865 thermoRTD = Adafruit_MAX31865(KettleRTD);
|
Adafruit_MAX31865 thermoRTD = Adafruit_MAX31865(KettleRTD);
|
||||||
thermoControl Controller(&CurrentTemp, &KettleSetpoint, &KettleDuty, AUTOMATIC);
|
PID Controller(&CurrentTemp, &KettleDuty, &KettleSetpoint, kettleKp, kettleKi, kettleKd, P_ON_M, DIRECT);
|
||||||
|
|
||||||
//PID ControllerPID(&CurrentTemp, &KettleDuty, &KettleSetpoint, eepromKp, eepromKi, eepromKd, P_ON_M, DIRECT);
|
|
||||||
|
|
||||||
unsigned long lastRun = 0;
|
|
||||||
|
|
||||||
// Return a character array to represent the
|
// Return a character array to represent the
|
||||||
// On/Off state of the kettle.
|
// On/Off state of the kettle.
|
||||||
@ -74,6 +70,8 @@ LiquidMenu menu(lcd);
|
|||||||
// Increases/decreases the kettle output to a max
|
// Increases/decreases the kettle output to a max
|
||||||
// of 100% and minimum of 0%.
|
// of 100% and minimum of 0%.
|
||||||
void doEncoder() {
|
void doEncoder() {
|
||||||
|
if (tuning) return;
|
||||||
|
|
||||||
uint8_t result = rotary.read();
|
uint8_t result = rotary.read();
|
||||||
uint8_t inc = 1;
|
uint8_t inc = 1;
|
||||||
|
|
||||||
@ -108,7 +106,6 @@ void doEncoder() {
|
|||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
|
||||||
lastRun = millis() - UpdateInterval;
|
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
rotary.begin();
|
rotary.begin();
|
||||||
thermoRTD.begin(MAX31865_3WIRE);
|
thermoRTD.begin(MAX31865_3WIRE);
|
||||||
@ -116,7 +113,6 @@ void setup() {
|
|||||||
attachInterrupt(digitalPinToInterrupt(encoderCLK), doEncoder, CHANGE);
|
attachInterrupt(digitalPinToInterrupt(encoderCLK), doEncoder, CHANGE);
|
||||||
attachInterrupt(digitalPinToInterrupt(encoderDT), doEncoder, CHANGE);
|
attachInterrupt(digitalPinToInterrupt(encoderDT), doEncoder, CHANGE);
|
||||||
|
|
||||||
|
|
||||||
pinMode(encoderCLK, INPUT_PULLUP);
|
pinMode(encoderCLK, INPUT_PULLUP);
|
||||||
pinMode(encoderDT, INPUT_PULLUP);
|
pinMode(encoderDT, INPUT_PULLUP);
|
||||||
Enter.begin(encoderBTN);
|
Enter.begin(encoderBTN);
|
||||||
@ -143,33 +139,48 @@ void run_kettle() {
|
|||||||
Controller.Compute();
|
Controller.Compute();
|
||||||
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void run_tuning() {
|
void run_tuning() {
|
||||||
|
|
||||||
if (Enter.pressed()) {
|
if (Enter.pressed()) {
|
||||||
stopAutoTune();
|
if(tuning) { //cancel autotune
|
||||||
|
Controller.Cancel();
|
||||||
|
Controller.Mode(OFF);
|
||||||
|
tuning=false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initial setup
|
||||||
|
if(!tuning) {
|
||||||
|
KettleDuty=50;
|
||||||
|
Controller.NoiseBand(0.5);
|
||||||
|
Controller.OutputStep(30);
|
||||||
|
Controller.LookbackSec(20);
|
||||||
|
Controller.Mode(AUTOMATIC);
|
||||||
|
tuning=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Controller.ComputeTune() != 0) {
|
||||||
|
tuning = false;
|
||||||
|
}
|
||||||
|
if(!tuning) {
|
||||||
|
//we're done, set the tuning parameters
|
||||||
|
Controller.SetTunings(Controller.TunedKp(),Controller.TunedKi(),Controller.TunedKd());
|
||||||
|
Controller.Mode(OFF);
|
||||||
}
|
}
|
||||||
int result = ControllerPID.ComputeTune();
|
|
||||||
if (result!=0)
|
|
||||||
{
|
|
||||||
tuning = false;
|
|
||||||
}
|
|
||||||
if(!tuning)
|
|
||||||
{ //we're done, set the tuning parameters
|
|
||||||
ControllerPID.SetTunings(ControllerPID.TunedKp(),ControllerPID.TunedKi(),ControllerPID.TunedKd());
|
|
||||||
ControllerPID.Mode(OFF);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
void loop() {
|
void loop() {
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
static unsigned long lastTime=now-2000;
|
static unsigned long lastTime=now-250;
|
||||||
unsigned long timeChange = (now - lastTime);
|
unsigned long timeChange = (now - lastTime);
|
||||||
static byte lastoutput = LOW;
|
static byte lastoutput = LOW;
|
||||||
static double lastKettleDuty = 0;
|
static double lastKettleDuty = 0;
|
||||||
static double lastKettleSetpoint = 0;
|
static double lastKettleSetpoint = 0;
|
||||||
static byte lastTemperature;
|
static byte lastTemperature;
|
||||||
|
|
||||||
if(timeChange >= 2000) {
|
if(timeChange >= 250) {
|
||||||
CurrentTemp = 32 + 1.8 * thermoRTD.temperature(RNOMINAL_KETTLE, RREF_KETTLE);
|
CurrentTemp = 32 + 1.8 * thermoRTD.temperature(RNOMINAL_KETTLE, RREF_KETTLE);
|
||||||
lastTime = now;
|
lastTime = now;
|
||||||
}
|
}
|
||||||
@ -177,7 +188,7 @@ void loop() {
|
|||||||
if (!tuning) {
|
if (!tuning) {
|
||||||
run_kettle();
|
run_kettle();
|
||||||
} else {
|
} else {
|
||||||
//run_tuning();
|
run_tuning();
|
||||||
}
|
}
|
||||||
|
|
||||||
byte output = boilPWM.Compute(KettleDuty);
|
byte output = boilPWM.Compute(KettleDuty);
|
||||||
@ -195,31 +206,11 @@ void loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void startAutoTune() {
|
|
||||||
if(!tuning) {
|
|
||||||
//Set the output to the desired starting frequency.
|
|
||||||
KettleDuty=50;
|
|
||||||
ControllerPID.SetNoiseBand(1);
|
|
||||||
ControllerPID.SetOutputStep(30);
|
|
||||||
ControllerPID.SetLookbackSec(20);
|
|
||||||
ControllerPID.Mode(AUTOMATIC);
|
|
||||||
tuning=true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void stopAutoTune() {
|
|
||||||
if(tuning) { //cancel autotune
|
|
||||||
ControllerPID.Cancel();
|
|
||||||
ControllerPID.Mode(OFF);
|
|
||||||
tuning=false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SaveTunings() {
|
void SaveTunings() {
|
||||||
eepromKp = ControllerPID.GetKp();
|
kettleKp = Controller.Kp();
|
||||||
eepromKi = ControllerPID.GetKi();
|
kettleKi = Controller.Ki();
|
||||||
eepromKd = ControllerPID.GetKd();
|
kettleKd = Controller.Kd();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialSend()
|
void SerialSend()
|
||||||
@ -230,9 +221,9 @@ void SerialSend()
|
|||||||
if(tuning){
|
if(tuning){
|
||||||
Serial.println("tuning mode");
|
Serial.println("tuning mode");
|
||||||
} else {
|
} else {
|
||||||
Serial.print("kp: ");Serial.print(ControllerPID.GetKp());Serial.print(" ");
|
Serial.print("kp: ");Serial.print(Controller.Kp());Serial.print(" ");
|
||||||
Serial.print("ki: ");Serial.print(ControllerPID.GetKi());Serial.print(" ");
|
Serial.print("ki: ");Serial.print(Controller.Ki());Serial.print(" ");
|
||||||
Serial.print("kd: ");Serial.print(ControllerPID.GetKd());Serial.println();
|
Serial.print("kd: ");Serial.print(Controller.Kd());Serial.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,13 +233,10 @@ void SerialReceive()
|
|||||||
String myinput;
|
String myinput;
|
||||||
myinput = Serial.readString();
|
myinput = Serial.readString();
|
||||||
myinput.trim();
|
myinput.trim();
|
||||||
if(myinput=="start"){
|
if(myinput=="tune"){
|
||||||
startAutoTune();
|
tuning=true;
|
||||||
} else if(myinput=="stop") {
|
|
||||||
stopAutoTune();
|
|
||||||
} else if(myinput=="save") {
|
} else if(myinput=="save") {
|
||||||
SaveTunings();
|
SaveTunings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
@ -1 +1 @@
|
|||||||
Subproject commit 7787498eda8955288e99a18d02581a425203bac5
|
Subproject commit d565cded53094ac01a63078cd4c0f1295aad67b4
|
@ -14,24 +14,27 @@ thermoControl::thermoControl(double* current_temp, double* setpoint, double* pow
|
|||||||
actual_temp = current_temp;
|
actual_temp = current_temp;
|
||||||
hysteresis = 1.0;
|
hysteresis = 1.0;
|
||||||
max_pwr_threshold = 5.0;
|
max_pwr_threshold = 5.0;
|
||||||
|
isheating=false;
|
||||||
Serial.println("Controller Started");
|
Serial.println("Controller Started");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool thermoControl::Compute() {
|
bool thermoControl::Compute() {
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
unsigned long timeChange = (now - lastTime);
|
unsigned long timeChange = (now - lastTime);
|
||||||
|
|
||||||
if(timeChange >= SampleInterval && OpMode == AUTOMATIC) {
|
if(timeChange >= SampleInterval && OpMode == AUTOMATIC) {
|
||||||
double error = *control_temp - *actual_temp;
|
double error = *control_temp - *actual_temp;
|
||||||
|
|
||||||
if (error >= max_pwr_threshold) {
|
if (error >= max_pwr_threshold) {
|
||||||
*output_pwm = outMax;
|
*output_pwm = outMax;
|
||||||
} else if (error > hysteresis) {
|
isheating=true;
|
||||||
|
} else if (error > hysteresis || (error <= hysteresis && error > 0 && isheating)) {
|
||||||
*output_pwm = 100 * error / max_pwr_threshold;
|
*output_pwm = 100 * error / max_pwr_threshold;
|
||||||
if (*output_pwm > 100) *output_pwm = 100;
|
if (*output_pwm > 100) *output_pwm = 100;
|
||||||
if (*output_pwm < 0) *output_pwm = 0;
|
isheating=true;
|
||||||
} else {
|
} else {
|
||||||
*output_pwm = 0;
|
*output_pwm = 0;
|
||||||
|
isheating=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastTime = now;
|
lastTime = now;
|
||||||
|
@ -17,6 +17,7 @@ class thermoControl {
|
|||||||
int outMin;
|
int outMin;
|
||||||
int SampleInterval;
|
int SampleInterval;
|
||||||
unsigned long lastTime;
|
unsigned long lastTime;
|
||||||
|
bool isheating;
|
||||||
modes OpMode;
|
modes OpMode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user