Projet IMA3 P6, 2016/2017, TD2

De Wiki d'activités IMA
Révision datée du 17 juin 2017 à 19:45 par Ezalczer (discussion | contributions) (Préparation de la séance)

Projet IMA3-SC 2016/2017 : <Réveil bien être>

Cahier des charges

Description du système


Pour le projet de Système communicant, nous avons décidé de réaliser un reveil bien être, permettant d'avoir une gestion du sommeil en temps réel ainsi qu'une personnalisation du réveil. L'idée générale est d'avoir un contrôle sur son sommeil et sur l'environnement qui nous entoure sans devoir passer par un site web ou un application mobile tout en ayant un design simple et reposant.


Ce réveil devra répondre à différents critères :

-Afficher l'heure actuelle

-Permettre de régler une horloge

-LEDs qui s'éclaire par intensité croissante

-Driver FM ou buzzer afin de jouer un son lorsque l'heure de l'horloge est atteinte

-Affichage de la météo (température et temps)

-Bouton heure du coucher, heure du réveil (Statistique)

-Température et humidité de la pièce


L'objet sera de forme ovale avec une partie plate afin d'avoir de la stabilité, le matériau qui l'entoure se devra d'être translucide pour laisser passer la lumière mais aussi opaque afin de ne pas avoir une vue sur l'électronique interne. Un ouverture sur l'avant permettra de laisser passer l'afficheur de l'heure ainsi que l'affichage des valeurs de la température, de l'humidité ainsi que de la météo. Une série de bouton permettront d'incrémenter l'heure ou l'horloge. De plus un bouton proche d'un LED de couleur permettra d'afficher si la gestion du sommeil est active ou non. Cette gestion s’arrête lors de l'appuie sur le bouton avec extinction de la LED ou lorsque l'horloge sonne. Les LEDS seront «blanches » et commenceront à éclaire une heure avant l'heure du réveil d'intensité croissante afin d'obtenir une lumière croissante semblable au lever du soleil et éviter le réveil brutal. Le buzzer ou le driver FM permettrait d'émettre un son lorsque l'heure du réveil est atteinte. Le choix de l'un ou l'autre sera en fonction de l'avancement et de la difficulté.

Le matériel

- 1 Arduino Uno (Remplacé par un FPGA)

- 1 Raspeberry Pi version 2 ou 3

- 1 câble d'alimentation ou Batterie

- 1 câble Ethernet

- 6 LEDs Blanches

- 1 LED de couleur

- 4 Afficheurs ou Un écran 3 ou 4 pouces

- 1 Capteur d'humidité

- 1 Capteur de température (Possibilité de les fabriquer)

- Carcasse en plastique

- 1 Buzzer ou 1 driver radio

- Résistances de différentes valeurs

Séance 1

Préparation de la séance

En amont de la séance, nous avons commencé à effectuer un travail de modélisation de notre système. Il nous faut une application Web permettant de régler le réveil de manière efficace. Nous avons envisagé les réglages suivants : réglage de l'heure de réveil, réglage de l'heure, choix de la mélodie au réveil. Nous avons également envisagé de mettre en place des statistiques sur le temps de sommeil. Nous aurons donc besoin d'une base de données pour sauvegarder des données utilisateur.

De plus, nous avons également bien avancé le programme sur Arduino et ce dernier est déjà en mesure d'effectuer les différentes actions requises du réveil : allumage des leds, gestion de l'heure etc...

Partie électronique

Cette séance a été l'occasion d'aborder un bon nombre de questions pratiques concernant le projet. Nous avons beaucoup profité de cette séance pour aborder la partie électronique car il s'agit de la partie la plus difficile à réaliser en-dehors de Polytech. Nous avons tout d'abord effectué un choix de capteurs pour obtenir les informations qui seront données à l'utilisateur. Nous avons choisi un capteur d'humidité et de température : le DH11 de Aosong Electronics. Ce capteur a l'avantage de nous donner deux informations intéressantes et d'être assez fréquemment utilisé. Il ne nous a donc pas été difficile de trouver des exemples d'utilisation sur internet.

Nous avons également choisi un bloc afficheur 7-segments permettant d'afficher 4 digits, que nous utiliserons pour tout nos affichages. Malheureusement, nous ne pourrons pas avoir de séparateur ":" entre nos heures et nos minutes mais cette version sera suffisante pour un prototype.

