#include <Arduino.h>
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <HX711.h>
// --- Definicje Pinów ---
// MAX7219 (SPI)
#define MAX7219_CS_PIN 5 // Pin CS (LOAD)
// Piny DIN i CLK (MOSI i SCK) są domyślne dla SPI na ESP32 (GPIO 23 i 18)
// HX711
#define HX711_DT_PIN 2
#define HX711_SCK_PIN 4
// Przyciski
#define TARA_PIN 32
#define KALIBRACJA_PIN 33
// --- Definicje Wyświetlacza ---
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW // Typ sprzętu (FC16 jest najczęstszy)
#define MAX_DEVICES 4 // Ile modułów 8x8 połączonych
// --- Obiekty ---
// Obiekt Parola, który zarządza wyświetlaczem
MD_Parola p = MD_Parola(HARDWARE_TYPE, MAX7219_CS_PIN, MAX_DEVICES);
HX711 scale;
// --- Zmienne Globalne ---
float kalibracyjnyCzynnik = -400.0; // Przykładowa wartość startowa dla 5kg - KALIBRUJ!
float waga = 0;
unsigned long czasNacisnieciaTara = 0;
bool przyciskTaraAktywny = false;
// Zmienna do przechowywania ostatnio wyświetlanej wagi, aby nie odświeżać bez potrzeby
char ostatniaWaga[50] = "";
// Jednostki wagi
enum Jednostka { GRAMY, KILOGRAMY, UNCE };
Jednostka aktualnaJednostka = GRAMY;
// --- Funkcje ---
void setupDisplay() {
p.begin();
p.setIntensity(5); // Ustaw jasność (0-15)
p.displayClear();
p.displayText("HELLO", PA_CENTER, 1000, 1000, PA_PRINT, PA_NO_EFFECT);
}
void setupButtons() {
pinMode(TARA_PIN, INPUT_PULLUP);
pinMode(KALIBRACJA_PIN, INPUT_PULLUP);
}
void setupHX711() {
scale.begin(HX711_DT_PIN, HX711_SCK_PIN);
scale.set_scale(kalibracyjnyCzynnik);
scale.tare();
}
void wyswietlWiadomosc(const char* msg, textEffect_t effectIn, textEffect_t effectOut) {
p.displayText(msg, PA_CENTER, 50, 2000, effectIn, effectOut);
}
void changeUnit() {
aktualnaJednostka = static_cast<Jednostka>((aktualnaJednostka + 1) % 3);
}
void performTare() {
scale.tare();
wyswietlWiadomosc("Tarowanie...", PA_SCROLL_LEFT, PA_SCROLL_UP);
}
void performCalibration() {
wyswietlWiadomosc("Kalibracja", PA_SCROLL_LEFT, PA_SCROLL_UP);
delay(2000); // Dajemy czas na animację
while(digitalRead(KALIBRACJA_PIN) == LOW);
while(digitalRead(KALIBRACJA_PIN) == HIGH);
scale.tare();
wyswietlWiadomosc("Zerowanie OK", PA_SCROLL_LEFT, PA_SCROLL_UP);
delay(1500);
wyswietlWiadomosc("Poloz 100g", PA_SCROLL_LEFT, PA_SCROLL_UP);
delay(1500);
while(digitalRead(KALIBRACJA_PIN) == LOW);
while(digitalRead(KALIBRACJA_PIN) == HIGH);
float znanaWaga = 100.0;
long odczytSurowy = scale.get_units(10);
if (odczytSurowy != 0) {
kalibracyjnyCzynnik = odczytSurowy / znanaWaga;
scale.set_scale(kalibracyjnyCzynnik);
wyswietlWiadomosc("Kal OK!", PA_SCROLL_LEFT, PA_SCROLL_UP);
} else {
wyswietlWiadomosc("Blad!", PA_SCROLL_LEFT, PA_SCROLL_UP);
}
}
void checkButtons() {
if (digitalRead(TARA_PIN) == LOW) {
if (!przyciskTaraAktywny) {
przyciskTaraAktywny = true;
czasNacisnieciaTara = millis();
}
} else {
if (przyciskTaraAktywny) {
unsigned long czasTrzymania = millis() - czasNacisnieciaTara;
przyciskTaraAktywny = false;
if (czasTrzymania < 1000) {
performTare();
} else {
changeUnit();
}
}
}
static unsigned long ostatniCzasKalibracji = 0;
if (digitalRead(KALIBRACJA_PIN) == LOW && (millis() - ostatniCzasKalibracji > 500)) {
ostatniCzasKalibracji = millis();
performCalibration();
}
}
void setup() {
Serial.begin(115200);
setupDisplay();
setupButtons();
setupHX711();
}
void loop() {
checkButtons();
if (scale.is_ready()) {
waga = scale.get_units(5);
} else {
waga = 0;
}
// Formatuj wagę do wyświetlenia
char aktualnaWaga[50];
switch (aktualnaJednostka) {
case KILOGRAMY:
snprintf(aktualnaWaga, sizeof(aktualnaWaga), "%.3f kg", waga / 1000.0);
break;
case UNCE:
snprintf(aktualnaWaga, sizeof(aktualnaWaga), "%.2f oz", waga / 28.3495);
break;
case GRAMY:
default:
snprintf(aktualnaWaga, sizeof(aktualnaWaga), "%.1f g", waga);
break;
}
// Jeśli waga się zmieniła, zaktualizuj wyświetlacz
if (strcmp(aktualnaWaga, ostatniaWaga) != 0) {
strcpy(ostatniaWaga, aktualnaWaga);
p.displayText(aktualnaWaga, PA_LEFT, 100, 0, PA_PRINT, PA_NO_EFFECT);
}
// Animuj wyświetlacz (to jest kluczowa funkcja biblioteki Parola)
p.displayAnimate();
}