#include <Arduino.h>
#include <Wire.h>
#include "HX711.h"
#include "U8g2lib.h"
#include "ezButton.h"
#include <Preferences.h>
// --- KONFIGURACJA PINÓW ---
const int LOADCELL_DOUT_PIN = 6;
const int LOADCELL_SCK_PIN = 7;
const int TARA_BUTTON_PIN = 2;
const int CAL_BUTTON_PIN = 3;
// --- USTAWIENIA WAGI ---
const int CALIBRATION_HOLD_TIME_MS = 2000;
const int PRECISION_HOLD_TIME_MS = 1000; // Czas do uznania wciśnięcia za długie
// Dostępne odważniki kalibracyjne w gramach
const int calibrationWeights[] = {100, 200, 250, 500, 750, 1000};
const int numWeights = sizeof(calibrationWeights) / sizeof(int);
// --- INICJALIZACJA OBIEKTÓW ---
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
HX711 scale;
ezButton taraButton(TARA_BUTTON_PIN);
ezButton calButton(CAL_BUTTON_PIN);
Preferences preferences;
// --- ZMIENNE GLOBALNE ---
float calibration_factor = -7050.0;
int currentUnit = 0; // 0: g, 1: dkg, 2: kg
int currentPrecision = 0; // 0: 1g, 1: 0.1g
// --- ZMIENNE DO OBSŁUGI DŁUGIEGO WCIŚNIĘCIA PRZYCISKU TARA ---
unsigned long taraPressStartTime = 0;
bool taraIsBeingHeld = false;
bool taraLongPressHandled = false;
// Funkcje pomocnicze
void drawDisplay();
void runCalibration();
void loadSettings();
void saveSettings();
void setup() {
Serial.begin(115200);
Serial.println("Start wagi cyfrowej...");
pinMode(TARA_BUTTON_PIN, INPUT_PULLUP);
pinMode(CAL_BUTTON_PIN, INPUT_PULLUP);
taraButton.setDebounceTime(50);
calButton.setDebounceTime(50);
u8g2.begin();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB10_tr);
u8g2.drawStr(10, 22, "Waga Startuje...");
u8g2.sendBuffer();
delay(1500);
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
long startTime = millis();
while(digitalRead(CAL_BUTTON_PIN) == LOW){ // Czytamy stan bezpośrednio
if (millis() - startTime > CALIBRATION_HOLD_TIME_MS) {
runCalibration();
}
}
loadSettings();
scale.set_scale(calibration_factor);
scale.tare();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB10_tr);
u8g2.drawStr(30, 22, "Gotowa!");
u8g2.sendBuffer();
delay(1000);
}
void loop() {
taraButton.loop();
calButton.loop();
// --- RĘCZNA OBSŁUGA DŁUGIEGO/KRÓTKIEGO WCIŚNIĘCIA PRZYCISKU TARA ---
int taraState = taraButton.getState();
// 1. Wykryto wciśnięcie przycisku (zbocze opadające)
if (taraState == LOW && !taraIsBeingHeld) {
taraPressStartTime = millis();
taraIsBeingHeld = true;
taraLongPressHandled = false;
}
// 2. Przycisk jest trzymany
else if (taraState == LOW && taraIsBeingHeld) {
// Sprawdź, czy minął czas dla długiego wciśnięcia i czy akcja nie została już wykonana
if (millis() - taraPressStartTime > PRECISION_HOLD_TIME_MS && !taraLongPressHandled) {
// AKCJA DLA DŁUGIEGO WCIŚNIĘCIA
currentPrecision = (currentPrecision + 1) % 2; // Zmiana 0 -> 1 -> 0
saveSettings();
Serial.print("Zmieniono precyzje na: ");
Serial.println(currentPrecision == 0 ? "1 g" : "0.1 g");
taraLongPressHandled = true; // Zaznacz, że akcja została wykonana
}
}
// 3. Wykryto puszczenie przycisku (zbocze narastające)
else if (taraState == HIGH && taraIsBeingHeld) {
// Jeśli nie wykonano akcji długiego wciśnięcia, to było to krótkie wciśnięcie
if (!taraLongPressHandled) {
// AKCJA DLA KRÓTKIEGO WCIŚNIĘCIA
Serial.println("Tarowanie...");
scale.tare();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB10_tr);
u8g2.drawStr(25, 22, "Tarowanie...");
u8g2.sendBuffer();
delay(500);
}
taraIsBeingHeld = false; // Zresetuj stan
}
// --- Obsługa przycisku Kalibracja (tylko krótkie wciśnięcie) ---
if (calButton.isPressed()) {
currentUnit = (currentUnit + 1) % 3; // Zmiana 0 -> 1 -> 2 -> 0
saveSettings();
Serial.print("Zmieniono jednostke na: ");
if (currentUnit == 0) Serial.println("g");
if (currentUnit == 1) Serial.println("dkg");
if (currentUnit == 2) Serial.println("kg");
}
// Aktualizacja wyświetlacza
drawDisplay();
}
// Pozostałe funkcje (drawDisplay, runCalibration, loadSettings, saveSettings)
// pozostają bez zmian - wklej tutaj te z poprzedniej odpowiedzi.
// Poniżej wklejam je dla kompletności.
void drawDisplay() {
float weight = scale.get_units(5); // Uśredniony odczyt
String weightStr = "";
String unitStr = "";
// Formatowanie wagi i jednostki
switch (currentUnit) {
case 0: // g
unitStr = "g";
if (currentPrecision == 0) weightStr = String(round(weight));
else weightStr = String(weight, 1);
break;
case 1: // dkg
unitStr = "dkg";
weight = weight / 10.0;
weightStr = String(weight, 2);
break;
case 2: // kg
unitStr = "kg";
weight = weight / 1000.0;
weightStr = String(weight, 3);
break;
}
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB14_tr); // Używamy czcionki o wysokości 14px
String displayText = weightStr + " " + unitStr;
int textWidth = u8g2.getStrWidth(displayText.c_str());
int x = (128 - textWidth) / 2;
if (x < 0) x = 0;
u8g2.drawStr(x, 22, displayText.c_str());
u8g2.sendBuffer();
}
void runCalibration() {
int selectedWeightIndex = 0;
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(0, 12, "Oproznij wage i");
u8g2.drawStr(0, 28, "wcisnij 'Kalibracja'");
u8g2.sendBuffer();
while(!calButton.isPressed()){ calButton.loop(); }
scale.set_scale();
scale.tare();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(0, 12, "Wybierz odwaznik:");
u8g2.drawStr(0, 28, "Tara: Zmiana, Kal: OK");
u8g2.sendBuffer();
delay(2000);
while (true) {
taraButton.loop();
calButton.loop();
if (taraButton.isPressed()) {
selectedWeightIndex = (selectedWeightIndex + 1) % numWeights;
}
if (calButton.isPressed()) {
break;
}
String weightText = String(calibrationWeights[selectedWeightIndex]) + " g";
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB14_tr);
int textWidth = u8g2.getStrWidth(weightText.c_str());
u8g2.drawStr((128 - textWidth) / 2, 22, weightText.c_str());
u8g2.sendBuffer();
delay(100);
}
int known_mass = calibrationWeights[selectedWeightIndex];
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
String placeText = "Poloz " + String(known_mass) + " g";
u8g2.drawStr(0, 12, placeText.c_str());
u8g2.drawStr(0, 28, "i wcisnij 'Kalibracja'");
u8g2.sendBuffer();
while(!calButton.isPressed()){ calButton.loop(); }
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB10_tr);
u8g2.drawStr(20, 22, "Kalibruje...");
u8g2.sendBuffer();
calibration_factor = scale.get_units(10) / known_mass;
preferences.begin("waga-app", false);
preferences.putFloat("calFactor", calibration_factor);
preferences.end();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(10, 12, "Kalibracja");
u8g2.drawStr(25, 28, "Zakonczona!");
u8g2.sendBuffer();
delay(2000);
ESP.restart();
}
void loadSettings() {
preferences.begin("waga-app", true);
calibration_factor = preferences.getFloat("calFactor", calibration_factor);
currentUnit = preferences.getInt("unit", 0);
currentPrecision = preferences.getInt("precision", 0);
preferences.end();
Serial.println("Wczytano ustawienia:");
Serial.print(" Wspolczynnik kalibracji: "); Serial.println(calibration_factor);
Serial.print(" Jednostka: "); Serial.println(currentUnit);
Serial.print(" Precyzja: "); Serial.println(currentPrecision);
}
void saveSettings() {
preferences.begin("waga-app", false);
preferences.putInt("unit", currentUnit);
preferences.putInt("precision", currentPrecision);
preferences.end();
Serial.println("Zapisano ustawienia jednostki/precyzji.");
}Loading
xiao-esp32-c3
xiao-esp32-c3
Loading
ssd1306
ssd1306