salut a tous si jamais cela vous interresse, voici un programme pour une bombe airsoft que j'ai fait y a 2 ans.desamorcage avec code de 1 a 12 caractère ou double clefs,temps de jeu 99h60min60sec
Affichage d'une variable de temps sur un Ã
cran
*/
#include <LiquidCrystal.h> //Appel de la librairie LCD
#include <Wire.h> //Appel librairie I2C
#define ITG3200_Address 0x68 //Adresse I2C ITG3200 0X68
// Variable Gyroscope
float GyroX,GyroY,GyroZ,GyroTemp;
unsigned long time_1=0;
unsigned long time_2=0;
int g_offx = 0;
int g_offy = 0;
int g_offz = 0;
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
#include <Keypad.h> //Appel de la librairie Keypad
const byte ROWS = 4; //four rows
const byte COLS = 3; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {// Déclaration des BP du key pad
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}};
byte rowPins[ROWS] = {33,31,27,23}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {25, 29, 35}; //connect to the column pinouts of the keypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); //initialize an instance of class NewKeypad
int chariot[6]={4,5,7,8,10,11}; //Déclaration des position chariot pour le temps
unsigned long refTemps=0; // reference prise dans le flux du temps
unsigned long diff=0; // difference entre le temps voulu et le temps reel
unsigned long temps_selec=0; //Temps sélectionner par la personne.
unsigned int tampon; // mémoire de l'ancien temps pour le bit de cadensement
unsigned int last_time1=0; // première mémoire de temps
unsigned int last_time2=0; // première mémoire de temps
unsigned int last_time3=0;
unsigned long temps_enc; // temps en cours d'éxecution
unsigned long temps_a_aff; // Temps a affiché
unsigned long temps_handicap; // temps handicap
unsigned int reste_temps; //reste du temps
unsigned long tp_aut=1000;// temps de blocage des touches
int deg_verrou=30;// Vitesse angulaire a ne pas dépasser pour verrouiller la bomb sur place
int nbr_dg=1; //nombre de digit pour le code
int adc_key_val[5] ={50, 200, 400, 600, 800 }; // registre des touche analogique
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;
int pos_x=0; //ordonnées de position
int pos_code=0; //ordonnées de position
int led_commut1=50;// selecteur a clé entré 50
int led_commut2=51;// Selecteur a clé entré 51
int select1=39; //Position du commutateur a clé
int select2=41; //Position du commutateur a clé
unsigned long tpselect1=0;// temps du premier selecteur
unsigned long tpselect2=0;// temps du premier selecteur
boolean auxselect1=LOW;//Auxilière front montant selecteur
boolean fmselect1=LOW;//Front montant selesteur
boolean auxselect2=LOW;//Auxilière front montant selecteur
boolean fmselect2=LOW;//Front montant selesteur
boolean selectenc=LOW;// Select en cour (1 des 2 commut a 1)
boolean discordance_select=LOW;//Discordance des selecteurs sur le temps impartie
int Val_discor=500;//Valeur de temps pour discordance
char code_saisie[9]={'0','0','0','0','0','0','0','0','0'}; // premier code tapper
char code_dev[9]= {'0','0','0','0','0','0','0','0','0'};// code de désamorcage tapper
int temps[6]={0,0,0,0,0,0};//Valeur de temps, Dizaine heure, Uh, Dminute,Um,DSeconde,US
int temps_acc=600; // accélération du temps valeur préselectionner
int temporaire;//bit temporaire
int pos_digit;// position des digit d'affichage
int i ;// boucle de comparaison
int ii;// boucle de comparaison
boolean Fin=LOW;// fin de compteur
boolean Start=LOW; // démarrage du compteur
boolean Unlock=LOW; // déverrouillage de la Bomb
boolean lcd_bp_haut=LOW;
boolean lcd_bp_bas=LOW;
boolean lcd_bp_droit=LOW;
boolean lcd_bp_gauche=LOW;
boolean lcd_bp_select=LOW;
boolean Cad_1=LOW;// Premier bit de cadensement de temps
boolean etats_cad;// résultat du cadensement
boolean fm_cad=LOW; // front montant du bit de cadencement pour l'états
boolean acc; // accélération du temps
boolean saisie_code=LOW; // saisie du code éffectuer
boolean digit_ok=LOW; //saisie du nombre de digit.
boolean aut_code=HIGH;// clavier déverrouiller pour saisie.
boolean auxdiscordance=LOW; // auxilère de discordance.
void setup()
{
Wire.begin(); //Carte I2C Maitre
delay(100);
initGyro(); //Init Gyro
delay(100);
GyroCalibrate(); //Calibration Gyro
delay(100);
pinMode(led_commut1,OUTPUT);//Sortie LED
digitalWrite(led_commut1,HIGH);//Initialisation de la sortie Mise a 0.
pinMode(led_commut2,OUTPUT);//Sortie pour klaxon
digitalWrite(led_commut2,HIGH);//Initialisation de la sortie Mise a 0.
pinMode(48,OUTPUT);//Sortie pour klaxon
digitalWrite(48,HIGH);//Initialisation de la sortie.
pinMode(select1,INPUT);//Initialiser les PIN comme étant une entrées.
pinMode(select2,INPUT);//Initialiser les PIN comme étant une entrées.
lcd.begin(16,2);// définition de l'écran 16 colonne 2 ligne
lcd.clear(); // éffacer écran
lcd.setCursor(0,0);
lcd.print("REMETRE CLE A 0");
while (digitalRead(select1) || digitalRead(select2) == HIGH)
{}
lcd.clear(); // éffacer écran
Serial.begin(9600);// initialisation du port serie pour debug
lcd.setCursor(0,0);// pointage du curseur pour affichage du caractère non int
lcd.print("S-AIRSOFT V0.1");
lcd.setCursor(1,1);// pointage du curseur pour affichage du caractère non int
lcd.print("BY RIDDICK");
delay(4000);
lcd.clear(); // éffacer écran
lcd.setCursor(0,0);// pointage du curseur pour affichage du caractère non int
lcd.print("VEUILLEZ ENTREER");
lcd.setCursor(2,1);// pointage du curseur pour affichage du caractère non int
lcd.print("LE NOMBRE DE");
delay(4000);
lcd.clear(); // éffacer écran
lcd.setCursor(2,0);// pointage du curseur pour affichage du caractère non int
lcd.print("DIGIT POUR LE");
lcd.setCursor(1,2);// pointage du curseur pour affichage du caractère non int
lcd.print("CODE (DE 1 A 9)");
delay(4000);
lcd.clear(); // éffacer écran
}
/*****************************************************************************
************************ création d'un cadencement
******************************************************************************/
void cad(unsigned int time)
{
unsigned int t_enc; // vairable temps en cours
t_enc=(millis()/time);
if (t_enc==tampon) {fm_cad=LOW;}
else
{
etats_cad=1-etats_cad; // inversion du bit
fm_cad=HIGH;
}
tampon=t_enc; // rechargement du tampons
}
/*****************************************************************************
************************Gestion de la base de temps sur ARDUINO
******************************************************************************/
void time() //Gestion du temps temps écoulé a partir de l'appel
{
diff=(millis()-refTemps); // on calcule les millisecondes qui seront perdues dans la comparaison de la boucle "if"
lcd.setCursor(4,0); // ligne du bas
temps_enc=(((diff/420UL)+diff)/1000UL); //temps écoulé a modifier ne plus afficher mais a exploité
temps_a_aff=temps_selec-temps_enc-temps_handicap; // temps a afficher est un temps calculé e, seconde pour
reste_temps=temps_a_aff/3600UL; // on désire savoir le nombre d'heure a afficher
temps[0]=reste_temps/10; // affichage des dizaine
temps[1]=reste_temps%10; // affichage des unité
reste_temps=(temps_a_aff%3600UL)/60; // on désire savoir le nombre de minute a afficher
temps[2]=reste_temps/10; // affichage des dizaine
temps[3]=reste_temps%10; // affichage des unité
reste_temps=(temps_a_aff%3600UL)%60; // on désire savoir le nombre de seconde a afficher
temps[4]=reste_temps/10; // affichage des dizaine
temps[5]=reste_temps%10; // affichage des unité
if(temps_a_aff==0) {Fin=HIGH;} //temps arrivé a 0
}
/*****************************************************************************
************************Saisie du temps sur l'afficheur et position chariot
******************************************************************************/
void saisie()
{
lcd.setCursor(0,0);// animation du curseur selon la position
lcd.print("COMPTE A REBOURS:");
if(lcd_bp_haut==HIGH) {temps[pos_x]++;}
if(lcd_bp_bas==HIGH) {temps[pos_x]--;}
if (pos_x==2 || pos_x==4) //controle des dixaine de seconde et minute ne doit pas excéder 60
{
if (temps[pos_x]==6) {temps[pos_x]=0;}
if (temps[pos_x]==-1) {temps[pos_x]=5;}
}
else // si on n'est hors des dixaine de secondes et minutes on passe ici
{
if (temps[pos_x]==10) {temps[pos_x]=0;}
if (temps[pos_x]==-1) {temps[pos_x]=9;}
}
// ajouter condition pour base de temps animation sur 250ms
if(lcd_bp_gauche==HIGH) {pos_x--;}
if(lcd_bp_droit==HIGH) {pos_x++;}
if (pos_x==6)
{pos_x=0;}
if (pos_x==-1)
{pos_x=5;}
tampon=last_time1; //charger l'ancien tampon dans la var publique
cad(500); // appel de la fonction
last_time1=tampon; // sauvegarde de la var publique pour prochain tour de scrut
lcd.setCursor(chariot[pos_x],1);// animation du curseur selon la position
if (etats_cad==HIGH) //cadensement a 1
{
lcd.print(" "); // carractère blanc pour animation
delay (30);// tampo de 20 milliseconde afin de ne pas figer l'écran avec la valeur
}
// mettre la saisie des touches
}
/*****************************************************************************
******************************************************************************
************************ Routine Principale ****************************
******************************************************************************
******************************************************************************/
void loop()
{
char customKey = customKeypad.getKey();
if(!saisie_code)
{
if(!digit_ok)
{
lcd.setCursor(3,0);// pointage du curseur pour affichage du caractère
lcd.print("NBR DIGIT:");
lcd.setCursor(7,1);// pointage du curseur pour affichage du caractère
lcd.print(nbr_dg);
if (lcd_bp_haut) {nbr_dg++;}
if (lcd_bp_bas) {nbr_dg--;}
if (nbr_dg==10) {nbr_dg=1;}
if (nbr_dg==0) {nbr_dg=9;}
if (lcd_bp_select) {digit_ok=HIGH; lcd.clear();}
}
if(digit_ok)
{
lcd.setCursor(2,0);// pointage du curseur pour affichage du caractère
lcd.print("UNLOCK CODE:");
temporaire=(8-(nbr_dg/2)+pos_code);
if (customKey != NO_KEY)
{
lcd.setCursor(temporaire,1);// pointage du curseur pour affichage du caractère
code_saisie[pos_code]=customKey;
lcd.print(customKey);
pos_code++;
}
}
if (pos_code==nbr_dg) {
saisie_code=HIGH;
delay(2000);
lcd.clear();
}
}
/********************************** Affichage du temps sur l'écran **************************************************/
if (saisie_code) {
// Lancement du chrono est début de la partie
lcd.setCursor(6,1);// pointage du curseur pour affichage du caractère non int
lcd.print(":");
lcd.setCursor(9,1);// pointage du curseur pour affichage du caractère non int
lcd.print(":");
lcd.setCursor(4,1);// affichage de l'heure
lcd.print(temps[0]);// Dizaine
lcd.print(temps[1]);//Unité
lcd.setCursor(7,1);// affichage des minutes
lcd.print(temps[2]);// Dizaine
lcd.print(temps[3]);//Unité
lcd.setCursor(10,1);// affichage des secondes
lcd.print(temps[4]);// Dizaine
lcd.print(temps[5]);//Unité
if (Start==LOW && !Fin && saisie_code) { saisie();}
}
/********************************** Démarrage du décomptage du temps **************************************************/
if (Start && !Fin && !Unlock) //Si on demande la mise en marche du compteur et qu'il n'est pas arriver a terme et que c'est pas désamorcer
{
GyroRead(); //Appel routine Gyroscope
if (int(GyroX/14.375) >=deg_verrou | int(GyroX/14.375) <=-deg_verrou | int(GyroY/14.375) >=deg_verrou | int(GyroY/14.375) <=-deg_verrou |int(GyroZ/14.375) >=deg_verrou | int(GyroZ/14.375) <=-deg_verrou) {Fin=HIGH;} // controle de la vitesse angulaire
// Serial.println(GyroX/14.375);
// Serial.print(";");
// Serial.print(GyroY/14.375);
// Serial.print(";");
// Serial.print(GyroZ/14.375);
// Serial.print(";");
time(); /* appel de la routine de temps*/
pos_digit=(8-(nbr_dg/2)+temporaire);
if (customKey != NO_KEY && aut_code)
{
lcd.setCursor(pos_digit,0);// pointage du curseur pour affichage du caractère
lcd.print(customKey);
code_dev[temporaire]=customKey;
temporaire++;
if (temporaire==nbr_dg)
{
for(int i=0;
{
if (code_saisie[i]!=code_dev[i])
{
temporaire=0;
while (temporaire!=nbr_dg)
{
pos_digit=(8-(nbr_dg/2)+temporaire);
lcd.setCursor(pos_digit,0);// pointage du curseur pour affichage du caractère
lcd.print('_');
temporaire++;
}
temporaire=0;
aut_code=LOW;
last_time3=millis()/tp_aut;// debut de cycle pour le bit de cadencement
break;
}
i++;
if (i==nbr_dg) {Unlock=HIGH;}
}
}
}
}
/********************************** Vérrouillage du clavier en cas de mauvais code **************************************************/
if (!aut_code)
{
tampon=last_time3; //charger l'ancien tampon dans la var publique
cad(tp_aut); // appel de la fonction
last_time3=tampon; // sauvegarde de la var publique pour prochain tour de scrut
if (fm_cad){aut_code=HIGH; tp_aut*=2UL;}
}
/********************************** Creation d'une accélération du temps en cas de mauvais désamorcage **************************************************/
if (acc) // génération du temps d'handicape
{
tampon=last_time2; //charger l'ancien tampon dans la var publique
cad(temps_acc); // appel de la fonction
last_time2=tampon; // sauvegarde de la var publique pour prochain tour de scrut
if (fm_cad) {temps_handicap++;}
}
/********************************** Lecture des entrée analogique **************************************************/
adc_key_in = analogRead(0);
key = get_key(adc_key_in);
if (key != oldkey)
{
switch (key)
{
case 0:
lcd_bp_droit=HIGH;
break;
case 1:
lcd_bp_haut=HIGH;
break;
case 2:
lcd_bp_bas=HIGH;
break;
case 3:
lcd_bp_gauche=HIGH;
break;
case 4:
lcd_bp_select=HIGH;
break;
}
}
else
{
lcd_bp_droit=LOW;
lcd_bp_haut=LOW;
lcd_bp_bas=LOW;
lcd_bp_gauche=LOW;
lcd_bp_select=LOW;
}
oldkey=key; // chargement de la valeur pour génerer un front montant
/********************************** Démarrage du compteur de temps **************************************************/
if (lcd_bp_select==HIGH && saisie_code) // Démarrage du décomptage
{
if (Start == LOW) // on contôle que le start n'as pa été envoyer si 2 impulsion BP on ne compte plus la suivante
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("FERMER LE CLAPET");
lcd.setCursor(2,1);
lcd.print("ET LA VALISE");
delay(3000);
lcd.clear();
refTemps=millis();
temps_selec=(((temps[0]*10UL+temps[1])*3600UL)+((temps[2]*10UL+temps[3])*60UL)+(temps[4]*10UL+temps[5]));// le L derriére les valeur numérique signifie que c'est du Long (double mots).
temporaire=0;
while (temporaire!=nbr_dg)
{
pos_digit=(8-(nbr_dg/2)+temporaire);
lcd.setCursor(pos_digit,0);// pointage du curseur pour affichage du caractère
lcd.print('_');
temporaire++;
}
temporaire=0;
}
Start=HIGH;
}
/********************************** Désamorcage de la Bomb air soft **************************************************/
if (Unlock) // Désamorcage réussi
{
delay(2000);
while (1)
{
lcd.clear();
delay(1000);
lcd.setCursor(5,0);
lcd.print("SYSTEM");
lcd.setCursor(3,1);
lcd.print("DESAMORCER");
delay(1000);
}
}
/********************************** Temps arriver a échéance **************************************************/
if (Fin)
{
lcd.setCursor(3,0);
lcd.print("BOOOOOOOOM");
digitalWrite(48,LOW);
delay (10000); //10 secondes d'attentes avec le buzzer!!!
delay (10000); //10 secondes d'attentes avec le buzzer!!!
delay (10000); //10 secondes d'attentes avec le buzzer!!!
delay (10000); //10 secondes d'attentes avec le buzzer!!!
delay (10000); //10 secondes d'attentes avec le buzzer!!!
delay (10000); //10 secondes d'attentes avec le buzzer!!!
digitalWrite(48,HIGH);
while (1==1)
{}
}
/*************************************************************************
***************************************************************************
******************** clé de désamorcage ***********************
**************************************************************************/
if (!auxselect1 && !auxselect2) {discordance_select=LOW;}
fmselect1=digitalRead(select1) && !auxselect1;
auxselect1=digitalRead(select1);
fmselect2=digitalRead(select2) && !auxselect2;
auxselect2=digitalRead(select2);
selectenc =auxselect1 || auxselect2;
if (fmselect1==HIGH) { tpselect1=millis();}
if (auxselect1==LOW) {tpselect1=0;}
if (fmselect2==HIGH) { tpselect2=millis();}
if (auxselect2==LOW) {tpselect2=0;}
if ((tpselect1!=0) && (auxselect2==LOW)){
if (millis()>(tpselect1+Val_discor)){ discordance_select=HIGH;}}
if ((tpselect2!=0) && (auxselect1==LOW)){
if (millis()>(tpselect2+Val_discor)){ discordance_select=HIGH;}}
if (discordance_select && !auxdiscordance) {
if (temps_acc!=100) {temps_acc=temps_acc-100;}
acc=HIGH;}
auxdiscordance=discordance_select;
Serial.print ("auxdiscordance:");
Serial.println(auxdiscordance);
Serial.print ("temps accélération:");
Serial.println(temps_acc);
if (auxselect1 && auxselect2 && !discordance_select) {
Unlock=HIGH;}
}
/*****************************************************************************
************************Conversion des signaux analogyque des touches du LCD KEYPAD en touches
******************************************************************************/
int get_key(unsigned int input)
{
int k;
for (k = 0; k < NUM_KEYS; k++)
{
if (input < adc_key_val[k])
{return k;}
}
if (k >= NUM_KEYS)k = -1; // No valid key pressed
return k;
}
// **************************
// I2C Gyroscope ITG3200
// **************************
void initGyro() {
Wire.beginTransmission(ITG3200_Address); //Début transmition Gyro
Wire.write(0x3E); //Mise en stby du Gyro
Wire.write(0x00); //Requette qui est tu?
Wire.endTransmission();
Wire.beginTransmission(ITG3200_Address);
Wire.write(0x15); //Diviseur de fréquence d'échantillonnage
Wire.write(0x07); //Envoie 7 au diviseur de fréquence
Wire.endTransmission();
Wire.beginTransmission(ITG3200_Address);
Wire.write(0x16); //Parametrage de l'échelle de mesure
Wire.write(0x1E); // +/- 2000 dgrs/sec, 1KHz, 1E, 19
Wire.endTransmission();
Wire.beginTransmission(ITG3200_Address);
Wire.write(0x17); //Intéruption des données
Wire.write(0x00); //Désactivé
Wire.endTransmission();
}
void GyroCalibrate(){
int tmpx = 0;
int tmpy = 0;
int tmpz = 0;
g_offx = 0;
g_offy = 0;
g_offz = 0;
for (char i = 0;i<10;i++)
{
delay(10);
GyroRead(); //lecture des données Gyroscope suite a init
tmpx += GyroX; //Définition du 0 en X
tmpy += GyroY; //Définition du 0 en Y
tmpz += GyroZ; //Définition du 0 en Z
}
g_offx = tmpx/10; //position de l'offset
g_offy = tmpy/10;
g_offz = tmpz/10;
}
void GyroRead() {
Wire.beginTransmission(ITG3200_Address);
Wire.write(0x1B);
Wire.endTransmission();
Wire.beginTransmission(ITG3200_Address);
Wire.requestFrom(ITG3200_Address,
; // request 8 bytes from ITG3200
int i = 0;
byte buff[8];
while(Wire.available())
{
buff[i] = Wire.read();
i++;
}
Wire.endTransmission();
GyroX = ((buff[4] <<
| buff[5]) - g_offx;
GyroY = ((buff[2] <<
| buff[3]) - g_offy;
GyroZ = ((buff[6] <<
| buff[7]) - g_offz;
GyroTemp = (buff[0] <<
| buff[1]; // temperature
}