20170517 232347.jpg

Après avoir réglé ces premiers détails, nous nous sommes intéressés à la lecture et au contrôle de ces périphériques à l'aide de l'Arduino. Nous avons placé nos composants sur la plaque à essais et avons en premier lieu tenté d'afficher des chiffres sur l'afficheur 7 segments. Il a pour cela fallu choisir un mode de communication entre l'Arduino et l'afficheur et brancher les pins correspondant.. Nous avons pris un peu de temps pour obtenir un affichage correct à cause du fonctionnement particulier de l'afficheur : nos digits avaient tendance à se décaler vers la droite à chaque nouvel affichage.

Cerceau de Leds blanches en allumage progressif lors de l'envoi d'un char "blanc" / int fonctionne aussi

Utilisation du DH11 pour la température et l'humidité.

Utilisation de l'afficheur 7-seg avec l'arduino.

Modification d'architecture: Un FPGA remplace l'arduino pour la gestion de l'allumage des Leds et la gestion des afficheurs

Initiation FPGA

Partie informatique

La partie informatique de la première séance a été assez limitée car nous nous sommes principalement attardés sur l'électronique. Cependant, nous y avons pris plusieurs décisions importantes pour la suite du projet. Nous avons en effet décidé d'utiliser une architecture Node.js au lieu de la structure classique C/PHP. Ce choix est motivé en partie par le fait qu'un des membres de nos groupes utilisera ce framework dans le cadre de son stage, mais s'est également imposé comme plus pratique et moderne. Même si des fichiers d'exemple C nous étaient fournis pour la communication par port série ainsi que les websockets, nous avons préféré découvrir une technologie différente, quitte à devoir tout apprendre par nous-mêmes.

Cette première séance en informatique a donc essentiellement été utilisée pour se renseigner et lire de la documentation sur le fonctionnement de node.js, en particulier les modules serialport (port série) et socket.io (websockets). A l'issue de cette séance, nous avons créé sur le Gitlab les fichier source et avons essayé quelques exemples. Node.js n'étant pas installé sur les PC de la salle de projet, nous n'avons pas pu avancer beaucoup plus sur le développement du serveur durant la séance.

Séance 2

Préparation de la séance

Suite à la séance précédente, la préparation de cette séance a principalement été axée sur le développement de l'application web. Il était en effet plus difficile d'avancer sur la partie électronique car nous n'avions pas le matériel. Nous avons toutefois pu avancer un peu sur le code Arduino sur le modèle d'un des membres du groupe, notamment pour l'allumage progressif des LEDS.

Pour la partie informatique, nous avons commencé le développement à proprement parler sur un PC portable. Nous sommes conscients que des adaptations seront nécessaires lors de l'utilisation sur le Raspberry Pi mais il est plus simple pour commencer de pouvoir tester le programme en direct sur un PC. Nous avons donc installé node.js sur un PC personnel et avons commencé à faire différents tests sur le module socket.io. Nous avons donc créé un certain nombre de fichiers d'exemple afin d'en comprendre précisément l'utilisation. L'existence d'un code javascript correspondant côté client a grandement facilité la tâche car la partie client est principalement réduite à :

<script src="/socket.io/socket.io.js" type="text/javascript"></script>
var socket = io.connect('http://172.26.79.17:8080');

Toutefois, le développement côté client a été plus difficile et il a fallu commencer à déterminer un protocole d'échange de données. En javascript, il est facile de transférer des objets par websockets mais il nous fallait déterminer comment envoyer uniquement les informations nécessaires au moment opportun. La gestion du temps réel a également été assez difficile. En effet, node.js se comporte différemment de ce qu'on a l'habitude d'utiliser car il s'agit d'un processus non bloquant : lorsqu'une opération longue est effectuée, le programme continue et revient à la ligne correspondante une fois l'opération terminée. Il est donc essentiel de ne pas tenter d'accéder aux variables pendant le traitement d'un message, par exemple. En outre, node.js utilise énormément de fonctions de callback, c'est à dire des fonctions qui sont appelées une fois qu'un événement donné est survenu. La maitrise de ce principe est essentielle car socket.io s'appuie énormément dessus, notamment avec les méthodes :

- socket.on();
- socket.emit();
- socket.broadcast();

