Commit e18f6847242d6f6737746e402a3cfda3e70321fd

Authored by Geoffrey PREUD'HOMME
1 parent f629950c

Définition de comment est stocké le temps

Showing 3 changed files with 65 additions and 27 deletions   Show diff stats
@@ -37,35 +37,22 @@ Voici la hiérarchie du menu qui sera utilisée pour configurer le thermostat : @@ -37,35 +37,22 @@ Voici la hiérarchie du menu qui sera utilisée pour configurer le thermostat :
37 - Heures 37 - Heures
38 - Minutes 38 - Minutes
39 39
40 -On peut passer d'un menu à son menu hiérarchiquement supérieur (parent) avec le bouton retour. On passe d'un menu à un autre de niveau identique mais de même parent (frère) avec les boutons Incrémenter et Décrémenter. Lorsque l'on appuie sur le bouton valider, deux choses peuvent se produire : si le menu possède des sous-menus (enfants), il passe au premier enfant, sinon, il permettra l'édition d'une valeur que l'on poura incrémenter ou décrémenter avec les boutons du même nom, et qui seront sauvegardées à l'aide du bouton retour. 40 +On peut passer d'un menu à son menu hiérarchiquement supérieur (parent) avec le bouton Retour. On passe d'un menu à un autre de niveau identique mais de même parent (frère) avec les boutons Incrémenter et Décrémenter. Lorsque l'on appuie sur le bouton Valider, deux choses peuvent se produire : si le menu possède des sous-menus (enfants), il passe au premier enfant, sinon, il permettra l'édition d'une valeur que l'on poura incrémenter ou décrémenter avec les boutons du même nom, et qui seront sauvegardées à l'aide du bouton retour. Même si ce menu peut sembler simple à en voir sa vue d'ensemble, il est beaucoup plus difficile à comprendre lorsqu'il est réduit à 4 afficheurs 7 segments. On oubliera pas de mettre ce genre d'information dans un guide si jamais ce système doit être utilisé par quelqu'un d'autre.
  41 +
