#include "HX711_ADC.h"
#include <LiquidCrystal_I2C.h>
#include <AccelStepper.h>
const int loadConstant = 420; //calibrate when build
const int openPosition = 200;
const int closedPosition = 0;
/* IRL
const int subtractButton = 10;
const int addButton = 13;
const int freeButton = 11;
const int pourButton = 2;
const int dir = 5;
const int step = 6;
*/
const int subtractButton = 12;
const int addButton = 13;
const int freeButton = 11;
const int pourButton = 2;
const int dir = 5;
const int step = 6;
float setWeight = 5;
float oldLoad;
int oldAdd = HIGH;
int oldSubtract = HIGH;
bool startScreen = false;
bool confirmScreen = false;
bool pouring = false;
bool taring = false;
bool noLeakOrLift = true;
bool freePouring = false;
bool valveShouldOpen = false;
#define I2C_ADDR 0x27
#define LCD_COLUMNS 16
#define LCD_LINES 2
#define motorInterfaceType 1
AccelStepper myStepper(motorInterfaceType, step, dir);
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
HX711_ADC LoadCell(A1, A0);
void setup() {
Serial.begin(115200);
pinMode(subtractButton, INPUT);
pinMode(addButton, INPUT);
pinMode(freeButton, INPUT);
pinMode(pourButton, INPUT);
pinMode(step, OUTPUT);
pinMode(dir, OUTPUT);
myStepper.setMaxSpeed(1000);
myStepper.setAcceleration(300);
myStepper.setSpeed(1000);
myStepper.moveTo(closedPosition);
lcd.init();
lcd.backlight();
LoadCell.begin();
LoadCell.start(1000);
LoadCell.setCalFactor(1);
lcd.setCursor(0, 0);
}
void reset(){
valveShouldOpen = false;
valve(valveShouldOpen);
lcd.setCursor(0, 0);
lcd.print(" Resetting ");
lcd.setCursor(0, 1);
lcd.print(" System ");
setWeight = 5;
oldAdd = HIGH;
oldSubtract = HIGH;
confirmScreen = false;
pouring = false;
taring = false;
noLeakOrLift = true;
freePouring = false;
startScreen = false;
delay(750);
}
void askConfirmation(){
startScreen = false;
confirmScreen = true;
lcd.setCursor(0, 0);
lcd.print(" Press Again To ");
lcd.setCursor(0, 1);
lcd.print(" Confirm: L ");
lcd.setCursor(10, 1);
lcd.print(setWeight, 1);
delay(500);
}
void pour(float set){
startScreen = false;
noLeakOrLift = true;
tare();
Serial.println(set);
valveShouldOpen = true;
valve(valveShouldOpen);
float load = LoadCell.getData() / loadConstant;
while(load <= set && noLeakOrLift){
oldLoad = load;
LoadCell.update();
load = LoadCell.getData() / loadConstant;
Serial.println(load);
if((oldLoad > load) || !digitalRead(subtractButton) || !digitalRead(addButton) || !digitalRead(freeButton) || !digitalRead(pourButton)){
noLeakOrLift = false;
}
pouring = true;
if (pouring) {
lcd.setCursor(0, 0);
lcd.print(" Pouring:");
lcd.setCursor(9, 0);
lcd.print(load);
lcd.print("L ");
lcd.setCursor(0, 1);
lcd.print(" Do Not Touch ");
}
}
reset();
}
void tare(){
startScreen = false;
taring = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Taring ");
lcd.setCursor(0, 1);
lcd.print(" Do Not Touch! ");
LoadCell.start(1000);
delay(500);
lcd.clear();
}
void freePour() {
startScreen = false;
bool showFreePour = true;
delay(750);
valveShouldOpen = true;
valve(valveShouldOpen);
while (true) {
lcd.clear();
if (showFreePour) {
lcd.setCursor(0, 0);
lcd.print(" Free ");
lcd.setCursor(0, 1);
lcd.print(" Pour ");
} else {
lcd.setCursor(0, 0);
lcd.print(" Press Any ");
lcd.setCursor(0, 1);
lcd.print(" Button To Stop ");
}
showFreePour = !showFreePour;
if (!digitalRead(subtractButton) || !digitalRead(addButton) || !digitalRead(pourButton) || !digitalRead(freeButton)) {
reset();
break;
}
startScreen = false;
delay(750);
}
}
void loop() {
LoadCell.update();
int add = digitalRead(addButton);
int subtract = digitalRead(subtractButton);
if (add == LOW && oldAdd == HIGH && startScreen) {
if (setWeight <= 14.5) {
setWeight += 0.5;
}
unsigned long addStart = millis();
while (digitalRead(addButton) == LOW) {
lcd.setCursor(11, 0);
lcd.print(setWeight, 1);
if (millis() - addStart >= 500) {
while (digitalRead(addButton) == LOW) {
if (setWeight <= 14.5) {
setWeight += 0.5;
lcd.setCursor(11, 0);
lcd.print(setWeight, 1);
lcd.print("L ");
delay(100);
} else {
break;
}
}
break;
}
}
}
if (subtract == LOW && oldSubtract == HIGH && startScreen) {
if (setWeight >= 1) {
setWeight -= 0.5;
}
unsigned long subtractStart = millis();
while (digitalRead(subtractButton) == LOW) {
lcd.setCursor(11, 0);
lcd.print(setWeight, 1);
if (millis() - subtractStart >= 500) {
while (digitalRead(subtractButton) == LOW) {
if (setWeight >= 1) {
setWeight -= 0.5;
lcd.setCursor(11, 0);
lcd.print(setWeight, 1);
lcd.print("L ");
delay(100);
} else {
break;
}
}
break;
}
}
}
oldSubtract = subtract;
oldAdd = add;
if (!confirmScreen && !pouring && !taring && !freePouring) {
startScreen = true;
lcd.setCursor(0, 0);
lcd.print("Salt Water:");
lcd.setCursor(0, 1);
lcd.print(" Press To Pour ");
lcd.setCursor(11, 0);
lcd.print(setWeight, 1);
lcd.print("L ");
}
if (!digitalRead(pourButton) && !taring && !freePouring) {
askConfirmation();
while(digitalRead(addButton) && digitalRead(subtractButton) && digitalRead(freeButton)){
if(!digitalRead(pourButton)){
pour(setWeight);
break;
}
else if(!digitalRead(addButton) || !digitalRead(subtractButton) || !digitalRead(freeButton)){
reset();
break;
}
}
}
if (!pouring && !digitalRead(freeButton)){
freePour();
}
}
void valve(bool open){
if(open){
myStepper.moveTo(openPosition);
while(myStepper.distanceToGo() != 0){
myStepper.run();
}
}else{
myStepper.moveTo(closedPosition);
while(myStepper.distanceToGo() != 0){
myStepper.run();
}
}
}