167 lines
3.8 KiB
C++
167 lines
3.8 KiB
C++
//Built-in
|
|
#include <Arduino.h>
|
|
#include <SPI.h>
|
|
#include <Ethernet.h>
|
|
|
|
// Additional Libraries
|
|
#include <ArduinoJson.h>
|
|
#include <MQTT.h>
|
|
#include <LiquidCrystal_I2C.h>
|
|
#include <LiquidMenu.h> // LiquidMenu_config.h needs to be modified to use I2C.
|
|
#include <MD_REncoder.h>
|
|
#include <Adafruit_MAX31865.h>
|
|
|
|
// My Includes
|
|
#include "config.h"
|
|
#include "button.h"
|
|
#include "slowPWM.h"
|
|
#include "thermoControl.h"
|
|
|
|
// Global variables.
|
|
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;
|
|
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;
|
|
|
|
unsigned long lastRun = 0;
|
|
|
|
// Return a character array to represent the
|
|
// On/Off state of the kettle.
|
|
char* KettleState() {
|
|
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
|
|
// of 100% and minimum of 0%.
|
|
void doEncoder()
|
|
{
|
|
uint8_t result = rotary.read();
|
|
uint8_t inc;
|
|
|
|
if (result) {
|
|
uint8_t speed = rotary.speed();
|
|
speed >= 10 ? inc = 5 : inc = 1;
|
|
}
|
|
|
|
if (result == DIR_CW && KettleDuty < 100) {
|
|
KettleDuty = (KettleDuty / inc) * inc + inc;
|
|
} else if (result == DIR_CCW && KettleDuty > 0) {
|
|
KettleDuty = (KettleDuty / inc) * inc - inc;
|
|
}
|
|
|
|
}
|
|
|
|
// LCD menu setup.
|
|
LiquidLine KettleState_line(0, 0, "Boil Kettle ", KettleState);
|
|
LiquidLine kettle_power_line(0, 1, ShowKettleSetting);
|
|
LiquidScreen home_screen(KettleState_line, kettle_power_line);
|
|
LiquidMenu menu(lcd);
|
|
|
|
void setup() {
|
|
|
|
unsigned long lastRun = millis() - UpdateInterval;
|
|
Serial.begin(9600);
|
|
rotary.begin();
|
|
Ethernet.begin(mac, ip);
|
|
Serial.println("Setting up...");
|
|
|
|
attachInterrupt(digitalPinToInterrupt(encoderCLK), doEncoder, CHANGE);
|
|
attachInterrupt(digitalPinToInterrupt(encoderDT), doEncoder, CHANGE);
|
|
|
|
pinMode(encoderCLK, INPUT_PULLUP);
|
|
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) {
|
|
SetupMQTT(MQTT_BROKER);
|
|
} else {
|
|
// if you didn't get a connection to the server:
|
|
Serial.println("connection failed");
|
|
}
|
|
|
|
lcd.init();
|
|
lcd.backlight();
|
|
|
|
menu.init();
|
|
menu.add_screen(home_screen);
|
|
menu.update();
|
|
|
|
};
|
|
|
|
void UpdateBoilKettle(){
|
|
static byte last_KettleDuty = 0;
|
|
|
|
if (Enter.pressed()) {
|
|
|
|
KettleMode = !KettleMode;
|
|
menu.update();
|
|
}
|
|
|
|
if (last_KettleDuty != KettleDuty) {
|
|
last_KettleDuty = KettleDuty;
|
|
menu.update();
|
|
}
|
|
|
|
if (KettleMode) {
|
|
KettleController.Compute();
|
|
digitalWrite(kettlePWM, boilPWM.compute(KettleDuty));
|
|
} else {
|
|
digitalWrite(kettlePWM, boilPWM.compute(0));
|
|
}
|
|
}
|
|
|
|
void loop() {
|
|
KettleTemp = KettleThermo.readRTD();
|
|
UpdateBoilKettle();
|
|
|
|
unsigned long elapsedTime = (millis() - lastRun);
|
|
|
|
if (Ethernet.linkStatus() == LinkON && elapsedTime >= UpdateInterval) {
|
|
mqtt_client.loop();
|
|
//if (!mqtt_client.connected()) ConnectMQTT();
|
|
|
|
SendSensorData();
|
|
lastRun = millis();
|
|
}
|
|
|
|
}
|