Timer/counter trên avr/arduino


In this guide, you’ll learn how lớn use interrupts và timers with the ESP8266 NodeMCU using Arduino IDE. Interrupts allow you khổng lồ detect changes in the GPIO state without the need khổng lồ constantly kiểm tra its current value. With interrupts, when a change is detected, an event is triggered (a function is called).

Bạn đang xem: Timer/counter trên avr/arduino


This is especially useful to lớn trigger an action whenever motion is detected or whenever a pushbutton is pressed without the need to constantly check its state.

attachInterrupt() Function

To set an interrupt in the Arduino IDE, you use the attachInterrupt() function, that accepts as arguments: the GPIO interrupt pin, the name of the function khổng lồ be executed, & mode:

attachInterrupt(digitalPinToInterrupt(GPIO), ISR, mode);

GPIO interrupt pin

The first argument is a GPIO interrupt. You should use digitalPinToInterrupt(GPIO) to mix the actual GPIO as an interrupt pin. For example, if you want to lớn use GPIO 14 as an interrupt, use:

digitalPinToInterrupt(14)The ESP8266 supports interrupts in any GPIO, except GPIO16.


The second argument of the attachInterrupt() function is the name of the function that will be called every time the interrupt is triggered – the interrupt service routine (ISR).

The ISR function should be as simple as possible, so the processor gets back to lớn the execution of the main program quickly.

The best approach is lớn signal the main code that the interrupt has happened by using a global variable and within the loop() kiểm tra & clear that flag, và execute code.

ISRs need lớn have sầu ICACHE_RAM_ATTR before the function definition to run the interrupt code in RAM.

Interrupt modes

The third argument is the mode and there are 3 different modes:

CHANGE: to trigger the interrupt whenever the pin changes value – for example from HIGH lớn LOW or LOW to HIGH;FALLING: for when the pin goes from HIGH to lớn LOW;RISING: to lớn trigger when the pin goes from LOW lớn HIGH.

For our example, will be using the RISING mode, because when the PIR motion sensor detects motion, the GPIO it is connected lớn goes from LOW khổng lồ HIGH.

Introducing ESP8266 Timers


ESP8266 NodeMCU with PIR Motion Sensor

In this section, you’ll learn how khổng lồ detect motion with a PIR motion sensor using interrupts & timers in your code.

Parts Required

Here’s a menu of the parts required to lớn complete this tutorial:

You can use the preceding liên kết or go directly khổng lồ MakerAdvisor.com/tools khổng lồ find all the parts for your projects at the best price!


Recommended reading: ESP8266 Pinout Reference Guide

Important: the Mini AM312 PIR Motion Sensor used in this project operates at 3.3V. However, if you’re using another PIR motion sensor like the HC-SR501, it operates at 5V. You can either modify it lớn operate at 3.3V or simply power it using the Vin pin.

The following figure shows the AM312 PIR motion sensor pinout.


After wiring the circuit as shown in the schematic diagram, copy the code provided to your Arduino IDE.

You can upload the code as it is, or you can modify the number of seconds the LED is lit after detecting motion. Simply change the timeSeconds variable with the number of seconds you want.

/********* Rui Santos Complete project details at https://6struyenky.vn *********/#define timeSeconds 10// Set GPIOs for LED & PIR Motion Sensorconst int led = 12;const int motionSensor = 14;// Timer: Auxiliary variablesunsigned long now = millis();unsigned long lastTrigger = 0;boolean startTimer = false;// Checks if motion was detected, sets LED HIGH và starts a timerICACHE_RAM_ATTR void detectsMovement() Serial.println("MOTION DETECTED!!!"); digitalWrite(led, HIGH); startTimer = true; lastTrigger = millis();void setup() // Serial port for debugging purposes Serial.begin(115200); // PIR Motion Sensor mode INPUT_PULLUP. pinMode(motionSensor, INPUT_PULLUP); // Set motionSensor pin as interrupt, assign interrupt function and phối 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; View raw code

How the Code Works

Let’s take a look at the code.

Start by assigning two GPIO pins to the led & motionSensor variables.

Xem thêm: Toàn C Ảnh Cưới Công Vinh Thủy Tiên Và Công Vinh, Lộ Ảnh Cưới Tuyệt Đẹp Của Công Vinh

const int led = 12;const int motionSensor = 14;Then, create variables that will allow you phối a timer to lớn turn the LED off after motion is detected.

unsigned long now = millis();unsigned long lastTrigger = 0;boolean startTimer = false;The now variable holds the current time. The lastTrigger variable holds the time when the PIR sensor detects motion. The startTimer is a boolean variable that starts the timer when motion is detected.


In the setup(), start by initializing the serial port at 115200 baud rate.

Serial.begin(115200);Set the PIR Motion sensor as an INPUT_PULLUP..

pinMode(motionSensor, INPUT_PULLUP);To phối the PIR sensor pin as an interrupt, use the attachInterrupt() function as described earlier.

attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING);The pin that will detect motion is GPIO 14 & it will điện thoại tư vấn the function detectsMovement() on RISING mode.

The LED is an OUTPUT whose state starts at LOW.

pinMode(led, OUTPUT);digitalWrite(led, LOW);loop()The loop() function is constantly running over & over again. In every loop, the now variable is updated with the current time.

now = millis();Nothing else is done in the loop(). But, when motion is detected, the detectsMovement() function is called because we’ve set an interrupt previously in the setup().

The detectsMovement() function prints a message in the Serial Monitor, turns the LED on, sets the startTimer boolean variable khổng lồ true and updates the lastTrigger variable with the current time.

ICACHE_RAM_ATTR void detectsMovement() Serial.println("MOTION DETECTED!!!"); digitalWrite(led, HIGH); startTimer = true; lastTrigger = millis();After this step, the code goes baông chồng khổng lồ the loop(). This time, the startTimer variable is true. So, when the time defined in seconds has passed (since motion was detected), the following if statement will be true.

if(startTimer && (now - lastTrigger > (timeSeconds*1000))) Serial.println("Motion stopped…"); digitalWrite(led, LOW); startTimer = false;The “Motion stopped…” message will be printed in the Serial Monitor, the LED is turned off, & the startTimer variable is phối to lớn false.


Upload the code to lớn your ESP8266. Make sure you have theright board and COM port selected.

mở cửa the Serial Monitor at a baud rate of 115200.

Move your h& in front of the PIR sensor. The LED should turn on, và a message is printed in the Serial Monitor saying “MOTION DETECTED!!!”. After 10 seconds the LED should turn off.

Xem thêm: Điện Thoại Nokia X2 00 Zin 100% Nhẹ Trong Các Dòng X2, Điện Thoại Nokia X2

Wrapping Up

To sum up, interrupts are useful lớn detect a change in a GPIO state & instantly trigger a function. You’ve also learned that you should use timers to write non-blocking code.

We hope you’ve sầu found this tutorial useful. We have sầu other tutorials on how lớn handle interrupts using MicroPybé và using ESP32:

Chuyên mục: Tin Tức