Avant le début de cette séance, nous avons divers fichiers d'exemple fonctionnels qu'il nous faut maintenant assembler pour obtenir un ensemble cohérent et répondant au cahier des charges.

Concernant la partie électronique, des calculs ont été fais afin d'avoir un allumage progressif et constant des leds sur une période d'une heure compris entre l'heure de l'alarme-1 et l'heure de l'alarme dans le but d'avoir une luminosité constante et non agressive. De plus, une lecture de la doc technique du buzzer nous a permis de trouver une fréquence d'utilisation semblable à l'alarme d'un réveil classique avec la possibilité si le temps le permet de créer une mélodie.

Partie électronique

Le matériel étant disponible en salle de TP, nous avons tester l'allumage des leds progressif sur différentes périodes afin de valider le choix en extrapolant pour une heure de temps. Pour cela, nous avons défini les variables suivantes : int led = 11; int brightness = 0; int fadeAmount = 5; int buzzer = 2; Nous avons brancher le buzzer sur la pin2 de l'arduino et la led sur la pin 11. La pin 11 accepte une valeur analogique, ce qui est nécessaire si nous voulons pouvoir changer l'intensité des leds. Dans le setup, nous avons définie c'est deux pins en sortie afin d'envoyer des valeurs aux deux composants,en code arduino, cela se définit par:

 pinMode(led, OUTPUT);
 pinMode(buzzer,OUTPUT);

Pour obtenir un affichage progressif sur une heure, nous utilisons:

analogWrite(led, brightness);
brightness = brightness + fadeAmount;
int x=1;

if(x=1)

   {
    brightness = brightness + fadeAmount;
    delay(2823); 
    if(brightness=255)
    {
     x=0;
     brightness=0;
    }

En effet, lors de l'envoie de la commande pour l'allumage, nous rentrons dans une boucle grâce à la variable X, permettant d’incrémenter la luminosité jusqu'à sa valeur max au bout d'une heure puis la variable x passe à 0 ce qui permet de sortir de la boucle et entraine l'extinction des leds.

Pour finir avec le buzzer, nous utilisons la fonction TONE permettant d'envoyer une fréquence à une sortie, ici le buzzer avec une fréquence de 440 hertz

tone(buzzer, 440);
noTone(buzzer);

Partie informatique

L'objectif de cette seconde séance était de commencer à mettre en commun tous nos fichiers d'exemple dans un ensemble cohérent. Nous avons créé le fichier principal server.js visible sur le Gitlab ainsi que le fichier dashboard.ejs.

Le format Embedded Javascript Template est un des langages de templates HTML les plus utilisés avec Javascript. Il permet de générer une page HTML, écrite à l'avance, en lui passant divers paramètres. Ce langage permet également l'utilisation de boucles et de conditions qui facilitent très nettement la création de pages lorsqu'on souhaite y insérer des valeurs pré-enregistrées. Dans notre cas, l'objectif est d'utiliser ce langage pour renseigner les choix de sonneries dans le champ de sélection. Nous avons donc créé la première partie de notre page destinée à l'application finale : le choix des sonneries.

Pour le test, nous avons mis trois sonneries différentes. Lorsque l'utilisateur appuie sur le bouton, un message est émis par les websockets contenant le choix de sonnerie ainsi qu'un message texte. Cette partie était relativement simple car pour le moment il ne s'agissait que d'un nom de fichier, mais il était évident que nous devions être en mesure de lire ce fichier. Afin de lire le fichier audio, nous sommes penchés sur le module play-sound.

Ce module possède comme avantage d'être simple d'utilisation, mais il est très récent et donc assez peu documenté et utilisé de manière générale. Il a donc été assez difficile de trouver des exemples, d'autant que nous voulions lire le fichier audio directement dans le navigateur et non sur le PC. Nous avons réussi à ouvrir et lancer la lecture du fichier sur le PC, mais ce dernier se lisait à une vitesse environ 2x inférieure à la vitesse normale, et ce quels que soient nos réglages. Nous en avons conclu qu'il s'agissait d'un problème interne au module et potentiellement lié au format audio. Vu que la lecture sur le PC n'est pas notre but final, nous ne nous sommes pas particulièrement attardés sur ce problème.

Séance 3

Préparation de la séance

Durant cette semaine, nous avons assez peu avancé sur le développement de l'application web, et plutôt sur sa forme et sa conception. Nous avons créé la feuille de style CSS pour la page, d'abord très simpliste, et avons amélioré le HTML.

Afin de pouvoir intégrer la feuille de style, il nous a fallu redéfinir le répertoire du serveur. En effet, de base, le serveur est créé dans un répertoire différent du répertoire du projet et le lien vers la feuille de style est donc erroné. Le module express pour node.js nous a permis de redéfinir le répertoire de lancement du serveur et ainsi de garantir tous les liens entre les fichiers avec la ligne :

app.use(express.static(__dirname + "/views"));

Nous avons profité de cette amélioration pour revoir la structure du programme. Nous avons créé un dossier views pour la partie EJS/CSS.

La semaine était consacré au capteur de température et à l'utilisation de l'afficheur et des différentes fonctions qui le composeront. En effet celui-ci devra afficher l'heure puis switcher sur la température et ce sur un cycle régulier. Pour cela, il fallait se documenter sur l'afficheur de sparkfun ainsi que sur l'utilisation du DH11 et prévoir l'utilisation de la température, puis en complément l'humidité.

Partie électronique

Concernant le DHT11, il existe une librairie pour arduino permettant en fonction du modèle de visualiser la température et l'humidité. #include "DHT.h" Nous avons donc branché la pin1 et la pin 4 du composant à l'alimentation(5V car 3.3V ne fonctionne que partiellement) et la masse. Puis la seconde pin sera connectée à la pin 5 de l'arduino. Pour ce faire nous le déclarons de cette manière : DHT dht(5,DHT11); //Pin et type du capteur Contrairement à l'utilisation précédente, nous n'allons pas déclarer le DHT comme une entrée-> pinMode(dht,INPUT) mais en utilisant dht.begin();

Le code permettant l'affichage et le calcul est: void loop() {

   float h = dht.readHumidity();
   float t = dht.readTemperature();
   if (isnan(t) || isnan(h)) 
   {
       Serial.println("Erreur");
   } 
   else 
   {
       Serial.print("Humidité: "); 
       Serial.print(h);
       Serial.print(" %\t");
       Serial.print("Temperature: "); 
       Serial.print(t);
       Serial.println(" *C");
   }

}

