ESP32 con sensor de movimiento PIR mediante interrupciones y temporizadores

¿Te gustaría aprender a utilizar un sensor de movimiento PIR con tu ESP32 de una manera más eficiente y precisa? En este artículo te explicaremos cómo implementar este sensor utilizando interrupciones y temporizadores para sacarle el máximo provecho a tu proyecto. ¡Sigue leyendo para descubrir todo lo que necesitas saber!

Este tutorial muestra cómo detectar movimiento con el ESP32 usando un sensor de movimiento PIR. En este ejemplo, cuando se detecta movimiento (lo que desencadena una interrupción), el ESP32 inicia un temporizador y enciende un LED durante un número predefinido de segundos. Cuando expire el temporizador, el LED se apagará automáticamente.

ESP32 con sensor de movimiento PIR mediante interrupciones y temporizadores

En este ejemplo, también examinaremos dos conceptos importantes: interrupciones y temporizadores.

Antes de continuar con este tutorial, debes tener el complemento ESP32 instalado en tu IDE de Arduino. Siga uno de los siguientes tutoriales para instalar ESP32 en el IDE de Arduino si aún no lo ha hecho.

  • Instalación de la placa ESP32 en Arduino IDE (Guía de Windows)
  • Instalación de la Placa ESP32 en el IDE Arduino (Guía para Mac y Linux)

Mira el vídeo tutorial y la demostración del proyecto.

Este tutorial está disponible en formato de video (ver más abajo) y formato escrito (sigue leyendo).

Piezas requeridas

Para seguir este tutorial necesitarás los siguientes elementos

Puedes utilizar los enlaces anteriores o ir directamente MakerAdvisor.com/tools ¡Para encontrar todas las piezas para tus proyectos al mejor precio!

ESP32 con sensor de movimiento PIR mediante interrupciones y temporizadores

Introducción a las interrupciones

Para activar un evento con un sensor de movimiento PIR, utilice interrupciones. Las interrupciones son útiles para hacer que las cosas sucedan automáticamente en programas de microcontroladores y pueden ayudar a resolver problemas de sincronización.

Con las interrupciones no es necesario comprobar constantemente el valor actual de un pin. Con las interrupciones, se activa un evento (se llama a una función) cuando se detecta un cambio.

Para configurar una interrupción en el IDE de Arduino, use el añadirInterrupción() Función que acepta como argumentos: el pin GPIO, el nombre de la función a ejecutar y el modo:

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

interrupción GPIO

El primer argumento es un número GPIO. Normalmente deberías usar digitalPinToInterrupt(GPIO) para configurar el GPIO real como un pin de interrupción. Por ejemplo, si desea utilizar GPIO27 Usar como interrupción:

digitalPinToInterrupt(27)

Para una placa ESP32, todos los pines marcados con un rectángulo rojo en la siguiente figura se pueden configurar como pines de interrupción. En este ejemplo utilizamos GPIO27 como una interrupción conectada al sensor de movimiento PIR.

ESP32 con sensor de movimiento PIR mediante interrupciones y temporizadores

Función a activar

El segundo argumento añadirInterrupción() Función es el nombre de la función que se llamará cada vez que se active la interrupción.

modo

El tercer argumento es la moda. Hay 5 modos diferentes:

  • BAJO: para activar la interrupción siempre que el pin esté BAJO;
  • ALTO: para activar la interrupción cuando el pin está ALTO;
  • CAMBIAR: para activar la interrupción cuando el pin cambia su valor, por ejemplo de ALTO a BAJO o de BAJO a ALTO;
  • CAER: en caso de que el pin cambie de ALTO a BAJO;
  • CRECIENTE: para activar cuando el pin cambia de BAJO a ALTO.

Para este ejemplo, estamos usando el modo RISING porque el GPIO al que está conectado pasa de BAJO a ALTO cuando el sensor de movimiento PIR detecta movimiento.

Introducción a los temporizadores

