Xin chào các bạn đến với bài viết về Mạch Timer bật tắt thiết bị dùng DS1307 và ESP8266 cài đặt thời gian thông qua Websever. Ứng dụng vào những nơi như đồng ruộng, đường đi, nhà kho,…. Để bật tắt đèn hoặc một số thiết bị khác…
- Linh kiện thì mình dùng:
+ ESP8266 ( CHIP ESP 12F)
+ Module thời gian thực DS1307
+ Relay 5V
+ Và một số linh kiện khác như điện trở, ams1117,… - Về sơ đồ nguyên lý mình thiết kế trên Altium:
- Mạch In PCB 2 lớp mình ghép mạch đặc bên trung nếu bạn nào cần có thể tham khảo file nguyên lý và layout tại đây nha.
- Về phần code các nội dung được sử dụng:
+ EEPROM: dùng để lưu thời gian bật và thời gian tắt khi setup để mất điện không bị reset dữ liệu
+ HTML + JS: nhúng giao diện website lên ESP8266 để setup thời gian bật tắt
- Nội dung code:
Ở đây mình dùng thư viện RTClib dùng để dọc data giờ và phút trên ds1307 và thư viện EEPROM.
- Tiếp đến là khai báo đối tượng:
//Khai báo thông tin wifi
const char* ssid = “HAO NGUYEN”;
const char* password = “0907014149”;
//Khai báo đối tượng webserver, sử dụng port 80
IPAddress ip(192, 168, 4, 1);
IPAddress gateway(192, 168, 4, 1);
IPAddress subnet(255, 255, 255, 0);
ESP8266WebServer server(80);
RTC_DS1307 rtc;
//Khai báo chân LED
const int LED_PIN = 2;
const int RL = 14;
const int SET = 12;
int tt=0;
int time_on = 0;
int time_off = 0;
int timem, gio, phut;
- Khai báo mã nguồn phần này mình để file ở đây nha ae có thể tải về tại nó hơi dài
- hàm void setup();
//Hàm setup
void setup() {
Serial.begin(115200);
pinMode(0, INPUT_PULLUP);
pinMode(RL, OUTPUT);
pinMode(SET, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
digitalWrite(RL, LOW);
EEPROM.begin(12);
time_on = EEPROM.read(2)*100+EEPROM.read(3);
time_off = EEPROM.read(4)*100+EEPROM.read(5);
Serial.println(time_on);
Serial.println(time_off);
delay(3000);
digitalWrite(14, HIGH);
if(!digitalRead(0))
{
tt = 1;
}
if(tt == 1)
{
WiFi.mode(WIFI_AP); // Thiết lập chế độ access point
WiFi.softAPConfig(ip, gateway, subnet); // Thiết lập địa chỉ IP, gateway và subnet mask
WiFi.softAP(ssid, password);
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.on("/", handleRoot);
server.on("/setTime", HTTP_GET, handleSetTime);
server.onNotFound(handleNotFound);
server.begin();
Serial.println("Webserver started");
}
while(! rtc.begin()) {
Serial.println(".");
delay(100);
}
}
ở đây mình dùng địa chỉ eeprom 2 và 3 để lưu giờ và phút thời gian bật đèn và 4 5 để lưu thời gian tắt đèn. Nếu không dùng eeprom thì khi mất điện ta phải setup lại từ đầu.
Chuyển ESP sang chết độ access point nghĩa lại esp sẽ phát 1 wifi ra để cho điện thoại truy cập để setup thời gian.
Delay 3s để khi ấn nút reset nếu muốn cài lại thời gian thì lúc này ta ấn phím BOOT trên ESP để vào chế độ setup còn mặc định thì nó sẽ tự chạy theo giờ đã lưu trên EEPROM
- Một số hàm khai báo mã nguồn
void handleRoot() {
//Gửi biến chứa mã nguồn html cho người dùng
server.send(200, "text/html", html);
}
void handleNotFound() {
//Gửi mã lỗi 404 cho người dùng
server.send(404, "text/html", "Khong tim thay trang Web");
}
- hàm dùng để tách giá trị thời gian bật và tắt:
void handleSetTime() {
if (server.hasArg("time_on") && server.hasArg("time_off")) {
time_on = server.arg("time_on").toInt(); // Lấy giá trị time_on
time_off = server.arg("time_off").toInt(); // Lấy giá trị time_off
Serial.print("Time On: ");
Serial.println(time_on);
Serial.print("Time Off: ");
Serial.println(time_off);
EEPROM.write(2, time_on/100);
EEPROM.commit();
EEPROM.write(3, time_on%100);
EEPROM.commit();
EEPROM.write(4, time_off/100);
EEPROM.commit();
EEPROM.write(5, time_off%100);
EEPROM.commit();
tt=2;
}
server.send(200, "text/plain", "Time set successfully");
}
Vì thời gian mình đã ghép lại trước khi đưa về esp . VD: 14h 35p thì nó sẽ có dạng 1435 nên khi đưa về và lưu vào eeprom ta phải tách ra. Do 1 địa chỉ trên eeprom chỉ lưu dc từ 0 - 256, nêu nếu muốn lấy 14h thì chia 100 và lấy phút thì % cho 100.
thời gian on vs off khi đọc từ eeprom sẽ được ghép lại như sau:
time_on = EEPROM.read(2)*100+EEPROM.read(3);
time_off = EEPROM.read(4)*100+EEPROM.read(5);
- Và cuối cùng là hàm loop
//Hàm loop
void loop() {
if(tt==1)
{
server.handleClient();
}
if(tt==2)
{
server.close();
WiFi.mode(WIFI_OFF);
tt=0;
}
if(tt==0)
{
DateTime now = rtc.now();
gio = now.hour();
phut = now.minute();
timem = gio*100 + phut;
Serial.println(timem);
Serial.print("Time ON:");
Serial.println(time_on);
Serial.print("Time OFF:");
Serial.println(time_off);
if(time_off>time_on)
{
if((timem>=time_on) && (timem<=time_off))
{
digitalWrite(14, LOW);
}
else
{
if(!digitalRead(12))
{
digitalWrite(14, LOW);
}
else
digitalWrite(14, HIGH);
}
}
else
{
if((timem>=time_on) || (timem<=time_off))
{
digitalWrite(14, LOW);
}
else
{
if(!digitalRead(12))
{
digitalWrite(14, LOW);
}
else
digitalWrite(14, HIGH);
}
}
digitalWrite(2, LOW);
delay(3000);
digitalWrite(2, HIGH);
delay(3000);
}
}
nếu setup thời gian thì tt=1 thì hàm loop chỉ chạy web thôi nên không bị delay, sau khi setup xong thì sẽ tiến hành đóng websever, tắt wifi cho tiết kiệm năng lượng và cho esp không nóng trong quá trình hoạt động tránh bị treo (lệnh tắt chỉ thực hiện 1 lần sau đó tt sẽ quay về 0) thực hiện lệnh bật tắt đèn(hoặc thiết bị) dựa trên thời gian đã cài.
Thành phẩm: