Commit 7fe247413cb87bd12b4fa94244246d4c2a5114e1

Authored by Geoffrey PREUD'HOMME
1 parent 514fdb6d

Encore des modifications du CR

Est-ce vraiment nécessaire de faire des messages explicites ?
Showing 2 changed files with 57 additions and 14 deletions   Show diff stats
... ... @@ -16,7 +16,7 @@ Enfin, afin de vérifier la validité de notre algorithme et de nos configuratio
16 16  
17 17 ## Entrées
18 18  
19   -On utilisera 4 boutons : pour valider, revenir en arrière, incrémenter et décrémenter. Ils sont branchés sur les ports d'interruption INT0 à INT3 respectivement pour éviter une scrutation afin d'économiser de l'énergie. <!-- TODO Pourquoi résistances et capa -->
  19 +On utilisera 4 boutons pour pouvoir modifier les paramètres : pour valider, revenir en arrière, incrémenter et décrémenter. Ils sont branchés sur les ports d'interruption INT0 à INT3 respectivement pour éviter une scrutation afin d'économiser de l'énergie. <!-- TODO Pourquoi résistances et capa -->
20 20  
21 21 Le capteur de température est connecté sur le convertisseur analogique-numérique numéro 0 (`ADC0`).
22 22 Pour la simulation, nous avons utilisé un potentiomètre afin de régler la température d'entrée du thermostat.
... ... @@ -31,7 +31,7 @@ Enfin, le signal de contrôle de la chaudière est branchée sur un port parallÃ
31 31  
32 32 ## Menu
33 33  
34   -Pour pouvoir afficher et modifier les différentes valeurs dont l'utilisateur a accès, on a créé un menu, dont voici sa hiérarchie :
  34 +Pour pouvoir afficher et modifier les différentes valeurs dont l'utilisateur a accès, on a créé un menu, dont voici la hiérarchie :
35 35  
36 36 - Veille
37 37 - Association mode ↔ heure de la semaine
... ... @@ -66,7 +66,7 @@ Les accès à la RAM nécessitant plus d&#39;instructions et donc étant plus gourma
66 66 - `PORTC` : afficheur 7 segment actuellement en cours d'affichage. Cela permet d'alterner les 4 dans l'ordre. Pour économiser un registre d'utilisation générale, on utilisera le fait que le port C est considéré comme un registre et sauvegarde les états qui lui sont envoyés.
67 67 - `t2`, `t1` et `t0` : stockage du temps actuel. Il y a $7 \times 24 \times 60 \times 60$ $=604800$ valeurs possibles pour ce compteur de temps. On a donc besoin de 3 registres $\left( 2^{8 \times 2} = 65536 < 604800 < 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 pour stocker les secondes de la minute. Cela permet de simplifier les calculs et d'éviter de faire des opérations sur des entiers de 24 bits.
68 68 - `etat` et `compteur` : ils permettent de stocker l'état actuel du menu.
69   -- `reference` : contient la température désirée actuelle (c'est à dire pour le mode de l'heure actuelle). Étant comparée toutes les 10 secondes avec la température réelle et le calcul de sa valeur nécessitant de connaître le temps actuel, le mode associé à ce temps et la température associée à ce mode, on a jugé avantageux de le stoceker dans un registre qui sera mis à jour au besoin.
  69 +- `reference` : contient la température désirée actuelle (c'est à dire pour le mode de l'heure actuelle). Étant comparée toutes les 10 secondes avec la température réelle et le calcul de sa valeur nécessitant de connaître le temps actuel, le mode associé à ce temps et la température associée à ce mode, on a jugé avantageux de le stocker dans un registre qui sera mis à jour au besoin.
70 70 - `temp` : registre dédié à certaines opérations temporaires. Il n'a pas de rapport (la plupart du temps) avec la température.
71 71  
72 72 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.
... ... @@ -94,6 +94,7 @@ Il sera configuré pour s&#39;activer sur demande, ici toutes les dix secondes. En e
94 94 TODO toutes les deux secondes, déclenche une interruption, nécessite d'être un multiple de 10 secondes, au final il marche pas parce qu'on sait pas du coup on utilise le timer (pas trop étaler là dessus, c'est expliqué plus en détails dans algorithme)
95 95  
96 96 ↓↓ à réintégrer
  97 +
97 98 On s'est rendu compte que la fréquence d'appel était ~100× plus élevé que ce qui devrait être. N'ayant pas réussi à corriger ce comportement (que l'on a pu aussi constater en TP), nous avons dû trouver un autre moyen de procéder.
98 99  
99 100  
... ... @@ -113,11 +114,11 @@ boucle:
113 114  
114 115 En effet, nous avons dit précédemment que pour économiser l'énergie, toutes les actions seraient gérées par des interruptions, le reste du temps le micro-contrôleur ne fait que dormir. On peut se le permettre car les actions sont très courtes, et il n'y a donc peu de risque de conflit au cas où deux interruptions se déclenchent en même temps.
115 116  
116   -L'algorithme étant assez imposant (~620 lignes) et redondant, on ne présentera que les principes clefs et quelques exemples d'astuces utilisés. Le code complet (et les outils utilisés pour l'ensemble du projet) sont disponibles à l'adresse suivante : <https://archives.plil.fr/gbontoux/s6-mp-tutorat> (`Fies` > `principal.txt`).
  117 +L'algorithme étant assez lourd et redondant, on ne présentera que les principes clefs et quelques exemples d'astuces utilisés. Le code complet (et les outils utilisés pour l'ensemble du projet) sont disponibles à l'adresse suivante : <https://archives.plil.fr/gbontoux/s6-mp-tutorat> (`Files` > `principal.txt`).
117 118  
118   -## Menu
  119 +## Gestion des états
119 120  
120   -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 :
  121 +Chacun des boutons provoque une interruption qui modifie l'affichage et les valeurs nécessaires en fonction de celui qui a été appuyé et de l'état précédent du menu. Il faut alors stocker dans quel état est le menu en mémoire. On utilisera pour cela un registre `etat`, qui prendra les valeurs suivantes :
121 122  
122 123 - 0→1 : Veille (Heure / Température)
123 124 - 2 : Menu Association mode ↔ Heure de la semaine
... ... @@ -205,13 +206,13 @@ On utilise le fait qu&#39;une décrémentation depuis la valeur 0 effectue un dépas
205 206  
206 207 ## Fonction d'agissement
207 208  
208   -Ces fonctions permettent de prendre des actions en fonction du temps.
  209 +Ces fonctions permettent de réaliser des actions en fonction du temps.
209 210  
210 211 - `agir1s` : déclenchée toutes les secondes, elle met à jour les registres de temps, et appelle les fonctions `agir10s` et `agirHeure`
211   -- `agir10s` : déclenchée toutes les dix secondes, elle change l'état de veille si l'appareil est en veille. Dans tous les cas, elle déclenche une conversion analogique numérique pour lire le capteur de température.
  212 +- `agir10s` : déclenchée toutes les dix secondes, elle change l'état de veille (affichage de l'heure ou température) si l'appareil est en veille. Dans tous les cas, elle déclenche une conversion analogique numérique pour lire le capteur de température.
212 213 - `agirHeure` : elle recharge depuis la RAM le mode actuel, et met à jour le registre `reference` contenant la température à utiliser.
213 214  
214   -Voici à titre d'exemple une de ces fonctions (bien qu'elles soient toutes radicalement différentes) :
  215 +*Note : On a laissé la possibilité à l'utilisateur de changer de mode de veille avec les boutons Incrémenter / Décrémenter, mais `agir10s` ne prend pas en compte ce changement. Il est donc possible que l'utilisateur change d'état de veille et que le système revienne juste après à l'état précédent.*
215 216  
216 217 ## Interruptions
217 218  
... ... @@ -221,24 +222,66 @@ Les fonctions que nous avons vues jusqu&#39;à lors sont appelées uniquement par le
221 222  
222 223 Déclenchée toutes les ~4 ms, elle change le digit de l'afficheur 4 × 7 segments actuellement affiché en modifiant la configuration du port C, et cenvoie sur le port A les données du registre `dX` correspondant.
223 224  
  225 +```avrasmplus
  226 +timer:
  227 + ; Notre composant requiert d'envoyer 0 sur PC7-4
  228 + ; afin d'activer le digit qui y est connecté
  229 +
  230 + ; Affiche le digit suivant sur l'afficheur 7seg
  231 + temp <- PORTC@IO ; On lis l'état précédent du port
  232 + lsr temp ; On change de digit
  233 + ; Il y a 4 digits et 8 bits, on doit donc boucler plus tôt
  234 + si temp < 0b00001111 alors temp <- 0b11110111
  235 + PORTC@IO <- temp
  236 + ; On envoie le registre correpspondant
  237 + si temp = 0b11110111 alors PORTA@IO <- d3
  238 + si temp = 0b01111011 alors PORTA@IO <- d2
  239 + si temp = 0b00111101 alors PORTA@IO <- d1
  240 + si temp = 0b00011110 alors PORTA@IO <- d0
  241 +```
  242 +
224 243 ### Watchdog
225 244  
226   -Le watchdog ne fonctionnant pas, nous avons utilisé le timer, et un registre supplémentaire, `tt`, qui est incrémenté à chacune de ses interruptions. Le timer ayant une fréquence exacte de $\frac{16 MHz}{256^2}=244.140625 Hz$;, dès que `tt` a depassé `244` on appelle donc `agir1s`.
  245 +Le watchdog ne fonctionnant pas, nous avons utilisé le timer, et un registre supplémentaire, `tt`, qui est incrémenté à chacune de ses interruptions. Le timer ayant une fréquence exacte de $\frac{16 MHz}{256^2}=244.140625 Hz$, dès que `tt` a depassé `244` on appelle donc `agir1s`.
227 246  
228   -D'un point de vue énergétique, cette approche est beacoup moins efficace car elle rajoute des instructions supplémentaires à l'interruption du timer, qui est la fonction « critique » du système car appelée 244 fois par secondes.
  247 +D'un point de vue énergétique, cette approche est beacoup moins efficace car elle rajoute des instructions supplémentaires à l'interruption du timer, qui est la fonction « critique » du système car appelée 244 fois par seconde.
229 248  
230 249 ### ADC
231 250  
232 251 Cette interruption est déclenchée à chaque fois qu'une conversion analogique→numérique est terminée. Elle est donc déclenchée à peu près toutes les 10 secondes car les conversions ne sont demandées que depuis la fonction `agir10s`. Elle s'occupe d'activer ou de désactiver la chaudière en fonction de la température récupérée lors de la conversion, en se basant sur le registre `reference`. Par exemple, la chaudière est éteinte si la température dépasse de plus de 0,5 degrés la température de référence. Dans le code, on vérifiera si `ADCH > reference + 5`, car 0,1°C correspond à une unité. On remarque que l'on peut obtenir un dépassement si jamais `reference > 250`, ce qui n'est pas censé arriver car on ne propose à l'utilisateur que de choisir une température entre 5,5 et 30,0°C, `reference` est donc compris entre 5 et 250. Si jamais la température est comprise dans l'intervalle, le port G conserve l'état de la chaudière actuel.
233 252  
234   -*Note : Pour la présentation orale vous pourrez constater dans le code que cette interruption en déclenche une autre afin d'avoir un retour immédiat sur nos actions.*
  253 +*Note : Vous pourrez constater dans le code que cette interruption en déclenche une autre afin d'avoir un retour immédiat sur nos actions. Cela n'a été fait que pour simplifier la présentation orale.*
235 254  
236 255 ### Boutons
237 256  
238 257 À chaque bouton est associé une interruption, et chacun d'entre elle appelle une fonction d'état selon la valeur actuelle de compteur. Par exemple, si l'état actuel est `veilleHeure` et que le bouton Valider est pressé, la fonction `etatMenuAssoc` est appelée. Pour les boutons Incrémenter et Décrémenter, le registre `compteur` est incrémenté ou décrémenté respectivement avant d'appeler la fonction d'état.
239 258  
  259 +Voici par exemple la fonction appelée par le bouton Incrémenter :
  260 +
  261 +```avrasmplus
  262 +incrementer:
  263 + inc compteur
  264 + si etat = 0 saut etatVeilleTemp
  265 + si etat = 1 saut etatVeilleHeur
  266 + si etat = 2 saut etatMenuTJour
  267 + si etat <= 9 saut etatMenuJoursC
  268 + si etat <= 16 saut etatParaJoursC
  269 + si etat = 17 saut etatMenuTNuit
  270 + si etat = 18 saut etatParaTJourC
  271 + si etat = 19 saut etatMenuHorloge
  272 + si etat = 20 saut etatParaTNuitC
  273 + si etat = 21 saut etatMenuAssoc
  274 + si etat = 22 saut etatMenuHHeur
  275 + si etat = 23 saut etatMenuHMinu
  276 + si etat = 24 saut etatMenuHJour
  277 + si etat = 25 saut etatParaHJourC
  278 + si etat = 26 saut etatParaHHeurC
  279 + si etat = 27 saut etatParaHMinuC
  280 + reti ; Ne devrait pas arriver, mais permet d'éviter les dégâts
  281 +```
  282 +
240 283 # Conclusion
241 284  
242   -Pour ce projet de thermostat, nous avons réalisé son architecture matérielle, son algorithme, et même réussi à en faire une simulation sur du matériel réel, ce qui a nécessite l'écriture de l'algorithme complet. Bien qu'un sujet similaire était proposé dans un des TP, on s'est rendu compte que l'ajout de certaines fonctions paraissant anodines (telles que la gestion du temps, ou un menu) nécessitent un gros travail pour tout coordonner. La réalisation de la simulation, bien que non nécessaire, a été utile pour se rendre compte que certains chemins envisagés au débuts n'étaient pas réalisables, et a permis de pouvoir tester notre algorithme. Au final
  285 +Pour ce projet de thermostat, nous avons réalisé son architecture matérielle, son algorithme, et même réussi à en faire une simulation sur du matériel réel, ce qui a nécessite l'écriture de l'algorithme complet. Bien qu'un sujet similaire était proposé dans un des TP, on s'est rendu compte que l'ajout de certaines fonctions paraissant anodines (telles que la gestion du temps, ou un menu) nécessitent un gros travail pour tout coordonner. La réalisation de la simulation, bien que non nécessaire, a été utile pour se rendre compte que certains chemins envisagés au débuts n'étaient pas réalisables, et a permis de pouvoir tester notre algorithme. Au final ce fut une experience très enrichissante.
243 286  
244 287  
... ...
README.md
... ... @@ -11,7 +11,7 @@ Pour générer un fichier PDF, assurez-vous d&#39;avoir lancé `./configure` une foi
11 11  
12 12 ## Programme
13 13  
14   -Pour envoyer un programme sur l'Arduino, assurez-vous d'avoir lancé `./configure` une fois sans erreur, puis lancez la commande `make programme.upload`, en supposant qu'il existe un fichier `programme.txt` ou `programme.hex`. Les fichiers intermédiaires nécessaires seront reconstruits si besoin. Si vous voulez juste vérifier que ça compile, `make programme.hex`.
  14 +Pour envoyer un programme sur l'Arduino, assurez-vous d'avoir lancé `./configure` une fois sans erreur, puis lancez la commande `make programme.upload`, en supposant qu'il existe un fichier `programme.txt` ou `programme.asm`. Les fichiers intermédiaires nécessaires seront reconstruits si besoin. Si vous voulez juste vérifier que ça compile, `make programme.hex`.
15 15  
16 16 *(ne fonctionne que sur un environnement Linux)*
17 17  
... ...