21:33 05/04/2023
Bộ định thời và ngắt ESP8266 sử dụng Arduino IDE (NodeMCU)
Bộ định thời và ngắt ESP8266 sử dụng Arduino IDE
(NodeMCU)
Trong hướng dẫn này, bạn sẽ học cách sử dụng ngắt và hẹn giờ với ESP8266
NodeMCU bằng Arduino IDE. Ngắt cho phép bạn phát hiện các thay đổi trong trạng thái
GPIO mà không cần phải liên tục kiểm tra giá trị hiện tại của nó. Với các ngắt, khi một
thay đổi được phát hiện, một sự kiện sẽ được kích hoạt (một chức năng được gọi).
Ví dụ: chúng tơi sẽ phát hiện chuyển động bằng cảm biến chuyển động PIR: khi phát
hiện chuyển động, ESP8266 bắt đầu hẹn giờ và bật đèn LED trong một số giây được
xác định trước. Khi bộ hẹn giờ kết thúc đếm ngược, đèn LED sẽ tự động tắt.
Để tạo ngắt, hãy gọi attachmentInterrupt() và chuyển làm đối số chân ngắt GPIO, ISR
(chức năng được gọi) và chế độ. Hàm ISR phải được khai báo thuộc tính
ICACHE_RAM_ATTR . Chế độ có thể là THAY ĐỔI , TĂNG hoặc GIẢM .
attachInterrupt(digitalPinToInterrupt(GPIO), ISR, mode);
Trước khi tiếp tục với hướng dẫn này, bạn nên cài đặt tiện ích bổ sung ESP8266 trong
Arduino IDE của mình. Làm theo hướng dẫn này để Cài đặt ESP8266 trong Arduino IDE
, nếu bạn chưa cài đặt.
Giới thiệu ngắt ESP8266
Ngắt rất hữu ích để làm cho mọi thứ diễn ra tự động trong các chương trình vi điều khiển
và có thể giúp giải quyết các vấn đề về thời gian.
/>
1/12
21:33 05/04/2023
Bộ định thời và ngắt ESP8266 sử dụng Arduino IDE (NodeMCU)
Với các ngắt, bạn không cần phải liên tục kiểm tra giá trị pin hiện tại. Khi một thay đổi
được phát hiện, một sự kiện được kích hoạt – một chức năng được gọi. Chức năng này
được gọi là thường trình dịch vụ ngắt (ISR).
Khi một ngắt xảy ra, bộ xử lý dừng thực hiện chương trình chính để thực hiện một tác
vụ, sau đó quay lại chương trình chính như minh họa trong hình bên dưới.
Điều này đặc biệt hữu ích để kích hoạt một hành động bất cứ khi nào phát hiện chuyển
động hoặc bất cứ khi nào nhấn nút ấn mà không cần phải liên tục kiểm tra trạng thái của
nó.
Hàm AttachInterrupt()
Để thiết lập một ngắt trong Arduino IDE, bạn sử dụng hàm attachmentInterrupt() , nhận
làm đối số: chân ngắt GPIO, tên của hàm sẽ được thực thi và chế độ:
attachInterrupt(digitalPinToInterrupt(GPIO), ISR, mode);
Chân ngắt GPIO
Đối số đầu tiên là ngắt GPIO. Bạn nên sử dụng digitalPinToInterrupt(GPIO) để đặt GPIO
thực tế làm chân ngắt. Ví dụ: nếu bạn muốn sử dụng GPIO 14 làm ngắt, hãy sử dụng:
digitalPinToInterrupt(14)
ESP8266 hỗ trợ các ngắt trong bất kỳ GPIO nào, ngoại trừ GPIO16.
ISR
Đối số thứ hai của hàm attachmentInterrupt() là tên của hàm sẽ được gọi mỗi khi ngắt
được kích hoạt – thường trình dịch vụ ngắt (ISR).
Chức năng ISR phải càng đơn giản càng tốt để bộ xử lý quay lại thực hiện chương trình
chính một cách nhanh chóng.
/>
2/12
21:33 05/04/2023
Bộ định thời và ngắt ESP8266 sử dụng Arduino IDE (NodeMCU)
Cách tiếp cận tốt nhất là báo hiệu mã chính rằng ngắt đã xảy ra bằng cách sử dụng một
biến tồn cục và trong vịng lặp () kiểm tra và xóa cờ đó rồi thực thi mã.
ISR cần phải có ICACHE_RAM_ATTR trước định nghĩa chức năng để chạy mã ngắt
trong RAM. chế độ ngắt
Đối số thứ ba là chế độ và có 3 chế độ khác nhau:
THAY ĐỔI: để kích hoạt ngắt bất cứ khi nào chân thay đổi giá trị - ví dụ từ CAO
xuống THẤP hoặc THẤP lên CAO;
FALLING: khi chân chuyển từ CAO xuống THẤP;
RISING: để kích hoạt khi chân đi từ THẤP lên CAO.
Ví dụ của chúng tôi, sẽ sử dụng chế độ RISING, bởi vì khi cảm biến chuyển động PIR
phát hiện chuyển động, GPIO mà nó được kết nối sẽ chuyển từ THẤP sang CAO.
Giới thiệu Bộ hẹn giờ ESP8266
Đối với hướng dẫn này, chúng tôi sẽ sử dụng bộ hẹn giờ. Chúng tôi muốn đèn LED sáng
trong một số giây định trước sau khi phát hiện chuyển động. Thay vì sử dụng hàm
delay() chặn mã của bạn và không cho phép bạn làm bất kỳ điều gì khác trong một số
giây xác định, chúng tôi sẽ sử dụng bộ đếm thời gian.
độ trễ () so với millis ()
Hàm delay() chấp nhận một số int làm đối số. Con số này biểu thị thời gian tính bằng mili
giây mà chương trình phải đợi cho đến khi chuyển sang dòng mã tiếp theo. delay(time
in
milliseconds);
Khi bạn gọi độ trễ (1000), chương trình của bạn sẽ dừng trên dịng đó trong 1 giây.
delay() là một chức năng chặn. Các chức năng chặn ngăn chương trình thực hiện bất kỳ
điều gì khác cho đến khi nhiệm vụ cụ thể đó được hồn thành. Nếu bạn cần nhiều tác vụ
xảy ra cùng một lúc, bạn không thể sử dụng delay() . Đối với hầu hết các dự án, bạn nên
tránh sử dụng độ trễ và thay vào đó hãy sử dụng bộ hẹn giờ.
/>
3/12
21:33 05/04/2023
Bộ định thời và ngắt ESP8266 sử dụng Arduino IDE (NodeMCU)
Sử dụng một hàm gọi là millis() , bạn có thể trả về số mili giây đã trơi qua kể từ khi
chương trình bắt đầu lần đầu tiên. millis();
Tại sao chức năng đó hữu ích? Bởi vì bằng cách sử dụng một số phép tốn, bạn có thể
dễ dàng xác minh lượng thời gian đã trôi qua mà không chặn mã của mình.
Nháy đèn LED bằng millis() (khơng chậm trễ)
Nếu bạn chưa quen với hàm millis() , chúng tôi khuyên bạn nên đọc phần này. Nếu bạn
đã quen thuộc với bộ hẹn giờ, bạn có thể bỏ qua dự án cảm biến chuyển động PIR.
Đoạn mã sau đây cho biết cách bạn có thể sử dụng hàm millis() để tạo dự án nháy mắt.
Nó bật đèn LED trong 1000 mili giây rồi tắt.
/>
4/12
21:33 05/04/2023
Bộ định thời và ngắt ESP8266 sử dụng Arduino IDE (NodeMCU)
/*********
Rui Santos
Complete project details at
*********/
// constants won't change. Used here to set a pin number :
const int ledPin = 26;
// the number of the LED pin
// Variables will change : int ledState = LOW;
ledState used to set the LED
//
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;
// will store last time LED was updated
// constants won't change : const long interval = 1000;
which to blink (milliseconds)
// interval at
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}
void loop() {
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long
currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
}
else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
Xem mã thô
Cách thức hoạt động của mã
Chúng ta hãy xem xét kỹ hơn bản phác thảo nhấp nháy này hoạt động mà khơng cần
hàm delay() (thay vào đó, nó sử dụng hàm millis() ).
Về cơ bản, mã này trừ thời gian đã ghi trước đó ( previousMillis ) khỏi thời gian hiện tại (
currentMillis ). Nếu phần còn lại lớn hơn khoảng thời gian (trong trường hợp này là 1000
/>
5/12
Bộ định thời và ngắt ESP8266 sử dụng Arduino IDE (NodeMCU)
21:33 05/04/2023
mili giây), chương trình sẽ cập nhật biến previousMillis thành thời điểm hiện tại và bật
hoặc tắt đèn LED.
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
(...)
Bởi vì đoạn mã này khơng bị chặn, bất kỳ mã nào nằm bên ngồi câu lệnh if đầu tiên đó
sẽ hoạt động bình thường.
Bây giờ bạn có thể hiểu rằng bạn có thể thêm các tác vụ khác vào hàm loop() của mình
và mã của bạn sẽ vẫn nhấp nháy đèn LED mỗi giây.
Bạn có thể tải mã này lên ESP8266 của mình để kiểm tra. Đèn LED trên bo mạch sẽ
nhấp nháy mỗi giây.
ESP8266 NodeMCU với Cảm biến chuyển động PIR
Trong phần này, bạn sẽ tìm hiểu cách phát hiện chuyển động bằng cảm biến chuyển
động PIR bằng cách sử dụng ngắt và hẹn giờ trong mã của bạn.
Bộ phận bắt buộc
Dưới đây là danh sách các phần cần thiết để hoàn thành hướng dẫn này:
ESP8266 (đọc bảng phát triển ESP8266 tốt nhất )
Cảm biến chuyển động PIR (AM312)
/>
6/12
Bộ định thời và ngắt ESP8266 sử dụng Arduino IDE (NodeMCU)
21:33 05/04/2023
đèn LED 5mm
điện trở 330
Ohm bánh mì
dây nhảy
Sơ đồ
Lắp cảm biến chuyển động PIR và đèn LED vào ESP8266 của bạn. Chúng tôi sẽ kết nối
đèn LED với GPIO 12 (D6) và chân dữ liệu cảm biến chuyển động PIR với GPIO 14
(D5).
/>
7/12
21:33 05/04/2023
Bộ định thời và ngắt ESP8266 sử dụng Arduino IDE (NodeMCU)
Đề xuất đọc: Hướng dẫn tham khảo sơ đồ chân ESP8266 Quan trọng: Cảm biến
chuyển động Mini AM312 PIR được sử dụng trong dự án này hoạt động ở mức 3,3V.
Tuy nhiên, nếu bạn đang sử dụng một cảm biến chuyển động PIR khác như HC-
/>
8/12
21:33 05/04/2023
Bộ định thời và ngắt ESP8266 sử dụng Arduino IDE (NodeMCU)
SR501, thì nó sẽ hoạt động ở mức 5V. Bạn có thể sửa đổi nó để hoạt động ở mức
3,3V hoặc chỉ cần cấp nguồn cho nó bằng chân Vin.
Hình dưới đây cho thấy sơ đồ chân của cảm biến chuyển động AM312 PIR.
Mã số
Sau khi đấu dây mạch như trong sơ đồ nguyên lý, hãy sao chép mã được cung cấp vào
Arduino IDE của bạn.
Bạn có thể tải lên mã nguyên trạng hoặc bạn có thể sửa đổi số giây đèn LED sáng sau
khi phát hiện chuyển động. Chỉ cần thay đổi biến timeSeconds bằng số giây bạn muốn.
/*********
Rui Santos
Complete project details at
*********/
#define timeSeconds 10
// Set GPIOs for LED and PIR Motion Sensor
const int led = 12; const int motionSensor
= 14;
// Timer: Auxiliary variables
unsigned long now = millis();
unsigned long lastTrigger = 0;
boolean startTimer = false;
// Checks if motion was detected, sets LED HIGH and starts a timer
ICACHE_RAM_ATTR void detectsMovement() {
Serial.println("MOTION DETECTED!!!");
digitalWrite(led, HIGH);
startTimer =
true;
lastTrigger = millis();
}
void setup() {
// Serial port for debugging purposes
/>
9/12
21:33 05/04/2023
Bộ định thời và ngắt ESP8266 sử dụng Arduino IDE (NodeMCU)
Serial.begin(115200);
// PIR Motion Sensor mode INPUT_PULLUP
pinMode(motionSensor, INPUT_PULLUP);
// Set motionSensor pin as interrupt, assign interrupt function and set RISING mode
attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING);
// Set LED to LOW
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
}
void loop() {
// Current time
now = millis();
// Turn off the LED after the number of seconds defined in the timeSeconds variable
if(startTimer && (now - lastTrigger > (timeSeconds*1000))) {
Serial.println("Motion stopped...");
digitalWrite(led, LOW);
startTimer =
false;
}
}
Xem mã thô
Cách thức hoạt động của mã
Chúng ta hãy xem mã.
Bắt đầu bằng cách gán hai chân GPIO cho các biến led và motionSensor .
const int led = 12; const
int motionSensor = 14;
Sau đó, tạo các biến cho phép bạn đặt bộ hẹn giờ để tắt đèn LED sau khi phát hiện
chuyển động.
unsigned long now = millis();
unsigned long lastTrigger = 0;
boolean startTimer = false;
Biến now giữ thời gian hiện tại. Biến lastTrigger giữ thời gian khi cảm biến PIR phát hiện
chuyển động. startTimer là một biến boolean khởi động bộ hẹn giờ khi phát hiện chuyển
động . cài đặt()
Trong setup() , hãy bắt đầu bằng cách khởi tạo cổng nối tiếp ở tốc độ 115200 baud.
Serial.begin(115200);
Đặt cảm biến chuyển động PIR là INPUT_PULLUP .
pinMode(motionSensor, INPUT_PULLUP);
/>
10/12
Bộ định thời và ngắt ESP8266 sử dụng Arduino IDE (NodeMCU)
21:33 05/04/2023
Để đặt chân cảm biến PIR làm ngắt, hãy sử dụng hàm attachmentInterrupt() như đã mơ
tả
trước
đó.
attachInterrupt(digitalPinToInterrupt(motionSensor),
detectsMovement,
RISING);
Chân sẽ phát hiện chuyển động là GPIO 14 và nó sẽ gọi hàm detectMovement() ở chế
độ RISING .
Đèn LED là ĐẦU RA có trạng thái bắt đầu ở mức THẤP .
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
vòng()
Hàm loop () liên tục chạy đi chạy lại. Trong mỗi vòng lặp, biến now được cập nhật với
thời gian hiện tại. now
= millis();
Khơng có gì khác được thực hiện trong loop() . Tuy nhiên, khi phát hiện chuyển động,
chức năng detectsMovement() được gọi vì chúng ta đã đặt ngắt trước đó trong setup() .
Hàm detectMovement() in một thơng báo trong Màn hình nối tiếp, bật đèn LED, đặt biến
boolean startTimer thành true và cập nhật biến lastTrigger với thời gian hiện tại.
ICACHE_RAM_ATTR void detectsMovement() {
Serial.println("MOTION DETECTED!!!");
digitalWrite(led, HIGH);
startTimer =
true;
lastTrigger = millis(); }
Sau bước này, mã sẽ quay trở lại loop() . Lần này, biến startTimer là true. Vì vậy, khi
thời gian được xác định bằng giây đã trôi qua (kể từ khi phát hiện chuyển động), câu
lệnh if sau đây sẽ đúng.
if(startTimer && (now - lastTrigger > (timeSeconds*1000))) {
Serial.println("Motion stopped…");
digitalWrite(led, LOW);
startTimer = false;
}
Thông báo “Chuyển động đã dừng…” sẽ được in trong Màn hình Nối tiếp, đèn LED bị tắt
và biến startTimer được đặt thành false.
trình diễn
Tải mã lên ESP8266 của bạn. Đảm bảo rằng bạn đã chọn đúng bo mạch và cổng COM.
Mở Màn hình nối tiếp ở tốc độ truyền 115200.
/>
11/12
21:33 05/04/2023
Bộ định thời và ngắt ESP8266 sử dụng Arduino IDE (NodeMCU)
Di chuyển bàn tay của bạn trước cảm biến PIR. Đèn LED sẽ bật và một thông báo được
in trong Màn hình nối tiếp có nội dung “ PHÁT HIỆN CHUYỂN ĐỘNG!!! ”. Sau 10 giây,
đèn LED sẽ tắt.
kết thúc
Tóm lại, các ngắt rất hữu ích để phát hiện sự thay đổi trong trạng thái GPIO và ngay lập
tức kích hoạt một chức năng. Bạn cũng đã học được rằng bạn nên sử dụng bộ hẹn giờ
để viết mã không chặn.
/>
12/12