41 42
42 ## Contrôle de la température 43 ## Contrôle de la température
43 44
44 -Concernant la régulation de la température, il a été prévu que celle-ci se fasse chaque 10 secondes. Puisque l'allumage de la chaudière est asservit en température, notre dispositif utilise un capteur de température, lequel fournit une tension variant de 0 à 5V, pour une plage de température allant de 5 à 30.6°C. Pour une précision de 0.1°C, cette plage correspond peut se coder sur 8bits en 256 valeurs. 45 +Concernant la régulation de la température, il a été prévu que celle-ci se fasse chaque 10 secondes. Puisque l'allumage de la chaudière est asservit en température, notre dispositif utilise un capteur de température, lequel fournit une tension variant de 0 à 5V, pour une plage de température allant de 5 à 30.6°C. Pour une précision de 0.1°C, cette plage peut se coder sur 8bits car elle contient 256 valeurs.
45 46
46 La température mesurée (et convertie via le convertisseur ADC), ne doit pas dépasser un intervalle de plus ou moins 0.5°C par rapport à la température de référence. Il s'agit donc d'incémenter et de décrémenter de 5 octets la valeur de référence pour la comparer à la température mesurée. Pour éviter un dépassement lors de l'incrémentation ou de la décrémentation, on oblige l'utilisateur à choisir une température entre 5.5°C et 30.1°C. 47 La température mesurée (et convertie via le convertisseur ADC), ne doit pas dépasser un intervalle de plus ou moins 0.5°C par rapport à la température de référence. Il s'agit donc d'incémenter et de décrémenter de 5 octets la valeur de référence pour la comparer à la température mesurée. Pour éviter un dépassement lors de l'incrémentation ou de la décrémentation, on oblige l'utilisateur à choisir une température entre 5.5°C et 30.1°C.
47 48
48 -## États  
49 -  
50 -- 0→1 : Veille (Heure, Température)  
51 -- 2 : Menu Association mode ↔ Heure de la semaine  
52 -- 3→9 : Menu jours (Lundi - Dimanche)  
53 -- 10→16 : Paramétrage des jours (Lundi - Dimanche)  
54 -- 17 : Menu température du mode jour  
55 -- 18 : Paramétrage température du mode jour  
56 -- 19 : Menu température du mode nuit  
57 -- 20 : Paramétrage température du mode nuit  
58 -- 21 : Menu réglage de la date et heure  
59 -- 22→24 : Menu réglage du jour / heure / minute  
60 -- 25→27 : Paramétrage du jour / heure / minute  
61 -  
62 ## Stockage des données 49 ## Stockage des données
63 50
64 Les accès à la RAM nécessitant plus d'instructions et donc étant plus gourmands en énergie, on stockera le maximum d'informations dans les registres, de préférences les données étant lues/écrites les plus fréquemment. On y stockera donc : 51 Les accès à la RAM nécessitant plus d'instructions et donc étant plus gourmands en énergie, on stockera le maximum d'informations dans les registres, de préférences les données étant lues/écrites les plus fréquemment. On y stockera donc :
65 52
66 - **4 registres** : les 4 digits de l'afficheur 7 segments en cours d'affichage. Ces informations devant être récupérées 4 fois toutes les quelques millisecondes, on ne calculera leur représentation que lors de leur changement et on les stockera dans ces registres. 53 - **4 registres** : les 4 digits de l'afficheur 7 segments en cours d'affichage. Ces informations devant être récupérées 4 fois toutes les quelques millisecondes, on ne calculera leur représentation que lors de leur changement et on les stockera dans ces registres.
67 -- **1 registre (dont 6 bits inutilisés)** : afficheur 7 segment actuellement en cours d'affichage. Cela permet d'alterner les 4 dans l'ordre. <!-- TODO Voir si c'est pas possible d'utiliser le timer pour stocker ces infos -->  
68 -- **3 registres** : Stockage du temps. Le compteur de temps le plus grand mais à la fois diviseur de la période de changement de mode veille et d'une heure sur l'Atmega 2560 est deux secondes. On comptera le temps de la semaine avec cette période de deux secondes. Il y a alors $\frac{7 \times 24 \times 60 \times 60 }{ 2 }$ $=302400$ valeurs possibles pour ce compteur de temps. On a donc besoin de 3 registres $\left( 2^{8 \times 2} = 65536 < 302400 < 16777216 = 2^{8 \times 3} \right)$ pour stocker cette valeur. Afin de simplifier, sur le premier registre on utilisera 3 bits pour stocker le jour de la semaine, 5 bits pour l'heure du jour, on utilisera le deuxième registre pour stocker la minute de l'heure, et le troisième registre pour stocker le <!-- TODO --> 54 +- **1 registre (dont 4 bits inutilisés)** : afficheur 7 segment actuellement en cours d'affichage. Cela permet d'alterner les 4 dans l'ordre. <!-- TODO Voir si c'est pas possible d'utiliser le timer pour stocker ces infos -->
  55 +- **3 registres** : Stockage du temps. Le compteur de temps le plus grand mais à la fois diviseur de la période de changement de mode veille et d'une heure sur l'Atmega 2560 est deux secondes. On comptera le temps de la semaine avec cette période de deux secondes. Il y a alors $\frac{7 \times 24 \times 60 \times 60 }{ 2 }$ $=302400$ valeurs possibles pour ce compteur de temps. On a donc besoin de 3 registres $\left( 2^{8 \times 2} = 65536 < 302400 < 16777216 = 2^{8 \times 3} \right)$ pour stocker cette valeur. Afin de simplifier, sur le premier registre on utilisera 3 bits pour stocker le jour de la semaine, 5 bits pour l'heure du jour, on utilisera le deuxième registre pour stocker la minute de l'heure, et le troisième registre pour stocker le nombres de fois qu'il y a eu 2 secondes dans la minute actuelle. Cela permet de simplifier les calculs et d'éviter de faire des opérations sur des entiers de 24 bits.
