Arduino – Motion Sensor | Arduino Tutorial

Arduino - Motion Sensor | Arduino Tutorial Самолеты

Analogread() values at 20, 40, 60 and 80 cm from the sensor

AnalogRead() values were taken by looking at the serial monitor while the Arduino program was run from my laptop computer. Distances were measured using a standard 1 foot ruler with cm markings and a white infrared reflective paper was placed perpendicularly at the desired distances.

The results can be found tabulated below along with a plot of distance vs analogRead() values. Most notably we find what resembles an exponentially decaying relationship with an R-squared value of 0.985 between distance and our experimental analogRead() values. This seem to fall perfectly in line with the behavior predicted above in the datasheets.

Arduino – motion sensor | arduino tutorial

When you approach some places that the doors are automatically opened/closed, the light bulbs are automatically turned on/off or escalator is automatically activated, have you ever make a question: “How can it do that?” ? If yes, this tutorial not only answers but also tells you how to make it. Let’s start!

HC-SR501 PIR sensor is a sensor that can detect the motion of humans (or animals). It’s widely used to detect the presence of humans in many applications (automatically turning ON/OFF light bulb, opening/closing the door, activating/deactivating escalator, detecting an intruder …)

The HC-SR501 motion sensor has 3 pins:

The HC-SR501 also has one jumper and two potentiometers, which are used to adjust the sensor’s setting. Firstly, keep the default setting. The detail is described in the Advanced Uses section.

The HC-SR501 sensor detects motion based on the change of infrared radiation from the moving object. To be detected by the HC-SR501 sensor, the object must meet two conditions:


Humans and animals naturally emit the infrared. Therefore, the sensor can detect the movement of humans and animals.

OUTPUT pin’s state:

The above video illustrates how the motion sensor works in principle. In practice, the motion sensor works a little bit different, depending on the sensor setting (described in the Advanced Uses section)

The sensor itself does NOT detect the presence of humans, the sensor just detects the motion. We use Arduino (or MCU) to deduce the presence of humans basing on motion detection from the sensor, according to the following rule:

This rule is incorrect in a practical case: the humans are present in sensor range but NOT moving. The motion is NOT detected. The Arduino (or MCU) deduces that human is NOT present.

For example, your meeting room uses the motion sensor to automatically turn on/off light, the light is turned on automatically when people move into the room. During the meeting time, if everybody sits still without moving, motion is NOT detected ⇒ human is NOT present ⇒ light is turned off automatically. To turn on the light, someone needs to move.

However, this issue is NOT serious and the sensor is cheap. Therefore, The sensor’s widely used to detect the human in many application.

When an Arduino’s pin is configured as a digital input, It can read the state (LOW or HIGH) of anything it connected to.

By connecting the Arduino’s pin with the OUTPUT pin of the HC-SR501 sensor, we can use the Arduino code to check the value of the OUTPUT pin to detect the motion.

We are considering to make the video tutorials. If you think the video tutorials are essential, please subscribe to our YouTube channel to give us motivation for making the videos.

Смотрите про коптеры:  Радиоуправляемые самолеты для начинающих

This section is the in-depth knowledge. DON’T worry if you don’t understand. Ignore this section if it overloads you, and come back in another day. Keep reading the next sections.

As mentioned above, we can change adjust the sensor’s setting via one jumper and two potentiometers.

This potentiometer is used to adjust the detection range (approximately 3 meters to 7 meters).

We can adjust the potentiometer to achieve the desired range (a value in between 3m and 7m)

This potentiometer is used to adjust the time delay.

The meaning of time delay is explained in combination with Repeat Trigger in the next part.

There is a jumper, which is used to select trigger modes: single trigger or repeatable trigger.

Let’s call time delay setting (is set via Time Delay Adjuster) is time_delay. Suppose that you keep moving in the range of the sensor in a long time (called motion_time) (several times longer than time_delay)

To see how the trigger modes work, let’s make a test. Set Time Delay Adjuster fully anti-clockwise to the time delay to 3 seconds.

As we can see, in a single trigger mode, the sensor triggers two or three times. In the repeatable trigger mode, the sensor triggers only one time.

When human is detected NOT present, the automation system will take action after a time delay.

The time delay can be set on the motion sensor and Arduino code:

If we do NOT set a timeout in the Arduino code, the timeout is equal to the time delay in the sensor’s setting.

If we set a timeout in the Arduino code, the timeout is the sum of time delay in the sensor’s setting and time delay in the Arduino code.

Suppose that the repeatable trigger mode is set. Delay in this code is set to 30 seconds. It means the delay time is equal to 30 seconds plus time_delay, which is set on the sensor’s setting (via Time Delay Adjuster).

Use the motion sensor to do one of the following projects:

The above code also works with the following motion sensors:

Arduino – touch sensor | arduino tutorial

Touch sensor (also called touch button or touch switch) is widely used to control devices (e,g. touchable lamp). It has the same functionality as a button. It is used instead of the button on many new devices because it makes the product look neat.