Nous stockons nos deux valeurs dans les variable h et t puis nous les affichons sur le moniteur série de l'arduino que l'on initialise avec serial.begin

Concernant l'afficheur, nous avons définis plusieurs variables ainsi que des defines pour l'initialisation.

define AFF_RESET 0x76

define AFF_CTRL_LUM 0xFA

define AFF_CTRL_BAUDRATE 0x7F

define AFF_CRTL_DP 0x77

define DP_1 0x01 // 0x01 -> point décimal de gauche 1/4

define DP_2 0x02 // 0x02 -> point décimal de 2/4

define DP_3 0x04 // 0x04 -> point décimal de 3/4

define DP_4 0x08 // 0x08 -> point décimal de droite 4/4

define DP_HORAIRE 0x10 // 0x10 -> double point horaire

define DP_APOSTROPHE 0x20 // 0x20 -> apostrophe

define AFF_CTRL_DIGITS_1 0x7B

define AFF_CTRL_DIGITS_2 0x7C

define AFF_CTRL_DIGITS_3 0x7D

define AFF_CTRL_DIGITS_4 0x7E

Nous avons ensuite défini un serial.write(AFF_RESET) qui permet lors de l'allumage de l'arduino de tester chaque digit de l'afficheur.

Pour écrire sur les digits nous utilisons la fonction :

void set_digits(char d1, char d2, char d3, char d4) {

 Serial.write(d1);
 Serial.write(d2);
 Serial.write(d3);
 Serial.write(d4);

}

Concernant la luminosité nous utilisons:

void set_luminosity(byte lum) {

 Serial.write(AFF_CTRL_LUM);
 Serial.write(lum);

}

La fonction suivante autorise l'utilisation de point décimaux, utiles lors de l'affichage de float comme pour la température

void set_dp(byte value) {

 Serial.write(AFF_CRTL_DP);
 Serial.write(value);

}

Nous allons maintenant définir les deux fonctions principales de l'afficheur à savoir, l'affichage de la température et l'affichage de l'heure:

