/***** Blynk IoT - điền thông tin của bạn *****/
#define BLYNK_TEMPLATE_ID "TMPL6b6tDHeg-"
#define BLYNK_TEMPLATE_NAME "ThongBaoQuaTai"
#define BLYNK_AUTH_TOKEN "ebbmCnq6lPeQj7FZtiTp3hguHIKCYabD"
/*********************************************/
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "HX711.h"
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
// HX711
#define DT 19
#define SCK 18
HX711 scale;
// Nút nhấn
#define TARE_BUTTON 12
#define ADD_BUTTON 14
#define RESET_BUTTON 27
// Calibration
float calibration_factor = 420;
// Biến tổng
float totalWeight = 0;
int countAdd = 0;
// Biến chống dội
bool lastAddState = HIGH;
bool lastTareState = HIGH;
bool lastResetState = HIGH;
// Timer cho Blynk
BlynkTimer timer;
// Ngưỡng cảnh báo
float MAX_WEIGHT = 4.0; // 4kg
// Biến lưu cân nặng hiện tại (đọc 1 lần trong loop)
float currentWeight = 0;
void sendOverloadToBlynk(float weight) {
if (weight > MAX_WEIGHT) {
Serial.println("⚠️ WARNING: Quá tải > 4kg !!!");
lcd.setCursor(0, 0);
lcd.print("Overload >4kg ");
// Gửi sự kiện cảnh báo
Blynk.logEvent("overload", "Cảnh báo: Trọng lượng vượt quá 4kg!");
}
}
void setup() {
Serial.begin(115200);
// LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Digital Scale");
// HX711
scale.begin(DT, SCK);
scale.set_scale(calibration_factor);
scale.tare();
// Buttons
pinMode(TARE_BUTTON, INPUT_PULLUP);
pinMode(ADD_BUTTON, INPUT_PULLUP);
pinMode(RESET_BUTTON, INPUT_PULLUP);
// Kết nối Blynk (dùng port 80 để dễ chạy trên Wokwi)
Serial.println("Connecting to Blynk...");
Blynk.begin(auth, ssid, pass, "blynk.cloud", 80);
// Gửi dữ liệu lên Blynk mỗi 1 giây
timer.setInterval(1000L, []() {
Blynk.virtualWrite(V0, currentWeight); // cân hiện tại
Blynk.virtualWrite(V1, totalWeight); // tổng số cân đã cộng
Blynk.virtualWrite(V2, countAdd); // tổng số lần cộng
sendOverloadToBlynk(currentWeight);
});
delay(2000);
lcd.clear();
}
void loop() {
Blynk.run();
timer.run();
// 🔹 Đọc 1 lần giá trị cân trong loop
currentWeight = scale.get_units(5);
// Nút Tare
bool tareState = digitalRead(TARE_BUTTON);
if (lastTareState == HIGH && tareState == LOW) {
scale.tare();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Tare Done");
Serial.println("Button Tare pressed -> Reset cân về 0");
delay(200);
}
lastTareState = tareState;
// Nút cộng
bool addState = digitalRead(ADD_BUTTON);
if (lastAddState == HIGH && addState == LOW) {
totalWeight += currentWeight;
countAdd++;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Added: ");
lcd.print(currentWeight, 2);
lcd.print(" kg");
Serial.print("Button ADD pressed -> Add ");
Serial.print(currentWeight, 2);
Serial.println(" kg");
delay(200);
}
lastAddState = addState;
// Nút reset
bool resetState = digitalRead(RESET_BUTTON);
if (lastResetState == HIGH && resetState == LOW) {
totalWeight = 0;
countAdd = 0;
scale.tare();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("All Reset");
Serial.println("Button RESET pressed -> Xóa tổng + reset cân");
delay(200);
}
lastResetState = resetState;
// Hiển thị LCD
lcd.setCursor(0, 0);
if (currentWeight > MAX_WEIGHT) {
lcd.print("Overload >4kg ");
} else {
lcd.print("W:");
lcd.print(currentWeight, 2);
lcd.print("kg ");
}
lcd.setCursor(0, 1);
lcd.print("T:");
lcd.print(totalWeight, 2);
lcd.print("kg ");
lcd.print(countAdd);
lcd.print("x ");
}