Dans ce petit exercice, je vais résumer comment connecter une camera pour que lorsque votre chat passe devant un détecteur de mouvement, la camera l’immortalisé.
Vous allez apprendre comment détecter un mouvement avec un capteur de mouvement PIR et sans détecteur de mouvement!
Plus précisément, sans le capteur de mouvement PIR. vous allez configurer votre camera pour qu’elle compare les pixels de deux images. C’est cette différence qui va déclencher la capture de l’image.
Contrairement à cet article « transformer votre raspberry en camera de surveillance » nous n’allons pas utiliser un Raspberry, mais un micro-controlleur Adafruit Feather MO Adalogger avec un processeur ATSAMD21G18 ARM Cortex M0 (48 MHz) et 256KB de FLASH + 32KB de RAM. Ce micro-controlleur a une lecteur de carte SD intégré qui nous permettra d’enregistrer les images.
Matériel
- Micro-controlleur avec carte lecteur SD
- Carte microSD
- Camera TTL Serie 5V
- Détecteur de mouvement (PIR)
- Librairie Adafruit_VC0706
Lecture
Connexions
Pin de la Camera => boche (pin) du micro-controlleur
Vcc => 5V
GND => GND
Rx => Tx
Tx => Rx
Fils du capteur de mouvement => broche micro-controlleur
Vcc => 3.3V
GND => GND
SIG => 12
Code
Tout d’abord, vous devez importer la librairie d’Adafruit VC0706 ainsi que les librairie SPI et SD (dans votre nouveau fichier.ino
#include <Adafruit_VC0706.h> // https://github.com/adafruit/Adafruit-VC0706-Serial-Camera-Library #include <SPI.h> #include <SD.h>
Vous devrez encore donner un nom à deux constances ainsi que sa valeur, qui sera nécessaire au capteur de mouvement. J’attire votre attention que je crée aussi une constance CAMERA_MOTION qui nous permettra d’activer cette fonction ou de la désactiver en la commentant. C’est ceci qui nous permettra de détecter un mouvement sans le détecteur PIR. Vous devez faire de même pour la carte SD
/* * Motion */ #define PIR_PIN 12 // Pin definition for the signal #define LED 13 // Pin definition for the LED //#define CAMERA_MOTION // To activate or not the Camera detection /* * SD */ #define chipSelect 4
Si vous utilisez un autre micro-controlleur et une lecteur SD séparé, vous devez connecter la broche (pin) CS du lecteur SD à la broche de votre micro-controlleur. Vous pouvez très bien choisir une autre broche que celle que j’ai choisie. Étant donné que le lecteur SD est intégré au micro-controlleur que je propose, la broche 4 est imposée par le constructeur.
Le mico-controlleur a deux port Hardware: Serial et Serial1. J’utilise le Serial pour afficher des messages dans le terminal
Serial.print(F("Hello, voici la veleur de ")); Serial.println(ma_variable);
Alors que Serial1 est utilisé pour les ports Rx et Tx.
C’est ces deux broches que nous allons utilisé (rx/Tx) pour communiquer avec la camera. Autrement dit, c’est sur ce port (Hardware) que le micro-controlleur va traiter les données envoyées par la camera. Vous devez donc ajouter ceci à la suite de votre code, qui va créer un objet en indiquant le port à utiliser.
La fonction setup()
setup() initialise et fixe les valeurs de démarrage du programme. Il va définir l’état des broches, et initier certaines fonctionnalités.
Serial.begin(115200); Serial1.begin(115200); //#define CAMERA_MOTION pinMode(PIR_PIN,INPUT_PULLUP); // Define the pin as Input digitalWrite(PIR_PIN,LOW); // Put to LOW pinMode(PIR_PIN,INPUT_PULLUP); // Define the pin as Input pinMode(LED,OUTPUT); // Define as Input digitalWrite(LED,LOW); // Put to low
Vous devez ensuite, initier votre lecteur de carte SD et la camera
if (!SD.begin(chipSelect)) // see if the card is present and can be initialized: { Si.sprintln(F("Card failed, or not present"),0); // don't do anything more: while(1); // Do not continue } if (cam.begin()){ // Try to locate the camera Si.sprintln(F("Camera Found:"),0); } else { Si.sprintln(F("No camera found?"),0); while(1); // No, Do not continue } /* * Get the version of the Camera */ char *reply = cam.getVersion(); // Print out the camera version information if (reply == 0) { Si.sprint(F("Failed to get version"),0); } else { Si.sprint(F("Cam version: "),0); Si.sprintln(reply,0); }
Vous pouvez encore définir la taille de vos photos. Plus elles seront lourdes, plus le programme mettra du temps pour les sauver (env. 4 à 24s. pour une taille moyenne)
// Set the picture size - you can choose one of 640x480, 320x240 or 160x120 // Remember that bigger pictures take longer to transmit! //cam.setImageSize(VC0706_640x480); // biggest cam.setImageSize(VC0706_320x240); // medium //cam.setImageSize(VC0706_160x120); // small // You can read the size back from the camera (optional, but maybe useful?) uint8_t imgsize = cam.getImageSize(); Serial.print(F("Image size: ")); if (imgsize == VC0706_640x480) Serial.println("640x480"); if (imgsize == VC0706_320x240) Serial.println("320x240"); if (imgsize == VC0706_160x120) Serial.println("160x120")
Finalement, nous allons ici spécifier si nous utilisons la détection avec le détecteur PIR ou si la camera va elle remplir cette fonction.
#ifdef CAMERA_MOTION // If defined or commented // Motion detection system can alert you when the camera 'sees' motion! cam.setMotionDetect(true); // turn it on #else cam.setMotionDetect(false); // turn it off (default) #endif // You can also verify whether motion detection is active! Serial.print("Camera Motion detection is "); if (cam.getMotionDetect()) Serial.println("ON"); else { Serial.println("OFF"); Serial.println("PIR sensor ON"); snap(); // Take a snap (Can be commented) }
La fonction loop()
loop() (boucle en anglais) fait exactement ce que son nom suggère et s’exécute en boucle sans fin, permettant à votre programme de s’exécuter et de répondre.
Pour que la détection de mouvement se fasse grâce à la camera, soit sans le détecteur PIR, vous devez dé-commenter ceci
//#Define CAMERA_MOTION
Ainsi, le code fera appelle à la fonction motionDetected() qui retournera TRUE si la camera détecte un mouvement. La détection des mouvements sera temporairement désactivée le temps de prendre la photo et de la sauver sur la carte SD.
void loop(){ #ifdef CAMERA_MOTION // IF camera is set to act as MOTION (NO PIR detector) if (cam.motionDetected()) // If the camera detect a motion { Serial.println("Motion!"); cam.setMotionDetect(false); // Turn off the functionnality snap(); // Take a picture and save it cam.resumeVideo(); cam.setMotionDetect(true); // Turn on the functionnality } #else if(isPIRMotionDetected()==true) // Call the function isPIRMotionDetected which will { // will return true if the PIR sensor detect a movement Serial.println("PIR!"); snap(); // take a picture and save it } #endif }
Si en revanche, vous n’activer pas la détection par la camera, la fonction isPIRMotionDetected() sera appelée et le détecteur PIR indiquera au micro-controlleur si un mouvement est détecté ou pas.
Avec le détecteur PIR
Vous pouvez commencer par un peu de lecture (en anglais) sur les détectuers de mouvements PIR.
Le fil SIG est donc connecté à la broche 12 (pin 12) qui elle, attend (INPUT) un état haut ou bas. Quand un mouvement est détecté par le détecteur PIR, la broche 12 passe à l’état haut. isPIRMontionDetected() retourne TRUE et le fonction snap() va lancé le processus de la prise de vue et sauver la photo sur la carte SD.
isPIRMontionDetected()
boolean isPIRMotionDetected() { int sensorValue = digitalRead(PIR_PIN); // Read if PIR_PIN is HIGH or LOW //Serial.print("SensorValue:"); Serial.println(sensorValue); if(sensorValue == HIGH) // if the sensor value is HIGH? { Si.sprintln(F("\r\nMotition detected!!"),0); digitalWrite(PIR_LED,HIGH); delay(500); digitalWrite(PIR_LED,LOW); return true; // yes,return true } else { return false; // no,return false } }
La camera
Comme indiqué plus haut, quand isPIRMotionDetected() ou si cam.motionDetected() retournent TRUE, la fonction snap() est appelée.
void snap() { if (! cam.takePicture()) { Si.sprintln(F("Failed to snap!"),0); } else { Si.sprintln(F("Picture taken!"),0); // Create an image with the name IMAGExx.JPG // Increment the file name if it exists char filename[13]; strcpy(filename, "IMAGE00.JPG"); for (int i = 0; i < 100; i++) { filename[5] = '0' + i/10; filename[6] = '0' + i%10; // create if does not exist, do not open existing, write, sync after write if (! SD.exists(filename)) { break; } } File imgFile = SD.open(filename, FILE_WRITE); // Open the created file for writing uint16_t jpglen = cam.frameLength(); // Get the size of the image (frame) taken Si.sprint(F("Storing "),0); Si.sprint(jpglen, DEC,0); Si.sprint(F(" byte image in "),0); Si.sprintln(filename,0); int32_t time = millis(); // Init the time for save the image byte wCount = 0; // Read all the data up to # bytes! while (jpglen > 0) // For counting # of writes { uint8_t *buffer; uint8_t bytesToRead = min(64 , jpglen); // change 32 to 64 for a speedup but may not work with all setups! buffer = cam.readPicture(bytesToRead); imgFile.write(buffer, bytesToRead); if(++wCount >= 64) // Every 2K, give a little feedback so it doesn't appear locked up { Si.sprint(F("."),0); wCount = 0; } //Serial.print("Read "); Serial.print(bytesToRead, DEC); Serial.println(" bytes"); jpglen -= bytesToRead; } imgFile.close(); // Close the file time = millis() - time; // Print the elasped time while saving the image Si.sprintln(F("\r\ndone!"),0); Serial.print(time); Si.sprintln(F(" ms elapsed"),0); } }
La fonction ci-dessus est relativement simple à comprendre
La photo est prise grâce à
cam.takePicture();
En suite, la boucle for va parcourir votre carte SD et va contrôler les fichiers commençant par IMAGE00.JPG pour donner un nom à la nouvelle image qui finira par un numéro, pour autant que le nom n’existe pas encore. Si par exemple :
IMAGE00.JPG
IMAGE01.JPG
IMAGE03.JPG
La nouvelle image sera IMAGE02.JPG et la suivante IMAGE04.JPG (etc).
La fonction
SD.open(filename, FILE_WRITE)
va ouvrir le nouveau fichier en mode écriture.
La boucle
while (jpglen > 0){}
va « écrire » ou sauver la photo prise dans le fichier .
La fonction
imgFile.close();
va « fermer » le fichier.
Bravo!
Vous avez mis en place un petit système espion pour capturer un intru. Vous pouvez aussi vous passer du capteur de mouvement afin de configurer votre caméra pour qu’elle détecte elle-même un mouvement.
Si vous avez aimé cet article, publiez-le!