#include <Encoder.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <Fonts/FreeSerifBold18pt7b.h>
#define TFT_CS 4
#define TFT_DC 2
#define BUTTON_START 25
#define BUTTON_STOP 26
#define BUTTON_RESET 27
#define ENCODER_CLK 22
#define ENCODER_DT 21
#define ENCODER_SW 14
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
Encoder myEnc(ENCODER_CLK, ENCODER_DT);
long oldPosition = -999;
int syringeSelection = 0; // 0 = 10ml, 1 = 20ml, 2 = 50ml
String syringeTypes[3] = {"10ml", "20ml", "50ml"};
bool syringeSelected = false; // Kiểm tra xem đã chọn bơm tiêm chưa
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50; // Debounce delay cho các nút
int speedDigits[4] = {0, 0, 0, 0}; // Lưu từng chữ số của tốc độ: AB.CD
int currentDigit = 0; // Vị trí chữ số hiện tại đang được điều chỉnh (0-3)
String speedUnit = "ml/h"; // Đơn vị mặc định
bool isEditing = false; // Kiểm tra xem có đang điều chỉnh tốc độ không
// Hàm hiển thị các tùy chọn bơm tiêm
void displaySyringeOptions() {
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(30, 60);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.print("Select Syringe:");
for (int i = 0; i < 3; i++) {
tft.setCursor(30, 100 + i * 40);
if (i == syringeSelection) {
tft.setTextColor(ILI9341_YELLOW); // Hiển thị loại bơm đang được chọn
} else {
tft.setTextColor(ILI9341_WHITE);
}
tft.print(syringeTypes[i]);
}
}
// Hàm hiển thị loại bơm tiêm đã được chọn
void displaySelectedSyringe() {
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(10, 10);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.print("Loai Bom: ");
tft.print(syringeTypes[syringeSelection]);
}
// Hàm hiển thị tốc độ
void displaySpeed() {
tft.setCursor(30, 100);
tft.setTextSize(3);
// Hiển thị tốc độ dưới dạng AB.CD với chữ số đang chỉnh sửa được in đậm
for (int i = 0; i < 4; i++) {
if (i == currentDigit) {
tft.setTextColor(ILI9341_YELLOW); // Chữ số đang chỉnh sửa
} else {
tft.setTextColor(ILI9341_WHITE); // Các chữ số khác
}
tft.print(speedDigits[i]);
if (i == 1) tft.print("."); // Thêm dấu chấm
}
tft.print(" ");
tft.print(speedUnit);
}
// Hàm bắt đầu bơm
void startPump() {
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(30, 100);
tft.setTextColor(ILI9341_GREEN);
tft.print("Starting Pump...");
Serial.println("Pump started");
}
// Hàm dừng bơm
void stopPump() {
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(30, 100);
tft.setTextColor(ILI9341_RED);
tft.print("Pump Stopped");
Serial.println("Pump stopped");
}
// Hàm reset hiển thị
void resetDisplay() {
syringeSelected = false; // Cho phép chọn lại loại bơm tiêm
displaySyringeOptions();
Serial.println("Display reset");
}
void setup() {
Serial.begin(115200);
// Setup for display
tft.begin(40000000); // Tăng tốc SPI cho màn hình
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
// Setup for buttons
pinMode(BUTTON_START, INPUT_PULLUP);
pinMode(BUTTON_STOP, INPUT_PULLUP);
pinMode(BUTTON_RESET, INPUT_PULLUP);
// Setup for rotary encoder button (SW pin)
pinMode(ENCODER_SW, INPUT_PULLUP);
// Hiển thị các tùy chọn bơm tiêm khi khởi động
displaySyringeOptions();
}
void loop() {
unsigned long currentTime = millis();
// Kiểm tra nút nhấn để khởi động/dừng/reset bơm tiêm
if ((currentTime - lastDebounceTime) > debounceDelay) {
if (digitalRead(BUTTON_START) == LOW) {
startPump();
lastDebounceTime = currentTime;
}
if (digitalRead(BUTTON_STOP) == LOW) {
stopPump();
lastDebounceTime = currentTime;
}
if (digitalRead(BUTTON_RESET) == LOW) {
resetDisplay();
lastDebounceTime = currentTime;
}
}
// Xử lý di chuyển khi xoay rotary encoder để chọn loại bơm tiêm
static int lastClkState = HIGH;
int clkState = digitalRead(ENCODER_CLK);
if (clkState != lastClkState && clkState == LOW) { // Phát hiện thay đổi của CLK
int dtState = digitalRead(ENCODER_DT);
if (dtState != clkState) {
syringeSelection++;
if (syringeSelection > 2) syringeSelection = 0;
} else {
syringeSelection--;
if (syringeSelection < 0) syringeSelection = 2;
}
displaySyringeOptions();
}
lastClkState = clkState; // Cập nhật trạng thái CLK
// Nhấn nút trên rotary encoder để chọn bơm tiêm
if (digitalRead(ENCODER_SW) == LOW && !syringeSelected && (currentTime - lastDebounceTime) > debounceDelay) {
syringeSelected = true;
Serial.print("Selected Syringe: ");
Serial.println(syringeTypes[syringeSelection]);
displaySelectedSyringe();
delay(1000); // Chờ 1 giây trước khi hiển thị tốc độ
displaySpeed(); // Hiển thị tốc độ
lastDebounceTime = currentTime;
isEditing = true; // Bắt đầu điều chỉnh tốc độ
}
// Nếu đang điều chỉnh tốc độ
if (isEditing) {
// Xử lý điều chỉnh giá trị của từng chữ số khi xoay rotary encoder
static int lastSpeedClkState = HIGH;
int speedClkState = digitalRead(ENCODER_CLK);
if (speedClkState != lastSpeedClkState && speedClkState == LOW) { // Phát hiện thay đổi của CLK
int dtState = digitalRead(ENCODER_DT);
if (dtState != speedClkState) {
speedDigits[currentDigit]++;
if (speedDigits[currentDigit] > 9) speedDigits[currentDigit] = 0;
} else {
speedDigits[currentDigit]--;
if (speedDigits[currentDigit] < 0) speedDigits[currentDigit] = 9;
}
displaySpeed(); // Cập nhật tốc độ hiển thị
delay(50); // Thêm một khoảng trễ nhỏ
}
lastSpeedClkState = speedClkState; // Cập nhật trạng thái CLK
// Nhấn nút trên rotary encoder để chuyển sang chữ số tiếp theo hoặc đổi đơn vị
if (digitalRead(ENCODER_SW) == LOW && (currentTime - lastDebounceTime) > debounceDelay) {
lastDebounceTime = currentTime;
currentDigit++;
if (currentDigit > 3) { // Nếu chỉnh xong 4 chữ số, chuyển đổi đơn vị
currentDigit = 0;
speedUnit = (speedUnit == "ml/h") ? "ml/p" : "ml/h"; // Chuyển đổi giữa ml/h và ml/p
}
displaySpeed(); // Cập nhật hiển thị tốc độ
}
}
}