A la fin du TP, vous me rendrez un dossier compressé nommé NOM1_NOM2_TP_Arduino_Centrale_Alarme.zip contenant :
Les fichiers sources des programmes écrits en C associés aux différents montages.
Les codes devront être commentés le plus possible.
Nous disposons d'un coffre fort contenant des documents importants.
Nous souhaitons protéger ce coffre-fort dans une salle ultra-sécurisée.
Comment parvenir à maintenir un niveau de sécurité optimal ?
Comment faire pour dissuader d'éventuels cambrioleurs ?
Proposer comment détecter des intrusions possibles dans la salle sécurisée.
Proposer comment détecter des tentatives d'ouverture illicite du coffre fort.
Quel type de réaction peut-on mettre en oeuvre si une tentative d'effraction est détectée ?
Dans ce TP nous allons utiliser le matériel suivant :
Une carte Arduino est une petite (5,33 x 6,85 cm) carte électronique équipée d'un micro-contrôleur. Le micro-contrôleur permet, à partir d'événements détectés par des capteurs, de programmer et commander des actionneurs ; la carte Arduino est donc une interface programmable.
Supposons que l'on veuille faire clignoter une lampe (DEL) à l'aide d'un bouton poussoir (BP).
Il est possible de programmer la carte Arduino à l'aide de différents langages : langage C, Python ou avec une programmation par blocs (Blockly Arduino). Dans ce TP, nous programmerons la carte Arduino avec le langage C et à l'aide de l'IDE fourni par Arduino :
Voici une solution possible pour le programme C permettant d'allumer la diode lumineuse à partir d'un bouton poussoir.
#define BOUTON_POUSSOIR 1 // le bouton poussoir est relié à l'entrée digitale D1
#define LED 12 // La LED est associée à la sortie digitale D12
//-------------------------------------------------------------------------
// La méthode setup() est appelée une seule fois au lancement du programme
//------------------------------------------------------------------------
void setup()
{
pinMode(BOUTON_POUSSOIR,INPUT);
pinMode(LED,OUTPUT);
}
//-------------------------------------------------------------------------
// La méthode loop() est appelée plusieurs fois par seconde
//------------------------------------------------------------------------
void loop()
{
if (digitalRead(BOUTON_POUSSOIR)) // La méthode digitalRead() retourne 1 si le bouton poussoir est pressé
{
digitalWrite(LED,HIGH); // On éclaire la LED
delay(1000); // temporisation d'une seconde
digitalWrite(LED,LOW); // on éteint la LED
delay(1000);
}
else
{
digitalWrite(LED,LOW); // on éteint la LED
}
}
Chacun des connecteurs D0 à D13 peut être configuré par programmation en entrée ou en sortie, nous pouvons donc avoir par exemple les connecteurs 2 et 3 configurés comme des entrées et les connecteurs 7, 8 et 9 configurés comme des sorties.
Les signaux véhiculés par ces connecteurs sont des signaux logiques, c'est-à-dire qu'ils ne peuvent prendre que deux états : HAUT (5 Volts) ou BAS (0 Volt), par rapport au connecteur de masse GND, qui lui est toujours, par définition, à 0 Volt.
Attention : les connecteurs ne peuvent pas fournir en sortie un courant supérieur à 40 mA, ce qui interdit de brancher directement un moteur sur une sortie logique.
Vocabulaire : on qualifie parfois ces entrées/sorties de numériques, de logiques ou de digitales, ces trois adjectifs sont ici considérés comme synonymes.
Contrairement aux entrées/sorties numériques qui ne peuvent prendre que deux états HAUT et BAS, ces six entrées peuvent admettre un millier de valeurs (1024 exactement) analogiques comprises entre 0 et 5 Volts. Nous pourrons donc avoir des valeurs de tension précises à 5 mV près (≈ 5V/1024) .
Exemples d'utilisation d'une entrée analogique :
L' « entrée/sortie numérique » D1 est utilisée en entrée (INPUT) :
L' « entrée/sortie numérique » D12 est utilisée en sortie (OUTPUT).
Pour allumer la diode (DEL), le programme alimente la sortie D12 en 5V, il la place en niveau « Haut ».
Notez la présence obligatoire de la résistance de 330 Ohms en série avec la Diode, elle limite le courant à une valeur acceptable . En son absence, la carte Arduino ne résisterait pas.
Une plaque d'essai permet de réaliser des montages électroniques sans soudure. La plaque d'essai s'utilise avec des « straps » qui sont des fils de cuivre isolés, de longueur et couleur variables.
La température de la salle du coffre-fort est régulée à 24 ±2 °C, toute intrusion ou usage d’outillage de type chalumeau ou disqueuse provoquerait inévitablement une augmentation de température.
Nous utilisons un capteur analogique de température.
Ce capteur est capable de mesurer des températures comprises entre -40°C et +120°C. La sortie analogique du capteur est proportionnelle à la température. Il suffit donc de mesurer la tension en sortie du capteur pour en déduire la température. Chaque degré Celsius correspond à une tension de +10mV.
Réalisez le montage suivant du capteur de température :
Saisissez le code C suivant associé à ce montage dans l'IDE Arduino et téléchargez le programme dans le micro-controller de la carte Arduino.
float sensor=0;
float celsius=0;
float voltage=0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
sensor=analogRead(0); // On lit la valeur analogique du capteur sur l'entrée A0
voltage=sensor*5000/1024; // On convertit cette valeur en une tension sachant que l'entrée est de 5000 mV avec 1024 analogiques discrètes possibles.
celsius =(voltage-500)/10; // On convertit la tension en une température en degré Celsius à partir d'une relation affine (qui dépend du capteur de température utilisé)
celsius = round(celsius*10)/10.0; // On arrondit la température au dixième de degré près
Serial.print("La temperature est de : "); // On affiche sur le moniteur série la valeur de la température ainsi acquise.
Serial.print(celsius);
Serial.println(" Celsius");
delay(1000);
}
Donner la température relevée dans la salle de TP.
La salle du coffre est plongée dans le noir. Seul le bloc d’éclairage de sécurité fonctionne. L’ouverture de la porte pourrait provoquer une augmentation du niveau lumineux.
Nous utilisons ici une photorésistance.
Une photorésistance est un composant dont la résistivité dépend de la luminosité ambiante. On peut donc s’en servir pour détecter les fortes variations de la luminosité.
Une unité de mesure de l'éclairement lumineux se nomme le lux. Un lux caractérise l'intensité lumineuse reçue par unité de surface.
Réalisez le montage de la photorésistance en série avec une résistance de 10 kohms.
Proposer un code en langage C qui lit la valeur du capteur de lumière et convertit cette valeur en pourcentage de la pleine échelle du capteur (entre 0% : pas de lumière et 100% lumière maximale).
Indication : la tension de sortie varie de 0 à 5V ce qui correspond à une variation de l'intensité lumineuse de 0 à 100%.
// Initialisation des constantes :
const int analogInPin = A0; // Numéro de la broche à laquelle est connecté la photorésistance
void setup() {
// Initialise la communication avec l'ordinateur,
// pour afficher les valeurs sensorValue
// sur l'écran de l'ordi.
Serial.begin(9600);
// Indique que la broche analogInPin est une entrée :
pinMode(analogInPin, INPUT);
}
void loop() {
// La commande suivante lit la valeur "analogique" du photorésistance
// (une valeur entière comprise entre 0 et 1023)
// et stocke le résultat dans sensorValue :
int sensorValue = analogRead(analogInPin);
// Les commandes suivantes affichent les valeurs dans
// le "serial monitor" de l'ordinateur
Serial.print("sensor = " );
Serial.println(sensorValue);
float pourcentage_intensite_lumineuse = sensorValue/1024.0*100;
Serial.print("pourcentage_intensite_lumineuse : ");
Serial.println(pourcentage_intensite_lumineuse);
delay(1000);
}
On souhaite sécuriser également la pièce voisine permettant de mettre en service l'alarme avec un détecteur de présence.
Nous allons utiliser pour cela le capteur de distance à ultrasons HC-SR04.
Principe de fonctionnement d'un capteur à ultrason
Les capteurs de distance à ultrasons utilisent le principe de l’écho pour déterminer la distance à laquelle se trouve un objet :
La durée entre l’instant de l’émission et l’instant de la réception peut être mesurée. Le signal ayant parcouru 2 fois la distance entre le capteur et la surface (un aller-retour), on peut la calculer ainsi :
$distance =\frac{vitesse\ du\ son}{2}\times{duree}$
Remarque : La vitesse du son est environ égale à 340 m/s.
Cablage d'un capteur à ultrason
Les capteurs de distance à ultrasons fonctionnent de la manière suivante :
Calculer la distance en cm pour une durée d'écho de 10 ms.
Réalisez le montage d'un capteur à ultra-sons HC-SR04 avec la carte Arduino et proposez un programme en C qui affiche dans le moniteur série la distance entre un objet et le capteur.
const int trigPin = 9;
const int echoPin = 10;
int frequence = 0;
long cm, duree;
void setup()
{
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop()
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// met une impulsion de 10 microseconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Lit le temps de retour de l'echo pin et met la valeur du temps de parcous en microseconds
duree = pulseIn(echoPin, HIGH);
cm = 0.01723 * duree ;
Serial.print("Distance en cm = ");
Serial.println(cm);
Serial.print("Duree en ms = ");
Serial.println(duree);
}
Un buzzer (transducteur) piézoélectrique est typiquement composé d'un diaphragme piézoélectrique, d'une cavité avec un orifice et de connexions pour les bornes électriques. Il nécessite une tension alternative pour fonctionner, de quelques volts à quelques dizaines de volts (3 V à 30 V par exemple). C'est ce type de transducteur que l'on retrouve au dos des montres ayant une fonction alarme.
Réalisez le montage d'un buzzer piézoélectrique
Pour jouer une mélodie sur le haut-parleur, on va utiliser la méthode tone(pin,note,duree) qui admet comme paramètres :
pin : la sortie digitale à laquelle est raccordée le buzzernote : la note qui est un entier représentant la fréquence en Hz de la noteduree : durée (en ms) pendant laquelle la note est jouéeEtudiez le programme suivant qui joue une fois une mélodie composée de 8 notes.
#define NOTE_B0 31
#define NOTE_C1 33
#define NOTE_CS1 35
#define NOTE_D1 37
#define NOTE_DS1 39
#define NOTE_E1 41
#define NOTE_F1 44
#define NOTE_FS1 46
#define NOTE_G1 49
#define NOTE_GS1 52
#define NOTE_A1 55
#define NOTE_AS1 58
#define NOTE_B1 62
#define NOTE_C2 65
#define NOTE_CS2 69
#define NOTE_D2 73
#define NOTE_DS2 78
#define NOTE_E2 82
#define NOTE_F2 87
#define NOTE_FS2 93
#define NOTE_G2 98
#define NOTE_GS2 104
#define NOTE_A2 110
#define NOTE_AS2 117
#define NOTE_B2 123
#define NOTE_C3 131
#define NOTE_CS3 139
#define NOTE_D3 147
#define NOTE_DS3 156
#define NOTE_E3 165
#define NOTE_F3 175
#define NOTE_FS3 185
#define NOTE_G3 196
#define NOTE_GS3 208
#define NOTE_A3 220
#define NOTE_AS3 233
#define NOTE_B3 247
#define NOTE_C4 262
#define NOTE_CS4 277
#define NOTE_D4 294
#define NOTE_DS4 311
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_FS4 370
#define NOTE_G4 392
#define NOTE_GS4 415
#define NOTE_A4 440
#define NOTE_AS4 466
#define NOTE_B4 494
#define NOTE_C5 523
#define NOTE_CS5 554
#define NOTE_D5 587
#define NOTE_DS5 622
#define NOTE_E5 659
#define NOTE_F5 698
#define NOTE_FS5 740
#define NOTE_G5 784
#define NOTE_GS5 831
#define NOTE_A5 880
#define NOTE_AS5 932
#define NOTE_B5 988
#define NOTE_C6 1047
#define NOTE_CS6 1109
#define NOTE_D6 1175
#define NOTE_DS6 1245
#define NOTE_E6 1319
#define NOTE_F6 1397
#define NOTE_FS6 1480
#define NOTE_G6 1568
#define NOTE_GS6 1661
#define NOTE_A6 1760
#define NOTE_AS6 1865
#define NOTE_B6 1976
#define NOTE_C7 2093
#define NOTE_CS7 2217
#define NOTE_D7 2349
#define NOTE_DS7 2489
#define NOTE_E7 2637
#define NOTE_F7 2794
#define NOTE_FS7 2960
#define NOTE_G7 3136
#define NOTE_GS7 3322
#define NOTE_A7 3520
#define NOTE_AS7 3729
#define NOTE_B7 3951
#define NOTE_C8 4186
#define NOTE_CS8 4435
#define NOTE_D8 4699
#define NOTE_DS8 4978
int notes[]={NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, NOTE_G1, NOTE_B3, NOTE_C4};
int buttonPin= 12;
int durees[]={400, 800, 800, 400, 400, 400, 400, 400};
void setup()
{
//parcourt toutes les notes de la mélodie
for (int note=0; note < 9; note++)
{
int noteDuration = 1000 / durees [thisNote];
tone(9, notes[note], durees[note]);
delay(durees[note]);
//Arrête de jouer la note
noTone(9);
}
}
void loop()
{
}
On peut noter que la liste des notes choisies est stockée dans la variable :
int melody[]={NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, NOTE_G1, NOTE_B3, NOTE_C4};
Ce type de variable, en langage C, se nomme un tableau (qui est comparable à une liste en Python.)
Que se passe-t-il si on déplace le code présent dans la fonction setup() dans le corps de la fonction loop()?
Modifier ce programme afin que le nombre de notes jouées soit égal à 12.
Les capteurs et détecteurs sont prêts. Le buzzer aussi ! Vérifions si le coffre-fort est imprenable !
Proposez un montage, qui regroupe les capteurs d'entrée de température et de lumière ainsi que le buzzer.
Proposez un programme en C, qui répond aux spécifications suivantes :
int const LUMIERE = 1;
int const TEMPERATURE = 0;
int const BUZZER = 2;
float sensor=0;
float celsius=0;
float voltage=0;
#define NOTE_B0 31
#define NOTE_C1 33
#define NOTE_CS1 35
#define NOTE_D1 37
#define NOTE_DS1 39
#define NOTE_E1 41
#define NOTE_F1 44
#define NOTE_FS1 46
#define NOTE_G1 49
#define NOTE_GS1 52
#define NOTE_A1 55
#define NOTE_AS1 58
#define NOTE_B1 62
#define NOTE_C2 65
#define NOTE_CS2 69
#define NOTE_D2 73
#define NOTE_DS2 78
#define NOTE_E2 82
#define NOTE_F2 87
#define NOTE_FS2 93
#define NOTE_G2 98
#define NOTE_GS2 104
#define NOTE_A2 110
#define NOTE_AS2 117
#define NOTE_B2 123
#define NOTE_C3 131
#define NOTE_CS3 139
#define NOTE_D3 147
#define NOTE_DS3 156
#define NOTE_E3 165
#define NOTE_F3 175
#define NOTE_FS3 185
#define NOTE_G3 196
#define NOTE_GS3 208
#define NOTE_A3 220
#define NOTE_AS3 233
#define NOTE_B3 247
#define NOTE_C4 262
#define NOTE_CS4 277
#define NOTE_D4 294
#define NOTE_DS4 311
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_FS4 370
#define NOTE_G4 392
#define NOTE_GS4 415
#define NOTE_A4 440
#define NOTE_AS4 466
#define NOTE_B4 494
#define NOTE_C5 523
#define NOTE_CS5 554
#define NOTE_D5 587
#define NOTE_DS5 622
#define NOTE_E5 659
#define NOTE_F5 698
#define NOTE_FS5 740
#define NOTE_G5 784
#define NOTE_GS5 831
#define NOTE_A5 880
#define NOTE_AS5 932
#define NOTE_B5 988
#define NOTE_C6 1047
#define NOTE_CS6 1109
#define NOTE_D6 1175
#define NOTE_DS6 1245
#define NOTE_E6 1319
#define NOTE_F6 1397
#define NOTE_FS6 1480
#define NOTE_G6 1568
#define NOTE_GS6 1661
#define NOTE_A6 1760
#define NOTE_AS6 1865
#define NOTE_B6 1976
#define NOTE_C7 2093
#define NOTE_CS7 2217
#define NOTE_D7 2349
#define NOTE_DS7 2489
#define NOTE_E7 2637
#define NOTE_F7 2794
#define NOTE_FS7 2960
#define NOTE_G7 3136
#define NOTE_GS7 3322
#define NOTE_A7 3520
#define NOTE_AS7 3729
#define NOTE_B7 3951
#define NOTE_C8 4186
#define NOTE_CS8 4435
#define NOTE_D8 4699
#define NOTE_DS8 4978
//Tableau des fréquences des notes jouées pour l'alarme liée à la température
int notes_melodie_temperature[]={NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, NOTE_B7, NOTE_B3, NOTE_C4};
//Tableau des durées des notes jouées pour l'alarme liée à la température (en ms)
int durees_melodie_temperature[]={400, 800, 800, 400, 400, 400, 400, 400};
//Tableau des fréquences des notes jouées pour l'alarme liée à la luminosité
int notes_melodie_lumiere[]={NOTE_A2, NOTE_CS8, NOTE_A2, NOTE_CS8, NOTE_A2, NOTE_CS8, NOTE_A2, NOTE_CS8};
//Tableau des durées des notes jouées pour l'alarme liée à la luminosité
int durees_melodie_lumiere[]={400, 800, 800, 400, 400, 1000, 2000, 400};
//-------------------------------------------------------
// Procédure appelée une fois au lancement du programme
//--------------------------------------------------------
void setup()
{
pinMode(LUMIERE,INPUT); // On assigne de capteur de luminosité à l'entrée digitale LUMIERE
pinMode(TEMPERATURE,INPUT); // On assigne de capteur de température à l'entrée digitale TEMPERATURE
Serial.begin(9600); // On initialise le moniteur série avec une vitesse de transmission de 9600 bauds.
}
//-------------------------------------------------------
// Procédure alarme()
// Paramètres :
// - notes[] : tableau des fréquences des notes à jouer sur le piezo
// - durees[] : tableau des fréquences des notes à jouer sur le piezo
//--------------------------------------------------------
void alarme(int notes[],int durees[])
{
int taille = sizeof(notes) / sizeof(int); // permet de calculer la taille du tableau notes (moins facile qu'en Python !)
// On parcourt le tableau des fréquences des notes
for (int note=0; note < taille; note++)
{
tone(BUZZER, notes[note] , durees[note]); // on joue la note de la fréquence donnée pour une dirée donnée
delay(durees[note]);
noTone(BUZZER);
}
}
//-------------------------------------------------------
// Procédure loop()
// Cette procédure est appelée plusieurs fois par seconde
//--------------------------------------------------------
void loop()
{
sensor=analogRead(TEMPERATURE); // On lit la valeur analogique du capteur de température sur l'entrée TEMPERATURE
voltage=sensor*5000/1024; // On convertit cette valeur en une tension sachant que l'entrée est de 5000 mV avec 1024 analogiques discrètes possibles.
celsius =(voltage-500)/10.0; // On convertit la tension en une température en degré Celsius à partir d'une relation affine (qui dépend du capteur de température utilisé)
celsius = round(celsius*10)/10.0; // On arrondit la température au dixième de degré près
Serial.print("La temperature est de : "); // On affiche sur le moniteur série la valeur de la température ainsi acquise.
Serial.print(celsius);
Serial.println(" Celsius");
sensor = analogRead(LUMIERE); // On lit la valeur analogique du capteur de luminosité sur l'entrée LUMIERE
float pourcentage_intensite_lumineuse = sensor/1024.0*100; // On traduit cette valeur analogique (comprise entre 0 et 1024) en un pourcentage de luminisotié comprise entre 0% et 100%
Serial.print("pourcentage_intensite_lumineuse : ");
Serial.println(pourcentage_intensite_lumineuse); // On affiche sur le moniteur série le pourcentage de luminosité.
if (celsius > 40) // Si la température détectée est supérieure à 40°C, on appelle la procédure alarme avec la mélodie associée à la température
alarme(notes_melodie_temperature,durees_melodie_temperature);
else // Sinon le pourcentage de luminosité détecté est supérieur à 40%, on appelle la procédure alarme avec la mélodie associée à la luminosité
if (pourcentage_intensite_lumineuse > 40)
alarme(notes_melodie_lumiere,durees_melodie_lumiere);
delay(100); // On fait une pause de 100 ms
}
Proposez l'utilisation d'autres capteurs qui permettraient d'améliorer le niveau de sécurité de notre centrale d'alarme.
Afin de faciliter la mise en service et la maintenance de cette centrale d'alarme, on souhaite ajouter les fonctionnalités suivantes :
Documentez-vous sur l'utilisation d'un afficheur LCD avec la carte Arduino à partir de cette vidéo :
Proposez un montage ainsi qu'un programme en C qui permet d'implémenter ces nouvelles fonctionnalités.
#include
LiquidCrystal lcd(12,11,6,5,4,3);
int const LUMIERE = 1;
int const TEMPERATURE = 0;
int const BUZZER = 2;
int const INTERRUPTEUR = 9;
float sensor=0;
float celsius=0;
float voltage=0;
#define NOTE_B0 31
#define NOTE_C1 33
#define NOTE_CS1 35
#define NOTE_D1 37
#define NOTE_DS1 39
#define NOTE_E1 41
#define NOTE_F1 44
#define NOTE_FS1 46
#define NOTE_G1 49
#define NOTE_GS1 52
#define NOTE_A1 55
#define NOTE_AS1 58
#define NOTE_B1 62
#define NOTE_C2 65
#define NOTE_CS2 69
#define NOTE_D2 73
#define NOTE_DS2 78
#define NOTE_E2 82
#define NOTE_F2 87
#define NOTE_FS2 93
#define NOTE_G2 98
#define NOTE_GS2 104
#define NOTE_A2 110
#define NOTE_AS2 117
#define NOTE_B2 123
#define NOTE_C3 131
#define NOTE_CS3 139
#define NOTE_D3 147
#define NOTE_DS3 156
#define NOTE_E3 165
#define NOTE_F3 175
#define NOTE_FS3 185
#define NOTE_G3 196
#define NOTE_GS3 208
#define NOTE_A3 220
#define NOTE_AS3 233
#define NOTE_B3 247
#define NOTE_C4 262
#define NOTE_CS4 277
#define NOTE_D4 294
#define NOTE_DS4 311
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_FS4 370
#define NOTE_G4 392
#define NOTE_GS4 415
#define NOTE_A4 440
#define NOTE_AS4 466
#define NOTE_B4 494
#define NOTE_C5 523
#define NOTE_CS5 554
#define NOTE_D5 587
#define NOTE_DS5 622
#define NOTE_E5 659
#define NOTE_F5 698
#define NOTE_FS5 740
#define NOTE_G5 784
#define NOTE_GS5 831
#define NOTE_A5 880
#define NOTE_AS5 932
#define NOTE_B5 988
#define NOTE_C6 1047
#define NOTE_CS6 1109
#define NOTE_D6 1175
#define NOTE_DS6 1245
#define NOTE_E6 1319
#define NOTE_F6 1397
#define NOTE_FS6 1480
#define NOTE_G6 1568
#define NOTE_GS6 1661
#define NOTE_A6 1760
#define NOTE_AS6 1865
#define NOTE_B6 1976
#define NOTE_C7 2093
#define NOTE_CS7 2217
#define NOTE_D7 2349
#define NOTE_DS7 2489
#define NOTE_E7 2637
#define NOTE_F7 2794
#define NOTE_FS7 2960
#define NOTE_G7 3136
#define NOTE_GS7 3322
#define NOTE_A7 3520
#define NOTE_AS7 3729
#define NOTE_B7 3951
#define NOTE_C8 4186
#define NOTE_CS8 4435
#define NOTE_D8 4699
#define NOTE_DS8 4978
//Tableau des fréquences des notes jouées pour l'alarme liée à la température
int notes_melodie_temperature[]={NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, NOTE_B7, NOTE_B3, NOTE_C4};
//Tableau des durées des notes jouées pour l'alarme liée à la température (en ms)
int durees_melodie_temperature[]={400, 800, 800, 400, 400, 400, 400, 400};
//Tableau des fréquences des notes jouées pour l'alarme liée à la luminosité
int notes_melodie_lumiere[]={NOTE_A2, NOTE_CS8, NOTE_A2, NOTE_CS8, NOTE_A2, NOTE_CS8, NOTE_A2, NOTE_CS8};
//Tableau des durées des notes jouées pour l'alarme liée à la luminosité
int durees_melodie_lumiere[]={400, 800, 800, 400, 400, 1000, 2000, 400};
//-------------------------------------------------------
// Procédure appelée une fois au lancement du programme
//--------------------------------------------------------
void setup()
{
pinMode(LUMIERE,INPUT); // On assigne de capteur de luminosité à l'entrée digitale LUMIERE
pinMode(TEMPERATURE,INPUT); // On assigne de capteur de température à l'entrée digitale TEMPERATURE
pinMode(INTERRUPTEUR,INPUT); // On assigne de capteur de température à l'entrée digitale TEMPERATURE
Serial.begin(9600); // On initialise le moniteur série avec une vitesse de transmission de 9600 bauds.
lcd.begin(16,2); // On initialise l'écran LCD avec 16 colonnes et 2 lignes
lcd.setCursor(0,0); // On positionne le cursor dans l'écran LCD à la colonne 0 et la ligne 0
lcd.print("Temperature"); // On écrit "Temperature" sur l'écran LCD à partir de la position courante du curseur
lcd.setCursor(0,1); // On positionne le cursor dans l'écran LCD à la colonne 0 et la ligne 1
lcd.print("Luminosite"); // On écrit "Luminosite" sur l'écran LCD à partir de la position courante du curseur
}
//-------------------------------------------------------
// Procédure alarme()
// Paramètres :
// - notes[] : tableau des fréquences des notes à jouer sur le piezo
// - durees[] : tableau des fréquences des notes à jouer sur le piezo
//--------------------------------------------------------
void alarme(int notes[],int durees[])
{
int taille = sizeof(notes) / sizeof(int); // permet de calculer la taille du tableau notes (moins facile qu'en Python !)
// On parcourt le tableau des fréquences des notes
for (int note=0; note < taille; note++)
{
tone(BUZZER, notes[note] , durees[note]); // on joue la note de la fréquence donnée pour une dirée donnée
delay(durees[note]);
noTone(BUZZER);
}
}
//-------------------------------------------------------
// Procédure loop()
// Cette procédure est appelée plusieurs fois par seconde
//--------------------------------------------------------
void loop()
{
int interrupteur = digitalRead(INTERRUPTEUR); // On lit l'état de l'interrupteur
sensor=analogRead(TEMPERATURE); // On lit la valeur analogique du capteur de température sur l'entrée TEMPERATURE
voltage=sensor*5000/1024; // On convertit cette valeur en une tension sachant que l'entrée est de 5000 mV avec 1024 analogiques discrètes possibles.
celsius =(voltage-500)/10.0; // On convertit la tension en une température en degré Celsius à partir d'une relation affine (qui dépend du capteur de température utilisé)
celsius = round(celsius*10)/10.0; // On arrondit la température au dixième de degré près
Serial.print("La temperature est de : "); // On affiche sur le moniteur série la valeur de la température ainsi acquise.
Serial.print(celsius);
Serial.println(" Celsius");
lcd.setCursor(12,0); // On affiche sur l'écran LCD la température
lcd.print(celsius);
lcd.setCursor(14,0);
lcd.print(" C");
sensor = analogRead(LUMIERE); // On lit la valeur analogique du capteur de luminosité sur l'entrée LUMIERE
float pourcentage_intensite_lumineuse = sensor/1024.0*100; // On traduit cette valeur analogique (comprise entre 0 et 1024) en un pourcentage de luminisotié comprise entre 0% et 100%
Serial.print("pourcentage_intensite_lumineuse : ");
Serial.println(pourcentage_intensite_lumineuse); // On affiche sur le moniteur série le pourcentage de luminosité.
lcd.setCursor(12,1);
lcd.print(pourcentage_intensite_lumineuse); // On affiche sur l'écran LCD le pourcentage de luminosité.
lcd.setCursor(14,1);
lcd.print(" %");
if (interrupteur == 1) // Si l'interrupteur est sur la position ON
{
if (celsius > 40) // Si la température détectée est supérieure à 40°C, on appelle la procédure alarme avec la mélodie associée à la température
alarme(notes_melodie_temperature,durees_melodie_temperature);
else // Sinon le pourcentage de luminosité détecté est supérieur à 40%, on appelle la procédure alarme avec la mélodie associée à la luminosité
if (pourcentage_intensite_lumineuse > 40)
alarme(notes_melodie_lumiere,durees_melodie_lumiere);
}
delay(100); // On fait une pause de 100 ms
}
On souhaiterait que lorsque l'alarme est enclenchée (avec l'interrupteur à glissière), on active une temporisation de 5 secondes qui permette de sortir de la salle. Si la personne n'est pas sortie de la salle après cette temporisation alors une alarme se déclenche.
De même, si l'alarme est enclenchée, une personne entrant dans la salle dispose de 5 secondes pour la désactiver.
Pour mettre en place ce scénario, nous allons utiliser le capteur de distance à ultra-sons pour détecter la présence d'une personne dans la pièce et le buzzer piézoélectrique pour l'alarme.
Proposez un montage ainsi qu'un programme en C qui permet d'implémenter ces nouvelles fonctionnalités.
const int trigPin = 9;
const int echoPin = 10;
const int BuzzerPin = 6;
const int InterupteurPin = 3;
int etat_interrupteur = 0;
float cm, duree;
int alarme_en_cours = false;
int frequence = 0;
int etat_precedent_interrupteur = 0;
void setup()
{
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop()
{
etat_interrupteur = digitalRead(InterupteurPin);
cm = determine_distance();
// Si on passe d'un etat off à on de l'interrupteur
if (etat_precedent_interrupteur == 0 && etat_interrupteur == 1)
{
Serial.println("Alarme enclenchee");
Serial.println("Vous avez 5 secondes pour sortir de la piece");
delay(5000);
etat_interrupteur = digitalRead(InterupteurPin);
cm = determine_distance();
if (etat_interrupteur == 1 && cm < 100) // l'alarme est déclenchée au bout de 5 secondes si la personne est à moins de 1 m du capteur de distance
{
tone(BuzzerPin, 247);
alarme_en_cours = true;
}
else
{
noTone(BuzzerPin);
alarme_en_cours = false;
}
}
// Si l'alarme est active et si la personne est à moins de 1 m du capteur de distance
if (etat_interrupteur == 1 && cm < 100 && !alarme_en_cours)
{
Serial.println("Vous avez 5 secondes pour désactiver l'alarme ou sortir de la salle");
delay(5000); // On laisse 5 secondes à la personne pour sortir de la salle
etat_interrupteur = digitalRead(InterupteurPin);
cm = determine_distance();
if (etat_interrupteur == 1 && cm < 100) // si la personne n'est pas sortie on déclenche l'alarme
{
tone(BuzzerPin, 247);
alarme_en_cours = true;
}
else
{
noTone(BuzzerPin);
alarme_en_cours = false;
}
}
if (etat_interrupteur == 0)
{
if (etat_precedent_interrupteur == 1)
Serial.println("Alarme desactivee");
alarme_en_cours = false;
noTone(BuzzerPin);
}
etat_precedent_interrupteur = etat_interrupteur; // on mémorise l'état précédent de l'interrupteur
delay(10);
}
//---------------------------------------------
// Retourne la distance en cm entre un objet et le capteur de distance
//--------------------------------------------
float determine_distance()
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// met une impulsion de 10 microseconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Lit le temps de retour de l'echo pin et met la valeur du temps de parcous en microseconds
duree = pulseIn(echoPin, HIGH);
cm = 0.01723 * duree ;
return cm;
}
Trouvez la combinaison secrète du coffre à 4 chiffres et vous aurez accès à la simulation de la centrale d'alarme avec le logiciel en ligne Tinkercad.
Un indice : le code secret est l'année de parution du célèbre livre Runaround écrit par Isaac Asimov où sont énoncées les Trois règles de la robotique.
Auteur : Hugues Malherbe inspiré librement :