#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Adafruit_NeoPixel.h>
#include <HCSR04.h>
#define PIN1 6 // Pin pro původní LED pásek
#define PIN2 5 // Pin pro nový LED pásek
#define NUMPIXELS 66 // Celkový počet LED na obou páscích
#define MAX_DISTANCE 100 // Maximální vzdálenost (prázdná nádrž) v cm
#define FULL_DISTANCE 10 // Minimální vzdálenost (plná nádrž) v cm
Adafruit_NeoPixel pixels1(NUMPIXELS, PIN1, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels2(6, PIN2, NEO_GRB + NEO_KHZ800); // Nový LED pásek pro písmena "ONCESS"
LiquidCrystal_I2C lcd(0x27, 16, 2);
UltraSonicDistanceSensor distanceSensor(9, 10); // Inicializace senzoru vzdálenosti, který používá digitální piny 9 a 10.
const int nadrz_sirka_cm = 120;
const int nadrz_delka_cm = 100;
const float max_objem_litru = 1200.0; // Maximální objem nádrže v litrech
const int pocet_nadrzi = 4; // Počet nádrží
float filterMeasurement(float measurement) {
static float measurements[5] = {0}; // Uchovává posledních 5 měření
static int index = 0; // Index pro ukládání nových měření
static bool initialized = false; // Indikátor, zda byl buffer inicializován
static float sum = 0; // Suma měření
if (!initialized) { // Pokud není buffer inicializován, proveď inicializaci
for (int i = 0; i < 5; ++i) {
measurements[i] = measurement; // Nastav všechna měření na aktuální hodnotu
sum += measurement; // Aktualizuj sumu měření
}
initialized = true; // Nastav indikátor inicializace na true
} else {
sum -= measurements[index]; // Odeber staré měření z sumy
measurements[index] = measurement; // Ulož nové měření
sum += measurement; // Přidej nové měření do sumy
index = (index + 1) % 5; // Posuň index na další pozici v bufferu
}
return sum / 5; // Vrať průměr posledních 5 měření
}
void setup() {
pixels1.begin(); // Spuštění LED pásku
pixels1.clear(); // Nastavení všech barev pixelů na 'vypnuto'
pixels1.show(); // Odeslání aktualizovaných barev pixelů na hardware.
pixels2.begin(); // Spuštění nového LED pásku
pixels2.clear(); // Nastavení všech barev pixelů na 'vypnuto'
pixels2.show(); // Odeslání aktualizovaných barev pixelů na hardware.
lcd.init(); // Inicializace LCD displeje
lcd.backlight(); // Zapnutí podsvícení
lcd.setCursor(0, 0);
lcd.print("OncesSuv "); // Nulový stav
lcd.setCursor(0, 1);
lcd.print(" HLADINOMER"); // Nulový stav
// Bliknutí písmen "ONCESS" na novém LED pásku
for (int i = 5; i >= -1; i--) {
pixels2.setPixelColor(i, pixels2.Color(255, 255, 255)); // Nastavení bílé barvy
pixels2.show();
delay(300); // Doba bliknutí
pixels2.setPixelColor(i, pixels2.Color(0, 0, 0)); // Vypnutí LED
}
delay(200); // Krátká pauza
}
float objem_v_litreach(int vzdalenost_cm) {
// Výpočet objemu nádrže v litrech
float objem = max_objem_litru - (max_objem_litru * (vzdalenost_cm - FULL_DISTANCE) / (MAX_DISTANCE - FULL_DISTANCE)); // Objem v litrach
return max(0, objem); // Zajištění, že hodnota objemu nebude záporná
}
void duhaEfekt() {
// Opakování efektu duhy 3x za sebou
for (int k = 0; k < 2; k++) {
// Efekt duhy
for(int j = 255; j > 0; j--) { // Obrácený směr efektu
for(int i = 0; i < pixels1.numPixels(); i++) {
pixels1.setPixelColor(i, pixels1.ColorHSV(i * 65536 / pixels1.numPixels() + j * 256));
}
pixels1.show();
delay(5);
}
}
}
void zobrazHladinuNaLCD(int hladinaProcent) {
lcd.setCursor(0, 0);
lcd.print("0% "); // Nulový stav
lcd.setCursor(12, 0);
lcd.print("100%"); // Plný stav
lcd.setCursor(2, 0);
int celkemSegmentu = map(hladinaProcent, 0, 100, 0, 10);
for (int i = 0; i < 10 - celkemSegmentu; i++) {
lcd.write(byte(0xFF)); // Plný segment
}
}
void vlniciVoda() {
// Efekt výrazného vlnění vody mezi jednotlivými diodami
for(int j = 0; j < 255; j+=10) { // Zvýšení kroku změny jasu
for(int i = 0; i < 6; i++) {
int brightness = map(j, 0, 255, 0, 255); // Postupné zvýšení jasu
pixels2.setPixelColor(i, pixels2.Color(brightness, brightness, 255)); // Nastavení barvy a jasu pixelu
}
pixels2.show();
delay(35); // Zkrácení zpoždění pro rychlejší vlnění
}
for(int j = 255; j >= 0; j-=10) { // Zvýšení kroku změny jasu
for(int i = 0; i < 6; i++) {
int brightness = map(j, 0, 255, 0, 255); // Postupné snížení jasu
pixels2.setPixelColor(i, pixels2.Color(brightness, brightness, 255)); // Nastavení barvy a jasu pixelu
}
pixels2.show();
delay(35); // Zkrácení zpoždění pro rychlejší vlnění
}
}
void cervenyScanner() {
// Efekt červeného skeneru s dlouhou stopou
for(int j = 0; j < NUMPIXELS * 2; j++) { // Vytvoření dlouhé stopy
for(int i = 0; i < NUMPIXELS; i++) {
int pixelIndex = (j + i) % NUMPIXELS; // Index pixelu posunutý o aktuální hodnotu j
int brightness = map(abs(j - NUMPIXELS) - abs(i - NUMPIXELS), 0, NUMPIXELS, 255, 0); // Postupné snižování jasu podle pozice
pixels1.setPixelColor(pixelIndex, pixels1.Color(brightness, 0, 0)); // Nastavení barvy a jasu pixelu
}
pixels1.show();
delay(10);
}
// Vymazání stopy
for(int i = 0; i < NUMPIXELS; i++) {
pixels1.setPixelColor(i, pixels1.Color(0, 0, 0)); // Vypnutí pixelu
}
pixels1.show();
}
void loop() {
// Měření vzdálenosti
int distance = filterMeasurement(distanceSensor.measureDistanceCm());
// Přepočet vzdálenosti pro výpočet objemu
int adjusted_distance = min(MAX_DISTANCE, max(FULL_DISTANCE, distance));
// Přemapování vzdálenosti na LED pásek
int current_Last_LED = map(adjusted_distance, FULL_DISTANCE, MAX_DISTANCE, 0, NUMPIXELS);
static int counter = 0; // Počítadlo pro efekt duhy
counter++; // Inkrementace počítadla
// Spuštění efektu duhy každých pět cyklů
if (counter % 13 == 0) {
duhaEfekt();
}
// Nastavení barev pixelů na LED pásku
if (objem_v_litreach(adjusted_distance) <= 120) {
// Pokud je objem v litrech roven 0, spusť efekt červeného skeneru
cervenyScanner();
} else {
// Jinak nastav LED pásek podle stavu hladiny
for(int i = 0; i < NUMPIXELS; i++) {
if(i < current_Last_LED) {
pixels1.setPixelColor(i, 100, 50, 50); // Nastavení barvy pixelu na modrou podle stavu hladiny
} else {
pixels1.setPixelColor(i, 0, 0, 255); // Nastavení barvy pixelu na červenou, pokud nesvítí
}
}
}
pixels1.show(); // Odeslání aktualizovaných barev pixelů na hardware.
// Výpočet objemu v litrech na základě naměřené vzdálenosti
float objem_litru = objem_v_litreach(adjusted_distance) * pocet_nadrzi;
// Zobrazení hladiny v nádrži na LCD displeji (v procentech)
int hladinaProcent = map(adjusted_distance, FULL_DISTANCE, MAX_DISTANCE, 0, 100);
zobrazHladinuNaLCD(hladinaProcent);
// Zobrazení celkového počtu litrů na LCD displeji (celé číslo)
lcd.setCursor(0, 1);
lcd.print("CELKEM: ");
lcd.print((int)objem_litru);
lcd.print(" l ");
// Efekt mírně se vlnící vody
vlniciVoda();
delay(1000); // Zpoždění pro snížení četnosti aktualizace
}