In this tutorial, we will learn how to use the touch sensor with Arduino.

We will run four example codes:

If the sensor is touched, turn LED on. If the sensor is not touched, turn LED off.

We are considering to make the video tutorials. If you think the video tutorials are essential, please subscribe to our YouTube channel to give us motivation for making the videos.

The above code also works with the following touch sensors:


For complete documentation of this library, see the qtr-sensors-arduino documentation. If you are already on that page, see the QTRSensors class reference.


Several example sketches are available that show how to use the library. You can access them from the Arduino IDE by opening the “File” menu, selecting “Examples”, and then selecting “QTRSensors”. If you cannot find these examples, the library was probably installed incorrectly and you should retry the installation instructions above.


The QTRSensors library supports Pololu’s second-generation dimmable QTR and QTRX reflectance sensor boards, as well as older QTR sensors. Before continuing, careful reading of the QTR Reflectance Sensor Application Note is recommended.

Software and code

Inspiration was found by researching online where I found this useful tutorial which explained an Arduino coding setup: 

Смотрите про коптеры:  Как сделать радиоуправляемый катер для доставки прикормки на рыбалке


This is a library for the Arduino IDE that helps interface with Pololu QTR reflectance sensors.

Supported platforms

This library is designed to work with the Arduino IDE versions 1.8.x or later; we have not tested it with earlier versions. This library should support any Arduino-compatible board, including the Pololu A-Star controllers.

Version history

  • 4.0.0 (2023-03-15): Major library rewrite: instead of a hierarchy of classes for different sensor types, the library now provides a single QTRSensors class, and instances of this class can be configured for a specific sensor type. Configuration of sensor pins and other settings is now done using more human-readable class methods instead of constructor parameters. Support for calibration using the odd/even read modes has been added.
  • 3.1.0 (2023-08-08): Added support for dimmable QTR and QTRX sensors with separate control of odd/even emitter banks.
  • 3.0.0 (2023-08-16): Updated library to work with the Arduino Library Manager.
  • 2.1.2 (2023-12-03): Corrected readLine() behavior to work with multiple instances (thanks to Tandy Carmichael).
  • 2.1.1 (2023-05-02): Minor improvements to read() behavior and whitespace cleanup.
  • 2.1.0 (2023-04-18): Improved existing examples and added two new examples for printing raw values.
  • 2.0.2 (2023-04-17): Made constructors initialize pointers to avoid possible problems.
  • 2.0.1 (2023-09-13): Added a 200 us delay after emitter state changes to ensure sensors do not start being sampled before the LEDs turn on/off.
  • 2.0.0 (2023-02-14): Initial release of library on GitHub (with Arduino 1.0 compatibility).

What is the effective range of operation:

The answer to this question was also found by researching online and pulling up the datasheet for this particular product. In the end, I found three different datasheets, but all of them appear to agree with one another and indicate that the effective range was 10 to 80cm. Although there were various documents, they all seem to verify one another.

Пробуждение по сторожевому таймеру

В основе сторожевого таймера (WatchDog Timer) лежит многоразрядный счетчик, снабженный собственным тактовым генератором. Если таймер включен, то значение счетчика будет постоянно увеличиваться и при его переполнении будет сгенерирован сигнал сброса МК.

Чтобы избежать сброса по переполнению программа должна постоянно обнулять счетчик специальной командой. Если программа зависла и счетчик не был вовремя сброшен, то сигнал сброса выведет МК из зависшего состояния, таким образом повышается стабильность системы на основе МК.

Наличие собственного тактового генератора и способность работать когда другие узлы МК остановлены позволяют использовать сторожевой таймер для вывода МК из спящего режима. Для этого следует настроить его на генерацию прерывания, а не сигнала сброса. Также необходимо задать значение предделителя, чтобы получить интересующую задержку.

#include<avr/wdt.h>#include<avr/sleep.h>volatile bool f = 0;

