#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSansBold18pt7b.h>
#include <Fonts/FreeSansBold9pt7b.h>
#include <ESP32Servo.h>
#include <HX711.h>
//#include "pitches.h" //audio
const int servoPin = 18;
const long LOADCELL_OFFSET = 50682624;
const long LOADCELL_DIVIDER = 5895655;
Servo servo;
HX711 scale;
#define SCREEN_WIDTH 128 // OLED width, in pixels
#define SCREEN_HEIGHT 64 // OLED height, in pixels
#define SPEAKER_PIN 27 // buzzer pin
// create an OLED display object connected to I2C
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
int pos = 0; //proměná serva
int ventil = 0; //proměná serva 180 otevřen 0 zavřen
int cil = 950; // požadovaná váha
int cilx = 0;
long stara_vaha = 1000;
int tara = 0;
int prodleva = cil;
boolean auto_c;
int auto_dif = 0;
int text_x = 60;
int text_y = 23;
void setup() {
Serial.begin(9600);
// initialize OLED display with I2C address 0x3C
if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("failed to start SSD1306 OLED"));
while (1);
}
delay(2000); // wait two seconds for initializing
servo.attach(servoPin, 500, 2400); // nastavení serva
scale.begin(13, 15);
// load cell factor 5 KG
scale.set_scale(420.0983); // TODO you need to calibrate this yourself.
// reset the scale to zero = 0
scale.tare(20);
hlavni_panel();
pinMode(34, INPUT); // sets
pinMode(32, INPUT); // sets
pinMode(35, INPUT); // sets
pinMode(27, OUTPUT); // sets
// pinMode(13, INPUT); // sets
// pinMode(12, OUTPUT); // sets
// pinMode(15, OUTPUT); // sets
servo_off(0);
buzzer1();
}
void loop() {
String vaha;
int hladina = 62; //dno sklenice
int poz; // = 45 pozice textu čísel hmotnosti
int n = 0;
//Serial.println("OK");
if (digitalRead(32) == HIGH) {
Serial.println("Servo 0 OFF");
Serial.print(ventil);
buzzer1();
menu();
}
if (digitalRead(35) == HIGH) { // tata
Serial.println("TARA");
buzzer1();
scale.tare(20); // tarra
delay (1500);
}
// start napouštění
if (digitalRead(34) == HIGH) {
buzzer1();
Serial.println("Vaha ON");
tara = scale.get_units() * 1000;
// kontrola petížení
if (tara + cil >= 4990) {
buzzer1();
Serial.println("Vaha bude přetižena");
oled.fillRect(0, 16, 128, 30, BLACK);
oled.setCursor((0), text_y + 18); // set position to display (x,y)
oled.print("Max5kg"); // set text
oled.display();
for (n = 0; n <= 5; n++) {
buzzer1();
delay(100);
}
oled.fillRect(0, 16, 128, 30, BLACK);
hlavni_panel();
goto konec;
}
sklenice();
scale.tare(20); // tarra
// cilx = (cil / 100) * prodleva;
// Serial.print("cilx = ");
// Serial.println(cilx );
Serial.println("auto_dif = " + String(auto_dif));
Serial.println("Prodleva = " + String(prodleva));
vaha = String(stara_vaha);
poz = text_x - 25;
poz = (poz + 18 * 4) - (vaha.length() * 18);
oled.setCursor(poz, text_y + 20); // smazat starou hodnotu na oled
oled.setTextColor(BLACK); // set text color
oled.setFont(&FreeSansBold18pt7b);
oled.print(vaha);
oled.setFont(&FreeSansBold9pt7b);
oled.setTextSize(1); // set text size
oled.setTextColor(WHITE); // set text color
oled.setCursor((text_x + 18 * 3), text_y + 18); // set position to display (x,y)
oled.print("g"); // set text
oled.setCursor((text_x - 20), text_y + 40); // set position to display (x,y)
oled.print("cil " + String(cil)); // set text
servo_on(180); // otevřít ventil
ventil = 0;
//važení do nastavené hodnoty pprodleva
while (n < prodleva) {
n = scale.get_units() * 1000; // načítá nové hodnoty
if (ventil == 0) oled.fillTriangle(6, 0, 25, 0, 15, 10, WHITE); //znak plnění
poz = text_x - 25; //pozice textu čísel hmotnosti
hladina = 60 - (n / (cil / 35)); // cíl/ počet linek hladiny
if (hladina <= 22) hladina = 20;
oled.fillRect(2, hladina, 29, 62, WHITE);
//oled.drawLine(1, hladina, 31, hladina, WHITE); //hladina sklenice
oled.setTextColor(WHITE); // set text color
vaha = String(n);
poz = (poz + 18 * 4) - (vaha.length() * 18);
oled.setFont(&FreeSansBold18pt7b);
oled.setCursor(poz, text_y + 20); // set position to display (x,y)
Serial.print("v_sen= ");
Serial.println(scale.get_units(), 2); // čtení váhy na senzoru
oled.print(vaha); // aktualní váha
oled.display();
delay (100);
oled.setCursor(poz, text_y + 20);
oled.setTextColor(BLACK); // set text color
oled.print(vaha);
oled.fillTriangle(6, 0, 25, 0, 15, 10, BLACK); //znak plnění
delay (100);
oled.display();
// pauza ve vážení
if (digitalRead(35) == HIGH) {
buzzer1();
if (ventil == 0) {
servo_off(0); // zavřít ventil
ventil = 180;
delay (500);
}
else {
servo_on(180); // otevřít ventil
ventil = 0;
delay (500);
}
} //
if (digitalRead(34) == HIGH) {
buzzer1();
goto konec;
}
}
// konec vážení
Serial.println("Vaha OFF");
servo_off(0); // zavřít ventil
ventil = 180;
Serial.println(" AUTO " + String(auto_c));
delay (1000);
if (auto_c == true) {
auto_dif = (scale.get_units() * 1000) - cil;
prodleva = cil - auto_dif;
Serial.println("auto_dif = " + String(auto_dif) + "vaha = " + String(scale.get_units() * 1000));
Serial.println("Prodleva = " + String(prodleva));
delay (5000);
}
else {
auto_dif = 0;
prodleva = cil;
}
konec:
sklenice_cls();
stara_vaha = scale.get_units() * 1000;
// oled.clearDisplay();
// delay (1000);
}
// vaha
if (stara_vaha != (int (scale.get_units() * 1000))) {
// oled.fillRect(0, 18, 128, 30, BLACK);
Serial.print("stara_vaha= "); //
Serial.println(stara_vaha);
vaha = String(stara_vaha); //
poz = text_x - 25;
poz = (poz + 18 * 4) - (vaha.length() * 18);
oled.setFont(&FreeSansBold18pt7b);
oled.setCursor(poz, text_y + 20); // smazat starou hodnotu na oled
oled.setTextColor(BLACK); // set text color
oled.print(vaha);
oled.display();
stara_vaha = scale.get_units() * 1000; // načítá nové hodnoty
vaha = String(stara_vaha);
poz = text_x - 25;
poz = (poz + 18 * 4) - (vaha.length() * 18);
oled.setTextColor(WHITE);
oled.setCursor(poz, text_y + 20); // set position to display (x,y)
Serial.print("sen= ");
Serial.println(scale.get_units() * 1000); // čtení váhy na senzoru
Serial.println(vaha); //
oled.print(vaha); // aktualní váha
oled.display();
delay (200);
}
delay (200);
}
void sklenice() {
oled.drawRoundRect(3, 12, 26, 9, 2, WHITE);
oled.drawRoundRect(1, 20, 30, 43, 3, WHITE);
oled.drawRoundRect(0, 20, 32, 42, 3, WHITE);
oled.display();
Serial.println("Sklenice OK");
}
void sklenice_cls() {
oled.fillRect(0, 0, 32, 64, BLACK);
oled.display();
}
void servo_off(int pos) {
// int pos = 0;
//servo.write(0);
Serial.println("servo pos off= " + String(pos));
for (pos = 0; pos <= 180; pos += 1) {
servo.write(pos);
ventil = 180;
// Serial.print(pos);
delay(15);
}
delay (2000);
}
void servo_on(int pos) {
//int pos = 180;
//servo.write(180);
Serial.println("servo pos on= " + String(pos));
for (pos = 180; pos >= 0; pos -= 1) {
servo.write(pos);
ventil = 0;
delay(15);
}
delay (2000);
}
void hlavni_panel() {
oled.clearDisplay(); // clear display
// uvodní obrazovka
oled.setFont(&FreeSansBold9pt7b);
oled.setTextSize(1); // set text size
oled.setTextColor(WHITE); // set text color
oled.setCursor((text_x + 18 * 3), text_y + 18); // set position to display (x,y)
oled.print("g"); // set text
oled.setCursor((text_x - 20), text_y + 40); // set position to display (x,y)
oled.print("cil " + String(cil)); // set text
oled.display();
oled.setFont(&FreeSansBold9pt7b);
oled.setTextSize(1); // set text size
oled.setTextColor(WHITE); // set text color
oled.setCursor(55, 12); // set position to display (x,y)
oled.println("Vaha"); // set text
oled.setTextSize(1); // set text size
oled.setCursor(55, 22); // set position to display (x,y)
oled.display(); // display on OLED
}
void buzzer1() {
// tone(SPEAKER_PIN, 127, 200);
// delay(300);
//for (byte i = 0; i < 10; i++) {
for (int pitch = 0; pitch <= 255; pitch++) {
//tone(SPEAKER_PIN, NOTE_C5 + pitch);
analogWrite(SPEAKER_PIN, pitch);
delay(1);
}
noTone(SPEAKER_PIN);
}
void menu() {
int menu_p = 1;
int hodnota = 0;
int menu_s = 2;
int hodnota_max = 4900; //maximum vážení
long cas1 = millis();
long cas2 = cas1;
String str_hodnota = "0";
oled.clearDisplay(); // clear display
oled.fillRoundRect(0, 0, 128, 18, 6, WHITE);
oled.setFont(&FreeSansBold9pt7b);
oled.setTextSize(1); // set text size
oled.setTextColor(BLACK); // set text color
oled.setCursor(40, 14); // set position to display (x,y)
oled.println("MENU"); // set text
oled.setTextColor(WHITE);
oled.setCursor(10, 33); // set position to display (x,y)
oled.display();
while (menu_p != 0) { // 0=navrat; 1= cílová váha; 2 = zavírání % z cíle ; 3 = ventil on/off
cas2 = millis();
if (digitalRead(34) == HIGH && digitalRead(35) == HIGH ) { //reset na AUTO
if (menu_p == 2) {
buzzer1();
oled.fillRect(0, 35, 128, 64, BLACK);
oled.setCursor(3, 62);
buzzer1();
str_hodnota = " AUTO ";
hodnota = 0;
auto_c = true;
Serial.println(" AUTO dabl " + auto_c);
delay(3000);
}
}
if (digitalRead(34) == HIGH) { // hodnota -1
oled.fillRect(0, 35, 128, 64, BLACK);
if (cas2 - cas1 <= 200) {
Serial.println(cas1);
Serial.println(cas2);
Serial.println(cas2 + cas1);
hodnota = hodnota - 25;
}
else {
buzzer1();
hodnota = hodnota - 1;
}
if (menu_p == 3 && ventil == 0) {
servo_off(0); // zavřít ventil
ventil = 180;
}
if (hodnota <= -1) hodnota = hodnota_max;
Serial.print("hodnota - ");
Serial.println(hodnota);
delay (200);
cas1 = millis();
//cas2 = millis();
}
if (digitalRead(35) == HIGH) { // hodnota +1
oled.fillRect(0, 35, 128, 64, BLACK);
if (cas2 - cas1 <= 200) {
Serial.println(cas1);
Serial.println(cas2);
Serial.println(cas2 + cas1);
hodnota = hodnota + 25;
}
else {
buzzer1();
hodnota = hodnota + 1;
}
if (menu_p == 3 && ventil == 180) {
servo_on(180); // otevřít ventil
ventil = 0;
}
if (hodnota >= hodnota_max + 1) hodnota = 0;
Serial.print("hodnota + ");
Serial.println(hodnota);
delay (200);
cas1 = millis();
}
//delay(500);
if (digitalRead(32) == HIGH) { // přepínání v MENU
buzzer1();
menu_p = menu_p + 1;
// if (menu_p >= 5) menu_p = 1;
Serial.print("menu = ");
Serial.println(menu_p);
oled.display();
}
if (menu_s != menu_p) {
Serial.println(menu_p);
oled.setFont(&FreeSansBold9pt7b);
oled.fillRect(0, 20, 128, 64, BLACK);
oled.setCursor(10, 33); // set position to display (x,y)
// oled.setTextColor(WHITE);
oled.setCursor(10, 33); // set position to display (x,y)
switch (menu_p) {
case 1:
hodnota = cil;
// hodnota_max = 4900;
//Serial.println(menu_p);
oled.println("cilova vaha"); // set text
break;
case 2:
cil = hodnota;
if (hodnota != 0) auto_c = false;
hodnota = prodleva;
// hodnota_max = cil;
oled.println("zavirani pri"); // set text
break;
case 3:
if (hodnota != 0) prodleva = hodnota;
hodnota = ventil;
oled.println("ventil"); // set text
//if (ventil==0) oled.println("ZAVREN"); // set text
// else oled.println("OTEVREN");
break;
}
menu_s = menu_p;
oled.display();
}
if (menu_p >= 4) menu_p = 0;
oled.setFont(&FreeSansBold18pt7b); //zpět na velký font
oled.setCursor(3, 62); // set position to display (x,y)
str_hodnota = String(hodnota);
if (menu_p == 3) {
oled.setTextSize(1); // set text size
oled.setFont(&FreeSansBold9pt7b); //zpět na velký font
if (ventil == 180) str_hodnota = "ZAVREN " + String(ventil); // set text
else str_hodnota = "OTEVREN " + String(ventil);
}
if (menu_p == 2 && hodnota == 0) {
oled.fillRect(0, 35, 128, 64, BLACK);
oled.setCursor(3, 62);
str_hodnota = " AUTO ";
auto_c = true;
auto_dif = 0;
prodleva = cil;
Serial.println(" AUTO " + String(auto_c));
Serial.println("auto_dif = " + String(auto_dif));
Serial.println("Prodleva_menu = " + String(prodleva));
}
oled.println(str_hodnota); // set text
oled.display();
}
oled.clearDisplay(); // clear display
hlavni_panel();
stara_vaha = 10;
// oled.println("konec MENU"); // set text
}
//hrdlo david 38mm vnitřní 34,6mm
// the SDA (D6/GPIO14) and SCL (D5/GPIO12) pins.