Différences entre versions de « Mon-Reveil-Programmer »
Ligne 37 : | Ligne 37 : | ||
* Le fichiers '''pitches.h''' contient les notes sous forme d'impulsions. | * Le fichiers '''pitches.h''' contient les notes sous forme d'impulsions. | ||
− | * Le fichier '''melodies.h''' contient plusieurs mélodies que vous pouvez définir comme | + | * Le fichier '''melodies.h''' contient plusieurs mélodies que vous pouvez définir comme sonneries d'alarmes. |
=== Définir les broches utilisés === | === Définir les broches utilisés === |
Version du 14 mars 2018 à 09:56
Environnement de travail
Si vous désirez obtenir le code complet, cliquez ici
N'hésitez pas à tester vos connectiques si se n'a pas été encore fait ! |
Dans ce tutoriel, nous travaillons sur l'environnement d'ArduinoIDE. Si vous ne l'avez pas encore installé, vous pouvez le télécharger ici.
Passon au vif du sujet.
- Premièrement, il vous faudra télécharger le projet ici.
- Décompressé le fichier zip téléchargé.
- Dans le dossier "Mon Reveil", ajoutez-y les fichiers Adafruit_LEDBackpack.h et Adafruit_LEDBackpack.cpp (disponible ici).
- Ouvrez le projet sur ArduinoIDE :
Menu -> Ouvrir -> "../Mon-Reveil-1-master/Mon-Reveil/Mon-Reveil.ino"
640px
Contenu du projet - cliquez pour agrandir
Entête
Dans l'entête se trouvent l'ensemble des variables globales.
Les inclusions de bibliothèques
Il est nécessaire d'ajouter ces bibliothèques pour le bon fonctionnement du code.
#include "Adafruit_LEDBackpack.h" // Afficheurs
#include <RTClib.h> // RTC
#include <EEPROM.h> // Mémoire non-volatile pour stocker les paramètres
#include "pitches.h" // Notes de musique
#include "melodies.h" // Playlists de musiques
- Le fichiers pitches.h contient les notes sous forme d'impulsions.
- Le fichier melodies.h contient plusieurs mélodies que vous pouvez définir comme sonneries d'alarmes.
Définir les broches utilisés
Ci-dessous, se trouve l'ensemble des entrées des boutons et du piezzo buzzer.
Vous pouvez les modifier si vous n'uilisez pas les mêmes entrées que dans l'assemblage.
// Boutons Piggrl
#define BOUTON_ALARME_CONTROLE 2 // Digitale
#define BOUTON_PLUS 3 // Digitale
#define BOUTON_MOINS 4 // Digitale
#define BOUTON_LUMINOSITE 5 // Digitale
// Boutons Arcade
#define BOUTON_OK 14 // Analogue 0
#define BOUTON_SNOOZE 15 // Analogue 1
#define LED_BOUTON_OK 16 // Analogue 2
#define LED_BOUTON_SNOOZE 17 // Analogue 3
// Piezzo Buzzer
#define PIEZO_BUZZER 13 // Digitale
Les boutons d'arcades utilisent les entrées analogiques comme entrées digitales. |
Personnaliser les paramètres par défaut
Il est possible de personnaliser les paramètres des alarmes.
// ================================================
// =============== Personnalisation ===============
// ================================================
const int SNOOZE_ATTENTE = 10; // Durant combien de temps l'utilisateur va t'il encore dormir ? (en secondes)
const int DUREE_ALARME = 20; // Durant combien de temps l'alarme va t'elle sonner (en secondes)
const int BOUTON_ALARME[] = {8, 7, 9, 10}; // Quelles pins pour activer/désactiver chaques alarmes
const float VITESSE_LECTURE = 1; // Vitesse sonore des alarmes (par défaut 1)
const int MELODIE[][ 2 ] = MARIO; // Sélectionner la musique que vous désirez pour vos alarmes (voir melodies.h)
// ================================================
- SNOOZE_ATTENTE permet de définir combien de secondes le snooze va encore attendre avant de se remettre à sonner.
- DUREE_ALARME permet de définir combien de secondes les alarmes vont sonner.
- BOUTON_ALARM permet de définir sur quel broche l'alarme va être activer/désactiver. Il permet aussi de savoir combien d'alarmes vont être utilisés.
- VITESSE_LECTURE permet de définir a quelle vitesse la mélodie va être jouée.
- MELODIE permet de définir la mélodie jouée. L'ensemble des mélodies se trouvent dans le fichier melodies.h qui doit se trouver dans la racine de votre projet.
Setup
Dans le setup se trouvent différentes routines :
Port série
Ouverture du port série et définition du débit de données à 9600 bps pour permettre la communication entre un arduino et un ordinateur via usb.
Serial.begin( 9600 );
Entrées
Configuration des broches des boutons pour qu'elles se comportent comme des entrées.
// Initialisation des boutons
pinMode( BOUTON_OK, INPUT_PULLUP );
pinMode( BOUTON_MOINS, INPUT_PULLUP );
pinMode( BOUTON_PLUS, INPUT_PULLUP );
pinMode( BOUTON_LUMINOSITE, INPUT_PULLUP );
pinMode( BOUTON_ALARME_CONTROLE, INPUT_PULLUP );
pinMode( BOUTON_SNOOZE, INPUT_PULLUP );
// Boucles pour les broches utilisées pour activer/désactiver les alarmes
for( int i=0 ; i<NBRALARMES ; i++ )
pinMode( BOUTON_ALARME[i], INPUT_PULLUP );
Il est important d'activer la résistance PULLUP sur le microcontrôlleur pour éviter de le sur alimenter. |
Sorties
Configuration des broches des leds des boutons et du piezo buzzer pour qu'elles se comportent comme des sorties.
// Initialisation des leds et du piezo
pinMode( LED_BOUTON_OK, OUTPUT );
pinMode( LED_BOUTON_SNOOZE, OUTPUT );
pinMode( PIEZO_BUZZER, OUTPUT );
Afficheur
Démarrer la connection I2C avec l'afficheur en lui insérant une adresse (0x70 par défaut).
// Adresse I2C des afficheurs
afficheurs.begin( 0x70 );
RTC
Démarrer la connection I2C avec le RTC
// Démarrer le lien avec le RTC en I2C
rtc.begin();
Réglage de l'heure si elle n'a pas encore été initialisé dans le RTC ou si elle n'est plus présente dans le RTC.
// Configuration de l'heure par l'utilisateur si ce n'a pas été encore fait
if ( !rtc.isrunning() ){
int h = 0;
int m = 0;
changerHeureVisuel( &h, &m );
rtc.adjust( DateTime(2018, 2, 20, h, m, 0) ); // Change l'heure de le RTC
}
EEPROM
L'EEPROM est formatté automatiquement si le fanion n'est pas égale à 255 ou si la version dans l'EEPROM n'est pas égale à la version du code pour éviter tout soucis de comptabilité.
La valeur du fanion a été choisie aléatoirement.
if( EEPROM.read(0) != 255 || EEPROM.read(1) != VERSION )
eepromConfiguration();
Luminosité
Changer la luminosité des afficheurs par rapport à la luminosité enregistré dans l'EEPROM.
// Définir la luminosité des afficheurs
afficheurs.setBrightness( EEPROM.read(2) );
Initialisation des variables des alarmes
Copier les données des alarmes enregistrées venant de l'EEPROM vers la structure des alarmes se trouvant dans le programme.
// Configuration des dates/heures sur les alarmes
DateTime maintenant = rtc.now();
int j = 0;
for( int i=3 ; i< ( NBRALARMES*2 )+6 ; i+=3 ){
alarme[j].heureSonne = DateTime( maintenant.year(), maintenant.month(), maintenant.day(), EEPROM.read(i), EEPROM.read(i+1), 0);
alarme[j].programme = EEPROM.read(i+2);
j++;
}
Loop
Dans la routine, différentes tâches tournent en boucle pour permettre au code de faire tourner l'ensemble des fonctions nécessaire.
Voici la routine au complet, les commentaires sont explicite à la compréhension.
/*
* Routine du code
*/
void loop() {
// ==============================================================
// ================ L'utilisateur peut intéragir ================
// ==============================================================
// Changer la luminosité
changerLuminosite();
// Changer heure
changerHeure();
// Changer les alarmes
changerHeureAlarme();
// On active/désactive une alarme ?
changerEtatAlarmes();
// Arrêter l'alarme ou la mettre en snooze
controlerAlarme();
// ==============================================================
// =================== Affichage de l'heure =====================
// ==============================================================
// Affichage de l'heure
afficherTemps();
// Afficher ou pas le séparateur (2 points)
afficherSeparateur();
// ==============================================================
// ============== Gestion automatique de l'alarme ===============
// ==============================================================
// Vérifie si une alarme sonne
alarmeGestionAutomatique();
}
Affichage
Comment afficher des valeurs ?
Voir un ancien wiki.
Ci-dessous, je vous propose une démo.
#include "Adafruit_LEDBackpack.h"
// Initialisation de l'afficheur 7 segments
Adafruit_7segment afficheurs = Adafruit_7segment();
boolean separateur = false;
void setup() {
// Adresse I2C des afficheurs
afficheurs.begin( 0x70 );
// Changer la luminosité des afficheurs
// 0 à 15
afficheurs.setBrightness( 13 );
// Afficher 1 2 3 4
afficher1234();
delay( 1000 );
}
void loop() {
// Changer l'état des 2 points
separateur = !separateur;
// Afficher les 2 points
afficheurs.drawColon( separateur );
// Envoyer les modifications aux afficheurs
afficheurs.writeDisplay();
delay( 500 );
// Afficher directement sur les 4 afficheurs (4321)
afficheurs.print(4321, DEC);
// Envoyer les modifications aux afficheurs
afficheurs.writeDisplay();
delay( 500 );
}
void afficher1234(){
// Afficheur 1 (droite à gauche) (point éteind)
afficheurs.writeDigitNum( 0, 1, false );
// Afficheur 2 (droite à gauche) (point éteind)
afficheurs.writeDigitNum( 1, 2, false );
// Afficheur 3 (droite à gauche) (point éteind)
afficheurs.writeDigitNum( 3, 3, false );
// Afficheur 4 (droite à gauche) (point allumé)
afficheurs.writeDigitNum( 4, 4, true );
// Envoyer les modifications aux afficheurs
afficheurs.writeDisplay();
}
Fonctions utiles pour l'afficheur
Ces 2 fonctions permettent d'afficher facilement les heures et les minutes. Elles permettent aussi de ne rien afficher (affichageNombre = false).
/*
* Afficher les minutes
*/
void affichageMinutes( int minutesT, boolean affichageNombre ){
if( affichageNombre ){
afficheurs.writeDigitNum( 3, minutesT/10, false );
afficheurs.writeDigitNum( 4, minutesT - ((int)(minutesT/10))*10, false );
}
else{
afficheurs.writeDigitNum( 3, 16, false );
afficheurs.writeDigitNum( 4, 16, false );
}
// Change les afficheurs
afficheurs.writeDisplay();
}
/*
* Afficher les heures
*/
void affichageHeures( int heuresT, boolean affichageNombre ){
// On affiche les heures
if( affichageNombre ){
afficheurs.writeDigitNum( 0, heuresT/10, false );
afficheurs.writeDigitNum( 1, heuresT - ((int)(heuresT/10))*10, false );
}
// On cache les heures
else{
afficheurs.writeDigitNum( 0, 16, false );
afficheurs.writeDigitNum( 1, 16, false );
}
// Change les afficheurs
afficheurs.writeDisplay();
}
Fonctions utiles
Fonction qui vérifie si un bouton est appuyé.
Elle compare si la première fois le bouton est appuyé et si la deuxième fois il l'est aussi. Si ils sont tout 2 appuyé alors on renvoie vrai, au sinon false.
boolean estAppuye( int pinAppuye ){
int val1 = digitalRead( pinAppuye );
delay( 10 );
int val2 = digitalRead( pinAppuye );
if ( val1 == val2 && val1 == 0 ) // 0 pour GND
return true;
else
return false;
}
'''Fonction qui vérfie si la seconde est passée.'''
Elle compare le temps précédent (ms) et le temps maintenant.
Si ok, on vérifie si on peut changer la valeur précédente à maintenant.
Passer uniquement false comme argument quand vous faites appel à cette fonction (sauf dans le cas des 2 points au milieu de l'afficheur).
<syntaxhighlight lang="c">
boolean clignote( boolean changerPeriode ){
unsigned long maintenant = millis();
if( maintenant - avantClignote >= 1000 ){
if( changerPeriode )
avantClignote = maintenant;
return true;
}
return false;
}
EEPROM
La mémoire EEPROM (Electrically-Erasable Programmable Read-Only Memory) est une mémoire ROM (Read-Only Memory : une mémoire qui ne perd pas ces données lors d'une mise hors tension) que l'on peut modifier via des impulsions électriques.
Cette mémoire a pour potentiel, de stocker des données même lorsque l'Arduino n'est plus alimenté.
Contenu de l'EEPROM
L'EEPROM de l'arduino UNO est capable d'enregistrer 1024 octets, ce qui offre 1024 entrées de données en 8bits !
Pour rendre plus compréhensible l'organisation de l'EEPROM, voici l'EEPROM sous forme de tableau :
Postions | Valeurs | Références |
0 | 255 | Fanion |
1 | 10 | Version |
2 | 15 | Luminosité |
3 | 0 | Heure Alarme 1 |
4 | 0 | Minute Alarme 1 |
5 | 0 | Programmé Alarme 1 |
6 | 0 | Heure Alarme 2 |
7 | 0 | Minute Alarme 2 |
8 | 0 | Programmé Alarme 2 |
... | ... | ... |
Lecture / Ecriture dans l'EEPROM
Premièrement, il est nécessaire d'ajouter la bibliothèque nécessaire au fonctionnement de l'EEPOM.
#include <EEPROM.h>
Pour écrire une donnée dans l'EEPROM, il suffit de définir une position et un nombre entier
// On écrit à la première position, la valeur 255
EEPROM.write( 0 , 255 );
Pour lire une donnée dans l'EEPROM, il suffit de définir une position où se trouve une information
// On lit la première entrée de 8 bits se trouvant dans la première position
EEPROM.read( 0 );
Fromattage de l'EEPROM
Il est important que cette EEPROM soit formattée avant toute utilisation. Pour se faire, une fonction existe dans la version test. Normalement, si vous avez effectué le test des boutons, l'EEPROM doit être déjà pré-formatté.
Si le formattage de l'EEPROM n'a pas été effectué, téléversez ce code :
#include <EEPROM.h>
void setup() {
Serial.begin( 9600 );
eepromConfiguration();
}
void loop() {
delay( 10000 ); // Attendre 10 secondes
}
/*
* Formatter l'EEPROM
*/
void eepromConfiguration(){
// Formatter l'EEPROM
for (int i = 0 ; i < EEPROM.length() ; i++)
EEPROM.write( i, 0 );
Serial.println( "EEPROM formatté !" );
// Valeur par défaut pour savoir si l'EEPROM est formatté
EEPROM.write( 0, 255 );
Serial.println( "Valeur par défaut définie !" );
// Définir une version
EEPROM.write( 1, 10 );
Serial.println( "Version définie !" );
// Définir une luminosité
EEPROM.write( 2, 15 );
Serial.println( "Valeur par défaut pour la luminosité est définie !" );
}
Faire sonner le piezo buzzer
Pour produire un son avec un piezo buzzer, c'est assez simple avec l'outil tone.
- Emettre un son : tone( PIN_BUZZER, FREQUENCE );
- Arrêter le son : noTone( PIN_BUZZER );
#define PIEZO_BUZZER 13
void setup() {
pinMode( PIEZO_BUZZER, OUTPUT );
}
void loop() {
// Emettre un son de fréquence 2000
tone( PIEZO_BUZZER, 2000 );
delay( 1000 ); // Atendre 1 secondes
// Emettre un son de fréquence 2000
tone( PIEZO_BUZZER, 1000 );
delay( 1000 );
// Ne plus émettre de son
noTone( PIEZO_BUZZER );
delay( 3000 );
}
Créé par Stefan pour MCHobby.be
Toute référence, mention ou extrait de cette traduction doit être explicitement accompagné du texte suivant : « Traduction par MCHobby (www.MCHobby.be) - Vente de kit et composants » avec un lien vers la source (donc cette page) et ce quelque soit le média utilisé.
L'utilisation commercial de la traduction (texte) et/ou réalisation, même partielle, pourrait être soumis à redevance. Dans tous les cas de figures, vous devez également obtenir l'accord du(des) détenteur initial des droits. Celui de MC Hobby s'arrêtant au travail de traduction proprement dit.