Domotique - détecteur de mouvement avec capteur infrarouge

Bonjour,

je viens vous présenter un démarrage de projet de détecteur de présence. Il est réalisé à partir d’un capteur de température infrarouge MLX90614. La version que j’avais acheté se révèle à grand angle de vue - 90°. Du coup, l’application prise de température n’étaient pas très adaptée.

Mais l’application détecteur de mouvement marche assez bien. Voici le montage:


Et le code à uploader: (dispo ici: Arduino Create)

// Include FIFO array
#include <CircularBuffer.h>
// Include dependencies for MLX communication
#include <Adafruit_MLX90614.h>

// Variables
const unsigned long measurement_period = 50; // delay between two measurements in ms
const unsigned int length_measurements = 20; // nb of consecutive measurements for calirbaiton and measurement
const byte pin_led = 8; // Pin to connect LED (LED blinks for calibration phase et flash when presence detected
const byte interruptPin = 2; // Declare pin 2 as pin for interrupt button
volatile boolean calibration_flag = false; // Flag to pass interruption to Arduino loop()
unsigned long currentMillis = 0; // Store current time at beginning of Arduino loop()
unsigned long measurement_timer = 0; // Check if it is time for measurement
unsigned long detection_timer = 0; // Check if it is time for presence detection
boolean isPresenceDetectedBefore = false;
boolean isPresenceDetectedNow = false;
boolean stateChange = false;
int LED_state = LOW; // State for LED
CircularBuffer<float,length_measurements> measure_data; // Array to store measurements
CircularBuffer<float,length_measurements> calibration_data; // Array to store measurements from calibration

// Instanciate MLX component
Adafruit_MLX90614 myMLX = Adafruit_MLX90614();

// Instanciate here all required: Serial output, led, interrupts and MLX
void setup() {  
  // Open Serial for output
  Serial.begin(9600);
  // Set pin for LED
  pinMode(pin_led, OUTPUT);
  // Set pin for button acting through interruption
  // INPUT_PULLUP mode allows using internal resistor and connect directly button to GND and pin
  pinMode(interruptPin, INPUT_PULLUP);
  // Attach interruption
  attachInterrupt(digitalPinToInterrupt(interruptPin), start_calibration_sequence, FALLING);
  // MLX equipment declaration
  myMLX.begin();
}

// Implementation using timer based event.
// Allow looping rapidly over possible states to handle, and sync tasks to be performed based on timer or interrupts
void loop() {
 // Retrieve current time for timer handling
 currentMillis = millis();
 // Handle calibration sequence: calibration sequence makes use of delay hence cannot be included in interrupt
 if (calibration_flag){   
    calibration_sequence();
 }  
 // Handle measurement sequence: add in FIFO buffer new measure every <measurement_period>
 if (currentMillis - measurement_timer >= measurement_period) {
    measurement_timer = currentMillis;
    // Measure now  
    Serial.println(myMLX.readObjectTempC());
    measure_data.push(myMLX.readObjectTempC());
 }   
 // Handle detection assessment sequence: regularly assess if presence is detected
 if (currentMillis - detection_timer >= measurement_period) {
    // Assess presence and react    
    isPresenceDetectedNow = presence_detected();
    // Check if detection state changes switches through old and new state
    // This is required to enable LED ON or LED OFF only when detection state is changed
    stateChange = isPresenceDetectedNow xor isPresenceDetectedBefore;
    isPresenceDetectedBefore = isPresenceDetectedNow;
    detection_timer = currentMillis;
 }    
 // Handle detection reaction in case presence is now detected 
 if (isPresenceDetectedNow and stateChange){
  LED_state = HIGH;
  stateChange = false;
  digitalWrite(pin_led, LED_state);
 }
 // Handle non detection reaction in case presence is now non detected 
 if (!isPresenceDetectedNow and stateChange){
  LED_state = LOW;
  stateChange = false;
  digitalWrite(pin_led, LED_state);
 }
}

// Event linked to button interrupt setiing calibration sequence flag
void start_calibration_sequence() {
  calibration_flag = true;
}

// Function to assess if presence is detected using calibration data and measurement data
boolean presence_detected(){
  float avg_calibration = 0;
  float avg_measurements = 0;    
  // Compute average of calibration data and measured data
  for(unsigned int idx = 0;idx<length_measurements;idx++){
    avg_calibration += calibration_data[idx]/length_measurements;
    avg_measurements += measure_data[idx]/length_measurements;
  }
  // Decide depending on difference   
  return (abs(avg_measurements - avg_calibration))>0.1;   
}

// Function to implement calibration sequence
void calibration_sequence(){
  Serial.println("Start calibration");
  // Blink LED rapidly to inform calibration starts
  for(int i=0;i<10;i++){
    digitalWrite(pin_led, HIGH);
    delay(50);
    digitalWrite(pin_led, LOW);
    delay(50);
  }
  // Measures calibration data
  for(int i=0;i<10;i++){
    calibration_data.push(myMLX.readObjectTempC());
    delay(measurement_period);
  }  
  // Set flag back to false
  calibration_flag = false;
}

Si vous ouvrez le traceur série, vous verrez en direct les changements détectés par votre capteur.
La LED sert à confirmer qu’une présence est détectée.
J’arrive à détecter facilement une personne dans un couloir ou une cage d’escalier.

Le fonctionnement de ce montage est le suivant:

  • Régulièrement, l’Arduino déclenche une mesure sur le MLX est l’enregistre dans un buffer
  • Régulièrement, l’Arduino vérifie si les informations enregistrées permettent de conclure à une présence ou non
  • A tout moment, le bouton peut interrompre ce comportement et déclencher une phase de calibration: à ce moment, une succession de mesures est effectuée et sert de référence pour la détection de présence

Si vous voulez une démo vidéo de ce montage, j’en ai postée une ici: https://youtu.be/1bXZUXVwsmM

Maintenant, j’aimerais rendre ce montage embarqué sur une carte indépendante de ma carte arduino, et remplacer la LED par un relais, pour permettre de déclencher une application électrique tierce sur la détection de mouvement (sirène, spot lumineux, …)

Mais je ne sais pas si ma méthode de détection (moyenne glissante) se prête bien à l’application de détection ?

bonjour simple mais efficace .Si j'utilise le module HC-SR501 est ce que ça marcherait ?