Revert master back to old code that actually worked.

This commit is contained in:
Chris Giacofei 2022-01-14 07:50:34 -05:00
parent e85a8d1704
commit da937ecde5
4 changed files with 106 additions and 246 deletions

View File

@ -11,265 +11,133 @@
#include <MD_REncoder.h> #include <MD_REncoder.h>
#include <Adafruit_MAX31865.h> #include <Adafruit_MAX31865.h>
// My Includes // My Includes
#include "button.h"
#include "config.h" #include "config.h"
#include "menu.h" #include "button.h"
enum kettle_mode {OFF=0, PWM=1, OVERFLOW}; // Pin definitions
enum encoder_state {ENC_ST_LINE=0, ENC_ST_SETTING=1, ENC_ST_OOB}; #define encoderCLK 2
enum function_types {increase=1, decrease}; #define encoderDT 3
#define encoderBTN 4
#define kettlePWM 5
/* ---------- Global variables ---------- */ // Global variables.
byte KettleDuty = 0; byte KettleDuty = 0;
bool NetworkOn = false; bool KettleOn = false;
kettle_mode KettleMode = OFF;
encoder_state EncoderState = ENC_ST_LINE;
/* ---------- User I/O objects ---------- */ // User I/O objects.
Button EncoderButton; Button Enter;
MD_REncoder RotaryEncoder = MD_REncoder(encoderDT, encoderCLK); MD_REncoder rotary = MD_REncoder(encoderDT, encoderCLK);
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27,20,4); LiquidCrystal_I2C lcd(0x27,20,4);
/* ---------- Controller I/O objects ---------- */ float output = 0;
Adafruit_MAX31865 kettleRTD = Adafruit_MAX31865(kettleRTDCS); int updateInterval = 1000;
Adafruit_MAX31865 mashRTD = Adafruit_MAX31865(mashRTDCS);
/* ---------- Network bits ---------- */
EthernetClient net; EthernetClient net;
MQTTClient mqtt_client; MQTTClient mqtt_client;
/* ---------- LCD menu setup ---------- */ unsigned long lastRun = 0;
LiquidLine kettle_mode_line(0, 0, "Output Mode ", KettleState);
LiquidLine kettle_setpoint_line(0, 1, "Kettle Power ", KettleSetpoint, SetpointUnit); // Return a character array to represent the
LiquidLine kettle_actual_line(0, 2, "Kettle Temp ", KettleActual, "F"); // On/Off state of the kettle.
LiquidScreen home_screen(kettle_mode_line, kettle_setpoint_line, kettle_actual_line); char* KettleState() {
if (KettleOn) {
return (char*)"On";
} 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();
if (result == DIR_CW && KettleDuty < 100) {
KettleDuty++;
} else if (result == DIR_CCW && KettleDuty > 0) {
KettleDuty--;
}
}
// LCD menu setup.
LiquidLine KettleState_line(0, 0, "Boil Kettle ", KettleState);
LiquidLine kettle_power_line(0, 1, "Kettle Power % ", KettleDuty);
LiquidScreen home_screen(KettleState_line, kettle_power_line);
LiquidMenu menu(lcd); LiquidMenu menu(lcd);
void setup() { void setup() {
unsigned long lastRun = millis() - updateInterval;
Serial.begin(9600); Serial.begin(9600);
Serial.println("Setting up..."); rotary.begin();
Ethernet.begin(mac, ip); Ethernet.begin(mac, ip);
Serial.println("Setting up...");
// Set all the I/O pin states
RotaryEncoder.begin();
EncoderButton.begin(encoderBTN);
kettleRTD.begin(MAX31865_3WIRE);
mashRTD.begin(MAX31865_3WIRE);
pinMode(encoderCLK, INPUT_PULLUP);
pinMode(encoderDT, INPUT_PULLUP);
pinMode(kettlePWM, OUTPUT);
// Attach interrupts to the rotary encoder
attachInterrupt(digitalPinToInterrupt(encoderCLK), doEncoder, CHANGE); attachInterrupt(digitalPinToInterrupt(encoderCLK), doEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(encoderDT), doEncoder, CHANGE); attachInterrupt(digitalPinToInterrupt(encoderDT), doEncoder, CHANGE);
// Attach functions to menu lines pinMode(encoderCLK, INPUT_PULLUP);
kettle_mode_line.attach_function(increase, kettle_mode_next); pinMode(encoderDT, INPUT_PULLUP);
kettle_mode_line.attach_function(decrease, kettle_mode_previous); Enter.begin(encoderBTN);
kettle_setpoint_line.attach_function(increase, increase_setpoint); pinMode(encoderBTN, INPUT_PULLUP);
kettle_setpoint_line.attach_function(decrease, decrease_setpoint);
// 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.init();
lcd.backlight(); lcd.backlight();
// Check for network connection before attemping MQTT setup.
if (Ethernet.linkStatus() == LinkON) {
NetworkOn = true;
lcd.setCursor(0, 1);
lcd.print("Ethernet connected.");
lcd.setCursor(1, 1);
lcd.print(net.remoteIP());
SetupMQTT(MQTT_BROKER);
} else {
lcd.setCursor(0, 1);
lcd.print("No network connection.");
}
delay(5000);
lcd.clear();
menu.init(); menu.init();
menu.add_screen(home_screen); menu.add_screen(home_screen);
menu.update(); menu.update();
}; };
void loop() { void UpdateBoilKettle(){
ButtonCheck(); static byte last_KettleDuty = 0;
if (KettleMode == PWM) { if (Enter.pressed()) {
KettleOn = !KettleOn;
menu.update();
}
if (last_KettleDuty != KettleDuty) {
last_KettleDuty = KettleDuty;
menu.update();
}
if (KettleOn) {
slowPWM(kettlePWM, KettleDuty, PeriodPWM); slowPWM(kettlePWM, KettleDuty, PeriodPWM);
} else { } else {
slowPWM(kettlePWM, 0, PeriodPWM); slowPWM(kettlePWM, 0, PeriodPWM);
} }
}
void loop() {
UpdateBoilKettle();
static unsigned long lastRun = millis() - UpdateInterval;
unsigned long elapsedTime = (millis() - lastRun); unsigned long elapsedTime = (millis() - lastRun);
// if (elapsedTime >= updateInterval) {
if (NetworkOn && elapsedTime >= UpdateInterval) {
mqtt_client.loop(); mqtt_client.loop();
if (!mqtt_client.connected()) ConnectMQTT(); //if (!mqtt_client.connected()) ConnectMQTT();
SendSensorData(); SendSensorData();
lastRun = millis(); lastRun = millis();
} }
} }
/* Interrupt function to run when encoder is turned.
Either switches focus of the menu lines or
changes setpoint of focused line. */
void doEncoder() {
uint8_t result = RotaryEncoder.read();
// check in which state the encoder is currently in
switch (EncoderState) {
case ENC_ST_LINE: // cycling focus through the lines
if (result == DIR_CW) {
menu.switch_focus(true);
} else {
menu.switch_focus(false);
}
break;
case ENC_ST_SETTING: // changing a setting
if (result == DIR_CW) {
menu.call_function(increase);
} else {
menu.call_function(decrease);
}
break;
default: // invalid state
EncoderState = 0; // return to a valid state
break;
}
menu.update();
}
// Cycle the rotary encoder state when button is pressed.
// Switches between menu navigation and adjusting setpoints.
void ButtonCheck(){
if (!EncoderButton.pressed()) { return; }
if (EncoderState + 1 < ENC_ST_OOB) { // check if the next state is valid
EncoderState = (encoder_state)(EncoderState + 1); // increment to the next state (ENC_ST_LINE -> ENC_ST_SETTING)
} else {
EncoderState = 0; // in case of press while changing a setting - wrap around to state ENC_ST_LINE
}
}
/**
* Return a character array to represent the state of the kettle.
*/
char* KettleState() {
if (KettleMode == OFF) {
return (char*)"OFF";
} else if (KettleMode == PWM) {
return (char*)"PWM";
} else {
return (char*)"PID";
}
}
/**
* Return the setpoint of the kettle
*/
char* KettleSetpoint() {
if (KettleMode == OFF) {
return (char*)"---";
} else if (KettleMode == PWM) {
return (char*)KettleDuty;
}
/* Eventually
else if (KettleMode == PID) {
return (char*)KettleTEMP;
}
*/
}
/**
* Return the actual temp as char.
*/
char* KettleActual() {
char buffer[6];
dtostrf(kettleRTD.temperature(RNOMINAL_KETTLE, RREF_KETTLE), 5, 1, buffer);
return buffer;
}
/**
* Return the actual temp as char.
*/
char* MashActual() {
char buffer[6];
dtostrf(mashRTD.temperature(RNOMINAL_MASH, RREF_MASH), 5, 1, buffer);
return buffer;
}
char* SetpointUnit(){
if (KettleMode == OFF) {
return (char*)" ";
} else if (KettleMode == PWM) {
return (char*)"%";
} else {
return (char*)"F";
}
}
/**
* Cycle kettle mode forward.
*/
void kettle_mode_next() {
if (KettleMode + 1 < OVERFLOW) {
KettleMode = (kettle_mode)(KettleMode + 1);
} else {
KettleMode = 0;
}
}
/**
* Cycle kettle mode backward.
*/
void kettle_mode_previous() {
if (KettleMode - 1 >= 0) {
KettleMode = (kettle_mode)(KettleMode - 1);
} else {
KettleMode = OVERFLOW - 1;
}
}
/**
* Increase setpoint for line.
*/
void increase_setpoint() {
if (KettleMode == PWM && KettleDuty < 100) {
KettleDuty++;
}
/* Eventually
else if (KettleMode == PID && KettleTEMP < 220) {
KettleTEMP++;
}
*/
}
/**
* Decrease setpoint for line.
*/
void decrease_setpoint() {
if (KettleMode == PWM && KettleDuty > 0) {
KettleDuty--;
}
/* Eventually
else if (KettleMode == PID && KettleTEMP > 0) {
KettleTEMP--;
}
*/
}

