Revert master back to old code that actually worked.
This commit is contained in:
parent
e85a8d1704
commit
da937ecde5
@ -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--;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -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();
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user