Différences entre versions de « Mon-Reveil-Programmer »

De MCHobby - Wiki
Sauter à la navigation Sauter à la recherche
 
(120 versions intermédiaires par 2 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
 
{{Mon-Reveil-NAV}}
 
{{Mon-Reveil-NAV}}
  
Si vous désirez obtenir le code complet directement, cliquez [https://github.com/mchobby/Mon-Reveil-1/archive/master.zip ici]
+
== Introduction ==
 +
Cette partie du tutoriel reprend le chargement du code du réveil... et s'attarde sur les éléments principaux du code.
  
{{ambox | text = N'hésitez pas à [[Mon-Reveil-Tester|tester]] vos connectiques si ce n'a pas été encore réalisé !}}
+
== Environnement de travail ==
 +
Vous pouvez obtenir la totalité du code sur le lien suivant:
  
== Environnement de travail ==
+
{{download-box|Télécharger l'intégralité du code|https://github.com/mchobby/Mon-Reveil-1/archive/master.zip}}
  
''Dans ce tutoriel, nous travaillons sur l'environnement d'ArduinoIDE. Si vous ne l'avez pas encore installé, vous pouvez le télécharger [https://www.arduino.cc/en/Main/Software ici].''
+
Si se n'a pas été encore fait, pensez à [[Mon-Reveil-Tester|tester vos connectiques]] avec le programme de test!
  
Passons au vif du sujet.
+
Dans ce tutoriel, nous travaillons Avec l'environnement d'ArduinoIDE. Si vous ne l'avez pas encore installé, vous pouvez le télécharger [https://www.arduino.cc/en/Main/Software ici].
  
* Premièrement télécharger le fichier compressé du réveil, se trouvant [https://github.com/mchobby/Mon-Reveil-1/archive/master.zip ici].
+
Passons au vif du sujet:
* Décompressé le fichier zip.
+
* Il faut installer le bibliothèque de [[Mon-Reveil-Lib|l'afficheur 4x7 segments]]
* Dans le dossier ''"Mon Reveil"'', ajoutez-y les fichiers '''Adafruit_LEDBackpack.h''' et '''Adafruit_LEDBackpack.cpp''' (disponible [https://github.com/adafruit/Adafruit_LED_Backpack ici]).
+
* Il faut télécharger les sources du projet [https://github.com/mchobby/Mon-Reveil-1/archive/master.zip ici].
* Ouvrez le projet sur ArduinoIDE :
+
* Décompresser le fichier zip téléchargé.
 +
* Vous trouverez les sources du projet dans le dossier "'''Mon-Reveil'''".<br />Ouvrez le projet sur ArduinoIDE :
  
  Menu -> Ouvrir -> "où_le_fichier_décompressé_est/Mon-Reveil-1-master/Mon-Reveil/Mon-Reveil.ino"
+
Menu -> Ouvrir -> "../Mon-Reveil-1-master/Mon-Reveil/Mon-Reveil.ino"
  
[[Fichier:Mon-Reveil-60.jpg|640px]]<small><br />''Contenu du projet - cliquez pour agrandir''</small>
+
[[Fichier:Mon-Reveil-60b.jpg]]<small><br />''Contenu du projet - cliquez pour agrandir''</small>
  
== Explication du code ==
+
== L'entête du programme ==
  
Pour mieux comprendre le code, je vais vous expliquez chaque parties du code ainsi que les différentes procédures à suivre.
+
Dans l'entête se trouvent l'ensemble des variables globales et autres éléments utiles.
  
 
=== Les inclusions de bibliothèques ===  
 
=== Les inclusions de bibliothèques ===  
 +
 +
Il est nécessaire d'ajouter ces bibliothèques pour le bon fonctionnement du code.
 +
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
 
#include "Adafruit_LEDBackpack.h" // Afficheurs
 
#include "Adafruit_LEDBackpack.h" // Afficheurs
Ligne 33 : Ligne 39 :
 
</syntaxhighlight>
 
</syntaxhighlight>
  
* 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 sonnerie d'alarmes
+
* Le fichier '''melodies.h''' contient plusieurs mélodies que vous pouvez définir comme sonneries d'alarmes.
  
=== Définir la position des boutons, des leds et du buzzer ===
+
=== Définir les broches utilisés ===
  
Ci-dessous, se trouve l'ensemble des entrées des boutons et piezzo buzzer
+
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.
 
   
 
   
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
Ligne 57 : Ligne 65 :
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== Personnaliser les paramètres par défaut ===
+
{{ambox | text = Les boutons d'arcades utilisent les entrées analogiques comme entrées digitales. Pour plus d'informations, voir si dessous.}}
 +
[[Fichier:Mon-Reveil-65.png|640px]]
 +
<small><br />''Connectiques de l'Arduino UNO - cliquez pour agrandir''<br />Source: [http://www.pighixxx.com/test/wp-content/uploads/2017/05/uno.png Pighixxx]</small>
 +
 
 +
=== Personnaliser les paramètres ===
 +
Il est possible de personnaliser les paramètres par défaut du projet (ex: les alarmes).
  
Il est possible de personnaliser les paramètres par défaut des alarmes.
+
{{ambox|text=Nous recommandons de tester le projet avec ses paramètres par défaut avant de les modifiers}}
  
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
Ligne 73 : Ligne 86 :
 
</syntaxhighlight>
 
</syntaxhighlight>
  
* '''SNOOZE_ATTENTE''' permet de définir combien de secondes le snooze va encore attendre avant de se remettre à sonner.
+
* '''SNOOZE_ATTENTE''' permet de définir combien de secondes le "bouton snooze" va mettre l'alarme en veille avant de se remettre à sonner. <font color="red">La valeur par défaut est de 10 secondes. '''Nous recommandons 5 minutes, soit 300 secondes'''.</font>
* '''DUREE_ALARME''' permet de définir combien de secondes les alarmes vont sonner.
+
* '''DUREE_ALARME''' permet de définir combien de secondes MAX les alarmes vont sonner si le bouton d'arrêt n'est pas pressé. <font color="red">La valeur par défaut est de 20 secondes. '''Nous recommandons 60 minutes, soit 3600 secondes'''.</font>
* '''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.
+
* '''BOUTON_ALARM''' permet de définir sur quelles broches les boutons d'alarme 1 à 4 sont branchés. Presser un bouton permet d'activer l'alarme correspondante. Re-presser le bouton une seconde fois permet de désactive l'alarme. Cette constante permet aussi de savoir combien d'alarmes doit être géré par le croquis.
 
* '''VITESSE_LECTURE''' permet de définir a quelle vitesse la mélodie va être jouée.
 
* '''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.
+
* '''MELODIE''' permet de définir la mélodie jouée. L'ensemble des mélodies se trouvent dans le fichier ''melodies.h''.
  
{{ambox | text = Il est important d'activer la résistance PULLUP sur le microcontrôlleur pour éviter de le sur alimenter}}
+
== setup() ==
 +
La fonction setup() permet d'initialiser les éléments matériels du réveil.
  
 +
=== Port série ===
 +
Ouverture du port série au débit de données de 9600 bauds, pour permettre la communication entre un arduino et un ordinateur via usb à des fins de débogages.
 +
<syntaxhighlight lang="c">
 +
Serial.begin( 9600 );
 +
</syntaxhighlight>
  
== Créer votre mélodie ==
+
=== Les entrées ===
 +
Configuration des broches en entrées (pour les boutons).
 +
<syntaxhighlight lang="c">
 +
// 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 );
 +
// Boucle pour les broches utilisées pour activer/désactiver les alarmes
 +
for( int i=0 ; i<NBRALARMES ; i++ )
 +
  pinMode( BOUTON_ALARME[i], INPUT_PULLUP );
 +
</syntaxhighlight>
 +
{{ambox-stop | text = Il est important d'activer la résistance PULLUP sur le microcontrôleur pour éviter de le sur alimenter.}}
  
Il est possible d'ajouter facilement une mélodie à la bibliothèque '''melodie.h'''.
+
=== Les sorties ===
 +
Configuration des broches en sortie pour:
 +
* Les leds des boutons "snooze" et "OK" (Alarme Stop)
 +
* Le piezo buzzer
 +
<syntaxhighlight lang="c">
 +
// Initialisation des leds et du piezo
 +
pinMode( LED_BOUTON_OK, OUTPUT );
 +
pinMode( LED_BOUTON_SNOOZE, OUTPUT );
 +
pinMode( PIEZO_BUZZER, OUTPUT );
 +
</syntaxhighlight>
  
Je vous invite à lire la bibliothèque de manière à comprendre son fonctionnement et si vous ne comprenez pas tout, je vous invite à lire le contenu suivant.  
+
=== Initialiser l'afficheur ===
 +
Initialisation de l'afficheur I2C (sur son adresse I2C par défaut, 0x70).
 +
<syntaxhighlight lang="c">
 +
afficheurs.begin( 0x70 );
 +
</syntaxhighlight>
 +
 
 +
=== RTC ===
 +
Initialisation de l'horloge RTC I2C.
 +
<syntaxhighlight lang="c">
 +
// Démarrer le lien avec le RTC en I2C
 +
rtc.begin();
 +
</syntaxhighlight>
  
=== A quoi sert l'antislash ? ===
+
Réglage d'une heure par défaut si elle n'a pas encore été initialisé dans le RTC ou si elle n'est plus présente dans le RTC.
 +
<syntaxhighlight lang="c">
 +
// 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
 +
}
 +
</syntaxhighlight>
 +
 
 +
=== EEPROM-Setup ===
 +
L'EEPROM est formattée automatiquement si le fanion (magic key) n'est pas égale à 255 ou si la version dans l'EEPROM n'est pas égale à la version attendue par le croquis (ps: permet d'éviter tout soucis de compatibilité).
 +
 
 +
<syntaxhighlight lang="c">
 +
if( EEPROM.read(0) != 255 || EEPROM.read(1) != VERSION )
 +
  eepromConfiguration();
 +
</syntaxhighlight>
 +
{{ambox | text = La valeur du fanion (magic key) à été choisie par le développer.}}
  
Comme vous pouvez voir dans la bibliothèque, chacune des mélodies contiennent un antislash à la fin de chaques lignes de code (excepté la dernière) :
+
=== Luminosité ===
 +
Changer la luminosité des afficheurs avec celle enregistrée enregistré dans l'EEPROM.
 +
<syntaxhighlight lang="c">
 +
// Définir la luminosité des afficheurs
 +
afficheurs.setBrightness( EEPROM.read(2) );
 +
</syntaxhighlight>
  
 +
=== Initialisation des variables des alarmes ===
 +
Copier les heures des alarmes enregistrées dans l'EEPROM vers la structure de données des alarmes en mémoire.
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
#define ALARM1{ \
+
// Configuration des dates/heures sur les alarmes
   {NOTE_A4, 20},\
+
DateTime maintenant = rtc.now();
   {NOTE_C4,  20}}
+
 
 +
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++;
 +
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
L'antislash ('''\''') sert de remise à la ligne pour le define et son contenu. Si cet antislash n'est pas mit, il sera impossible de compiler le code.  
+
On commence à la position 3, car les 3 premières valeurs de l'EEPROM sont utilisées pour :
 +
* Le fanion (Magic Key)
 +
* La version de la structure de donnée stockée dans l'EEPROM.
 +
* La luminosité
  
Si vous ne désirez pas mettre d'antislash, il vous sera obligatoire d'écrire tout le contenu du define en une ligne de code.
+
On utilise des incrémentations par 3 (et non par 1) de manière à lire un enregistrement tous les 3 octets en EEPROM.  
  
Pour des raisons de mise en page, nous avons préféré mettre l'antislash à fin de chaques lignes de façon à rendre le code plus lisible.
+
Chaque enregistrement de 3 octets contient:
 +
* Heure
 +
* Minute
 +
* Alarme activée ?
  
=== Que contiennent les define ? ===
+
Pour plus d'informations logiques, voir [[Mon-Reveil-Programmer#EEPROM|ici]].
  
Le define est un tableau 2 dimensions contenant des nombres entiers (int).
+
== loop() ==
 +
La fonction loop() exécutée régulièrement par Arduino Uno prend en charge les différentes tâches au fonctionnement du réveil.
 +
 
 +
Voici la fonction complète, les commentaires décrivent le fonctionnement.
  
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
#define ALARM1{ \
+
/*
   {NOTE_A4,  20},\
+
* Routine du code
   {NOTE_C4,  20}}
+
*/
 +
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();
 +
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
* La première colonne contient les notes a jouer
+
== Affichage ==
** La note (exemple: NOTE_A4) fait référence à un nombre entier se trouvant dans la bibliothèque ''pitches.h''. Cette bibliothèque provient du [https://github.com/nseidle/AxelF_DoorBell/blob/master/pitches.h GitHub de nseidle].  
+
=== Comment afficher des valeurs ? ===
{{ambox | text = Pour plus de précisons sur le fonctionnement de ''pitches.h'', visitez le [https://github.com/nseidle/AxelF_DoorBell/wiki/How-to-convert-sheet-music-into-an-Arduino-Sketch wiki de nseidle] (en anglais).}}
+
 
* La deuxièmre colonne contient la durée de chaques notes en milisecondes
+
Voir un [[ADF-LED-BACKPACK-I2C-Adresse|ancien wiki]].
 +
 
 +
Ci-dessous, nous vous proposons un petit exemple démontrant l'usage de l'afficheur 4x7 segments.
 +
<syntaxhighlight lang="c">
 +
#include "Adafruit_LEDBackpack.h"
 +
 
 +
// Initialisation de l'afficheur 7 segments
 +
Adafruit_7segment afficheurs = Adafruit_7segment();
 +
 
 +
boolean separateur = false;
  
=== Comment convertir une musique en mélodie ? ===
+
void setup() {
 +
 
 +
  // Adresse I2C des afficheurs
 +
  afficheurs.begin( 0x70 );
  
Malheureusement, nous avons pas trouvé un outil capable de convertir une musique (en entière) en mélodie polyphonique.
+
  // 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();
 +
}
 +
</syntaxhighlight>
 +
 +
=== Fonctions utilitaires d'affichage ===
 +
Les 2 fonctions ci-dessous permettent d'afficher facilement l'heure et les minutes.
 +
 +
Elles permettent aussi de ne rien afficher (affichageNombre = false).
 +
 +
<syntaxhighlight lang="c">
 +
/*
 +
* 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();
 +
}
 +
</syntaxhighlight>
 +
 +
== Fonctions utilitaires générales ==
 +
 +
'''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.
 +
 +
<syntaxhighlight lang="c">
 +
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;
 +
 +
</syntaxhighlight>
 +
 +
'''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;
 +
}   
 +
</syntaxhighlight>
 +
 +
== EEPROM ==
 +
La mémoire EEPROM (Electrically-Erasable Programmable Read-Only Memory) est une mémoire permanente de type 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 permet 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!
 +
 +
Les enregistrements contenu dans l'EEPROM sont représentés dans le tableau ci-dessous pour faciliter la compréhension:
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
| align="center" | Postions
 +
| align="center" | Valeurs
 +
| align="center" | Références
 +
|- style="font-size: 90%"
 +
| align="center" | 0
 +
| align="center" | 255
 +
| align="center" | Fanion (Magic Key)
 +
|- style="font-size: 90%"
 +
| align="center" | 1
 +
| align="center" | 10
 +
| align="center" | Version
 +
|- style="font-size: 90%"
 +
| align="center" | 2
 +
| align="center" | 15
 +
| align="center" | Luminosité
 +
|- style="font-size: 90%"
 +
| align="center" | 3
 +
| align="center" | 0
 +
| align="center" | Heure Alarme 1
 +
|- style="font-size: 90%"
 +
| align="center" | 4
 +
| align="center" | 0
 +
| align="center" | Minute Alarme 1
 +
|- style="font-size: 90%"
 +
| align="center" | 5
 +
| align="center" | 0
 +
| align="center" | Programmé Alarme 1
 +
|- style="font-size: 90%"
 +
| align="center" | 6
 +
| align="center" | 0
 +
| align="center" | Heure Alarme 2
 +
|- style="font-size: 90%"
 +
| align="center" | 7
 +
| align="center" | 0
 +
| align="center" | Minute Alarme 2
 +
|- style="font-size: 90%"
 +
| align="center" | 8
 +
| align="center" | 0
 +
| align="center" | Programmé Alarme 2
 +
|- style="font-size: 90%"
 +
| align="center" | ...
 +
| align="center" | ...
 +
| align="center" | ...
 +
|}
 +
 +
Le fanion (ou Magic Key) est une valeur arbitraire choisie par le développeur et écrite dans le premier octet de l'EEPROM par le croquis Arduino.
 +
 +
En lisant le premier octet de l'EEPROM et en vérifiant s'il contient le fanion (Magic Key) il est possible de savoir si l'EEPROM à déjà initialisée par le croquis Arduino.
 +
 +
=== Lecture / Ecriture dans l'EEPROM ===
 +
 +
Premièrement, il est nécessaire d'ajouter la bibliothèque nécessaire au fonctionnement de l'EEPOM.
 +
 +
<syntaxhighlight lang="c">
 +
#include <EEPROM.h>
 +
</syntaxhighlight>
 +
 +
Pour écrire une donnée dans l'EEPROM, il suffit de définir une position et un nombre entier
 +
 +
<syntaxhighlight lang="c">
 +
// On écrit à la première position, la valeur 255
 +
EEPROM.write( 0 , 255 ); 
 +
</syntaxhighlight>
 +
Pour lire une donnée dans l'EEPROM, il suffit de définir une position où se trouve une information
 +
 +
<syntaxhighlight lang="c">
 +
// On lit la première entrée de 8 bits se trouvant dans la première position
 +
EEPROM.read( 0 );
 +
</syntaxhighlight>
 +
 +
=== Formater de l'EEPROM ===
 +
Il est important que cette EEPROM soit formatée et initialisé avec des valeurs par défaut avant toute utilisation.
 +
 +
Pour se faire, une fonction existe dans le croquis de "Test" (celui qui teste les boutons).
 +
 +
Normalement, si vous avez exécutez le [[Mon-Reveil-Tester|test des boutons]] alors l'EEPROM est déjà pré-formatté.
 +
 +
Si l'EEPROM n'est pas encore formatée et initialisée alors saisissez le code suivant:
 +
 +
<syntaxhighlight lang="c">
 +
#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 !" );
 +
}
 +
</syntaxhighlight>
 +
 +
== 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 );'''
 +
<syntaxhighlight lang="c">
 +
#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 );
 +
}
 +
</syntaxhighlight>
  
 
{{Mon-Reveil-TRAILER}}
 
{{Mon-Reveil-TRAILER}}

Version actuelle datée du 9 avril 2018 à 15:58


MCHobby investit du temps et de l'argent dans la réalisation de traduction et/ou documentation. C'est un travail long et fastidieux réalisé dans l'esprit Open-Source... donc gratuit et librement accessible.
SI vous aimez nos traductions et documentations ALORS aidez nous à en produire plus en achetant vos produits chez MCHobby.

Introduction

Cette partie du tutoriel reprend le chargement du code du réveil... et s'attarde sur les éléments principaux du code.

Environnement de travail

Vous pouvez obtenir la totalité du code sur le lien suivant:

Download-icon.pngTélécharger l'intégralité du code

Si se n'a pas été encore fait, pensez à tester vos connectiques avec le programme de test!

Dans ce tutoriel, nous travaillons Avec l'environnement d'ArduinoIDE. Si vous ne l'avez pas encore installé, vous pouvez le télécharger ici.

Passons au vif du sujet:

  • Il faut installer le bibliothèque de l'afficheur 4x7 segments
  • Il faut télécharger les sources du projet ici.
  • Décompresser le fichier zip téléchargé.
  • Vous trouverez les sources du projet dans le dossier "Mon-Reveil".
    Ouvrez le projet sur ArduinoIDE :
Menu -> Ouvrir -> "../Mon-Reveil-1-master/Mon-Reveil/Mon-Reveil.ino"

Mon-Reveil-60b.jpg
Contenu du projet - cliquez pour agrandir

L'entête du programme

Dans l'entête se trouvent l'ensemble des variables globales et autres éléments utiles.

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

Mon-Reveil-65.png
Connectiques de l'Arduino UNO - cliquez pour agrandir
Source: Pighixxx

Personnaliser les paramètres

Il est possible de personnaliser les paramètres par défaut du projet (ex: les 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 "bouton snooze" va mettre l'alarme en veille avant de se remettre à sonner. La valeur par défaut est de 10 secondes. Nous recommandons 5 minutes, soit 300 secondes.
  • DUREE_ALARME permet de définir combien de secondes MAX les alarmes vont sonner si le bouton d'arrêt n'est pas pressé. La valeur par défaut est de 20 secondes. Nous recommandons 60 minutes, soit 3600 secondes.
  • BOUTON_ALARM permet de définir sur quelles broches les boutons d'alarme 1 à 4 sont branchés. Presser un bouton permet d'activer l'alarme correspondante. Re-presser le bouton une seconde fois permet de désactive l'alarme. Cette constante permet aussi de savoir combien d'alarmes doit être géré par le croquis.
  • 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.

setup()

La fonction setup() permet d'initialiser les éléments matériels du réveil.

Port série

Ouverture du port série au débit de données de 9600 bauds, pour permettre la communication entre un arduino et un ordinateur via usb à des fins de débogages.

Serial.begin( 9600 );

Les entrées

Configuration des broches en entrées (pour les boutons).

// 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 );
// Boucle pour les broches utilisées pour activer/désactiver les alarmes
for( int i=0 ; i<NBRALARMES ; i++ )
  pinMode( BOUTON_ALARME[i], INPUT_PULLUP );

Les sorties

Configuration des broches en sortie pour:

  • Les leds des boutons "snooze" et "OK" (Alarme Stop)
  • Le piezo buzzer
// Initialisation des leds et du piezo
pinMode( LED_BOUTON_OK, OUTPUT );
pinMode( LED_BOUTON_SNOOZE, OUTPUT );
pinMode( PIEZO_BUZZER, OUTPUT );

Initialiser l'afficheur

Initialisation de l'afficheur I2C (sur son adresse I2C par défaut, 0x70).

afficheurs.begin( 0x70 );

RTC

Initialisation de l'horloge RTC I2C.

// Démarrer le lien avec le RTC en I2C
rtc.begin();

Réglage d'une heure par défaut 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-Setup

L'EEPROM est formattée automatiquement si le fanion (magic key) n'est pas égale à 255 ou si la version dans l'EEPROM n'est pas égale à la version attendue par le croquis (ps: permet d'éviter tout soucis de compatibilité).

if( EEPROM.read(0) != 255 || EEPROM.read(1) != VERSION )
  eepromConfiguration();

Luminosité

Changer la luminosité des afficheurs avec celle enregistrée enregistré dans l'EEPROM.

// Définir la luminosité des afficheurs
afficheurs.setBrightness( EEPROM.read(2) );

Initialisation des variables des alarmes

Copier les heures des alarmes enregistrées dans l'EEPROM vers la structure de données des alarmes en mémoire.

// 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++;
}

On commence à la position 3, car les 3 premières valeurs de l'EEPROM sont utilisées pour :

  • Le fanion (Magic Key)
  • La version de la structure de donnée stockée dans l'EEPROM.
  • La luminosité

On utilise des incrémentations par 3 (et non par 1) de manière à lire un enregistrement tous les 3 octets en EEPROM.

Chaque enregistrement de 3 octets contient:

  • Heure
  • Minute
  • Alarme activée ?

Pour plus d'informations logiques, voir ici.

loop()

La fonction loop() exécutée régulièrement par Arduino Uno prend en charge les différentes tâches au fonctionnement du réveil.

Voici la fonction complète, les commentaires décrivent le fonctionnement.

/*
 * 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, nous vous proposons un petit exemple démontrant l'usage de l'afficheur 4x7 segments.

#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 utilitaires d'affichage

Les 2 fonctions ci-dessous permettent d'afficher facilement l'heure 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 utilitaires générales

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).

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 permanente de type 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 permet 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!

Les enregistrements contenu dans l'EEPROM sont représentés dans le tableau ci-dessous pour faciliter la compréhension:

Postions Valeurs Références
0 255 Fanion (Magic Key)
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
... ... ...

Le fanion (ou Magic Key) est une valeur arbitraire choisie par le développeur et écrite dans le premier octet de l'EEPROM par le croquis Arduino.

En lisant le premier octet de l'EEPROM et en vérifiant s'il contient le fanion (Magic Key) il est possible de savoir si l'EEPROM à déjà initialisée par le croquis Arduino.

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 );

Formater de l'EEPROM

Il est important que cette EEPROM soit formatée et initialisé avec des valeurs par défaut avant toute utilisation.

Pour se faire, une fonction existe dans le croquis de "Test" (celui qui teste les boutons).

Normalement, si vous avez exécutez le test des boutons alors l'EEPROM est déjà pré-formatté.

Si l'EEPROM n'est pas encore formatée et initialisée alors saisissez le code suivant:

#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.