// Temperature Controller with multi-Pump Control
// Equipment
// Board - ESP32
// Temp sensor - Max31865 - SPI interface
// Screen - 2.42" oled screen 1309 - I2C interface
// Hardware Design is divided into three components
// 1 - Main box - This is on the top of the tank and houses the main board, RTD sensor, and relays
// 2 - User interface - This is a low voltage box that houses the buttons and screen. Cat6 cable is run between the main and U/I boxes for the necessary connections
// 3 - Pump(s) - These are located on the back of the tank
// Controllers - Divided into 5 classes
// Fermenter - Primary fermentation vessel - FV1 to FV10
// Brite - Brite tank - BT1 to BT10
// Pilot - Pilot tanks. Same as Fermenter but smaller - P1 to P10
// Misc Active monitoring - Controls items such as a Walk-in cooler, glycol chiller, tapline chiller...
// Passive monitoring - Only relays information back to the master. Same program as above, but no outputs
// Wireless Communication
// System will be setup so every tank has it's own controller. All controllers report back to a master board using ESP-NOW in encrypted mode.
// Encryption causes minor problems because the manufacturer does not recommend using more than 10 boards at a time with encryption. Possible way around this is to have the main board send out a 'ping' to all boards, then they respond in a timed sequence to prevent overlap.
// The information is then displayed on a web page that is only accessible on the local network.
//Notes
//This sketch is preliminary. The pins used were whatever was convienent at the time and can be moved as needed.
// To Do
// Add alarm - OLED display flashes inverted colour - display.invertDisplay(true) and false
// Add alarm codes - Overtemp - RTD fault - loss of communication
// Update code for MAX31865
// - Possibly change all readings to two decimal places
// -
// Update code for OLED display
// Update pinout for ESP32
// Add temp crash features - anti-overshoot
// Add heating / cooling option
// Add ESP-NOW coding
// Rebuild menu structure so it's all in one sub and uses an array
// Split Quick Settings into Ferment and Crash
// Wireless To Do
// Create message structure
// Create message send/receive protocol to allow more than 10 boards using encryption
// Enable encryption
// Verification during initialization that no other board on the network has the same tank name
//int8_t -128 to 127
//uint8_t 0 to 255
//int16_t -32768 to 32767
//uint16_t 0 to 65535
//int32_t -2147483648 to 2147483647
//uint32_t 0 to 4294967295
/* Pinout - ESP8266 - Monitor only
Label GPIO Use
D0 16 SPI - CS
D1 5 OLED - SCL
D2 4 OLED - SDA
D3 0 Button 1 Pullup
D4 2 Button 2 Pullup
D5 14 SPI - CLK
D6 12 SPI - SDO
D7 13 SPI - SDI
D8 15 Alarm - Pulled down?
RX 3
TX 1
A0 A0 Button 3 */
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Preferences.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Preferences flashMemory;
//Pins - Needs to be updated
const uint8_t upperPumpPin = 27; // Upper Pump
const uint8_t lowerPumpPin = 26; // Lower Pump
const uint8_t buttonUp = 25; // Temperature Up Button
const uint8_t buttonDown = 33; // Temperature Down Button
const uint8_t buttonMenu = 32; // Pump Select Button
const uint8_t alarmPin = 23; // Alarm pin
const uint8_t tempSensorPin = 35; // Temperature Sensor
int8_t tempOffset; //Temperature offset
int8_t runMode; //Which crash mode is active - 0 normal - 1 lager crash
uint8_t alarmCode; //Which alarm is activated
uint8_t pumpSelection; // Variable to Hold Pump Selection
uint8_t tankIdent; //Numerical tank value => used for wireless communications
uint8_t Menu; //Menu level
uint8_t Debounce = 30; //Debounce delay
int16_t tankTemp; // Tank temperature
int16_t setTemp; // Set Temperature
int16_t maxTemp; //Max allowable temp
int16_t minTemp; //Min allowable temp
int16_t intTemp; //Intermediate temp used during lager crash
uint64_t menuTimer; //Menu timer
uint64_t LTime; //Lager crash timer
bool exitMenu; //Whether or not to exit the menu
bool pumpActive; //If there is a call for cooling
bool tempAlarm; //If alarm is on or off
bool initial; //If this is the first time the program has been run => disables menu timer and activates initialization routine
String tankID; //String for the tank ID
char menuTitle [10] [20] = {"Main", "Quick Settings", "Pump Settings", "General Settings", "4", "5", "6", "7", "8", "9"};
static const unsigned char PROGMEM Logo[] = { //Black Gold Logo
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7f, 0xe1, 0xf8, 0x01, 0xf8, 0x0f, 0xf3, 0xf1, 0xe0, 0x07, 0xfc, 0x1f, 0xe3, 0xf8, 0x3f, 0xf0,
0x7f, 0xf3, 0xfc, 0x03, 0xfc, 0x1f, 0xf3, 0xf3, 0xe0, 0x0f, 0xfe, 0x3f, 0xf3, 0xf8, 0x3f, 0xf0,
0x7f, 0xf9, 0xf8, 0x01, 0xf8, 0x3f, 0xf9, 0xf1, 0xc0, 0x0f, 0xfe, 0x7f, 0xf9, 0xf0, 0x1f, 0xf8,
0x3c, 0xf8, 0xf0, 0x01, 0xf8, 0x3e, 0x79, 0xf1, 0xc0, 0x0f, 0x9e, 0x7c, 0xf9, 0xf0, 0x1f, 0x78,
0x3c, 0xf8, 0xf0, 0x01, 0xf8, 0x3e, 0x79, 0xf3, 0xc0, 0x0f, 0x9e, 0x7c, 0xf9, 0xf0, 0x1f, 0x7c,
0x3c, 0x78, 0xf0, 0x03, 0xf8, 0x3e, 0x79, 0xf3, 0x80, 0x0f, 0x8e, 0x7c, 0xf9, 0xf0, 0x1f, 0x3c,
0x3c, 0x78, 0xf0, 0x03, 0xf8, 0x3e, 0x79, 0xf3, 0x80, 0x0f, 0x8e, 0x7c, 0xf9, 0xf0, 0x1f, 0x3e,
0x3c, 0x78, 0xf0, 0x03, 0xf8, 0x3e, 0x79, 0xf7, 0x80, 0x0f, 0x8e, 0x7c, 0xf9, 0xf0, 0x1f, 0x3e,
0x3c, 0x78, 0xf0, 0x03, 0xf8, 0x3e, 0x39, 0xf7, 0x80, 0x0f, 0x80, 0x7c, 0xf9, 0xf0, 0x1f, 0x1e,
0x3c, 0xf8, 0xf0, 0x03, 0x7c, 0x3e, 0x39, 0xf7, 0x80, 0x0f, 0x80, 0x7c, 0xf9, 0xf0, 0x1f, 0x1e,
0x3d, 0xf8, 0xf0, 0x03, 0x7c, 0x3e, 0x01, 0xff, 0x00, 0x0f, 0x80, 0x7c, 0xf9, 0xf0, 0x1f, 0x1e,
0x3f, 0xf0, 0xf0, 0x03, 0x7c, 0x3e, 0x01, 0xff, 0x00, 0x0f, 0x80, 0x7c, 0xf9, 0xf0, 0x1f, 0x1e,
0x3f, 0xc0, 0xf0, 0x07, 0x7c, 0x3e, 0x01, 0xff, 0x00, 0x0f, 0x9e, 0x7c, 0xf9, 0xf0, 0x1f, 0x1e,
0x3f, 0xf0, 0xf0, 0x07, 0x7c, 0x3e, 0x01, 0xff, 0x00, 0x0f, 0xbf, 0x7c, 0xf9, 0xf0, 0x1f, 0x1e,
0x3c, 0xf8, 0xf0, 0x07, 0x3c, 0x3e, 0x01, 0xff, 0x80, 0x0f, 0xbf, 0x7c, 0xf9, 0xf0, 0x1f, 0x1e,
0x3c, 0xf8, 0xf0, 0x07, 0x3c, 0x3e, 0x01, 0xff, 0x80, 0x0f, 0x9e, 0x7c, 0xf9, 0xf0, 0x1f, 0x1e,
0x3c, 0xf8, 0xf0, 0x07, 0x3e, 0x3e, 0x01, 0xff, 0x80, 0x0f, 0x9e, 0x7c, 0xf9, 0xf0, 0x9f, 0x1e,
0x3c, 0x78, 0xf1, 0xc6, 0x3e, 0x3e, 0x01, 0xf7, 0xc0, 0x0f, 0x9e, 0x7c, 0xf9, 0xf3, 0x9f, 0x1e,
0x3c, 0x78, 0xf1, 0xce, 0x3e, 0x3e, 0x39, 0xf7, 0xc0, 0x0f, 0x9e, 0x7c, 0xf9, 0xf3, 0x9f, 0x1e,
0x3c, 0x78, 0xf1, 0xcf, 0xfe, 0x3e, 0x39, 0xf7, 0xc0, 0x0f, 0x9e, 0x7c, 0xf9, 0xf3, 0x9f, 0x3e,
0x3c, 0x78, 0xf1, 0xcf, 0xfe, 0x3e, 0x79, 0xf7, 0xc0, 0x0f, 0x9e, 0x7c, 0xf9, 0xf3, 0x9f, 0x3e,
0x3c, 0x78, 0xf1, 0xcf, 0xfe, 0x3e, 0x79, 0xf7, 0xc0, 0x0f, 0x9e, 0x7c, 0xf9, 0xf3, 0x9f, 0x3c,
0x3c, 0xf8, 0xf3, 0xce, 0x1f, 0x3e, 0x79, 0xf7, 0xc0, 0x0f, 0x9e, 0x7c, 0xf9, 0xf3, 0x9f, 0x7c,
0x3c, 0xf8, 0xf3, 0xce, 0x1f, 0x3e, 0x79, 0xf3, 0xe0, 0x0f, 0x9e, 0x7c, 0xf9, 0xf3, 0x9f, 0x7c,
0x3c, 0xf8, 0xf3, 0xde, 0x1f, 0x3e, 0x79, 0xf3, 0xe0, 0x0f, 0x9e, 0x7c, 0xf9, 0xf7, 0x9f, 0x78,
0x7f, 0xf9, 0xff, 0xde, 0x1f, 0x3f, 0xfb, 0xf3, 0xe0, 0x0f, 0xfe, 0x7f, 0xfb, 0xff, 0xbf, 0xf8,
0x7f, 0xf3, 0xff, 0xdf, 0x3f, 0x9f, 0xfb, 0xf3, 0xf0, 0x07, 0xfc, 0x3f, 0xf3, 0xff, 0xbf, 0xf0,
0x7f, 0xe1, 0xff, 0xdf, 0x3f, 0x8f, 0xf3, 0xf3, 0xf0, 0x03, 0xf8, 0x1f, 0xe3, 0xff, 0xbf, 0xf0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void setup() {
pinMode(buttonUp, INPUT_PULLUP);
pinMode(buttonDown, INPUT_PULLUP);
pinMode(buttonMenu, INPUT_PULLUP);
pinMode(tempSensorPin, INPUT);
pinMode(upperPumpPin, OUTPUT);
pinMode(lowerPumpPin, OUTPUT);
pinMode(alarmPin, OUTPUT);
Serial.begin(115200); // For diagnostics. remove in final version
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
//Get values from memory
flashMemory.begin("Settings", true); // Opens memory file in read only
initial = flashMemory.getBool("initial", true); //Default initialization protocol on
tempAlarm = flashMemory.getBool("tempAlarm", false); //Default alarm off
pumpSelection = flashMemory.getUChar("pumpSelection", 1); //Default pumps off
tankIdent = flashMemory.getUChar("tankIdent", 10); //Default FV1
setTemp = flashMemory.getShort("setTemp", 190); //Default 19C
minTemp = flashMemory.getShort("minTemp", 0); //Default 0C
maxTemp = flashMemory.getShort("maxTemp", 999); //Default 100C
tempOffset = flashMemory.getChar("tempOffset", 0); //Default 0C
runMode = flashMemory.getChar("runMode", 0); //Default normal crash
flashMemory.end();
display.clearDisplay();
display.drawBitmap(0, 13, Logo, 128, 40, 1); //Display Black Gold Logo
display.display();
delay(5000);
if(initial==true) {Initialization();} // Initialization menu for first load
TankName();
}
void Initialization() {
lcd.setCursor(0,1);
lcd.print("Initilazion Required");
delay(1000);
Menu = 61; //Tank ident
MenuDisplay();
MainMenu();
Menu = 52; //Max temp
MenuDisplay();
Menu = 53; //Min temp
MenuDisplay();
Menu = 54; //Normal crash temp
MenuDisplay();
Menu = 55; //Lager crash temp
MenuDisplay();
exitMenu = 0;
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putBool("initial", false);
flashMemory.end();
initial=false;
}
void TankName() {
int x = (tankIdent / 10U) % 10;
int y = ((tankIdent / 1U) % 10) + 1;
if(x==1) {tankID = "FV";}
if(x==2) {tankID = "BT";}
if(x==3) {tankID = "P";}
if(x==4) {tankID = "CT ";}
if(x==5) {tankID = "MI ";}
tankID += y;
}
void SensorReadings() {
tankTemp = thermo.temperature(RNOMINAL, RREF)*10;
Serial.print("Raw reading = "); Serial.print(thermo.temperature(RNOMINAL, RREF)); Serial.println("C");
Serial.print("tankTemp: "); Serial.print(tankTemp*0.1, 1); Serial.println("C");
tankTemp += tempOffset;
Serial.print("Offset: "); Serial.print(tempOffset*0.1, 1); Serial.println("C");
Serial.print("Corrected: "); Serial.print(tankTemp*0.1, 1); Serial.println("C");
uint8_t fault = thermo.readFault(); // Check and print any faults - Modify this to generate an alarm code
if (fault) {
if (fault & MAX31865_FAULT_HIGHTHRESH) {alarmCode = 1;} // RTD High Threshold
if (fault & MAX31865_FAULT_LOWTHRESH) {alarmCode = 2;} // RTD Low Threshold
if (fault & MAX31865_FAULT_REFINLOW) {alarmCode = 3;} // REFIN Low - Circuit shorted
if (fault & MAX31865_FAULT_REFINHIGH) {alarmCode = 4;} // REFIN High - Circuit open
if (fault & MAX31865_FAULT_RTDINLOW) {alarmCode = 5;} // RTDIN High - Circuit open
if (fault & MAX31865_FAULT_OVUV) {alarmCode = 6;} // Under / Over voltage
}
/* - Move all this to the Menu
uint16_t rtd1 = thermo.readRTD();
float ratio = rtd1;
ratio /= 32768;
Serial.print("RTD1 value: "); Serial.println(rtd1);
Serial.print("Ratio = "); Serial.println(ratio,8);
Serial.print("Resistance = "); Serial.println(RREF*ratio,8);
Serial.print("Temperature = "); Serial.print(thermo.temperature(RNOMINAL, RREF)); Serial.println("C");
Serial.println();
*/
}
void Debug() { //Input whatever code requires debugging here - remove in final version
}
void loop() {
SensorReadings();// Read Temperature Sensor
Debug(); //remove in final version
lcdUpdate();
if(alarmCode > 0) {Alarm();}
if(digitalRead(buttonUp)==LOW) { //Temp up button - add while loop with decreasing delay
delay(Debounce);
if(digitalRead(buttonUp)==LOW) {
setTemp++;
if(setTemp > maxTemp) {setTemp = maxTemp;}
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putShort("setTemp", setTemp);
flashMemory.end();
}
}
if(digitalRead(buttonDown)==LOW) { //Temp down button - add while loop with decreasing delay
delay(Debounce);
if(digitalRead(buttonDown)==LOW) {
setTemp--;
if(setTemp < minTemp) {setTemp = minTemp;}
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putShort("setTemp", setTemp);
flashMemory.end();
}
}
if(digitalRead(buttonMenu)==LOW) {
delay(Debounce);
uint64_t mTime = millis();
while(digitalRead(buttonMenu)==LOW) {;}
if(millis() > (mTime+500) && millis() < (mTime+1500)) {
if(pumpSelection==0) {pumpSelection = 1;}
else {pumpSelection = 0;}
}
if(millis() > (mTime+3000)) {
Menu = 1;
menuTimer = millis();
MenuDisplay();
MainMenu();}
}
if(runMode==1 && ((LTime + 4320000) < millis())) {//Lager delayed temp drop 4320000 (72 min)
LTime = millis();
intTemp -= 1;
if(intTemp <= setTemp || tankTemp <= setTemp) {runMode = 0;} //Changes back to normal run mode when target temp reached
}
if((runMode==0 && (tankTemp > setTemp)) || (runMode==1 && (tankTemp > intTemp))) { Pumps(); } //Turn pumps on
if ((runMode==0 && (tankTemp <= setTemp)) || (runMode==1 && (tankTemp <= intTemp))) { //Turn pumps off
digitalWrite(upperPumpPin, LOW);
digitalWrite(lowerPumpPin, LOW);
pumpActive = 0; //Used for lcdUpdate() but should be replaced with digital read
}
} //End of main loop
void Alarm() { //Add stuff here - Disable pumps for temp sensor error
// 0 = Normal
switch (alarmCode) {
case 1: // RTD High Threshold
break;
case 2: // RTD Low Threshold
break;
case 3: // REFIN Low - Short in common wires
break;
case 4: // REFIN High - Common wire circuit open
break;
case 5: // RTDIN High - Circuit open
break:
case 6: // Under / Over voltage
break;
// thermo.clearFault(); // Not sure where to put this
// 10 - 19 = Program and temp issue
// 20 - 29 = Wireless issue
}
}
void Pumps() {
switch (pumpSelection) {
case 0: //Both off
digitalWrite(upperPumpPin, HIGH);
digitalWrite(lowerPumpPin, HIGH);
break;
case 1: //Both on
digitalWrite(upperPumpPin, LOW);
digitalWrite(lowerPumpPin, LOW);
break;
case 2: //Upper on
digitalWrite(upperPumpPin, HIGH);
digitalWrite(lowerPumpPin, LOW);
break;
case 3: //Lower on
digitalWrite(upperPumpPin, LOW);
digitalWrite(lowerPumpPin, HIGH);
break;
}
pumpActive = 1; //Used for lcdUpdate()
}
void lcdUpdate() {
// Display Fermenter, Current temp, and Target temp
display.clearDisplay();
display.setCursor(0, 2);
display.setTextSize(3);
display.setTextColor(WHITE);
display.print(tankID);
display.setTextSize(2);
y = (tankTemp*0.1);
RightJustifyTemp(y, 0);
display.setTextSize(1);
y = (setTemp*0.1);
y = "Set: " + y;
RightJustifyTemp(y, 20);
display.setCursor(0,56);
display.print("Pumps:");
if(pumpSelection==0) {
if(pumpActive==1) {display.print("ON"); }
else {display.print("Stby");}
}
if(pumpSelection==1) {display.print("OFF"); }
if(pumpSelection==2) {
if(pumpActive==1) {display.print("ON-OFF"); }
else {display.print("Stby-OFF");}
}
if(pumpSelection==3) {
if(pumpActive==1) {display.print("OFF-ON"); }
else {display.print("OFF-Stby");}
}
if(runMode==1) {display.setCursor(92, 56); display.setTextColor(BLACK, WHITE); display.print("2C/day");}
display.display();
}
void RightJustifyTemp(String buf, int y) {
int16_t x1, y1;
uint16_t w, h;
buf.remove(buf.length()-1);
buf += "C";
display.getTextBounds(buf, 0, y, &x1, &y1, &w, &h); //calc width of new string
display.setCursor(128 - w, y);
display.print(buf);
}
void NewMenu() {
while((initial==false && ((millis() - menuTimer) < 10000)) || (initial==true)){ //Main menu loop
display.clearDisplay(); //Redraw the menu page
display.setCursor(10, 0);
display.setTextColor(WHITE);
display.setTextSize(2);
display.println(menuTitle[Menu]); //Create this array
display.setTextSize(1);
display.setCursor(0, 20);
if(Menu==0) {display.print(menuOption[10])}; //Loops back
else {display.print(menuOption[Menu]);}
display.setTextColor(BLACK, WHITE);
display.print(menuOption[Menu]);
display.setTextColor(WHITE, BLACK);
if(digitalRead(buttonUp)==LOW) { //Button up is pressed
delay(Debounce); //Debounce
if(digitalRead(buttonUp)==LOW) { //Read again
Menu--;
menuTimer = millis();
//MenuDisplay();
}
while(digitalRead(buttonUp)==LOW){;} //Waits until the button is released
}
if(digitalRead(buttonDown)==LOW) {//Button down is pressed
delay(Debounce); //Debounce
if(digitalRead(buttonDown)==LOW) {
Menu++;
menuTimer = millis();
//MenuDisplay();
}
while(digitalRead(buttonDown)==LOW){;} //Waits until the button is released
}
if(digitalRead(buttonMenu)==LOW) {
delay(Debounce);
if(digitalRead(buttonMenu)==LOW) {
menuTimer = millis();
}
void MainMenu(){ //Menu navigation
while((initial==false && ((millis() - menuTimer) < 10000) && exitMenu==0) || (initial==true && exitMenu==0)){
if(digitalRead(buttonUp)==LOW) {//Button up is pressed
delay(Debounce);
if(digitalRead(buttonUp)==LOW) {
Menu--;
menuTimer=millis();
MenuDisplay();
}
while(digitalRead(buttonUp)==LOW){;}
}
if(digitalRead(buttonDown)==LOW) {//Button down is pressed
delay(Debounce);
if(digitalRead(buttonDown)==LOW) {
Menu++;
menuTimer=millis();
MenuDisplay();
}
while(digitalRead(buttonDown)==LOW){;}
}
if(digitalRead(buttonMenu)==LOW) {
delay(Debounce);
if(digitalRead(buttonMenu)==LOW) {
menuTimer=millis();
if(Menu==1) {Menu=11;} //Main Menu
else if(Menu==2) {Menu=21;} //Main Menu
else if(Menu==3) {Menu=31;} //Main Menu
else if(Menu==11){ //Fast crash
runMode = 0; //Fast crash mode
pumpSelection = 0; //All pumps on
flashMemory.begin("Settings", false); // Opens memory file in write mode
setTemp = flashMemory.getChar("CrashTemp", 10); //SetTemp to crash temp
flashMemory.putShort("setTemp", setTemp); //Save new SetTemp
flashMemory.putChar("runMode", runMode); //Save run Mode to normal crash
flashMemory.putUChar("pumpSelection", pumpSelection); //Save pump seletion
flashMemory.end();
while(digitalRead(buttonMenu)==LOW) {;}
lcd.clear();
return;
}
else if(Menu==12){ //Ferment 19C
runMode = 0;
setTemp = 190;
pumpSelection = 0;
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putShort("setTemp", setTemp); //Save new SetTemp
flashMemory.putChar("runMode", runMode); //Save run Mode to normal crash
flashMemory.putUChar("pumpSelection", pumpSelection); //Save pump seletion
flashMemory.end();
while(digitalRead(buttonMenu)==LOW) {;}
lcd.clear();
return;
}
else if(Menu==13){ //Ferment 25C
runMode = 0;
setTemp = 250;
pumpSelection = 0;
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putShort("setTemp", setTemp); //Save new SetTemp
flashMemory.putChar("runMode", runMode); //Save run Mode to normal crash
flashMemory.putUChar("pumpSelection", pumpSelection); //Save pump seletion
flashMemory.end();
while(digitalRead(buttonMenu)==LOW) {;}
lcd.clear();
return;
}
else if(Menu==14){ //Ferment 13C
runMode = 0;
setTemp = 130;
pumpSelection = 0;
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putShort("setTemp", setTemp); //Save new SetTemp
flashMemory.putChar("runMode", runMode); //Save run Mode to normal crash
flashMemory.putUChar("pumpSelection", pumpSelection); //Save pump seletion
flashMemory.end();
while(digitalRead(buttonMenu)==LOW) {;}
lcd.clear();
return;
}
else if(Menu==15){//Crash 2C per day - 72min per 0.1*
runMode = 1; //Changes to lager crash mode
intTemp = tankTemp - 1; //sets new intermediate target temp
pumpSelection = 0;
LTime =millis(); //Starts delay counter
flashMemory.begin("Settings", false); // Opens memory file in write mode
setTemp = flashMemory.getChar("lagerTemp", 40); //Loads new set temp
flashMemory.putShort("setTemp", setTemp); //Saves new set temp
flashMemory.putChar("runMode", runMode); //Saves new run mode
flashMemory.putUChar("pumpSelection", pumpSelection); //Save pump seletion
flashMemory.end();
while(digitalRead(buttonMenu)==LOW) {;}
lcd.clear();
return;}
else if(Menu==21){ //Pump - both on
pumpSelection=0;
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putUChar("pumpSelection", pumpSelection);
flashMemory.end();
lcd.clear();
while(digitalRead(buttonMenu)==LOW) {;}
return;}
else if(Menu==22){ //Pump - both off
pumpSelection=1;
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putUChar("pumpSelection", pumpSelection);
flashMemory.end();
lcd.clear();
while(digitalRead(buttonMenu)==LOW) {;}
return;}
else if(Menu==23){ //Pump - upper on
pumpSelection=2;
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putUChar("pumpSelection", pumpSelection);
flashMemory.end();
lcd.clear();
while(digitalRead(buttonMenu)==LOW) {;}
return;}
else if(Menu==24){ //Pump - lower on
pumpSelection=3;
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putUChar("pumpSelection", pumpSelection);
flashMemory.end();
lcd.clear();
while(digitalRead(buttonMenu)==LOW) {;}
return;}
else if(Menu==31){Menu=51;} //Review
else if(Menu==32){;} //Alarm menu - needs coding
else if(Menu==33){Menu=52;} //Max temp
else if(Menu==34){Menu=53;} //Min temp
else if(Menu==35){Menu=54;} //Crash temp
else if(Menu==36){Menu=55;} //Lager crash
else if(Menu==37){Menu=56;} //Temp offset
else if(Menu==38){Menu=61;} //Tank assignment
else if(Menu==39){Menu=71;} //Factory reset
else if(Menu==61){Menu=68; tankIdent = 10;}
else if(Menu==62){Menu=68; tankIdent = 20;}
else if(Menu==63){Menu=68; tankIdent = 30;}
else if(Menu==64){Menu=68; tankIdent = 40;}
else if(Menu==65){Menu=68; tankIdent = 50;}
else if(Menu==71){return;} //Exit factory reset
else if(Menu==72){ //Factory reset
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.clear(); //Erases all contents within the file
flashMemory.end();
lcd.clear();
lcd.print(" Factory Reset");
lcd.setCursor(0,2);
lcd.print(" Resetting");
delay(1000);
lcd.setCursor(11,2);
lcd.print(".");
delay(1000);
lcd.setCursor(12,2);
lcd.print(".");
delay(1000);
lcd.setCursor(13,2);
lcd.print(".");
delay(1000);
lcd.setCursor(14,2);
lcd.print(".");
delay(1000);
ESP.restart();}
else { //Error catching during testing
lcd.clear();
lcd.setCursor(0,1);
lcd.print(" Unexpected error");
delay(5000);
while(digitalRead(buttonMenu)==LOW) {;}
return;
}
while(digitalRead(buttonMenu)==LOW) {;}
lcd.clear();
MenuDisplay();
}
}
}
exitMenu = 0;
lcd.clear();
}
void MenuDisplay(){ //Menu structure
int8_t crashTemp;
int8_t lagerTemp;
uint8_t tNumber = 1;
switch(Menu){
case 0:
Menu = 1;
break;
case 1:
lcd.clear();
lcd.print(" Main Menu");
lcd.setCursor(0,1);
lcd.print(">Quick Settings");
lcd.setCursor(0,2);
lcd.print(" Pump Settings");
lcd.setCursor(0,3);
lcd.print(" General Settings");
break;
case 2:
lcd.clear();
lcd.print(" Main Menu");
lcd.setCursor(0,1);
lcd.print(" Quick Settings");
lcd.setCursor(0,2);
lcd.print(">Pump Settings");
lcd.setCursor(0,3);
lcd.print(" General Settings");
break;
case 3:
lcd.clear();
lcd.print(" Main Menu");
lcd.setCursor(0,1);
lcd.print(" Quick Settings");
lcd.setCursor(0,2);
lcd.print(" Pump Settings");
lcd.setCursor(0,3);
lcd.print(">General Settings");
break;
case 4:
Menu = 3;
break;
case 10:
Menu = 11;
break;
case 11:
lcd.clear();
lcd.print(" Quick Change Menu");
lcd.setCursor(0,1);
lcd.print(">Fast Crash");
lcd.setCursor(0,2);
lcd.print(" Ferment 19C");
lcd.setCursor(0,3);
lcd.print(" Ferment 25C");
break;
case 12:
lcd.clear();
lcd.print(" Quick Change Menu");
lcd.setCursor(0,1);
lcd.print(" Fast Crash");
lcd.setCursor(0,2);
lcd.print(">Ferment 19C");
lcd.setCursor(0,3);
lcd.print(" Ferment 25C");
break;
case 13:
lcd.clear();
lcd.print(" Quick Change Menu");
lcd.setCursor(0,1);
lcd.print(" Ferment 19C");
lcd.setCursor(0,2);
lcd.print(">Ferment 25C");
lcd.setCursor(0,3);
lcd.print(" Ferment 13C");
break;
case 14:
lcd.clear();
lcd.print(" Quick Change Menu");
lcd.setCursor(0,1);
lcd.print(" Ferment 25C");
lcd.setCursor(0,2);
lcd.print(">Ferment 13C");
lcd.setCursor(0,3);
lcd.print(" 2C/day crash");
break;
case 15:
lcd.clear();
lcd.print(" Quick Change Menu");
lcd.setCursor(0,1);
lcd.print(" Ferment 25C");
lcd.setCursor(0,2);
lcd.print(" Ferment 13C");
lcd.setCursor(0,3);
lcd.print(">2C/day crash");
break;
case 16:
Menu = 15;
break;
case 20:
Menu = 21;
break;
case 21:
lcd.clear();
lcd.print(" Pump Menu");
lcd.setCursor(0,1);
lcd.print(">Both ON");
lcd.setCursor(0,2);
lcd.print(" Both OFF");
lcd.setCursor(0,3);
lcd.print(" Upper ON, Lower OFF");
break;
case 22:
lcd.clear();
lcd.print(" Pump Menu");
lcd.setCursor(0,1);
lcd.print(" Both ON");
lcd.setCursor(0,2);
lcd.print(">Both OFF");
lcd.setCursor(0,3);
lcd.print(" Upper ON, Lower OFF");
break;
case 23:
lcd.clear();
lcd.print(" Pump Menu");
lcd.setCursor(0,1);
lcd.print(" Both OFF");
lcd.setCursor(0,2);
lcd.print(">Upper ON, Lower OFF");
lcd.setCursor(0,3);
lcd.print(" Upper OFF, Lower ON");
break;
case 24:
lcd.clear();
lcd.print(" Pump Menu");
lcd.setCursor(0,1);
lcd.print(" Both OFF");
lcd.setCursor(0,2);
lcd.print(" Upper ON, Lower OFF");
lcd.setCursor(0,3);
lcd.print(">Upper OFF, Lower ON");
break;
case 25:
Menu = 24;
break;
case 30:
Menu = 31;
break;
case 31:
lcd.clear();
lcd.print(" Settings Menu");
lcd.setCursor(0,1);
lcd.print(">Review saved values");
lcd.setCursor(0,2);
lcd.print(" Alarm");
lcd.setCursor(0,3);
lcd.print(" Max temp");
break;
case 32:
lcd.clear();
lcd.print(" Settings Menu");
lcd.setCursor(0,1);
lcd.print(" Review saved values");
lcd.setCursor(0,2);
lcd.print(">Alarm");
lcd.setCursor(0,3);
lcd.print(" Max temp");
break;
case 33:
lcd.clear();
lcd.print(" Settings Menu");
lcd.setCursor(0,1);
lcd.print(" Alarm");
lcd.setCursor(0,2);
lcd.print(">Max Temp");
lcd.setCursor(0,3);
lcd.print(" Min temp");
break;
case 34:
lcd.clear();
lcd.print(" Settings Menu");
lcd.setCursor(0,1);
lcd.print(" Max temp");
lcd.setCursor(0,2);
lcd.print(">Min temp");
lcd.setCursor(0,3);
lcd.print(" Fast crash temp");
break;
case 35:
lcd.clear();
lcd.print(" Settings Menu");
lcd.setCursor(0,1);
lcd.print(" Min temp");
lcd.setCursor(0,2);
lcd.print(">Fast crash temp");
lcd.setCursor(0,3);
lcd.print(" Lager crash temp");
break;
case 36:
lcd.clear();
lcd.print(" Settings Menu");
lcd.setCursor(0,1);
lcd.print(" Fast crash temp");
lcd.setCursor(0,2);
lcd.print(">Lager crash temp");
lcd.setCursor(0,3);
lcd.print(" Temp offset");
break;
case 37:
lcd.clear();
lcd.print(" Settings Menu");
lcd.setCursor(0,1);
lcd.print(" Lager crash temp");
lcd.setCursor(0,2);
lcd.print(">Temp offset");
lcd.setCursor(0,3);
lcd.print(" Tank assignment");
break;
case 38:
lcd.clear();
lcd.print(" Settings Menu");
lcd.setCursor(0,1);
lcd.print(" Temp offset");
lcd.setCursor(0,2);
lcd.print(">Tank assignment");
lcd.setCursor(0,3);
lcd.print(" Factory Reset");
break;
case 39:
lcd.clear();
lcd.print(" Settings Menu");
lcd.setCursor(0,1);
lcd.print(" Temp offset");
lcd.setCursor(0,2);
lcd.print(" Tank assignment");
lcd.setCursor(0,3);
lcd.print(">Factory Reset");
break;
case 40:
Menu = 39;
break;
case 50:
Menu = 51;
break;
case 51:
lcd.clear();
lcd.print(" Saved Values");
lcd.setCursor(0,1);
lcd.print("Alarm: ");
if(tempAlarm==false) {lcd.print("OFF");}
if(tempAlarm==true) {lcd.print("ON");}
lcd.setCursor(0,2);
lcd.print("Max Temp: "); lcd.print(maxTemp*0.1, 1); lcd.print("C");
lcd.setCursor(0,3);
lcd.print("Min Temp: "); lcd.print(minTemp*0.1, 1); lcd.print("C");
while(digitalRead(buttonMenu)==LOW) {;}
delay(Debounce);
while(digitalRead(buttonMenu)==HIGH && digitalRead(buttonDown)==HIGH && digitalRead(buttonUp)==HIGH) {;}
flashMemory.begin("Settings", true); // Opens memory file in read mode
crashTemp = flashMemory.getChar("crashTemp", 10);
lagerTemp = flashMemory.getChar("lagerTemp", 40);
flashMemory.end();
lcd.clear();
lcd.print(" Saved Values");
lcd.setCursor(0,1);
lcd.print("Fast Crash: "); lcd.print(crashTemp*0.1, 1); lcd.print("C");
lcd.setCursor(0,2);
lcd.print("Lager Crash: "); lcd.print(lagerTemp*0.1, 1); lcd.print("C");
lcd.setCursor(0,3);
lcd.print("Temp Offset: "); lcd.print(tempOffset*0.1,1); lcd.print("C");
while(digitalRead(buttonMenu)==LOW || digitalRead(buttonDown)==LOW || digitalRead(buttonUp)==LOW) {;}
delay(Debounce);
while(digitalRead(buttonMenu)==HIGH && digitalRead(buttonDown)==HIGH && digitalRead(buttonUp)==HIGH) {;}
lcd.clear();
lcd.print(" Saved Values");
lcd.setCursor(0,2);
lcd.print("Tank: "); lcd.print(tankID);
while(digitalRead(buttonMenu)==LOW || digitalRead(buttonDown)==LOW || digitalRead(buttonUp)==LOW) {;}
delay(Debounce);
while(digitalRead(buttonMenu)==HIGH && digitalRead(buttonDown)==HIGH && digitalRead(buttonUp)==HIGH) {;}
Menu = 31;
MenuDisplay();
menuTimer = millis();
break;
case 52:
lcd.clear();
lcd.print(" Max Temp Setting");
lcd.setCursor(0,2);
lcd.print("Current Value: ");
lcd.print(maxTemp*0.1, 1);
lcd.print(" ");
lcd.setCursor(0,3);
lcd.print("New Value: ");
lcd.print(maxTemp*0.1, 1);
lcd.print(" ");
while(digitalRead(buttonMenu)==HIGH && (initial==true || (initial==false && ((millis() - menuTimer) < 10000)))){
if(digitalRead(buttonUp)==LOW) {
delay(Debounce);
if(digitalRead(buttonUp)==LOW) {
maxTemp++;
menuTimer=millis();
if(maxTemp > 999) {maxTemp = 999;}
}
}
if(digitalRead(buttonDown)==LOW) {
delay(Debounce);
if(digitalRead(buttonDown)==LOW) {
maxTemp--;
menuTimer=millis();
if(maxTemp == minTemp) {maxTemp = minTemp + 1;}
}
}
lcd.setCursor(11,3);
lcd.print(maxTemp*0.1, 1);
lcd.print(" ");
}
if(digitalRead(buttonMenu)==LOW) {
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putShort("maxTemp", maxTemp);
flashMemory.end();
lcd.clear();
lcd.print(" Max Temp Setting");
lcd.setCursor(0,2);
lcd.print(" Setting saved");
delay(5000);
}
exitMenu = 1;
break;
case 53:
lcd.clear();
lcd.print(" Min Temp Setting");
lcd.setCursor(0,2);
lcd.print("Current Value: ");
lcd.print(minTemp*0.1, 1);
lcd.setCursor(0,3);
lcd.print("New Value: ");
lcd.print(minTemp*0.1, 1);
while(digitalRead(buttonMenu)==HIGH && (initial==true || (initial==false && ((millis() - menuTimer) < 10000)))){
if(digitalRead(buttonUp)==LOW) {
delay(Debounce);
if(digitalRead(buttonUp)==LOW) {
minTemp++;
menuTimer=millis();
if(minTemp > 100) {minTemp = 100;}
if(minTemp == maxTemp) {minTemp = maxTemp - 1;}
while(digitalRead(buttonUp)==LOW) {;}
}
}
if(digitalRead(buttonDown)==LOW) {
delay(Debounce);
if(digitalRead(buttonDown)==LOW) {
minTemp--;
menuTimer=millis();
if(minTemp < -100) {minTemp = -100;}
while(digitalRead(buttonDown)==LOW) {;}
}
}
lcd.setCursor(11,3);
lcd.print(minTemp*0.1, 1);
lcd.print(" ");
}
if(digitalRead(buttonMenu)==LOW) {
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putShort("minTemp", minTemp);
flashMemory.end();
lcd.clear();
lcd.print(" Min Temp Setting");
lcd.setCursor(0,2);
lcd.print(" Setting saved");
delay(5000);
}
exitMenu = 1;
break;
case 54:
flashMemory.begin("Settings", true); // Opens memory file in read mode
crashTemp = flashMemory.getShort("crashTemp", 10);
flashMemory.end();
lcd.clear();
lcd.print(" Crash Temp Setting");
lcd.setCursor(0,2);
lcd.print("Current Value: ");
lcd.print(crashTemp*0.1, 1);
lcd.setCursor(0,3);
lcd.print("New Value: ");
lcd.print(crashTemp*0.1, 1);
while(digitalRead(buttonMenu)==HIGH && (initial==true || (initial==false && ((millis() - menuTimer) < 10000)))){
if(digitalRead(buttonUp)==LOW) {
delay(Debounce);
if(digitalRead(buttonUp)==LOW) {
crashTemp++;
menuTimer=millis();
if(crashTemp > maxTemp) {crashTemp = maxTemp;}
}
while(digitalRead(buttonUp)==LOW) {;}
}
if(digitalRead(buttonDown)==LOW) {
delay(Debounce);
if(digitalRead(buttonDown)==LOW) {
crashTemp--;
menuTimer=millis();
if(crashTemp < -100) {crashTemp = -100;}
if(crashTemp < minTemp) {crashTemp = minTemp;}
}
while(digitalRead(buttonDown)==LOW) {;}
}
lcd.setCursor(11,3);
lcd.print(crashTemp*0.1, 1);
lcd.print(" ");
}
if(digitalRead(buttonMenu)==LOW) {
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putChar("crashTemp", crashTemp);
flashMemory.end();
lcd.clear();
lcd.print(" Crash Temp Setting");
lcd.setCursor(0,2);
lcd.print(" Setting saved");
delay(5000);
}
exitMenu = 1;
break;
case 55: //Lager temp setting
flashMemory.begin("Settings", true); // Opens memory file in read mode
lagerTemp = flashMemory.getChar("lagerTemp", 40);
flashMemory.end();
lcd.clear();
lcd.print(" Lager Temp Setting");
lcd.setCursor(0,2);
lcd.print("Current Value: ");
lcd.print(lagerTemp*0.1, 1);
lcd.setCursor(0,3);
lcd.print("New Value: ");
lcd.print(lagerTemp*0.1, 1);
while(digitalRead(buttonMenu)==HIGH && (initial==true || (initial==false && ((millis() - menuTimer) < 10000)))){
if(digitalRead(buttonUp)==LOW) {
delay(Debounce);
if(digitalRead(buttonUp)==LOW) {
lagerTemp++;
menuTimer=millis();
if(lagerTemp > 100) {lagerTemp = 100;}
while(digitalRead(buttonUp)==LOW) {;}
}
}
if(digitalRead(buttonDown)==LOW) {
delay(Debounce);
if(digitalRead(buttonDown)==LOW) {
lagerTemp--;
menuTimer=millis();
if(lagerTemp < -100) {lagerTemp = -100;}
if(lagerTemp < minTemp) {lagerTemp = minTemp;}
while(digitalRead(buttonDown)==LOW) {;}
}
}
lcd.setCursor(11,3);
lcd.print(lagerTemp*0.1, 1);
lcd.print(" ");
}
if(digitalRead(buttonMenu)==LOW) {
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putChar("lagerTemp", lagerTemp);
flashMemory.end();
lcd.clear();
lcd.print(" Lager Temp Setting");
lcd.setCursor(0,2);
lcd.print(" Setting saved");
delay(5000);
}
exitMenu = 1;
break;
case 56:
lcd.clear();
lcd.print("Temp Offset Setting");
lcd.setCursor(0,2);
lcd.print("Current Value: ");
lcd.print(tempOffset*0.1, 1);
lcd.setCursor(0,3);
lcd.print("New Value: ");
lcd.print(tempOffset*0.1, 1);
while(digitalRead(buttonMenu)==HIGH && (initial==true || (initial==false && ((millis() - menuTimer) < 10000)))){
if(digitalRead(buttonUp)==LOW) {
delay(Debounce);
if(digitalRead(buttonUp)==LOW) {
tempOffset++;
menuTimer = millis();
if(tempOffset > 100) {tempOffset = 100;}
}
while(digitalRead(buttonUp)==LOW) {;}
}
if(digitalRead(buttonDown)==LOW) {
delay(Debounce);
if(digitalRead(buttonDown)==LOW) {
tempOffset--;
menuTimer = millis();
if(tempOffset < -100) {tempOffset = -100;}
}
while(digitalRead(buttonDown)==LOW) {;}
}
lcd.setCursor(11,3);
lcd.print(tempOffset*0.1, 1);
lcd.print(" ");
}
if(digitalRead(buttonMenu)==LOW) {
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putChar("tempOffset", tempOffset);
flashMemory.end();
lcd.clear();
lcd.print("Temp Offset Setting");
lcd.setCursor(0,2);
lcd.print(" Setting saved");
delay(5000);
}
exitMenu = 1;
break;
case 57:
Menu = 56;
break;
case 60:
Menu = 61;
break;
case 61:
lcd.clear();
lcd.print("Tank Identification");
lcd.setCursor(0,1);
lcd.print(">Fermenter");
lcd.setCursor(0,2);
lcd.print(" Brite Tank");
lcd.setCursor(0,3);
lcd.print(" Pilot");
break;
case 62:
lcd.clear();
lcd.print("Tank Identification");
lcd.setCursor(0,1);
lcd.print(" Fermenter");
lcd.setCursor(0,2);
lcd.print(">Brite Tank");
lcd.setCursor(0,3);
lcd.print(" Pilot");
break;
case 63:
lcd.clear();
lcd.print("Tank Identification");
lcd.setCursor(0,1);
lcd.print(" Brite Tank");
lcd.setCursor(0,2);
lcd.print(">Pilot");
lcd.setCursor(0,3);
lcd.print(" Cooler / Chiller");
break;
case 64:
lcd.clear();
lcd.print("Tank Identification");
lcd.setCursor(0,1);
lcd.print(" Pilot");
lcd.setCursor(0,2);
lcd.print(">Cooler / Chiller");
lcd.setCursor(0,3);
lcd.print(" Monitor");
break;
case 65:
lcd.clear();
lcd.print("Tank Identification");
lcd.setCursor(0,1);
lcd.print(" Pilot");
lcd.setCursor(0,2);
lcd.print(" Cooler / Chiller");
lcd.setCursor(0,3);
lcd.print(">Monitor");
break;
case 66:
Menu = 65;
break;
case 67:
Menu = 68;
break;
case 68:
lcd.clear();
lcd.print("Tank Identification");
lcd.setCursor(0,2);
if(tankIdent == 10) {lcd.print("Type: Fermenter");}
if(tankIdent == 20) {lcd.print("Type: Brite");}
if(tankIdent == 30) {lcd.print("Type: Pilot");}
if(tankIdent == 40) {lcd.print("Type: Chiller");}
if(tankIdent == 50) {lcd.print("Type: Monitor");}
lcd.setCursor(0,3);
lcd.print("Select Tank #: ");
while(digitalRead(buttonMenu)==HIGH && (initial==true || (initial==false && ((millis() - menuTimer) < 10000)))){
if(digitalRead(buttonUp)==LOW) {
delay(Debounce);
if(digitalRead(buttonUp)==LOW) {
tNumber ++;
menuTimer=millis();
if(tNumber > 9) {tNumber = 9;}
while(digitalRead(buttonUp)==LOW) {;}
}
}
if(digitalRead(buttonDown)==LOW) {
delay(Debounce);
if(digitalRead(buttonDown)==LOW) {
tNumber--;
menuTimer=millis();
if(tNumber < 1) {tNumber = 1;}
while(digitalRead(buttonDown)==LOW) {;}
}
}
lcd.setCursor(15,3);
lcd.print(tNumber);
lcd.print(" ");
}
if(digitalRead(buttonMenu)==LOW) {
tankIdent += tNumber -1;
flashMemory.begin("Settings", false); // Opens memory file in write mode
flashMemory.putUChar("tankIdent", tankIdent);
flashMemory.end();
lcd.clear();
lcd.print("Tank Identification");
lcd.setCursor(0,2);
lcd.print(" Setting saved");
delay(5000);
}
else {
flashMemory.begin("Settings", true); // Opens memory file in read mode
tankIdent = flashMemory.getUChar("tankIdent", 10);
flashMemory.end();
}
exitMenu = 1;
TankName();
break;
case 69:
Menu = 68;
break;
case 70:
Menu = 71;
break;
case 71: //Factory reset
lcd.clear();
lcd.print(" Factory Reset");
lcd.setCursor(0,2);
lcd.print(" Are you sure??");
lcd.setCursor(0,3);
lcd.print(" >NO YES");
break;
case 72: //Factory reset
lcd.clear();
lcd.print(" Factory Reset");
lcd.setCursor(0,2);
lcd.print(" Are you sure??");
lcd.setCursor(0,3);
lcd.print(" NO >YES");
break;
case 73:
Menu = 72;
break;
}
}