void affiche_temperature(int temp, char unite) {

 if(temp > 999) temp = 999;
 if(temp < -99) temp = -99;

 char tmp[4] = { 0 };
 sprintf(tmp, "%3d", temp);
  
 set_dp(DP_APOSTROPHE);

 set_digits(tmp[0], tmp[1], tmp[2], unite);

}

void affiche_heure(byte heures, byte minutes) {

 if(heures > 99) heures = 99;
 if(minutes > 99) minutes = 99;

 char tmpA[3] = { 0 }, tmpB[3] = { 0 };
 sprintf(tmpA, "%02d", heures);
 sprintf(tmpB, "%02d", minutes);
  
 set_dp(DP_HORAIRE);

 set_digits(tmpA[0], tmpA[1], tmpB[0], tmpB[1]);

}

Elle permette de définir les champs d'utilisations des fonctions, par défaut nous avons choisis 999 et -99 pour la températures et 99 pour les heures et minutes. Bien que nous aurions pu utiliser 0 à 50 pour la température ainsi qu'une tolérance 24 et 60 pour les heures et minutes car nous n'utilisons que l'affichage de l'heure et non un compteur ou un chronomètre. Cependant dans le but d'une démarche d'amélioration et d'utilité, une plage plus grande permet de changer de capteur ou d'utilisation plus facilement.

Partie informatique

C'est pendant cette séance que nous avons commencé à travailler sur la Raspberry Pi. Une bonne partie de la séance a donc été consacrée au paramétrage et à l'installation. Nous avons effectué les branchements de la Raspberry et avons effectué les modifications permettant de se connecter au réseau. Un accès à internet était absolument indispensable pour nous car nous devions installer node.js. L'installation de node.js s'est passés sans problème, cependant certains modules n'ont pas pu s'installer tels que play-sound et serialport. En effet, ces derniers reposent sur des fichiers déjà présents sur le PC et qui ne font pas partie de l'architecture Raspberry Pi. Pour le moment, nous avons décidé de ne pas nous attarder sur ces problèmes et de plutôt se concentrer sur le réglage de l'heure.

L'heure est bien évidemment une problématique majeure pour un réveil, et d'autant plus sur un Raspberry Pi. Il est nécessaire d'avoir une connexion internet pour le réglage de l'heure car il n'y a pas d'horloge matérielle. Nous nous sommes en premier lieu attaqués au réglage de l'heure de réveil. Nous avons décidé d'utiliser un champ HTML5 de type time. Même si ce champ n'est actuellement pas supporté par firefox et est remplacé par un champ de texte, une bonne partie des navigateurs modernes possède un champ spécifique. En particulier pour les utilisateurs sur mobile, le datepicker des navigateurs portables sera plus pratique que deux champs séparés "heures" et "minutes".

Nous avons écrit les fonctions d'envoi et de réception par websockets pour le choix de l'heure de réveil. Pour le moment, le serveur affiche simplement l'heure reçue dans la console. Le formatage de cette heure a été assez difficile car nous voulons impérativement un affichage de la forme HH:MM mais le champ time renvoie des données sous forme d'entiers qui sont donc tronqués si inférieurs à 10. Nous avons fini par convertir ces valeurs en string, car de toute façon la conversion s'effectue de manière naturelle avec javascript.

Séance supplémentaire 1

Partie électronique

Nous nous sommes intéressés à la liaison série ainsi qu'à la communication entre la partie électronique et informatique. Pour cela, il fallait définir la liaison série et le programme principale en fonction des variables reçues et envoyées. Nous avions donc le code suivant:

if ( Serial.available() ) {
   Serial.readBytes(buffheure,4);

}

En fonction de la lecture de buffheure, nous pouvions aller dans les différentes options en effet si le premier bit de buffheure est égale à 5, nous allumons progressivement les heures if(buffheure[0]=='5')

   {  
     analogWrite(led, brightness);
     brightness = brightness + fadeAmount;
     int x=1;
   }

if(x=1)

   {
    brightness = brightness + fadeAmount;
    //delay(2823); 
    if(brightness=255)
    {
     x=0;
     brightness=0;
    }
   }

Si celui-ci est égale à 6, nous utilisons le buzzer: if(buffheure[0]=='6')

     {        
       tone(buzzer, 440);
     }
   else{
       noTone(buzzer);
     }

