/*#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Arduino_FreeRTOS.h>
// Cấu hình màn hình LCD I2C
LiquidCrystal_I2C lcd(0x27, 16, 2); // Địa chỉ I2C có thể khác nhau, kiểm tra trước khi chạy
#define LED1_PIN 4
#define LED2_PIN 2
#define BUTTON_PIN 7
void TaskBlinkLED1(void *pvParameters);
void TaskBlinkLED2(void *pvParameters);
void TaskLCD(void *pvParameters);
void TaskButton(void *pvParameters);
volatile bool led1State = false;
volatile bool led2State = false;
volatile bool toggleMode = false; // Chế độ bật/tắt xen kẽ
void setup() {
// Cài đặt chân LED và nút nhấn
pinMode(LED1_PIN, OUTPUT);
pinMode(LED2_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP); // Sử dụng điện trở kéo lên
// Khởi động LCD
lcd.init();
lcd.backlight();
// Tạo các Task điều khiển LED
xTaskCreate(TaskBlinkLED1, "BlinkLED1", 128, NULL, 2, NULL);
xTaskCreate(TaskBlinkLED2, "BlinkLED2", 128, NULL, 2, NULL);
// Tạo Task hiển thị LCD
xTaskCreate(TaskLCD, "LCDTask", 256, NULL, 1, NULL);
// Tạo Task điều khiển nút nhấn
xTaskCreate(TaskButton, "ButtonTask", 128, NULL, 3, NULL);
}
void loop() {
// Không cần code trong loop vì FreeRTOS sẽ quản lý các task.
}
void TaskBlinkLED1(void *pvParameters) {
(void) pvParameters;
for (;;) {
if (!toggleMode) {
led1State = true;
digitalWrite(LED1_PIN, HIGH);
vTaskDelay(2000 / portTICK_PERIOD_MS); // Bật 2 giây
led1State = false;
digitalWrite(LED1_PIN, LOW);
vTaskDelay(3000 / portTICK_PERIOD_MS); // Tắt 3 giây
}
}
}
void TaskBlinkLED2(void *pvParameters) {
(void) pvParameters;
for (;;) {
if (!toggleMode) {
led2State = true;
digitalWrite(LED2_PIN, HIGH);
vTaskDelay(2500 / portTICK_PERIOD_MS); // Bật 2.5 giây
led2State = false;
digitalWrite(LED2_PIN, LOW);
vTaskDelay(500 / portTICK_PERIOD_MS); // Tắt 0.5 giây
}
}
}
void TaskLCD(void *pvParameters) {
(void) pvParameters;
for (;;) {
// Xóa màn hình và hiển thị trạng thái LED
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("LED1: ");
lcd.print(led1State ? "ON " : "OFF");
lcd.setCursor(0, 1);
lcd.print("LED2: ");
lcd.print(led2State ? "ON " : "OFF");
vTaskDelay(500 / portTICK_PERIOD_MS); // Cập nhật mỗi 0.5 giây
}
}
void TaskButton(void *pvParameters) {
(void) pvParameters;
bool buttonState;
bool lastButtonState = HIGH;
for (;;) {
buttonState = digitalRead(BUTTON_PIN);
// Phát hiện nhấn nút (chuyển từ HIGH -> LOW)
if (buttonState == LOW && lastButtonState == HIGH) {
toggleMode = !toggleMode; // Chuyển chế độ
// Điều khiển LED xen kẽ nếu ở chế độ toggle
if (toggleMode) {
led1State = true;
led2State = false;
digitalWrite(LED1_PIN, HIGH);
digitalWrite(LED2_PIN, LOW);
} else {
// Khôi phục trạng thái ban đầu
led1State = false;
led2State = false;
digitalWrite(LED1_PIN, LOW);
digitalWrite(LED2_PIN, LOW);
}
}
lastButtonState = buttonState;
vTaskDelay(50 / portTICK_PERIOD_MS); // Debouncing
}
}
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Arduino_FreeRTOS.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Địa chỉ I2C của màn hình LCD
#define LED1_PIN 4
#define LED2_PIN 2
#define BUTTON_PIN 3 // Chân nút nhấn
void TaskBlinkLED(void *pvParameters);
void TaskLCD(void *pvParameters);
void TaskButton(void *pvParameters);
volatile bool led1State = false; // Trạng thái LED 1
volatile bool led2State = false; // Trạng thái LED 2
volatile int buttonPressCount = 0; // Đếm số lần nhấn nút
volatile bool toggleLED = false; // Trạng thái bật tắt xen kẽ
void setup() {
pinMode(LED1_PIN, OUTPUT);
pinMode(LED2_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP); // Sử dụng pull-up cho nút nhấn
lcd.init();
lcd.backlight();
// Tạo Task cho bật tắt LED
xTaskCreate(TaskBlinkLED, "BlinkLED", 128, NULL, 2, NULL);
// Tạo Task hiển thị LCD
xTaskCreate(TaskLCD, "LCDTask", 256, NULL, 1, NULL);
// Tạo Task cho nút nhấn
xTaskCreate(TaskButton, "ButtonTask", 128, NULL, 3, NULL);
}
void loop() {
// Không cần code trong loop vì FreeRTOS sẽ quản lý các task.
}
void TaskBlinkLED(void *pvParameters) {
(void) pvParameters;
for (;;) {
if (buttonPressCount % 2 == 0) { // Chế độ chạy bình thường
// Bật LED 1 và tắt LED 2
led1State = true;
digitalWrite(LED1_PIN, HIGH);
vTaskDelay(2000 / portTICK_PERIOD_MS); // LED 1 bật trong 2 giây
led1State = false;
digitalWrite(LED1_PIN, LOW);
vTaskDelay(3000 / portTICK_PERIOD_MS); // Tắt trong 3 giây
// Bật LED 2 và tắt LED 1
led2State = true;
digitalWrite(LED2_PIN, HIGH);
vTaskDelay(2500 / portTICK_PERIOD_MS); // LED 2 bật trong 2.5 giây
led2State = false;
digitalWrite(LED2_PIN, LOW);
vTaskDelay(500 / portTICK_PERIOD_MS); // Tạm dừng giữa các chu kỳ
} else { // Chế độ xen kẽ
// Bật LED 1 và tắt LED 2
led1State = true;
digitalWrite(LED1_PIN, HIGH);
led2State = false;
digitalWrite(LED2_PIN, LOW);
vTaskDelay(500 / portTICK_PERIOD_MS); // LED 1 bật trong 0.5 giây
led1State = false;
digitalWrite(LED1_PIN, LOW);
vTaskDelay(500 / portTICK_PERIOD_MS); // Tắt trong 0.5 giây
// Bật LED 2 và tắt LED 1
led2State = true;
digitalWrite(LED2_PIN, HIGH);
led1State = false;
digitalWrite(LED1_PIN, LOW);
vTaskDelay(500 / portTICK_PERIOD_MS); // LED 2 bật trong 0.5 giây
led2State = false;
digitalWrite(LED2_PIN, LOW);
vTaskDelay(500 / portTICK_PERIOD_MS); // Tạm dừng giữa các chu kỳ
}
}
}
void TaskLCD(void *pvParameters) {
(void) pvParameters;
for (;;) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("LED1: ");
lcd.print(led1State ? "ON " : "OFF");
lcd.setCursor(0, 1);
lcd.print("LED2: ");
lcd.print(led2State ? "ON " : "OFF");
vTaskDelay(500 / portTICK_PERIOD_MS); // Cập nhật mỗi 0.5 giây
}
}
void TaskButton(void *pvParameters) {
(void) pvParameters;
bool lastButtonState = HIGH; // Giả định trạng thái đầu tiên là không nhấn
for (;;) {
bool currentButtonState = digitalRead(BUTTON_PIN);
// Kiểm tra trạng thái của nút nhấn
if (lastButtonState == HIGH && currentButtonState == LOW) { // Nút được nhấn
buttonPressCount++; // Tăng số lần nhấn
toggleLED = buttonPressCount % 2 == 1; // Đảo trạng thái toggleLED
}
lastButtonState = currentButtonState;
vTaskDelay(50 / portTICK_PERIOD_MS); // Tạm dừng 50ms để tránh nhấn lặp
}
}