voidsetup() {

voidloop() {
  WDTCSR |= (1 << WDIE); 
  sleep_mode(); digitalWrite(LED_BUILTIN, f);

ISR (WDT_vect) {
  f = !f;

Здесь задается интервал сторожевого таймера и режим его работы для генерации прерываний через 2 секунды. После выполнения функции sleep_mode() Ардуино переходит в спящий режим. При генерации прерывания от сторожевого таймера и пробуждении МК, управление передается соответствующему обработчику (ISR (WDT_vect)).

Для получения более длительных интервалов можно использовать цикл и переводить МК в спящий режим внутри цикла. Но лучше использовать для этого часы реального времени с будильником.

Пробуждение при нажатии кнопки

Пробуждение микроконтроллера при замыкании/размыкании контактов, будь то кнопка, геркон, энкодер и т.п. – это пробуждение по внешнему прерыванию (INT) или по прерыванию изменения уровня (PCINT). Для работы с первыми в IDE Arduino предусмотрены удобные функции.

Для вторых ничего подобного в IDE нет, поэтому придется работать с регистрами микроконтроллера, отвечающими за настройку PCINT (хотя, наверняка, существуют библиотеки для работы с ними, я не искал). Для тех и других у меня есть подробные публикации с примерами использования:

, и 

Предположим, что микроконтроллер в нашем устройстве должен всегда спать, просыпаться при нажатии кнопки, подключенной к входу запроса прерывания INT0, что-то делать и снова засыпать. Вход запроса прерывания (для INT0 – это вывод D2 Ардуино) должен быть подтянут к питанию или земле.

#include<avr/sleep.h>#define INTERRUPT_PIN  2voidsetup() {

voidloop() {
  byte b = 0;
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), myISR, FALLING);
  sleep_mode(); detachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN));

  Serial.println("Wake up!");
  while (b < 5) { if (digitalRead(INTERRUPT_PIN) == HIGH) 
      b  ; else
      b = 0; delay(1); 

void myISR() {


Скетч содержит достаточно комментариев, я поясню лишь назначение цикла 

Смотрите про коптеры:  Радиоуправляемые модели самолетов купить в "Мир Моделей"


. Все электромеханические коммутирующие устройства подвержены дребезгу контактов. В нашем случае дребезг на входе запроса прерывания будет воспринят микроконтроллером как многократное нажатие кнопки, в результате чего он будет выходить из спящего режима, выполнять заданный код и уходить в сон несколько раз подряд.

Чтобы этого не происходило мы откладываем уход в сон до момента отпускания кнопки и возвращения сигнала на входе D2 к высокому уровню. Если сигнал остается высоким в течение 5 выборок с интервалом в 1мс, то считаем, что он стабилизировался и можно снова переводить микроконтроллер в режим энергосбережения.

Если добавить в схему аппаратное подавление дребезга, то можно обойтись без описанного цикла.

Пробуждение при нажатии кнопки, уход в сон по таймауту

Другой пример: есть устройство с дисплеем, которое должно просыпаться при нажатии кнопки, а засыпать по истечении некоторого времени, чтобы пользователь успел увидеть всё необходимое на дисплее. В простейшем случае хватило бы задержки на несколько секунд перед уходом в сон.

#include<avr/sleep.h>#include<Wire.h>#include<LiquidCrystal_I2C.h>#define INTERRUPT_PIN  2 #define TIME_BEFORE_SLEEP 10000 
LiquidCrystal_I2C lcd(0x27, 20, 4);
unsignedlong tm = 0;
bool buttonPrev = 0;
bool f = 0;

voidsetup() {
  lcd.print("Time: 12:00");

voidloop() {
  if (millis() - tm > TIME_BEFORE_SLEEP) { 
    lcd.noBacklight(); attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), myISR, FALLING);
    sleep_mode(); detachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN));
    tm = millis();
    buttonPrev = 0;

  if (isButtonPressed(INTERRUPT_PIN)) {
    f = !f;
    if (f) lcd.print("Temp: 24C");
    else lcd.print("Time: 12:00");
    tm = millis();

void myISR() {


bool isButtonPressed(uint8_t pin) {
  if (digitalRead(pin) == HIGH) {
    buttonPrev = 1;
  elseif (buttonPrev) {
    buttonPrev = 0;
    return true;
  return false;

Здесь уход микроконтроллера в сон возможен только при выполнении условия: разница между текущим значением 


 и значением переменной 


 должно быть больше 10 секунд. Для того чтобы отложить сон, достаточно записать в 




, что и делается при пробуждении и при нажатии на кнопку.

Также в данном примере отключается подсветка дисплея (текстовый дисплей типа 20*4 или 16*2) при переходе микроконтроллера в режим энергосбережения и включается при выходе из него. Сделано это в большей степени для демонстрации. В реальном же устройстве лучше отключать питание дисплея, поскольку он  не имеет режима энергосбережения, а отключение подсветки уменьшит ток недостаточно – экономия должна быть экономной.

Для минимизации энергопотребления необходимо активнее использовать энергосберегающие режимы, причем выбирать режим следует так, чтобы в нем функционировало минимально необходимое количество узлов микроконтроллера. Также следует помнить о модулях МК, работа которых может продолжаться в спящих режимах. Если эти модули не используются в программе, то их работу следует запретить. К таким модулям относятся:

What happens if an object is closer than the shortest distance:

Based on the plots provided in the datasheet, it appears that the Distance vs Voltage plot follows an exponentially decaying curve within the suggested range of 10 to 80cm, When plotting inverse distance vs voltage, this represents an friendly almost linear relationship.

However, going back to the distance vs voltage plot, it seems that the output voltage will suddenly change behavior and sharply decrease as the object moves closer than 10cm to the sensor. This will also cause the inverse distance vs voltage behavior to deviate from its linearity.

Оцените статью
Добавить комментарий