View File

@ -1,10 +0,0 @@
/* ---------- Menu Function Prototypes ---------- */
char* KettleState();
char* KettleSetpoint();
char* KettleActual();
char* SetpointUnit();
void kettle_mode_up();
void kettle_mode_down();
void increase_setpoint();
void decrease_setpoint();

View File

@ -1,16 +1,14 @@
char * Concatenate(char *first, char *second) {
static char buf[30];
strcpy(buf,first);
strcat(buf,second);
return buf;
}
void ConnectMQTT() { void ConnectMQTT() {
while (!mqtt_client.connect("brewhouse", MQTT_USER, MQTT_PASSWORD)) { static char *password = MQTT_PASSWORD;
static char *user = MQTT_USER;
Serial.println("connecting MQTT...");
while (!mqtt_client.connect("brewhouse", user, password)) {
Serial.print(".");
delay(1000); delay(1000);
} }
mqtt_client.subscribe(Concatenate(TOPIC_PREFIX, BK_SETPOINT_TOPIC)); Serial.println("\nconnected!");
mqtt_client.subscribe("brewery/setpoint/bk");
} }
void MessageReceived(String &topic, String &payload) { void MessageReceived(String &topic, String &payload) {
@ -28,8 +26,10 @@ void MessageReceived(String &topic, String &payload) {
Serial.println(error.f_str()); Serial.println(error.f_str());
return; return;
} }
char buf[30];
if (topic == Concatenate(TOPIC_PREFIX, BK_SETPOINT_TOPIC)) { strcpy(buf,TOPIC_PREFIX);
strcat(buf,BOIL_SETPOINT_TOPIC);
if (topic == buf) {
// Update PWM setpoint. // Update PWM setpoint.
String name = doc["entity"]; String name = doc["entity"];
String setting = doc["setpoint"]; String setting = doc["setpoint"];
@ -41,7 +41,7 @@ void MessageReceived(String &topic, String &payload) {
} }
} }
void SetupMQTT(char *broker) { void SetupMQTT(const char *broker) {
// Note: Local domain names (e.g. "Computer.local" on OSX) are not supported // Note: Local domain names (e.g. "Computer.local" on OSX) are not supported
// by Arduino. You need to set the IP address directly. // by Arduino. You need to set the IP address directly.
Serial.println("Setup MQTT client."); Serial.println("Setup MQTT client.");
@ -64,6 +64,9 @@ static void SendSensorData() {
String jstr; String jstr;
serializeJson(doc, jstr); serializeJson(doc, jstr);
mqtt_client.publish(Concatenate(TOPIC_PREFIX, BK_ACTUAL_TOPIC), jstr); String topic = TOPIC_PREFIX;
topic += "sensor/boil_kettle";
mqtt_client.publish(topic, jstr);
} }

View File

@ -1,12 +1,11 @@
/** Bit bang low frequency PWM. // Bit bang low frequency PWM.
* //
* Parameters: // Parameters:
* outputPin (byte) - Pin number to output PWM. // outputPin (byte) - Pin number to output PWM.
* dutyCycle (byte) - PWM from 0 - 100. // dutyCycle (byte) - PWM period from 0 - 100.
* period (unsigned long) - Period in milliseconds.
*/
void slowPWM(byte outputPin, byte dutyCycle, unsigned long period) void slowPWM(byte outputPin, byte dutyCycle, unsigned long period)
{ {
pinMode(outputPin, OUTPUT);
static byte outputState = LOW; static byte outputState = LOW;
static unsigned long lastSwitchTime = 0; static unsigned long lastSwitchTime = 0;