Et lors d'une utilisation "classique", Nous avions: if(i<5){

      affiche_temperature(t,'C');
     }
   else{
     if(buffheure[0]<='2'){
       heure=buffheure[0]*10+buffheure[1];
       minute=buffheure[2]*10+buffheure[3];
       heure=heure-16;
       minute=minute-16;
     }
     affiche_heure(heure,minute);
     
     }
     i++;
     if(i>=10)i=0;

Qui permet l'affichage en cycle de l'heure et de la température ainsi que la modification de l'heure si nécessaire. Lorsque nous recevions l'heure, la valeur reçue était égale à valeurenvoyée+16 c'est pourquoi nous devions soustraire 16 aux heures et minutes.

Le programme principale complet est défini si dessous :

void loop() {

 byte buffheure[4];
 float h = dht.readHumidity();
 float t = dht.readTemperature();
 if ( Serial.available() ) {
   Serial.readBytes(buffheure,4);
   if(x=1)
   {
    brightness = brightness + fadeAmount;
    //delay(2823); 
    if(brightness=255)
    {
     x=0;
     brightness=0;
    }
   }
   if(buffheure[0]=='5')
   {  
     analogWrite(led, brightness);
     brightness = brightness + fadeAmount;
     int x=1;
   }
   else if(buffheure[0]=='6')
     {        
       tone(buzzer, 440);
     }
   else{
       noTone(buzzer);
     }
   if(i<5){
      affiche_temperature(t,'C');
      //Serial.println(t);
     }
   else{
     if(buffheure[0]<='2'){
       heure=buffheure[0]*10+buffheure[1];
       minute=buffheure[2]*10+buffheure[3];
       heure=heure-16;
       minute=minute-16;
     }
     affiche_heure(heure,minute);
     
     }
     i++;
     if(i>=10)i=0;  
 }

}

IMG 20170614 193329-ConvertImage.jpg Ceci correspond à l'affichage sur l'écran, voici l'affichage sur le 7-segment :

IMG 20170614 193333-ConvertImage.jpgIMG 20170614 193337-ConvertImage.jpg

Partie informatique

Comme nous avions seulement commencé à travailler sur la Raspberry Pi à la dernière séance, il restait beaucoup de travail à faire en-dehors de séances, en particulier au niveau de l'architecture du projet. L'application requiert une base de données pour stocker les informations de l'utilisateur, et doit être capable de communiquer avec l'Arduino et/ou le FPGA via le port série. Il était donc nécessaire d'avoir accès à la plateforme définitive du projet pour pouvoir mettre en place ces fonctionnalités.

Au niveau des fonctionnalités, nous avons tout d'abord ajouté le champ de réglage de l'heure. Ce dernier offre une possibilité de réglage automatique basé sur l'heure de la Raspberry Pi à l'heure de Paris, et de réglage manuel. Ce réglage se présente sous la forme d'un champ HTML time comme pour la sélection de l'heure de réveil, et ne permet pas de régler les secondes car nous n'avons pas jugé cela nécessaire. L'heure réglée est sauvegardée sous la forme d'une différence en heures et en minutes : l'heure de l'utilisateur est calculée à partir de l'heure de la Raspberry Pi en appliquant les différences données. Pour l'heure de réveil et le réglage de l'heure, nous avons ajouté un message de vérification envoyé par websockets qui permet de valider ou non le réglage.

Html time ffmobile.png

- Pour la base de données, nous avons choisi Postgres car c'est le système que nous avons utilisé jusqu'à maintenant. Ce SGBD est assez lourd et pourrait probablement être remplacé avantageusement par MySQL ou SQLite par souci de légèreté. Cependant, dans le cas d'une amélioration future de l'application, par exemple pour permettre à plusieurs utilisateurs d'utiliser le même serveur simultanément, ce système pourrait s'avérer adapté. De même, si nous mettons en place des statistiques sur le sommeil, il deviendra nécessaire de stocker une grande quantité de données. Afin d'accéder à postgres, nous avons utilisé le module pg pour node.js qui offre une utilisation simple et adaptée à nos besoins. Pour pouvoir connecter notre application à notre base de données, il a fallu modifier les autorisations d'accès dans le fichier pg_hba.conf. Notre base de données est très simple : elle contient deux tables, une contenant l'heure de réveil et une autre le réglage de l'heure par l'utilisateur.

Conclusion