En este ejemplo también introduciremos temporizadores. Queremos que el LED brille durante un número predeterminado de segundos después de que se detecte movimiento. en lugar de uno Demora() Función que bloquea tu código y no te permite hacer nada más durante una cierta cantidad de segundos, deberíamos usar un temporizador.

ESP32 con sensor de movimiento PIR mediante interrupciones y temporizadores

La función de retraso ()

Deberías estar familiarizado con eso Demora() Funciona como se usa frecuentemente. Esta característica es bastante fácil de usar. Acepta un único número int como argumento. Este número representa el tiempo en milisegundos que el programa debe esperar antes de pasar a la siguiente línea de código.

delay(time in milliseconds)

si haces eso Retraso(1000) Su programa se detiene en esta línea durante 1 segundo.

Demora() es una función de bloqueo. Las funciones de bloqueo impiden que un programa haga cualquier otra cosa hasta que se complete la tarea en cuestión. Si es necesario realizar varias tareas al mismo tiempo, no puede utilizar Demora().

Para la mayoría de los proyectos, debes evitar retrasos y utilizar temporizadores.

La función milis()

Usando una función llamada milisegundos() Puede devolver el número de milisegundos que han pasado desde que se inició el programa por primera vez.

millis()

¿Por qué es útil esta característica? Porque puedes comprobar fácilmente cuánto tiempo ha pasado sin bloquear tu código mediante algunos cálculos matemáticos.

Parpadeando un LED con millis()

El siguiente fragmento de código muestra cómo hacer esto. milisegundos() Función para crear un proyecto LED intermitente. Enciende un LED durante 1000 milisegundos y luego lo apaga.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

// 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;           // interval at which to blink (milliseconds)

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);
  }
}

Ver código sin formato

Así es como funciona el código

Echemos un vistazo más de cerca a este boceto de Blink, el que no tiene Demora() función (utiliza la milisegundos() función en su lugar).

Básicamente, este código resta el tiempo registrado previamente (anteriorMillis) desde la hora actual (actualMillis). Si el resto es mayor que el intervalo (en este caso 1000 milisegundos), el programa actualiza el anteriorMillis Variable a la hora actual y enciende o apaga el LED.

if (currentMillis - previousMillis >= interval) {
  // save the last time you blinked the LED
  previousMillis = currentMillis;
  (...)

Debido a que este fragmento de código no es bloqueante, cualquier código fuera de este primero Si La instrucción debería funcionar normalmente.

Ahora debería comprender que tiene tareas adicionales para agregar a su Cinta() La función y su código seguirán haciendo parpadear el LED cada segundo.

Puede cargar este código en su ESP32 y armar el siguiente diagrama esquemático para probarlo y cambiar la cantidad de milisegundos para ver cómo funciona.

ESP32 con sensor de movimiento PIR mediante interrupciones y temporizadores

nota: Si tiene problemas para cargar código en su ESP32, consulte la guía de solución de problemas de ESP32.

ESP32 con sensor de movimiento PIR

Después de comprender estos conceptos: interrupciones y temporizadores, pasemos al proyecto.

Esquema

El circuito que construiremos es fácil de construir. Usamos un LED con una resistencia. El LED está conectado a GPIO26Usamos esos Minisensor de movimiento PIR AM312 que funciona con 3,3V. Estará conectado a GPIO27Simplemente siga el siguiente diagrama esquemático.

ESP32 con sensor de movimiento PIR mediante interrupciones y temporizadores

Importante: El Minisensor de movimiento PIR AM312 El sensor utilizado en este proyecto funciona con 3,3 V. Sin embargo, si tiene otro sensor de movimiento PIR como el. HC-SR501Funciona a 5 V. Puedes modificarlo para que funcione a 3,3 V o simplemente alimentarlo desde el pin Vin.

La siguiente figura muestra la distribución de pines del sensor de movimiento PIR AM312.

ESP32 con sensor de movimiento PIR mediante interrupciones y temporizadores

Sube el código

Después de cablear el circuito como se muestra en el esquema, copie el código proporcionado en su IDE de Arduino.

Puede cargar el código tal como está o puede cambiar la cantidad de segundos que el LED permanece encendido después de la detección de movimiento. Solo cambia el TiempoSegundos Variable con el número de segundos deseado.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

#define timeSeconds 10

// Set GPIOs for LED and PIR Motion Sensor
const int led = 26;
const int motionSensor = 27;

// Timer: Auxiliary variables
unsigned long now = millis();
unsigned long lastTrigger = 0;
boolean startTimer = false;
boolean motion = false;

// Checks if motion was detected, sets LED HIGH and starts a timer
void IRAM_ATTR detectsMovement() {
  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 set RISING mode
  attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING);

  // Set LED to LOW
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
}

