Certaines applications pour un réseau de trains miniatures ne requièrent pas toute la puissance d’un module Arduino/Genuino Uno et on peut trouver dommage de monopoliser un tel module pour si peu. La solution est de les confier à un microcontrôleur moins puissant, donc moins coûteux. Cette série d’articles vous présente le microcontrôleur ATtiny45 du constructeur Atmel et ses possibilités dans le domaine du modélisme ferroviaire.
On peut se demander pourquoi un site consacré aux modules Arduino parle d’un simple composant électronique ? Simplement parce que l’ATtiny45 est de la même famille de microcontrôleurs que celui qui équipe les modules Arduino/Genuino Uno et est programmable avec le logiciel Arduino.
Possibilités de l’ATtiny45
Ce microcontrôleur se présente sous la forme d’un boîtier à 8 broches, comme le montre la figure 1. C’est effectivement très peu mais les broches sont multiplexées, ce qui signifie qu’elles servent à plusieurs choses à la fois. La figure 1 donne les possibilités de chaque broche, mais il est inutile de tout retenir maintenant. Nous allons décrire les principales fonctions des broches.
- ATtiny45
La tension d’alimentation varie de 2,7 à 5,5 V (de 1,8 à 5,5 V pour la version ATtiny45V). Une simple pile de 4,5 V suffit donc pour l’alimenter. Le plus de l’alimentation est connecté à la broche 8 et le moins à la broche 4, soit deux broches diagonalement opposées comme c’est souvent le cas pour un circuit intégré.
L’ATtiny45 dispose de 6 lignes d’entrées-sorties, organisées en un PORT d’entrée-sortie appelé PORT B. Ces 6 lignes sont numérotées de 0 à 5 (on commence toujours par 0 en informatique) et on écrit PB0:5 pour parler des lignes 0 à 5 du PORT B qui sont respectivement sur les broches 5, 6, 7, 2, 3 et 1.
Six broches d’E/S (entrée-sortie) et deux broches pour alimenter le microcontrôleur, nous arrivons au total des 8 broches du boîtier. Ce µC (microcontrôleur) peut donc servir pour des applications qui ne requièrent que 6 lignes d’E/S. Pourtant, dans les applications que cette série d’articles proposera, nous nous limiterons à 5 lignes d’E/S seulement. En effet, la broche 1 sert aussi au RESET du µC (voir figure 1) et ce RESET peut être utile pour certaines applications, et en tout cas, il est indispensable pour la programmation du µC avec un module Arduino Uno comme nous le verrons ultérieurement. Retenons simplement que notre µC nous offre deux broches pour l’alimenter, 5 lignes d’E/S et une broche de RESET et si cela vous paraît peu, vous serez étonné de voir tout ce qu’on peut faire tout de même.
Maintenant que nous avons décrit comment exploiter ses broches, voyons maintenant le reste de ses possibilités. Sa fréquence d’horloge utilisable dépend de la tension d’alimentation ; s’il est alimenté en 5 V, la fréquence d’horloge peut aller de 0 à 20 MHz. La mémoire de programme est de 4 kilo-octets, la mémoire SRAM (Static Random Access Memory) est de 256 octets tout comme la mémoire EEPROM (Electrical Erasable Programmable Read Only Memory). Cela peut paraître peu mais c’est largement suffisant pour de petites applications. Ces chiffres sont à diviser par 2 si vous optez pour le petit frère ATtiny25 et à multiplier par 2 si vous choisissez le grand frère ATtiny85. Lorsque nous parlons de l’ATtiny45, nous parlons en fait de la famille ATtiny25/45/85 puisque les propriétés sont les mêmes en dehors de l’espace mémoire plus ou moins étendu.
Ce microcontrôleur est capable de produire de la PWM, dispose de timers, d’un convertisseur analogique-numérique sur 10 bits, de sources d’interruption externes et internes, un oscillateur interne calibré et un port SPI/I2C pour communiquer et qui incidemment permet aussi de le programmer.
Comme vous le voyez, ce petit microcontrôleur est tout de même un concentré de technologie et ce serait bien dommage de s’en passer, d’autant que son prix est inférieur à 1,50 € (en 2016).
Développement d’une application pour un réseau de train
Nous allons voir dans ce paragraphe, comment développer une application à base d’ATtiny, en donnant les grands principes généraux ; la suite de cette série d’articles présentera bien entendu des exemples concrets dont la réalisation sera décrite de A jusqu’à Z.
Phase 1 : on commence par évaluer les ressources nécessaires pour voir si cela tient dans les possibilités d’un ATtiny. N’oublions pas que nous sommes limités à 5 lignes d’E/S. Prenons par exemple les feux tricolores de carrefour routier, application qui a été décrite dans l’article Feux tricolores. Un carrefour est constitué de quatre feux tricolores et chaque feu possède trois ampoules (vert, orange, rouge). Cela ne donne pas 12 ampoules pour autant car les feux d’une même route sont allumés en même temps ; en fait, il nous reste 6 ampoules à gérer, ce qui est trop puisque nous n’avons que 5 lignes de sortie. Comment faire ? Nous pouvons considérer que lorsqu’un feu est au vert, le feu de la route perpendiculaire est au rouge ; ceci permet de réaliser nos feux avec seulement 3 sorties, mais dans ce cas, nous ne pouvons pas introduire la temporisation du chauffard dont on parlait dans l’article Feux tricolores. Ce n’est pas si grave car les feux tricolores construits avec des circuits intégrés classiques ne le permettent pas non plus (voir le chapitre 11 du cours d’électronique donné dans l’article Démarrer en électronique). Il y a bien entendu une autre solution : utiliser deux µC ATtiny et les faire travailler ensemble, chaque µC gérant les deux feux d’une même route du carrefour. Cela permet de réintroduire la temporisation du chauffard et ainsi de gagner en réalisme. Prenons un autre exemple, celui d’un passage à niveau non gardé dont on veut faire clignoter les feux rouges à l’approche d’un train. Une sortie pour faire clignoter deux DEL rouges et deux entrées reliées à des ILS pour détecter l’approche du train et son éloignement, cela donne 3 lignes d’E/S ce qui tient tout à fait dans un ATtiny.
Phase 2 : il faut mettre au point le montage sur une platine d’essai en remplaçant l’ATtiny par un module Arduino/Genuino Uno. En effet, celui-ci est plus facile à programmer grâce à son câble USB et il opère comme un µC ATtiny qui serait alimenté en 5 V ; on peut donc choisir les meilleures valeurs de composants, et écrire le programme pour le tester.
Phase 3 : lorsque le programme fonctionne, il faut l’adapter à un ATtiny dont les lignes d’E/S sont comprises entre 0 et 4 alors que vous avez peut-être utilisées d’autres numéros avec votre module Uno. Lorsque c’est fait, il reste à programmer la puce ATtiny et cela se fait avec un module Arduino/Genuino Uno, une platine d’essai et quelques câbles de liaison.
Phase 4 : une fois l’ATtiny programmé, le montage de l’application est réalisé à nouveau sur une platine d’essai, cette fois avec la puce et les composants définitifs autour afin de tester le fonctionnement avant de réaliser le montage définitif où les composants sont soudés soit sur un circuit imprimé, soit sur une plaque à bandes cuivrées (veroboard par exemple).
Dans cette procédure, nous avons utilisé le module Uno à deux reprises : pour la mise au point de l’application et de son programme, et pour programmer l’ATtiny. Cela nous ramène à un environnement connu, celui de l’IDE des modules Arduino et la programmation de l’application se fait directement dans le « langage » d’Arduino que vous commencez à connaître. Pour autant, toutes les fonctions ne seront peut-être pas utilisables avec un µC ATtiny mais cela vaut la peine d’essayer. Tout ce que vous risquez est que cela ne fonctionne pas une fois le programme téléversé dans le µC ATtiny, mais ce n’est pas important puisque ce dernier peut être reprogrammé à nouveau.
Architecture du microcontrôleur ATtiny45
Pour comprendre pourquoi une application mise au point avec un module Uno peut fonctionner avec un ATtiny45, il faut s’intéresser un peu à l’architecture des deux microcontrôleurs, l’ATtiny45 et l’ATmega328P qui équipe les modules Arduino/Genuino Uno. Nous allons voir qu’il y a de fortes similitudes et tant mieux pour nous car dans certains cas, nous aurons de bonnes chances que l’application fonctionne avec l’ATtiny alors que dans d’autres cas, nous saurons à l’avance que ce n’est même pas la peine d’essayer. L’étude de ce paragraphe est donc fortement conseillée si vous voulez comprendre ce que vous pouvez faire.
Il est bien évident que les deux µC n’ont pas les mêmes possibilités, l’un étant plus puissant que l’autre. L’ATtiny45 offre 6 lignes d’E/S alors que l’ATmega328P en offre 23. Peut-être allez-vous réagir : comment cela 23 ? Un module Uno dispose de 14 E/S digitales et 6 analogiques, donc 20 au total. Où sont passées les trois autres ? C’est un choix technologique qui a été fait dès la conception du module Uno. La figure 2 montre la correspondance entre les broches du µC ATmega328P et les connecteurs du module Uno.
- Figure 2
- Correspondance entre broches du µC ATmega328P et module Uno
La broche PC6 sert au RESET du module Uno (tout comme nous avons fait le choix de ne pas utiliser la broche PB5 de notre ATtiny et de la réserver au RESET). De même, les broches PB6 et PB7 (broches 9 et 10 du µC ATmega328P) servent à implanter un cristal de quartz pour que la fréquence de travail du module soit exactement calibrée. Cela revient donc à avoir un PORT B limité à 6 lignes sur un module Uno, forte similitude avec notre ATtiny45 !
La capacité mémoire est très différente entre les deux microcontrôleurs. L’ATmega328P dispose d’une mémoire flash de 32 kilo-octets accueillant le programme, alors que l’ATtiny45 est limité à 4 kilo-octets de mémoire flash (2 k pour l’ATtiny25 et 8 k pour l’ATtiny85). C’est bien entendu très peu, mais généralement suffisant pour de petites applications spécialisées à une seule tâche. De même, la mémoire SRAM permettant de stocker des variables est de 2 k sur l’ATmega328P alors qu’elle n’est que de 256 octets sur l’ATtiny45 (128 sur l’ATtiny25 et 512 sur l’ATtiny85). Cette capacité est en rapport avec la longueur de la mémoire flash : dans tous les cas un seizième, tout en gardant bien à l’esprit que ces deux mémoires (flash pour le programme et SRAM pour les variables) sont distinctes (architecture Harvard, c’est-à-dire avec des mémoires et des bus séparés pour les données et les programmes). Le mieux est de prendre dès le début les bons réflexes pour économiser la mémoire flash et la mémoire SRAM. Il existe des astuces de programmation qui donnent un code plus compact permettant d’économiser la mémoire flash et un choix judicieux des types de variables permet d’économiser la mémoire SRAM (voir à ce sujet l’article Types, constantes et variables).
Les figures 3 et 4 permettent de comparer l’architecture des deux microcontrôleurs ; elles sont extraites des datasheets des composants. Comme vous le voyez, la ressemblance est frappante. L’ALU (en rouge, Arithmetic Logic Unit ou encore Unité Arithmétique et Logique) est l’unité qui traite les informations ; elle est capable de réaliser trois catégories d’opérations : arithmétiques, logiques ou manipulation de bits sur les octets. L’ALU travaille avec 32 registres à usage général de 8 bits (en bleu) pour les deux microcontrôleurs. Un compteur de programme (en orange, Program Counter) permet de pointer l’instruction en cours de traitement dans la mémoire de programme (en violet). La valeur du compteur de programme peut être sauvegardée dans la mémoire SRAM (en jaune) en cas d’interruption ou de sous-programme. Enfin, dans les deux cas, on trouve un registre d’état (en vert, SREG pour Status Register) de 8 bits permettant d’avoir des informations sur le fonctionnement du µC et la structure des bits est la même pour l’ATmega328P et l’ATtiny45. Par exemple, le bit 0 indique si le résultat d’une opération génère une retenue ; on l’appelle bit de Carry (retenue en anglais). Le bit 1 indique si le résultat d’une opération est zéro. Chacun des bits du registre d’état peut être lu ou écrit par le programmeur pour les besoins du programme à réaliser. Par exemple, on peut écrire dans le bit 7 pour autoriser ou non les interruptions. Le registre d’état est automatiquement mis à jour après chaque opération de l’ALU.
- Figure 3
- Figure 4
Des registres, il en existe bien d’autres et nous n’allons pas plus entrer dans le détail de fonctionnement des deux microcontrôleurs, mais l’étude des datasheets des deux composants montrent des similitudes que nous pourrons exploiter. Les deux µC contiennent par exemple un convertisseur analogique-digital d’une résolution de 10 bits (ADC pour Analog to Digital Converter avec un résultat donné de 0 à 1023). Enfin, sur le plan matériel, les PORT d’entrée-sortie sont conçus exactement de la même façon et opèrent avec les mêmes registres (voir le chapitre 28 du cours d’électronique donné dans l’article Démarrer en électronique).
Bien entendu, il existe aussi des différences qui confèrent plus de puissance à l’ATmega328P, comme par exemple un timer 16 bits en plus des deux timers 8 bits qu’on retrouve sur les deux µC, six canaux PWM pour l’ATmega328P alors que l’ATtiny45 n’en a que 2, etc. Ces différences nous obligeront à nous adapter à la petitesse de l’ATtiny mais les possibilités de ce dernier n’ont quasiment pas de limites dans la mesure où l’application n’est pas trop gourmande en ressources et surtout est spécialisée sur une seule tâche (gestion d’un signal, gestion d’une aiguille, clignotement de feux de PN, etc.). Le prix à payer est de mettre plus de puces ATtiny sur son réseau, en s’arrangeant pour qu’elles soient indépendantes les unes des autres, ou bien qu’elles communiquent de façon rudimentaire, comme nous le verrons par la suite. En tout cas, cela fonctionne.
Dans les prochains articles, nous verrons comment programmer une puce ATtiny avec un module Arduino/Genuino Uno, puis nous étudierons des exemples simples de ce qu’elles peuvent faire sur un réseau de trains miniatures.