69 56
70 Les associations de chaque heure de la semaine à son mode (jour/nuit) seront stockées dans la RAM. Bien qu'en théorie nous n'avons besoin que de $\frac{ \text{nb jours/semaine} \times \text{nb heures/jour} \times \text{nb bits pour stocker le mode} }{ \text{nb bits stockables sur une adresse} }$ $=\frac{7 \times 24 \times 1 }{ 8 }$ $=\frac{168}{8}$ $=21$ adresses pour stocker ces informations, on préfèrera utiliser une adresse par heure de la semaine, soit $168$ adresses. Bien que l'on perd en espace mémoire disponible, on garde en rapidité d'éxecution (et donc en énergie), en effet il n'est pas nécessaire d'utiliser des masques pour récupérer la valeur des bits individuels. Dans notre cas le microprocesseur n'abritera aucun autre programme avec qui il devra partager la RAM, et la consommation énergétique ne change pas selon le nombre d'adresses utilisées, il n'y a donc que des avantages à utiliser cette technique. 57 Les associations de chaque heure de la semaine à son mode (jour/nuit) seront stockées dans la RAM. Bien qu'en théorie nous n'avons besoin que de $\frac{ \text{nb jours/semaine} \times \text{nb heures/jour} \times \text{nb bits pour stocker le mode} }{ \text{nb bits stockables sur une adresse} }$ $=\frac{7 \times 24 \times 1 }{ 8 }$ $=\frac{168}{8}$ $=21$ adresses pour stocker ces informations, on préfèrera utiliser une adresse par heure de la semaine, soit $168$ adresses. Bien que l'on perd en espace mémoire disponible, on garde en rapidité d'éxecution (et donc en énergie), en effet il n'est pas nécessaire d'utiliser des masques pour récupérer la valeur des bits individuels. Dans notre cas le microprocesseur n'abritera aucun autre programme avec qui il devra partager la RAM, et la consommation énergétique ne change pas selon le nombre d'adresses utilisées, il n'y a donc que des avantages à utiliser cette technique.
71 58
@@ -79,5 +66,31 @@ Il sera de plus configuré pour s&#39;activer sur demande et activera une interrupti @@ -79,5 +66,31 @@ Il sera de plus configuré pour s&#39;activer sur demande et activera une interrupti
79 66
80 # Algorithme 67 # Algorithme
81 68
  69 +## Menu
  70 +
  71 +Ce fonctionnement peut être implémenté de deux manières différentes. La première, étant que à chaque élément du menu correspond un emplacement dans le code assembleur, et le programme passe le plus clair de son temps à scruter les boutons. La deuxième, étant que le programme reste sur une instruction sleep, et que les boutons provoquent des interruptions qui gèrent modifient l'affichage et les valeurs nécessaires en fonction du bouton qui a été appuyé et de l'état précédent du menu. D'un point de vue énergétique, la deuxième solution est clairement gagnante. Il faut alors stocker dans quel état est le menu en mémoire. On utilisera pour cela un registre d'état, qui prendra les valeurs suivantes :
  72 +
  73 +- 0→1 : Veille (Heure / Température)
  74 +- 2 : Menu Association mode ↔ Heure de la semaine
  75 +- 3→9 : Menu jours (Lundi - Dimanche)
  76 +- 10→16 : Paramétrage des jours (Lundi - Dimanche)
  77 +- 17 : Menu température du mode jour
  78 +- 18 : Paramétrage température du mode jour
  79 +- 19 : Menu température du mode nuit
  80 +- 20 : Paramétrage température du mode nuit
  81 +- 21 : Menu réglage de la date et heure
  82 +- 22→24 : Menu réglage du jour / heure / minute
  83 +- 25→27 : Paramétrage du jour / heure / minute
  84 +
  85 +On parle de menu quand l'écran affiche le nom de l'élément que l'utilisateur s'apprête à modifier, et de paramétrage lorsque l'utilisateur voit la valeur qu'il est en train de modifier. Pour les paramètrages, un registre nommé `compteur` accompagne le registre `etat`, et permet de stocker la valeur qui est en cours de modification. À chaque appui sur un bouton, une interruption est émise et le code associé effectue une tâche qui varie selon la valeur d'`etat`. L'interruption peut changer certaines variables du système (la température du mode jour par exemple, ou l'heure actuelle), ou bien l'état lui-même.
  86 +
  87 +Pour chaque état on a défini plusieurs fonctions qui sont appelés par les différents boutons. Pour un état donné `Demo`, on aura alors :
  88 +
  89 +- `etatDemoU` qui permet de changer l'affichage pour l'état courant, éventuellement en fonction de la valeur de compteur dans le cas d'un paramètrage. Cette fonction est appelé à la fin de toutes les autres fonctions que l'on définira par la suite.
  90 +- `etatDemo` est l'action éxecutée lorsque l'utilisateur arrive sur l'état : la valeur du registre `etat` est changée, et la valeur de compteur est chargée avec la variable du système correspondante dans le cas d'un paramètrage.
  91 +- `etatDemoC` (paramètrages seulement) est appelé lorsque la valeur de compteur est changée par les boutons Incrementer ou Decrementer. Elle fait appel aux fonctions `boundType` qui permettent de remettre dans les bornes la valeur si elle passe hors de l'intervalle de définition (par exemple si une minute est incrémentée à 60 elle repasse à 0). Ensuite elle sauvegarde dans le bon endroit de la mémoire (registres ou RAM) la valeur de compteur.
  92 +
  93 +Pour certains états, on aura aussi un comportement plus spécifique. Par exemple, lorsqu'on fait Retour depuis les états 10 à 16, la valeur d'`etat` est décrémentée de 7. On créera donc deux fonctions : `etatMenuJours` qui est utilisé quand on arrive d'un niveau parent (on passe donc à l'état 3, Lundi par défaut), et `etatMenuJoursR` qui est utilisé quand on arrive d'un niveau enfant (on passe donc à l'état du menu correspondant au jour que l'on venait de modifier).
  94 +
