#include <ezButton.h>
#include <NewPing.h>
#include <Wire.h> //pripojeni pouzitych knihoven
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
byte u[8] = {B00110,B00110,B00000,B10001,B10001,B10011,B01101,B00000};
byte z[8] = {B01010,B00100,B11111,B00010,B00100,B01000,B11111,B00000};
byte a[8] = {B00010,B00100,B01110,B00001,B01111,B10001,B01111,B00000};
byte i[8] = {B00010,B00100,B00000,B01100,B00100,B00100,B01110,B00000}; //vlastni znaky jednotlive pixely ZDROJ: https://create.arduino.cc/projecthub/jacoslabbert99/arduino-lcd-icons-custom-characters-548f38
byte c[8] = {B01010,B00100,B01110,B10000,B10000,B10001,B01110,B00000};
byte e[8] = {B01010,B00100,B01110,B10001,B11111,B10000,B01110,B00000};
byte y[8] = {B00010,B00100,B10001,B10001,B01111,B00001,B01110,B00000};
byte n[8] = {B01010,B00100,B10110,B11001,B10001,B10001,B10001,B00000};
#define echoPin 10
#define trigPin 11
int distanceMin = 100;
//-----------------------------nastvani encoderu-----------------------------------------------------------
const int SHORT_PRESS_TIME = 1000; // 1000 milliseconds
const int LONG_PRESS_TIME = 1000; // 1000 milliseconds
unsigned long pressedTime = 0;
unsigned long releasedTime = 0;
bool isPressing = false;
bool isLongDetected = false;
ezButton button(3); // create ezButton object that attach to pin 3;
//---------------------------------------------------------------------------------------------------------
// Rotary Encoder Inputs
#define inputCLK 4
#define inputDT 5
// LED Outputs
#define cerpadlo 7
int currentStateCLK;
int previousStateCLK;
//------------------------------nastaveni provoznich hodnot--------------------------------------------
float VelikostPlneNadrze = 1700;
int maxNaliti = 500; // max mnozstvi [ml]
byte min = 100; // min mnozstvi [ml]
byte krok = 50; // o kolik se meni mnozstvi otocenim [ml]
float dobaNaLitr = 28; //doba pro vycerpani cele nadrze [s]
int nabidnuteMnozstvi = 300; //mnozstvi naboje nabidnuto [ml]
//--------------------------------------------------------------------------------------------------
float counter = nabidnuteMnozstvi; //prepis do pocitadla
int max = maxNaliti; //zaloha max mnozstvi
float obsahNadrze = VelikostPlneNadrze; // velikost obsahu nadrze [ml]
long duration; // variable for the duration of sound wave travel
int distance; // variable for the distance measurement
void setup() {
button.setDebounceTime(50); // set debounce time to 50 milliseconds
lcd.init(); // initialize the lcd
lcd.backlight(); // Turn on the LCD screen backlight
lcd.createChar(0, u);
lcd.createChar(1, a);
lcd.createChar(2, z); //vytvoreni vlastnich znaku ž ý á .....
lcd.createChar(3, i);
lcd.createChar(4, c); //lcd.write(2);
lcd.createChar(5, e);
lcd.createChar(6, y);
lcd.createChar(7, n);
// Set encoder pins as inputs
pinMode (inputCLK,INPUT);
pinMode (inputDT,INPUT);
pinMode(echoPin, INPUT);
pinMode(trigPin, OUTPUT);
// Set LED pins as outputs
pinMode (cerpadlo,OUTPUT);
// Setup Serial Monitor
Serial.begin (115200);
// Read the initial state of inputCLK
// Assign to previousStateCLK variable
previousStateCLK = digitalRead(inputCLK);
}
//-----------------------------------------------------------------------------------------------------------
void loop() { //pouze start programu
Serial.println("START");
Serial.println("Vlozte Sklenici");
vypisKolikZbyva();
detekceSklenice();
}
//------------------------------------------------------------------------------------------------------------
void detekceSklenice(){ // zakladni smycka cekani na sklenici, pripadne doplneni nadrze
while(obsahNadrze < 100){ //reset na plnou nadrz
Serial.println("Doplnte nadrz");
lcd.setCursor(1,0);
lcd.print("Dopl");
lcd.write(7);
lcd.print("te n");
lcd.write(1);
lcd.print("dr");
lcd.write(2);
if(stavTlacitko() == 2){
Serial.println("Restart sytemu");
vypisNadrzDoplnena();
obsahNadrze = VelikostPlneNadrze;
counter = nabidnuteMnozstvi;
max = maxNaliti;
Serial.println("Vlozte sklenici");
vypisKolikZbyva();
}
}
if(stavTlacitko() == 2){
Serial.println("Restart sytemu");
vypisNadrzDoplnena();
obsahNadrze = VelikostPlneNadrze;
counter = nabidnuteMnozstvi;
max = maxNaliti;
vypisKolikZbyva();
}
if(ultraSonicSensor() <= 6){
if((obsahNadrze) < 500){
max = obsahNadrze;
counter = obsahNadrze;
}
else {
max = maxNaliti;
counter = nabidnuteMnozstvi;
}
Serial.println("Vyberte mnozstvi");
lcd.clear();
lcd.setCursor(3,0);
lcd.print("Vyberte si");
lcd.setCursor(0,1);
lcd.print("mno");
lcd.write(2);
lcd.print("stv");
lcd.write(3);
lcd.print(":");
lcd.setCursor(10,1);
lcd.print(counter);
lcd.setCursor(13,1);
lcd.print(" ml");
vyberMnozstvi();
}
detekceSklenice();
}
//-------------------------------------------------------------------------------------------------------------------------
void vyberMnozstvi() { //encoder detekce pohybu + vlastni prepocet na potrebne jednotky ZDROJ: https://howtomechatronics.com/tutorials/arduino/rotary-encoder-works-use-arduino/
int zobrazeni = counter;
// Read the current state of inputCLK
currentStateCLK = digitalRead(inputCLK);
// If the previous and the current state of the inputCLK are different then a pulse has occured
if (currentStateCLK != previousStateCLK){
// the encoder is rotating counterclockwise
if (digitalRead(inputDT) != currentStateCLK ) {
counter = counter + krok/2;
zobrazeni = zobrazeni + 25;
}
else {
// Encoder is rotating clockwise
counter = counter - krok/2;
zobrazeni = zobrazeni - 25;
}
if(counter > max ){
counter = max;
zobrazeni = max;
}
if(counter < min){
counter = min;
zobrazeni = min;
}
Serial.print("Vyber si mnozstvi: ");
if(zobrazeni < 100){
lcd.setCursor(10,1);
lcd.print(" ");
lcd.setCursor(11,1);
lcd.print(zobrazeni);
}
else if(zobrazeni <10){
lcd.print(" ");
}
else{
lcd.setCursor(10,1);
lcd.print(zobrazeni);
}
}
// Update previousStateCLK with the current state
previousStateCLK = currentStateCLK;
if(ultraSonicSensor() > 6){ // pokracuj pokud je zde sklenice
Serial.println("Vlozte sklenici");
vypisKolikZbyva();
detekceSklenice();
}
switch(stavTlacitko()){ // tlacitko stisknuto = 1, tlacitko drzeno = 2
case 0:
vyberMnozstvi();
break;
case 1:
spustit();
break;
case 2:
Serial.println("Restart sytemu");
vypisNadrzDoplnena();
obsahNadrze = VelikostPlneNadrze;
counter = nabidnuteMnozstvi;
max = maxNaliti;
Serial.println("Vloz sklenici");
vypisKolikZbyva();
detekceSklenice();
break;
}
}
//-------------------------------------------------------------------------------------------------------------------------------------
void spustit(){
byte y = 3;
float cerpani = map(counter,min,max,dobaNaLitr/10,dobaNaLitr/2); //vypocet doby potrebne pro naliti daneho mnozstvi
lcd.clear();
lcd.setCursor(1,0);
lcd.print("Pros");
lcd.write(3);
lcd.print("m ");
lcd.write(4);
lcd.print("ekejte");
digitalWrite(cerpadlo,1);
for(int i = 0; i < cerpani*40; i++){ // smycka pro nalevani
delay(25);
obsahNadrze = obsahNadrze - ((counter/(cerpani*40))); //vypocet zbyvajiciho mnozstvi v nadrzi po kazdem navyseni -> i
Serial.println(obsahNadrze);
while (ultraSonicSensor() > 6 || stavTlacitko() == 1 ){ //kdyz je tady sklenice tak muzes pokracovat v nalevani
digitalWrite(cerpadlo,0);
vypisKolikZbyva();
detekceSklenice();
}
byte procento = i/(cerpani*40/100); //vypocet procentualniho pokroku nalevani
byte procentoMin;
// Serial.print("Prosim cekejte ");
Serial.print(procento);
Serial.println("%");
if(procento % 10 == 0 && procento != procentoMin && procento != 0){ // animace cerpani -> kazde 10. % + jedna tecka
procentoMin = procento;
lcd.setCursor(y,1);
lcd.print(".");
y++;
}
}
lcd.print(".");
delay(1000);
digitalWrite(cerpadlo,0);
// Serial.println("HOTOVO ODEBERTE NAPOJ");
lcd.clear();
lcd.setCursor(5,0);
lcd.print("HOTOVO");
delay(1000);
lcd.setCursor(1,1);
lcd.print("Odeberte n");
lcd.write(1);
lcd.print("poj");
counter = nabidnuteMnozstvi; //reset nabidnuteho mnozstvi
digitalWrite(cerpadlo,0);
while (ultraSonicSensor() <= 10){} // cekej na odebrani sklenice
delay(700);
vypisKolikZbyva();
detekceSklenice();
}
//-----------------------------------------------------------------------------------------------------------------------
int stavTlacitko() { //Detekuje stisknuti a drzeni tlacitka (drobne upraveno vraci cislo x) ZDROJ: https://arduinogetstarted.com/tutorials/arduino-button-long-press-short-press
int x = 0;
button.loop();
if(button.isPressed()){
pressedTime = millis();
isPressing = true;
isLongDetected = false;
}
if(button.isReleased()) {
isPressing = false;
releasedTime = millis();
long pressDuration = releasedTime - pressedTime;
if( pressDuration < SHORT_PRESS_TIME ){
x = 1;
//Serial.println(x);
//Serial.println("Vyberte mnozstvi");
return x;
}
}
if(isPressing == true && isLongDetected == false) {
long pressDuration = millis() - pressedTime;
if( pressDuration > LONG_PRESS_TIME ) {
isLongDetected = true;
x = 2;
//Serial.println(x);
//prechod na reset systemu
return x;
}
}
return x;
}
//------------------------------------------------------------------------------------------------------------------------------
void vypisKolikZbyva(){ // vypise hlavni informaci "Vlozte sklenici zbyva" x ml (upravuje pozici cisla podle poctu cifer)"
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Vlo");
lcd.write(2); //ž
lcd.print("te Sklenici");
lcd.setCursor(1,1);
lcd.print("Zb");
lcd.write(6); //ý
lcd.print("v");
lcd.write(1); //á
lcd.print(":");
if(obsahNadrze < 100){
lcd.clear();
}
else if(obsahNadrze < 1000){
lcd.setCursor(9,1);
lcd.print(obsahNadrze);
lcd.setCursor(12,1);
lcd.print(" ml");
}
else{
lcd.setCursor(8,1);
lcd.print(obsahNadrze);
lcd.setCursor(12,1);
lcd.print(" ml");
}
}
//------------------------------------------------------------------------------------------------------------------------------
void vypisNadrzDoplnena(){ // vypise informaci "Nadrz doplnena + animace"
lcd.clear();
lcd.setCursor(1,0);
lcd.print("N");
lcd.write(1);
lcd.print("dr");
lcd.write(2);
lcd.print(" Dopln");
lcd.write(5);
lcd.print("na");
lcd.setCursor(6,1);
delay(700);
lcd.print(".");
delay(700);
lcd.print(".");
delay(700);
lcd.print(".");
delay(700);
lcd.print(".");
delay(1000);
lcd.clear();
}
int ultraSonicSensor(){ //upraveno na vlastni funkci ZDROJ: https://create.arduino.cc/projecthub/abdularbi17/ultrasonic-sensor-hc-sr04-with-arduino-tutorial-327ff6
// Clears the trigPin condition
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin HIGH (ACTIVE) for 10 microseconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance = duration * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)
// Displays the distance on the Serial Monitor
// if(distance > 50 && distanceMin <= 10)
// distance = distanceMin;
Serial.print("Vzdalenost ");
Serial.println(distance);
//distanceMin = distance;
return distance;
}