Arduino - Code secret

Porteur(s) du projet : Amandine Long

Date : 20/05/2019

Contexte : Projet Arduino

Description

Dans le cadre de mon mémoire, j'aimerais travailler sur les mécanismes de jeux et les dispositifs interactifs. Dans cette optique, j'ai décidé d'explorer un mécanisme qui peut être utilisé dans le cadre d'un escape game : une serrure que l'on déverrouille grâce à un code. Comprendre son fonctionnement pourra me permettre de réinvestir ce dispositif ultérieurement.

Capteur utilisé - Le bouton poussoir : Le “pushbutton” (bouton poussoir) laisse passer le courant quand on appuie. Lorsqu'on le relâche, le courant ne passe plus, contrairement à un interrupteur qui resterait dans la même position.

Tutoriel

Nous allons créer un dispositif qui permet d'ouvrir une porte grâce à un code secret. L'interface pour rentrer le code se fait avec trois boutons poussoirs. Lorsqu'on rentre la bonne combinaison en appuyant sur les boutons dans un ordre précis, la porte s'ouvre. Dans ce tutoriel, nous représenterons la porte fermée par une LED rouge, et la porte déverrouillée par une LED verte. Nous ajouterons les messages “Porte verrouillée” et “Porte déverrouillée”, qui s'afficherons sur un écran LCD.

Matériaux

Carte Arduino

2 LEDS : une rouge et une verte

3 Boutons poussoirs

5 Résistances (environ 500 ohms)

Écran LDC “Grove-LCD RGB Blacklight”

Breadboard

Fils connecteurs

Câblages

Fonctionnement du programme

On pré-enregistre le code “correct”.

La porte est fermée au départ : la Led rouge est allumée, l'écran LCD affiche le message “Door locked” avec un fond rouge.