void loop() {
  // Current time
  now = millis();
  if((digitalRead(led) == HIGH) && (motion == false)) {
    Serial.println("MOTION DETECTED!!!");
    motion = true;
  }
  // 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;
    motion = false;
  }
}

Ver código sin formato

Nota: Si tuvo problemas para cargar código a su ESP32, consulte la guía de solución de problemas de ESP32.

Cómo funciona el código

Echemos un vistazo al código. Comience asignando dos pines GPIO al CONDUJO Y Sensor de movimiento Variables.

// Set GPIOs for LED and PIR Motion Sensor
const int led = 26;
const int motionSensor = 27;

Luego cree variables que le permitan configurar un temporizador para apagar el LED después de que se detecte movimiento.

// Timer: Auxiliar variables
long now = millis();
long lastTrigger = 0;
boolean startTimer = false;

El Ahora La variable contiene la hora actual. El último disparador La variable contiene el momento en que el sensor PIR detecta movimiento. El iniciar temporizador es una variable booleana que inicia el temporizador cuando se detecta movimiento.

configuración()

En el configuración()Primero inicialice el puerto serie con una velocidad de 115.200 baudios.

Serial.begin(115200);

Configure el sensor de movimiento PIR como INPUT PULLUP.

pinMode(motionSensor, INPUT_PULLUP);

Para configurar el pin del sensor PIR como una interrupción, use el añadirInterrupción() Funciona como se describió anteriormente.

attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING);

El lápiz que detecta el movimiento es GPIO27 y la función se llama detecta movimiento() en modo ASCENDENTE.

El LED es una SALIDA cuyo estado comienza en BAJO.

pinMode(led, OUTPUT);
digitalWrite(led, LOW);

Cinta()

El Cinta() La función se ejecuta constantemente una y otra vez. En cada bucle el Ahora La variable se actualiza con la hora actual.

now = millis();

No pasa nada más en el Cinta().

Sin embargo, si se detecta movimiento, detecta movimiento() La función se llama porque previamente configuramos una interrupción en el configuración().

El detecta movimiento() La función imprime un mensaje en el monitor serie, enciende el LED, configura el iniciar temporizador variable booleana a VERDADERO y actualiza el último disparador Variable con la hora actual.

void IRAM_ATTR detectsMovement() {
  Serial.println("MOTION DETECTED!!!");
  digitalWrite(led, HIGH);
  startTimer = true;
  lastTrigger = millis();
}

Nota: IRAM_ATTR se utiliza para ejecutar el código de interrupción en la RAM; de lo contrario, el código se almacena en la memoria flash y es más lento.

Después de este paso el código vuelve a Cinta().

Esta vez iniciar temporizador La variable es verdadera. Entonces, cuando ha transcurrido el tiempo especificado en segundos (desde que se detectó movimiento), esto es lo que sucede Si afirmación será cierta.

if(startTimer && (now - lastTrigger > (timeSeconds*1000))) {
  Serial.println("Motion stopped...");
  digitalWrite(led, LOW);
  startTimer = false;
}