82 ## Pseudo-code 95 ## Pseudo-code
83 !include(principal.txt lang=avrpseudo) 96 !include(principal.txt lang=avrpseudo)
@@ -32,8 +32,11 @@ @@ -32,8 +32,11 @@
32 .def d2 = r20 ; Digit 2 32 .def d2 = r20 ; Digit 2
33 .def d1 = r20 ; Digit 1 33 .def d1 = r20 ; Digit 1
34 .def d0 = r20 ; Digit 0 (tout à droite) 34 .def d0 = r20 ; Digit 0 (tout à droite)
35 -.def compteur = r20 ; Utilisé pour différentes choses  
36 -.def tempo = r20 ; Utilisé pour différentes choses mais très brièvement 35 +.def compteur = r20 ; Utilisé pour modifier des valeurs dans le menu
  36 +.def temp = r20 ; Utilisé pour différentes choses mais très brièvement
  37 +.def t2 = r20 ; Jour (3 premiers bits) et Heure (5 derniers bits)
  38 +.def t1 = r20 ; Minutes
  39 +.def t0 = r20 ; Secondes / 2
37 40
38 ; Vecteurs d'interruptions 41 ; Vecteurs d'interruptions
39 42
@@ -102,7 +105,12 @@ boucle: @@ -102,7 +105,12 @@ boucle:
102 ; Affichages 105 ; Affichages
103 afficherHorloge: 106 afficherHorloge:
104 ; Affiche l'heure actuelle 107 ; Affiche l'heure actuelle
105 - ; TODO 108 + temp <- t2 & 0b00011111
  109 + d3 <- 0x00
  110 + si temp > 10 alors d3 <- afficheur[temp/10]
  111 + d2 <- afficheur[temp%10] | 0b10000000
  112 + d1 <- afficheur[t2/10]
  113 + d0 <- afficheur[t2%10]
106 ret 114 ret
107 115
108 afficherTemperature: 116 afficherTemperature:
@@ -131,7 +139,7 @@ afficherMinu: @@ -131,7 +139,7 @@ afficherMinu:
131 ret 139 ret
132 140
133 afficherJour: 141 afficherJour:
134 - ; Considère le regustre compteur comme un jour et l'affiche 142 + ; Considère le registre compteur comme un jour et l'affiche
135 ; TODO 143 ; TODO
136 ret 144 ret
137 145
@@ -139,10 +147,12 @@ afficherJour: @@ -139,10 +147,12 @@ afficherJour:
139 agir10s: 147 agir10s:
140 ; Initialise une lecture ADC 148 ; Initialise une lecture ADC
141 ; Met à jour l'état de veille (si on est en état veille) 149 ; Met à jour l'état de veille (si on est en état veille)
  150 + ; TODO
