//DISPLAY
//#include <iostream>
//#include <iomanip>
#include <SPI.h>
#include <Wire.h>
#include <EEPROM.h>
#include <FastLED.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// SYStem
const int RELAY_PIN = 11; // the Arduino pin, which connects to the IN pin of relay
const int BUZZER_PIN = 9; // the Arduino pin, which connects to the IN pin of relay
const int ledPin = 8; // the number of the LED pin
// Buttons
const int buttonPinEnter = 5; // the number of the pushbutton pin
const int buttonPinUP = 4; // the number of the pushbutton pin
const int buttonPinDOWN = 3; // the number of the pushbutton pin
const int buttonPinEXIT = 2; // the number of the pushbutton pin
//OLED SYSTEM
#define LED_PIN 10
#define NUM_LEDS 3
#define BRIGHTNESS 255
#define LED_TYPE WS2811
CRGB leds[NUM_LEDS];
uint8_t hue = 0;
int fadeAmount = 10; // Set the amount to fade I usually do 5, 10, 15, 20, 25 etc even up to 255.
int brightness = 0;
//Process
int FeedLimit = 50; int FeedDelay = 10; int FeedDelaySet = 10;
int Drain = 0;
int TankCap = 1000;
int TankSet = 4000;
int buttonState = 0; // variable for reading the pushbutton status
int buttonStateUP = 0; // variable for reading the pushbutton status
int buttonStateDOWN = 0; // variable for reading the pushbutton status
int buttonStateEXIT = 0; // variable for reading the pushbutton status
int btnhold = 0; int btnhold2 = 0;
// Settings Navigation
int navi_home = 0;
int NAVIGATE_MENU_STAT = 1;
char Item1[] = "Tank Capacity";
char Item2[] = "Calibrate";
char Item3[] = "About";
void setup() {
Serial.begin(9600);
Serial.println("Water Rush!");
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.println(F("Booting...")); display.display();
FastLED.addLeds<WS2811, LED_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is assumed
pinMode(ledPin, OUTPUT); // initialize the LED pin as an output:
pinMode(RELAY_PIN, OUTPUT); // initialize the Relay pin as an output:
//digitalWrite(RELAY_PIN, HIGH);
pinMode(buttonPinEnter, INPUT); // initialize the pushbutton pin as an input:
pinMode(buttonPinUP, INPUT); // initialize the pushbutton pin as an input:
pinMode(buttonPinDOWN, INPUT); // initialize the pushbutton pin as an input:
pinMode(buttonPinEXIT, INPUT); // initialize the pushbutton pin as an input:
display.clearDisplay(); display.setTextColor(SSD1306_WHITE);
display.setCursor(34, 8); display.setTextSize(1); display.println(F("Welcome..."));
display.setCursor(16, 26); display.setTextSize(2); display.println(F("Infinity"));
display.setCursor(31, 50); display.setTextSize(1); display.println(F("Water Rush!"));
display.display();
//tone(BUZZER_PIN, 500, 100);delay(150);tone(BUZZER_PIN, 1000, 150);delay(200);tone(BUZZER_PIN, 1350, 200);delay(200);tone(BUZZER_PIN, 1800, 150);delay(150);(BUZZER_PIN, 1750, 500);delay(550);
//delay(1000);
TankCap = read2BytesIntFromEEPROM(12); //Read EPPROM tank cap last saved
TankSet = read2BytesIntFromEEPROM(16); //Read EPPROM tank cap last saved
FeedDelay = read2BytesIntFromEEPROM(20); //Read EPPROM tank cap last saved
if (TankCap < 0) {
TankCap = 1000;
}
if (TankSet < 0) {
TankSet = 1000;
}
if (FeedDelay < 0) {
FeedDelay = 10;
}
FeedDelaySet=FeedDelay;
}
void loop() {
FastLED.show();
brightness = brightness + fadeAmount;
// reverse the direction of the fading at the ends of the fade:
if (brightness == 0 || brightness == 250)
{
fadeAmount = -fadeAmount ;
}
for (int i = 0; i < NUM_LEDS; i++ ) { //BREATHING LED COLOR
leds[i].setRGB(50, 255, 0); leds[i].fadeLightBy(brightness);
} FastLED.show();
display.clearDisplay();
display.setCursor(0, 1); display.setTextSize(2); display.println(F("Water Tank"));
display.drawRoundRect(3, 20, 30, 43, 3, WHITE);
display.drawRoundRect(5, 22, 26, 39, 2, WHITE);
display.fillRoundRect(5, 22, 26, 39, 2, WHITE);
display.setCursor(37, 21); display.setTextSize(1); display.println(F("Select Limit"));
//display.drawRect(37, 33, 60, 21, WHITE);
display.setCursor(50, 38); display.setTextSize(2); display.print(FeedLimit);
display.drawRoundRect(3, 20, 30, 43, 3, WHITE);
display.setCursor(99, 42); display.setTextSize(1); display.println(F("ml"));
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPinEnter); buttonStateUP = digitalRead(buttonPinUP); buttonStateDOWN = digitalRead(buttonPinDOWN); buttonStateEXIT = digitalRead(buttonPinEXIT);
//Feed Limite Adjust
if (buttonStateUP == HIGH && FeedLimit < 1000) {
FeedLimit = FeedLimit + 25; tone(BUZZER_PIN, 3000, 25); delay(25);
}
if (buttonStateDOWN == HIGH && FeedLimit > 0) {
FeedLimit = FeedLimit - 25; tone(BUZZER_PIN, 3000, 25); delay(25);
}
if (buttonState == HIGH) {
btnhold2 = btnhold2 + 1;
if (btnhold2 >= 10) {
tone(BUZZER_PIN, 2000, 100); delay(100); btnhold2 = 0;
Drain = FeedLimit;
if (TankCap > 0 && FeedLimit <= TankCap) {
digitalWrite(RELAY_PIN, HIGH);
digitalWrite(ledPin, HIGH);
Feed();
}
else {
TankEmpty();
}
} else {
btnhold = 0;
}
}
if (buttonStateEXIT == HIGH) {
btnhold = btnhold + 1;
if (btnhold >= 15) {
tone(BUZZER_PIN, 2000, 100); delay(1000); btnhold = 0; Settings();
}
}
else {
btnhold = 0;
}
// Graphical Water Tank
int x = 6; int TankDisp = TankCap; int TankDispML;
if (TankCap >= 10000) {
TankDisp = TankCap / 1000;
TankDispML = TankCap - (TankDisp * 1000);
display.setTextColor(SSD1306_BLACK); display.setCursor(10, 34); display.setTextSize(1); display.print(TankDisp); display.print("L"); display.setTextColor(SSD1306_WHITE);
if (TankDispML > 0) {
display.setTextColor(SSD1306_BLACK);
display.setCursor(10, 44);
display.setTextSize(1);
display.print(TankDispML);
display.setTextColor(SSD1306_WHITE);
}
}
else {
if (TankCap < 1000) {
x = 10;
}
display.setTextColor(SSD1306_BLACK); display.setCursor(x, 38); display.setTextSize(1); display.print(TankDisp); display.setTextColor(SSD1306_WHITE);
}
display.display();
}
//Functions
void WaterDispence() {
}
void Feed() {
display.clearDisplay();
buttonState = digitalRead(buttonPinEnter); buttonStateUP = digitalRead(buttonPinUP); buttonStateDOWN = digitalRead(buttonPinDOWN); buttonStateEXIT = digitalRead(buttonPinEXIT);
display.setCursor(1, 1); display.setTextSize(2); display.print(TankCap); display.print(" ml");
display.setCursor(1, 20); display.setTextSize(1); display.print("Water");
display.setCursor(1, 30); display.setTextSize(1); display.print("Dispensing");
display.setCursor(1, 43); display.setTextSize(2); display.print(Drain); display.print(" ml");
if (Drain >= 0) {
Drain = Drain - 2;
TankCap = TankCap - 2;
delay(FeedDelay);
} else {
digitalWrite(RELAY_PIN, LOW); digitalWrite(ledPin, LOW);
tone(BUZZER_PIN, 3000, 50);
delay(250);
tone(BUZZER_PIN, 3000, 50);
delay(500);
TankCap = TankCap + 2;
goto xxx;
}
display.display();
if (buttonStateEXIT == HIGH) {
tone(BUZZER_PIN, 500, 100);
xxx:
digitalWrite(RELAY_PIN, LOW); digitalWrite(ledPin, LOW);
write2BytesIntoEEPROM(12, TankCap); //Save available Tank Capacity
delay(200); loop();
} else {
Feed();
}
}
void TankEmpty() {
display.clearDisplay();
display.drawRoundRect(1, 20, 127, 44, 3, WHITE);
display.fillCircle( 20, 42, 15, WHITE);
display.drawLine(5, 26, 36, 57, BLACK); display.drawLine(36, 26, 5, 57, BLACK);
display.drawLine(5, 27, 36, 58, BLACK); display.drawLine(36, 27, 5, 58, BLACK);
display.drawLine(5, 28, 36, 59, BLACK); display.drawLine(36, 28, 5, 59, BLACK);
display.drawCircle( 20, 42, 15, WHITE); display.drawCircle( 20, 42, 14, WHITE);
display.setCursor(1, 1); display.setTextSize(2); display.print("Error!");
display.setCursor(40, 34); display.setTextSize(1); display.print("Water Tank");
display.setCursor(40, 44); display.setTextSize(1); display.print("Depleted!");
display.display();
tone(BUZZER_PIN, 200, 50); delay(100); tone(BUZZER_PIN, 200, 50); delay(100); tone(BUZZER_PIN, 200, 100); delay(200);
delay(1000); FeedLimit = TankCap;
loop();
}
void Settings() {
display.clearDisplay();
buttonState = digitalRead(buttonPinEnter); buttonStateUP = digitalRead(buttonPinUP); buttonStateDOWN = digitalRead(buttonPinDOWN); buttonStateEXIT = digitalRead(buttonPinEXIT);
for (int i = 0; i < NUM_LEDS; i++ ) {
leds[i].setRGB(255, 0, 0);
} FastLED.show();
display.setCursor(0, 0); display.setTextSize(2); display.setTextColor(WHITE); display.println(F("Settings"));
display.drawLine(0, 15, 128, 15, 1);
if (navi_home == 0) {
display.fillRoundRect(0, 18, 120, 13, 4, WHITE);//Item 1
display.setCursor(20, 21); display.setTextSize(1); display.setTextColor(BLACK); display.println(Item1);
display.drawRoundRect(0, 32, 120, 13, 4, SSD1306_WHITE);//Item 2
display.setCursor(20, 35); display.setTextSize(1); display.setTextColor(WHITE); display.println(Item2);
display.drawRoundRect(0, 46, 120, 13, 4, SSD1306_WHITE);//Item 3
display.setCursor(20, 49); display.setTextSize(1); display.setTextColor(WHITE); display.println(Item3);
}
if (navi_home == 1) {
display.drawRoundRect(0, 18, 120, 13, 4, WHITE);//Item 1
display.setCursor(20, 21); display.setTextSize(1); display.setTextColor(WHITE); display.println(Item1);
display.fillRoundRect(0, 32, 120, 13, 4, SSD1306_WHITE);//Item 2
display.setCursor(20, 35); display.setTextSize(1); display.setTextColor(BLACK); display.println(Item2);
display.drawRoundRect(0, 46, 120, 13, 4, SSD1306_WHITE);//Item 3
display.setCursor(20, 49); display.setTextSize(1); display.setTextColor(WHITE); display.println(Item3);
}
if (navi_home == 2) {
display.drawRoundRect(0, 18, 120, 13, 4, WHITE);//Item 1
display.setCursor(20, 21); display.setTextSize(1); display.setTextColor(WHITE); display.println(Item1);
display.drawRoundRect(0, 32, 120, 13, 4, SSD1306_WHITE);//Item 2
display.setCursor(20, 35); display.setTextSize(1); display.setTextColor(WHITE); display.println(Item2);
display.fillRoundRect(0, 46, 120, 13, 4, SSD1306_WHITE);//Item 3
display.setCursor(20, 49); display.setTextSize(1); display.setTextColor(BLACK); display.println(Item3);
}
if (buttonStateDOWN == HIGH && navi_home < 2) {
navi_home++; tone(BUZZER_PIN, 1500, 100); delay(200);
}
if (buttonStateUP == HIGH && navi_home > 0) {
navi_home--; tone(BUZZER_PIN, 1500, 100); delay(200);
}
display.display();
//ACTION
if (buttonState == HIGH) {
tone(BUZZER_PIN, 2000, 200);
if (navi_home == 0) {
NAVIGATE_MENU_STAT = 0; delay(300); TankCapSet(); return;
}
if (navi_home == 1) {
NAVIGATE_MENU_STAT = 0; delay(300); Calibrate(); return;
}
if (navi_home == 2) {
NAVIGATE_MENU_STAT = 0; delay(300); //LAMINATOR();
}
display.clearDisplay();
}
if (buttonStateEXIT == HIGH) {
tone(BUZZER_PIN, 500, 100);
delay(200);
loop(); return;
}
else {
Settings(); return;
}
}
void TankCapSet() {
display.clearDisplay();
buttonState = digitalRead(buttonPinEnter); buttonStateUP = digitalRead(buttonPinUP); buttonStateDOWN = digitalRead(buttonPinDOWN); buttonStateEXIT = digitalRead(buttonPinEXIT);
display.setCursor(0, 0); display.setTextSize(2); display.setTextColor(WHITE); display.println(F("S >"));
display.setCursor(45, 3); display.setTextSize(1); display.setTextColor(WHITE); display.println(F("Tank Capacity"));
display.drawLine(0, 15, 128, 15, 1);
display.setCursor(3, 20); display.setTextSize(1); display.setTextColor(WHITE); display.println("Capacity of tank");
display.fillRoundRect(3, 30, 76, 22, 3, SSD1306_WHITE);
display.setCursor(7, 34); display.setTextSize(2); display.setTextColor(BLACK); display.println(TankSet);
display.setCursor(83, 37); display.setTextSize(1); display.setTextColor(WHITE); display.println("ml");
display.drawRoundRect(0, 55, 30, 10, 2, SSD1306_WHITE);
display.drawRoundRect(33, 55, 30, 10, 2, SSD1306_WHITE);
display.drawRoundRect(65, 55, 30, 10, 2, SSD1306_WHITE);
display.drawRoundRect(98, 55, 30, 10, 2, SSD1306_WHITE);
display.setCursor(4, 57); display.setTextSize(1); display.setTextColor(WHITE); display.println("Save");
display.setCursor(46, 57); display.setTextSize(1); display.setTextColor(WHITE); display.println("+");
display.setCursor(78, 57); display.setTextSize(1); display.setTextColor(WHITE); display.println("-");
display.setCursor(102, 57); display.setTextSize(1); display.setTextColor(WHITE); display.println("Exit");
if (buttonStateUP == HIGH && TankSet < 20000) {
TankSet = TankSet + 100; tone(BUZZER_PIN, 800, 2);
display.fillRoundRect(33, 55, 30, 10, 2, SSD1306_WHITE);
display.setCursor(46, 57); display.setTextSize(1); display.setTextColor(BLACK); display.println("+");
delay(50);
}
if (buttonStateDOWN == HIGH && TankSet > 50) {
TankSet = TankSet - 100; tone(BUZZER_PIN, 800, 2);
display.fillRoundRect(65, 55, 30, 10, 2, SSD1306_WHITE);
display.setCursor(78, 57); display.setTextSize(1); display.setTextColor(BLACK); display.println("-");
delay(50);
}
if (buttonState == HIGH) {
tone(BUZZER_PIN, 2000, 200);
//Save available Tank Capacity
TankCap = TankSet;
write2BytesIntoEEPROM(12, TankCap);
delay(500);
write2BytesIntoEEPROM(16, TankSet);
delay(500);
Settings();
return;
}
display.display();
if (buttonStateEXIT == HIGH) {
tone(BUZZER_PIN, 500, 100);
display.fillRoundRect(98, 55, 30, 10, 2, SSD1306_WHITE);
display.setCursor(102, 57); display.setTextSize(1); display.setTextColor(BLACK); display.println("Exit");
delay(200);
Settings();
return;
}
else {
TankCapSet();
}
}
void Calibrate() {
display.clearDisplay();
buttonState = digitalRead(buttonPinEnter); buttonStateUP = digitalRead(buttonPinUP); buttonStateDOWN = digitalRead(buttonPinDOWN); buttonStateEXIT = digitalRead(buttonPinEXIT);
display.setCursor(0, 0); display.setTextSize(2); display.setTextColor(WHITE); display.println(F("S >"));
display.setCursor(45, 3); display.setTextSize(1); display.setTextColor(WHITE); display.println(F("Calibrate"));
display.drawLine(0, 15, 128, 15, 1);
display.setCursor(3, 20); display.setTextSize(1); display.setTextColor(WHITE); display.println("Calibrate Pump ");
display.fillRoundRect(3, 30, 76, 22, 3, SSD1306_WHITE);
display.setCursor(7, 34); display.setTextSize(2); display.setTextColor(BLACK); display.println(FeedDelaySet);
display.setCursor(83, 37); display.setTextSize(1); display.setTextColor(WHITE); display.println("Points");
display.drawRoundRect(0, 55, 30, 10, 2, SSD1306_WHITE);
display.drawRoundRect(33, 55, 30, 10, 2, SSD1306_WHITE);
display.drawRoundRect(65, 55, 30, 10, 2, SSD1306_WHITE);
display.drawRoundRect(98, 55, 30, 10, 2, SSD1306_WHITE);
display.setCursor(4, 57); display.setTextSize(1); display.setTextColor(WHITE); display.println("Save");
display.setCursor(46, 57); display.setTextSize(1); display.setTextColor(WHITE); display.println("+");
display.setCursor(78, 57); display.setTextSize(1); display.setTextColor(WHITE); display.println("-");
display.setCursor(102, 57); display.setTextSize(1); display.setTextColor(WHITE); display.println("Exit");
if (buttonStateUP == HIGH && FeedDelaySet < 100) {
FeedDelaySet = FeedDelaySet + 1; tone(BUZZER_PIN, 800, 2);
display.fillRoundRect(33, 55, 30, 10, 2, SSD1306_WHITE);
display.setCursor(46, 57); display.setTextSize(1); display.setTextColor(BLACK); display.println("+");
delay(50);
}
if (buttonStateDOWN == HIGH && FeedDelaySet > 1) {
FeedDelaySet = FeedDelaySet - 1; tone(BUZZER_PIN, 800, 2);
display.fillRoundRect(65, 55, 30, 10, 2, SSD1306_WHITE);
display.setCursor(78, 57); display.setTextSize(1); display.setTextColor(BLACK); display.println("-");
delay(50);
}
if (buttonState == HIGH) {
tone(BUZZER_PIN, 2000, 200);
//Save available Tank Capacity
FeedDelay = FeedDelaySet;
write2BytesIntoEEPROM(20, FeedDelay);
delay(500);
Settings();
return;
}
display.display();
if (buttonStateEXIT == HIGH) {
tone(BUZZER_PIN, 500, 100);
display.fillRoundRect(98, 55, 30, 10, 2, SSD1306_WHITE);
display.setCursor(102, 57); display.setTextSize(1); display.setTextColor(BLACK); display.println("Exit");
delay(200);
Settings();
return;
}
else {
Calibrate();
}
}
void write2BytesIntoEEPROM(int address, int number) {
EEPROM.write(address, (number >> 8) & 0xFF);
EEPROM.write(address + 1, number & 0xFF);
}
int read2BytesIntFromEEPROM(int address) {
return (EEPROM.read(address) << 8) + EEPROM.read(address + 1);
}