Lorsque l'utilisateur appuie sur un bouton, la valeur associée (bouton “1”, “2” ou “3”) est enregistrée à la suite d'une série de 5 valeurs (“5” correspondant à la taille du code correct, c'est à dire au nombre de boutons sur lesquels on doit appuyer pour rentrer celui-ci).

Par défaut, si aucun bouton n'est appuyé au terme d'un délai défini, on enregistre “0” à la suite de la série.

A chaque nouvelle valeur, on compare la dernière série enregistrée (les 5 derniers boutons appuyés) avec le code pré-enregistré.

Si cette série (le code entré) est égale au code “correct” pré-enregistré, on éteint la LED rouge, on allume la verte, et on affiche sur l'écran LCD le message “Door unlocked”, sur fond vert.

Pour refermer la porte, il suffit d'appuyer sur un des boutons.

Programme

Variables globales :

// DECLARATION DES VARIABLES GLOBALES
const int NbPoussoirs = 3;
// Le nombre de boutons poussoirs
const int PinPoussoirs[NbPoussoirs] = {2, 3, 4};
// pins d'entrée des poussoirs 1 à 3
//============
const int LedPin1 = 5;
// La led 1 (rouge, qui signale que la combinaison est mauvaise)
// est placée sur l'entrée/sortie numérique 5 de l'arduino
const int LedPin5 = 9;
// La led 5 (verte qui signale que la combinaison est correcte)
//est placée sur l'entrée/sortie numérique 9 de l'arduino
//============
const int SizeCode = 5;
// La taille du code
// = Il faut appuyer sur 5 boutons pour entrer le code complet
int Code[SizeCode] = {2, 3, 2, 1, 3};
// La combinaison correcte du code
int CodeActuel[SizeCode] = {0};
// Initialisation du code
// Délai de sécurité
// Si il y a plus de temps entre deux appuis, le code est effacé
unsigned long DernierAppui;
const unsigned long Delai = 5E3; // 5000 ms = 10 s
//============
#include <Wire.h>
#include "rgb_lcd.h"
// Librairies pour l'écran LCD
rgb_lcd lcd;

Setup et Loop :

// VOID SETUP
// Initialisation des variables globales
void setup()
{
Serial.begin(9600);
pinMode(LedPin1, OUTPUT);
pinMode(LedPin5, OUTPUT);
// LED éteintes
for (int i = 0; i < NbPoussoirs; i++)
pinMode(PinPoussoirs[i], INPUT);
// Numéros des boutons poussoirs
// Délai pour appuyer sur un bouton
DernierAppui = millis();
//============
// Nombre de colonnes et lignes & couleur sur l'écran LCD
lcd.begin(16, 2);
lcd.setRGB(255, 0, 0);
// Message sur la première ligne du LCD
lcd.print("*** Door ***");
delay(1000);
}
void loop()
{
// Lire les boutons "appuyés"
lireBoutons();
// Si le code entré est le même que celui enregistré plus haut
// On appelle la méthode qui ouvre la porte
if ( comparerCodes() == true )
{
porteOuverte();
// On remet le chrono de sécurité à 0 pour ne pas que la porte se referme seule
// Il faudra appuyer un des boutons pour la refermer
DernierAppui = millis();
}
// Sinon, on appelle la méthode qui garde la porte fermée
else {
porteFermee();
}
// Si le délai pour appuyer sur un bouton est dépassé, enregistrer 0
if (millis() - Delai > DernierAppui){
remplirCode(0);
}
// Sur le LCD, place le curseur sur la deuxième ligne
// (Note: La deuxième ligne est notée 1 dans le code, car on commence à 0)
lcd.setCursor(0, 1);
delay(100);
}

Mes méthodes :

// MES METHODES
void porteOuverte()
{
digitalWrite(LedPin5, HIGH); //Allumage de la led verte
digitalWrite(LedPin1, LOW); //Extinction de la led rouge
lcd.print("*** unlocked ***"); //Message LCD "déverrouillé"
lcd.setRGB(0, 255, 0); //Couleur LDC : vert
}
void porteFermee()
{
digitalWrite(LedPin5, LOW); //Extinction de la led verte
digitalWrite(LedPin1, HIGH); //Allumage de la led rouge
lcd.print("*** locked ***"); //Message LCD "verrouillé"
lcd.setRGB(255, 0, 0); //Couleur LDC : rouge
}
void lireBoutons()
{
for (int i = 0; i < NbPoussoirs; i++)
if ( digitalRead( PinPoussoirs[i] ) == HIGH )
// Détecter l'appui sur un bouton
{
delay(15);
// Anti-rebond pour ne pas enregistrer plus d'un appui à la fois
while ( digitalRead( PinPoussoirs[i] ) == HIGH ) {}
// On attends d'avoir relaché le bouton
remplirCode( i + 1 );
// Et on stocke le numéro du bouton dans le tableau
}
// Si on est arrivé là, c'est qu'aucun bouton n'était appuyé : on retourne 0
}
void remplirCode(int valeur)
{
// On décale les cases vers la première, qui est CodeActuel[0], car les index commencent toujours à 0
for (int i = 1; i < SizeCode; i++)
CodeActuel[i - 1] = CodeActuel[i];
// Et on remplit la dernière, donc à l'index taille du tableau -1 puisque que l'index commence à 0
CodeActuel[SizeCode - 1] = valeur;
// Comme quelque-chose a changé, on l'affiche
afficherCodes();
// On remet à 0 le chrono de sécurité
DernierAppui = millis();
}
void afficherCodes()
{
Serial.println("--------Affichage du Code actuel-------");
for (int i = 0; i < SizeCode; i++)
{
Serial.print(CodeActuel[i]);
Serial.print(" ");
}
Serial.println();
Serial.println("--------Affichage du Code requis-------");
for (int i = 0; i < SizeCode; i++)
{
Serial.print(Code[i]);
Serial.print(" ");
}
Serial.println();
}
bool comparerCodes()
{
for (int i = 0; i < SizeCode; i++)
if (CodeActuel[i] != Code[i])
return false;
// Dès qu'une des valeurs est fausse, quitte et retourne faux
return true;
// Si on est arrivé là, c'est que le Code est ok, on retourne vrai
}

Bibliographie

Bouton Grove

LDC Grove

Bouton poussoir Arduino

LDC+Arduino

Curseur écran LCD