#include <Wire.h>
#include <U8g2lib.h>
#include <Servo.h>
// Khởi tạo OLED (U8g2 cho font chữ và biểu tượng)
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
// Khởi tạo servo
Servo sageServo;
// Cấu hình HC-SR04 và Buzzer
#define TRIG_PIN 5
#define ECHO_PIN 18
#define SERVO_PIN 13
#define BUZZER_PIN 12
// Danh sách câu triết lý tiếng Anh
const char* quotes[] = {
"Know yourself first.",
"Patience opens all doors.",
"Silence breeds wisdom.",
"A journey starts with one step.",
"Live in the present moment."
};
const int numQuotes = 5;
// Biến theo dõi thời gian và trạng thái
unsigned long lastCloseTime = 0;
unsigned long lastQuoteChange = 0;
bool isClose = false;
bool buzzerActive = false;
const long closeThreshold = 15 * 60 * 1000; // 15 phút (ms)
const long quoteInterval = 15 * 1000; // 15 giây (ms)
void setup() {
Serial.begin(115200);
u8g2.begin();
sageServo.attach(SERVO_PIN);
sageServo.write(0);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
// Hiển thị ban đầu
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(0, 20, "The Sage of the Desk");
u8g2.sendBuffer();
delay(2000);
}
int getDistance() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
return duration * 0.034 / 2; // Tính khoảng cách (cm)
}
void nodHead() {
sageServo.write(30);
delay(200);
sageServo.write(0);
delay(200);
sageServo.write(30);
delay(200);
sageServo.write(0);
}
void loop() {
// Đo khoảng cách
int distance = getDistance();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
// Theo dõi thời gian ở gần
if (distance < 30) {
if (!isClose) {
isClose = true;
lastCloseTime = millis();
}
} else {
isClose = false;
buzzerActive = false;
digitalWrite(BUZZER_PIN, LOW);
}
// Kích hoạt buzzer sau 15 phút
if (isClose && (millis() - lastCloseTime >= closeThreshold)) {
buzzerActive = true;
digitalWrite(BUZZER_PIN, HIGH); // Bật active buzzer
}
// Xử lý hiển thị và hành động
if (distance > 30) {
// Khoảng cách > 30cm: Mắt ngủ
u8g2.drawStr(40, 20, "- -");
u8g2.drawStr(0, 40, "Meditating...");
} else if (distance < 10) {
// Khoảng cách < 10cm: Mắt to nhỏ + thông điệp
u8g2.drawStr(40, 20, "O_o");
u8g2.drawStr(0, 40, "So close, do you");
u8g2.drawStr(0, 50, "really like me?");
} else {
// Khoảng cách ≤ 30cm: Mắt cười + gật đầu + triết lý
static bool firstClose = true;
static unsigned long nodTime = 0;
if (firstClose) {
u8g2.drawStr(40, 20, "^_^");
u8g2.drawStr(0, 40, "Hi Thai,...");
nodHead();
nodTime = millis();
firstClose = false;
} else if (millis() - nodTime < 2000) {
u8g2.drawStr(40, 20, "^_^");
u8g2.drawStr(0, 40, "Hi Thai,...");
} else {
// Hiển thị triết lý ngẫu nhiên mỗi 15 giây
if (millis() - lastQuoteChange >= quoteInterval) {
lastQuoteChange = millis();
}
int quoteIndex = (millis() / quoteInterval) % numQuotes;
u8g2.drawStr(40, 20, "^_^");
u8g2.drawStr(0, 40, quotes[quoteIndex]);
}
}
if (!isClose) {
firstClose = true; // Reset trạng thái khi ra khỏi vùng gần
}
u8g2.sendBuffer();
delay(100);
}