#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Ustawienia sprzętowe
constexpr uint8_t I2C_ADDR = 0x27; // zmień na 0x3F jeśli Twój LCD ma inny adres
LiquidCrystal_I2C lcd(I2C_ADDR, 16, 2);
constexpr int PIN_POT = 34; // suwak potencjometru pod ADC1 (GPIO34)
// Ustawienia paska postępu
constexpr int LCD_COLS = 16;
constexpr int LCD_ROWS = 2;
constexpr int SEG_PER_CELL = 5; // 5 “pikseli” poziomych na znak
constexpr int BAR_STEPS = LCD_COLS * SEG_PER_CELL;
// Wygładzanie (anti-flicker)
constexpr float ALPHA = 0.2f; // 0..1 (0 = brak zmian, 1 = brak wygładzania)
constexpr uint32_t REFRESH_MS = 50; // odświeżanie co 50 ms
// Własne znaki do paska (1..5 kolumn wypełnienia)
byte bar1[8] = {0b10000,0b10000,0b10000,0b10000,0b10000,0b10000,0b10000,0b10000}; // 1/5
byte bar2[8] = {0b11000,0b11000,0b11000,0b11000,0b11000,0b11000,0b11000,0b11000}; // 2/5
byte bar3[8] = {0b11100,0b11100,0b11100,0b11100,0b11100,0b11100,0b11100,0b11100}; // 3/5
byte bar4[8] = {0b11110,0b11110,0b11110,0b11110,0b11110,0b11110,0b11110,0b11110}; // 4/5
byte bar5[8] = {0b11111,0b11111,0b11111,0b11111,0b11111,0b11111,0b11111,0b11111}; // 5/5
float filtered = 0.0f;
uint32_t lastUpdate = 0;
void drawBar(int steps) {
// steps: 0..BAR_STEPS
if (steps < 0) steps = 0;
if (steps > BAR_STEPS) steps = BAR_STEPS;
lcd.setCursor(0, 0);
for (int i = 0; i < LCD_COLS; i++) {
int seg = steps - i * SEG_PER_CELL; // ile “pikseli” w tej komórce
if (seg <= 0) {
lcd.write(' '); // puste
} else if (seg >= SEG_PER_CELL) {
lcd.write(byte(4)); // w pełni wypełniona (bar5)
} else {
// seg: 1..4 -> bar1..bar4
lcd.write(byte(seg - 1));
}
}
}
void setup() {
// I2C na pinach 21 (SDA) i 22 (SCL) dla ESP32
Wire.begin(21, 22);
lcd.init();
lcd.backlight();
lcd.clear();
// Rejestracja własnych znaków (sloty 0..4)
lcd.createChar(0, bar1);
lcd.createChar(1, bar2);
lcd.createChar(2, bar3);
lcd.createChar(3, bar4);
lcd.createChar(4, bar5);
// Pierwszy odczyt jako start filtra
filtered = analogRead(PIN_POT);
}
void loop() {
uint32_t now = millis();
if (now - lastUpdate >= REFRESH_MS) {
int raw = analogRead(PIN_POT); // 0..4095 (12-bit)
filtered = ALPHA * raw + (1.0f - ALPHA) * filtered;
// mapowanie na kroki paska (0..80 dla 16x2)
int steps = map((int)filtered, 0, 4095, 0, BAR_STEPS);
drawBar(steps);
// Linia 2: procent + surowy ADC (czyści całą linię każdy cykl)
int percent = (int)((filtered * 100.0f) / 4095.0f + 0.5f);
lcd.setCursor(0, 1);
// Wypisz dokładnie 16 znaków, by nadpisać stare dane:
char buf[17];
snprintf(buf, sizeof(buf), "%3d%% ADC:%4d", percent, (int)filtered);
// Dopełnij spacjami do 16 kolumn
for (int i = 0; i < 16; ++i) {
char c = (buf[i] != '\0') ? buf[i] : ' ';
lcd.write(c);
}
lastUpdate = now;
}
}