142 ret 151 ret
143 152
144 agirHeur: 153 agirHeur:
145 ; Recharge la température de référence 154 ; Recharge la température de référence
  155 + ; TODO
146 ret 156 ret
147 157
148 ; Recadrage 158 ; Recadrage
@@ -166,6 +176,9 @@ boundTemperature: @@ -166,6 +176,9 @@ boundTemperature:
166 si compteur > 200 alors compteur <- 200 176 si compteur > 200 alors compteur <- 200
167 ret 177 ret
168 178
  179 +reti:
  180 + reti
  181 +
169 ; États 182 ; États
170 ; × : Arrivée à l'état par un niveau supérieur 183 ; × : Arrivée à l'état par un niveau supérieur
171 ; R : Arrivée à l'état par un niveau inférieur 184 ; R : Arrivée à l'état par un niveau inférieur
@@ -372,7 +385,7 @@ valider: @@ -372,7 +385,7 @@ valider:
372 reti ; Ne devrait pas arriver, mais permet d'éviter les dégâts 385 reti ; Ne devrait pas arriver, mais permet d'éviter les dégâts
373 386
374 retour: 387 retour:
375 - si etat <= 1 saut rien 388 + si etat <= 1 saut reti
376 si etat = 2 saut etatVeilleHeur 389 si etat = 2 saut etatVeilleHeur
377 si etat <= 9 saut etatMenuAssoc 390 si etat <= 9 saut etatMenuAssoc
378 si etat <= 16 saut etatMenuJoursR 391 si etat <= 16 saut etatMenuJoursR
@@ -387,12 +400,24 @@ retour: @@ -387,12 +400,24 @@ retour:
387 si etat = 27 saut etatMenuHMinu 400 si etat = 27 saut etatMenuHMinu
388 reti ; Ne devrait pas arriver, mais permet d'éviter les dégâts 401 reti ; Ne devrait pas arriver, mais permet d'éviter les dégâts
389 402
390 -rien:  
391 - reti  
392 -  
393 ; Interruption Watchdog 403 ; Interruption Watchdog
394 watchdog: 404 watchdog:
395 ; Met à jour les registres de temps, active agir10s ou agirHeur si nécessaire 405 ; Met à jour les registres de temps, active agir10s ou agirHeur si nécessaire
  406 + inc t0
  407 + si t0 % 5 != 0 saut reti ; Continue si on est sur un multiple de 10 secondes
  408 + call agir10s
  409 + si t0 < 30 saut reti ; Continue si on est sur un multiple de 60 secondes
  410 + t0 <- 0
  411 + inc t1
  412 + si t1 < 60 saut reti ; Continue si on est sur un multiple de 60 minutes
  413 + t1 <- 0
  414 + inc t2
  415 + si t2 & 0b00011111 >= 7 saut watchdogHeure ; Continue si il est minuit
  416 + t2 <- t2 + 0b00100000 ; Jour suivant
  417 + t2 <- t2 & 0b11100000 ; Heure à minuit
  418 + si t2 >= 0b11100000 t2 <- 0b00000000 ; Si on est dimanche soir, on revient à lundi matin
  419 +watchdogHeure:
  420 + call agirHeure
396 reti 421 reti
397 422
398 ; Interruption ADC 423 ; Interruption ADC
@@ -36,7 +36,7 @@ @@ -36,7 +36,7 @@
36 p { 36 p {
37 text-align: justify; 37 text-align: justify;
38 } 38 }
39 - p code { 39 + ul code, p code {
40 border: 1px solid #ccc; 40 border: 1px solid #ccc;
41 border-radius: 2px; 41 border-radius: 2px;
42 padding: 0px 2px; 42 padding: 0px 2px;