El mensaje «Movimiento detenido…» aparece en el monitor serie, el LED se apaga y la variable «StartTimer» se establece en «False».

demostración

Sube el código a tu placa ESP32. Asegúrese de haber seleccionado la placa y el puerto COM correctos.

Abra el monitor serie con una velocidad de baudios de 115200.

ESP32 con sensor de movimiento PIR mediante interrupciones y temporizadores

Mueva su mano frente al sensor PIR. El LED debería encenderse y aparecerá el mensaje “¡¡¡MOVIMIENTO DETECTADO!!!” en el monitor serie. Después de 10 segundos, el LED debería apagarse.

ESP32 con sensor de movimiento PIR mediante interrupciones y temporizadores

Envolver

En resumen, las interrupciones se utilizan para detectar un cambio en el estado de GPIO sin tener que leer constantemente el valor de GPIO actual. Las interrupciones activan una función cuando se detecta un cambio. También aprendió a configurar un temporizador simple que le permite verificar si ha pasado una cantidad predefinida de segundos sin tener que bloquear su código.

Tenemos más tutoriales sobre ESP32 que también te pueden gustar:

  • Servidor web ESP32 – IDE de Arduino
  • Temperatura de registro de datos ESP32 a la tarjeta MicroSD
  • Cómo usar I2C LCD con ESP32 en Arduino IDE
  • ESP32 vs ESP8266: pros y contras

Este es un extracto de nuestro curso: Aprendiendo ESP32 con Arduino IDE. Si te gusta ESP32 y quieres aprender más sobre él, te recomendamos apuntarte al curso Aprende ESP32 con Arduino IDE.

Gracias por leer.

Error 403 The request cannot be completed because you have exceeded your quota. : quotaExceeded







ESP32 con Sensor de Movimiento PIR

Introducción

Este tutorial muestra cómo detectar el movimiento con el ESP32 utilizando un sensor de movimiento PIR. En este ejemplo, cuando se detecta movimiento (se desencadena una interrupción), el ESP32 inicia un temporizador y enciende un LED durante un número de segundos predefinido. Una vez que el temporizador termina de contar, el LED se apaga automáticamente.

¿Qué son las Interrupciones?

Las interrupciones son útiles para hacer que las cosas ocurran automáticamente en los programas de microcontroladores y pueden ayudar a resolver problemas de temporización.

Para configurar una interrupción en el Arduino IDE, se utiliza la función attachInterrupt(), que acepta como argumentos: el pin GPIO, el nombre de la función que se ejecutará y el modo de interrupción.

¿Qué son los Temporizadores?

En este ejemplo también se introducen temporizadores. Queremos que el LED permanezca encendido durante un número predeterminado de segundos después de detectar movimiento. En lugar de usar la función delay(), que bloquea su código, es mejor utilizar un temporizador.

Funcionamiento del Código

El código verifica si se ha detectado movimiento y enciende el LED. Luego, inicia un temporizador que apaga el LED después del tiempo definido en la variable timeSeconds. Finalmente, se muestra un mensaje en el Monitor Serial cuando se detiene el movimiento.

Configuración del Circuito

El circuito incluye un LED conectado al GPIO 26 y el sensor de movimiento PIR al GPIO 27. Es importante tener en cuenta la diferencia de voltaje entre los sensores (3.3V o 5V).

Conclusión

En resumen, este tutorial muestra cómo detectar movimiento con el ESP32 utilizando interrupciones y temporizadores, evitando el bloqueo del código. Aprende más sobre el ESP32 y otros proyectos en Random Nerd Tutorials.


4 comentarios en «ESP32 con sensor de movimiento PIR mediante interrupciones y temporizadores»

  1. ¡Excelente manera de aprovechar al máximo las capacidades del ESP32! Me encanta la idea de integrar el sensor de movimiento PIR con interrupciones y temporizadores. Definitivamente voy a probarlo en mi propio proyecto. ¡Gracias por compartir esta información! 🤖🔥

Deja un comentario