Dans cet article nous allons continuer
notre exploration des attiny en essayant d'identifier et acquérir les bases
nécessaires pour programmer ces petites bêtes.
Dans le long, mais passionnant (mais long!), article précédent
nous avons découvert les fondamentaux sur les attiny. Nous avions appris
comment réaliser un programmateur ISP avec un Arduino afin d'injecter nos
programmes, nous avions vu comment installer un bootloader pour que le
microcontrôleur (MCU) devienne utilisable depuis une platine de développement
low cost et nous avions vu aussi, de manière un peu forcée j'avoue, comment
manipuler des bits spéciaux appelés " fusibles". Quand je dis "forcé", je
précise pour ceux qui n'ont pas lu l'article précédent (quelle honte), que
suite à des erreurs de manipulation j'avais bloqué mon attiny et seule une
intervention au niveau des fusibles m'a permis de m'en sortir.
Maintenant que nous avons acquis ces fondamentaux, pour avancer encore un peu,
je me suis rendu compte qu'il allait me falloir acquérir de nouvelles
connaissances qui me permettront de commencer à programmer l'attiny dans de
bonnes conditions. C'est pourquoi après plusieurs épuisantes journées de
réflexion, je me suis soudain dit:
- Tiens! Si je faisais un article sur les bases nécessaires pour programmer un attiny? Et si j'appelais cet article "Les bases pour programmer un attiny".
Au delà du coté impressionnant de ma réflexion, ce qui va être
intéressant c'est de savoir quelles sont ces bases que j'ai identifiées comme
nécessaires. Alors voilà ce que je vous propose:
- Se construire sur PCB un petit programmateur ISP un peu plus stable et facile à utiliser que ce bazar sur breadboard que nous avions installé.
- Mettre en place les procédures et outils nécessaires pour tester et déboguer nos programme. Principalement comment envoyer des traces à notre ordinateur en utilisant la liaison série.
- Valider notre capacité à échanger des données entre un attiny et d'autres équipements (PC, Arduino, ESP8266, Raspberry PI et surtout serveur domotique).
Le programme est ambitieux. Mais comme disait ma grand mère:
On ne réalise pas de grandes choses sans une grande ambition.
1 Construction d'un programmateur ISP avec un arduino
Je ne vais pas réécrire ici ce que nous avions vu au chapitre 2 de
l'article précédent. Si vous ne l'avez pas lu, si vous ne savez pas ce qu'est un programmeur ISP
et comment en réaliser un avec un Arduino, si vous ne savez tout simplement
pas comment téléverser un sketch dans un attiny, alors reportez vous-y (à
l'article précédent
ICI).
Par contre, si cela vous intéresse, dans ce chapitre, je vous propose de vous
montrer comment j'ai améliorer le programmateur ISP. J'y ai passé tout un week
end et
je suis fier comme un paon du résultat. N'allez pas croire que j'essaie subrepticement de glisser tout un chapitre
pour parler de moi! Ce chapitre va nous permettre d'apprendre des choses
intéressantes. Au delà de la réalisation de cet outil qui fait partie des
bases que je considère nécessaires pour programmer l'attiny confortablement,
je vais
partager avec vous la méthodologie
que j'ai suivi pour y parvenir. Il y en a certainement d'autres et des bien
meilleures, mais pour ma part, étant débutant en création d'objets
électroniques, cette manière de m'organiser a très bien fonctionné.
1.1 Etape 1: Conception sur breadboard
Le programmateur que nous avions réalisé dans l'article précédent était non
seulement sur breadboard, mais en plus, dans la précipitation, j'avais voulu
réaliser quelque chose de fonctionnel sans chercher à avoir l'outil le plus
complet possible, ni l'assemblage le mieux organisé. En général on voit
qu'un assemblage n'est pas bien organisé quand tout simplement ce n'est pas
joli, ça fait fouillis, il y a des fils partout qui se croisent dans tous
les sens. Cette fois, étant donné que mon objectif était de réaliser un
montage définitif sur PCB avec des composants soudés, je ne voulais pas
prendre le risque de partir d'une ébauche en fouillis. Il me fallait
absolument
réaliser un prototype sur breadboard
qui soit complet en terme de fonctionnalités et qui soit propre
d'aspect.
1.1.1 Liste des fonctionnalités à implémenter
Le montage que nous avons réalisé dans l'article précédent permettait de
téléverser un programme dans un attiny25/45/85 en utilisant l'IDE Arduino
sur PC comme interface de programmation et un Arduino Nano que j'avais en
stock comme programmeur ISP. Dans ce mode de programmation, l'Arduino doit
s'interfacer à l'attiny en mode SPI
(protocole de communication utilisant les broches MOSI/MISO/SCK/RST). En
plus de ces connexions, nous avions placé une LED (rouge) qui permettait
d'indiquer le
bon fonctionnement du programme ISP
sur l'Arduino. Mais lorsque le programme tourne correctement sur l'Arduino,
ce dernier est prévu pour donner d'autres informations visuelles:
- La broche D7 émet un signal lorsque l'Arduino transmet des données à l'attiny.
- La broche D8 émet un signal en cas d'erreur.
De plus, souvenez vous, dans le paragraphe
4.3.4
nous avions ajouté un morceau de code dans le sketch du programmeur ISP
afin qu'un signal d'horloge puisse être envoyé à l'attiny
au cas où nous ferions l'erreur de régler ce dernier pour qu'il s'attende
à avoir un signal d'horloge externe. Entre nous je ne vois pas qui
pourrait faire une erreur aussi grossière 😉. Mais au cas où cela
arriverait (à nouveau), ce sera utile de reprendre ce signal émis par
l'Arduino sur D3 et de réaliser le raccordement pour qu'il arrive à
destination de PB3 (ou CLKI) de l'attiny. Ainsi, notre attiny restera
programmable par l'Arduino et cela même si par erreur nous l'avions placé
dans un mode d'attente de signal d'horloge externe.
Et pour finir, je souhaite aussi reprendre la connexion de la broche PB4
vers une LED qui permet d'intégrer dans nos sketch un
clignotement qui valide le bon fonctionnement du programme
que l'on vient de téléverser dans le MCU.
J'aurais voulu ajouter un petit interrupteur au niveau du condensateur qui
relie RST et GND sur l'Arduino car tant que ce condensateur est relié aux
broches du microcontrôleur, on ne peut pas en changer le programme. Mais
n'ayant pas ce type d'interrupteur sous la main, j'ai décidé de m'en
passer. De toute manière ce n'est pas très important car je mettrais
l'Arduino dans un socle afin que ce dernier puisse être extrait
pour reprogrammation ou changement en cas de panne.
De manière résumée voici les fonctionnalités à implémenter dans le
plan de câblage:
- Alimentation:
- Arduino 5V vers Attiny VCC
- Arduino GND vers Attiny GND
- Connections SPI entre Arduino et Attiny pour téléversement du programme:
- SCK: Arduino D13A vers Attiny PB2
- MISO: Arduino D12 vers Attiny PB1
- MOSI: Arduino D11 vers Attiny PB0
- RESET: Arduino D10 vers Attiny PB5 (RESET)
- LED de contrôle (mettre résistance 330Ω entre la broche et le GND):
- Arduino D7 vers LED jaune (transfert de données vers Attiny)
- Arduino D8 vers LED rouge (Signal d'erreur)
- Arduino D9 vers LED verte (bon fonctionnement programmeur)
- Attiny PB4 vers LED blanche (contrôle visuel si programmé dans Attiny)
- Condensateur:
- Anode (le + ) vers Arduino RST
- Cathode (le - ) vers GND Arduino
1.1.2 Conception avec Fritzing
J'ai téléchargé le logiciel Fritzing
ICI. Je ne le
connaissais pas ... et d'ailleurs après une demie journée passée dessus je
ne peux pas dire que je le maîtrise. Mais au moins il m'a permis de réaliser
le synoptique d'un montage câblant l'ensemble des fonctionnalités que nous
venons d’identifier et ressemblant à quelque chose de propre.
Plan de câblage du prototype sur breadboard de notre programmateur |
J'ai choisi des LED avec des couleurs différents et chacune permet d'indiquer des informations spécifiques:
- LED jaune : Programmation en cours.
- LED rouge : Erreur.
- LED verte : Va s’allumer et s’éteindre progressivement pour indiquer que le programme fonctionne bien.
- LED blanche : Permettra de tester l'attiny car elle sera connectée à la broche BP4 de ce dernier. On pourra faire un programme de type "Blink" qui validera que notre montage est fonctionnel et que nous téléversons bien le sketch dans l'attiny.
Bien que les LED aient des tensions différentes:
2V - 2,2V pour les rouge et les jaunes.
3V - 3,2V pour les vertes
3,2V - 3,4V pour les bleues et les blanches.
2V - 2,2V pour les rouge et les jaunes.
3V - 3,2V pour les vertes
3,2V - 3,4V pour les bleues et les blanches.
=> Une résistance de 330Ω fera l'affaire pour toutes. Et si
vous n'en avez pas vous pouvez utiliser 220Ω et jusqu'à 1000Ω
1.1.3 Liste des composants nécessaires
Pour réaliser ce prototype mais aussi le montage final nous allons avoir besoin de matériel.
Je conseil toujours d'acheter un kit de démarrage complet. C'est comme cela que j'avais commencé et des siècles après il me sauve encore de temps en temps la vie lorsque j'ai besoin d'un composant spécifique. J'avais pris le kit le plus complet que j'avais pu trouver comme ICI. Avec ce kit vous aurez les résistances, les LED, la breadboard, les câbles dupond et le condensateur.
Sinon vous pouvez vous procurer des lots par type de composants. Voici ceux que j'ai commandé récemment:
- Une boite de LED de chaque couleur en tailles 5mm et 3mm: ICI.
- Un lot de 1280 résistances en 64 valeurs différentes, livré en quelques jours: ICI.
- Un lot archi complet de condensateurs. Plus de 30€ ça peut paraître un peu cher mais avec une telle quantité et diversité c'est la garanti d'être tranquille pour toutes vos réalisation durant des années. En plus bien plus pratique que des dizaines de sachets avec la boite de rangement: ICI.
- Des PCB qui sont les plaques à trou sur lequelles nous pourrons souder et réaliser nos montages. J'ai commandé un lot avec plusieurs dimensions: ICI.
Et bien entendu il vous faudra les microcontrôleurs:
- Un Arduino NANO (prenez en au moins 3, ça servira). Les moins chers sont sur eBay ICI. Bien qu'en prenant un lot de 5 ICI vous bénéficiez du service Amazon et de la livraison rapide pour presque le même prix (1€ de plus / Arduino).
- Surtout ne pas oublier les sockets pour les Attiny! C'est un équipement essentiel pour le montage final: ICI. Et également un lot de broches "Breakaway" avec un espacement de 2,54mm qui nous permettra de réaliser un socle sur lequel viendra s'enficher l'Arduino. J'ai commandé le lot ICI qui fournit diverses modèles de rangées de broches mâles et femelles. Il y en a même avec des couleurs (j'adore). Bien sur chacun fait en fonction de ses moyens mais on a toujours besoin de ce genre de petit accessoire alors plus vous prendrez un lot diversifié et important, plus vous serez tranquille.
- Des Attiny. Prenez des 85 et prenez en plusieurs car c'est fragile ces petites bêtes. J'en ai trouvé sur Amazon comme ICI mais sans le service Prime autant prendre sur eBay au moins cher comme ICI où vous trouverez des lots de 5 ou même 10.
1.1.4 Réalisation du montage sur Breadboard
Après avoir réalisé un beau schéma et récupéré tout le matériel nécessaire, nous allons pouvoir nous lancer dans le montage du prototype. L'étude ayant été bien menée, cette phase doit se révéler simple et rapide. Il suffira de suivre le schéma. Bien entendu n'oubliez pas de téléverser le sketch dans l'Arduino pour le transformer en programmateur ISP (tel que décrit dans le paragraphe 2.1 de l'article précédent).
Voici ma réalisation. J'avoue avoir du corriger une ou deux connexions
car sur une breadboard les lignes de trous sont vraiment très proches
(👓) les unes des autres.
En connectant l'Arduino au PC en USB, j'ai pu constater que les 3 LED
associées à l'Arduino (jaune, vert, rouge) se sont allumées de manière
séquentielle et ensuite la verte à commencé à varier comme un cœur qui
bat.
Ensuite, j'ai configuré l'IDE Arduino pour compiler du code pour
Attiny85 et configuré le programmateur en "Arduino as ISP". Puis j'ai
téléversé le programme décrit dans le chapitre 2.2.5 de l'article
précédent. Le LED blanche s'est mise à clignoter! Tout fonctionnait donc
parfaitement et j'étais encore fier comme un paon.
1.2 Etape 2: test de positionnement sur PCB
La réalisation d'une maquette sur breadboard permet avant tout de valider le bon fonctionnement des connexions et de visualiser (un peu) les problématiques de câblage. Mais avant de se lancer dans la soudure, j'ai décidé de prendre une plaque PCB et d'essayer le positionner l'ensemble de composants afin de voir comment les organiser au mieux.
Dans un premier temps, j'ai sélectionné tous les composants et je les ai mis sur une feuille de papier.
Ensuite j'ai choisi une plaque PCB qui me semblait être la taille nécessaire et j'ai commencé à placer les composants dessus. J'ai commencé par une plaque 4*6cm. J'ai réussi à tout mettre mais l'agencement était compliqué. Et surtout j'ai constaté qu'en dessous il ne me restait quasiment aucune place pour réaliser des câblages propres.
Premier essai de montage "à blanc" sur PCB 4*6 |
Par mesure de précaution, je me suis donc reporté sur une plaque un peu plus grande, de taille 5*7cm. Cette fois c'était mieux et après avoir joué comme sur un puzzle pendant un bon quart d'heure, j'ai trouvé un agencement recto mais aussi verso qui me convenait. Voici le résultat:
|
1.3 Etape 3: Schématisation du plan de câblage
Que ce soit sur notre montage à blanc ou sur notre prototype sur
breadboard, aucune de ces deux étapes ne me permettait vraiment de
visualiser comment tous ces composants allaient se raccorder et comment
j'allais devoir faire passer tous ces câbles pour avoir quelque chose de
propre et réalisable. Ce dont on ne se rend souvent pas compte lorsque
l'on a jamais vraiment soudé sur ce type de PCB, c'est que mettre en
relation un composant avec un câble cela nécessite souvent l'utilisation
de deux trous. Et entre ces deux trous il faudra laisser une goutte de
soudure qui fera le lien. Pour placer cette "goutte" de soudure il faudra
un peu de place car au moindre contact avec un composant ou un fil à coté,
il faudra dessouder. Et ça c'est pas simple!
Pour optimiser la manière de passer tous ces fils, j'ai réalisé un petit
schéma qui fait apparaître le PCB comme par transparence. J'ai placé
uniquement les espaces occupés par les sockets de l'attiny et de l'Arduino
afin de visualiser toutes la place qui sera disponible à l'arrière de ma
plaque.
J'aurais bien aimé pouvoir utiliser Fritzing pour réaliser cette étape,
mais je n'ai pas réussi à m'approprier la fonction d'aide à la réalisation
de circuits imprimés. Alors je me suis replié sur mon vieil ami MS Visio
que je maîtrise assez bien. Voici ce que cela donne:
Plan de câblage |
La réalisation de ce plan m'a permis de visualiser comment gérer au mieux le passage des fils sous la plaque en utilisant tous les espaces disponibles.
1.4 Etape 4: soudure
Nous voici arrivés à l'étape finale de ce premier chapitre durant lequel
j'ai pu à nouveau vous raconter ma vie. Donc pour finir en beauté, de
dernier paragraphe de ce dernier chapitre n'aura aucun autre objectif que
de vous parler de moi. L'avantage c'est que ça devrait me calmer pour un
temps et durant toute la suite de cet article vous devriez être
tranquille.
J'adore souder! C'est un peu ma madeleine de Proust. Ces odeurs de métal
qui fond, de composants électroniques, de plastique chauffé me rappellent
mon enfance quand je passais dans l'atelier de mon grand père et qu'il
était occupé à réparer téléviseurs ou postes radios. Bien que je pense que
ce n'est pas très bon pour la santé, je ne peux m’empêcher lorsque je
soude, de temps en temps, d'aspirer à plein poumons ces volutes de fumée
blanche à l'odeur acre et métallique . Et puis je trouve que c'est
particulièrement décontractant. C'est un travail hyper minutieux. Il faut
être concentré. Il faut regarder dans la loupe, ne pas bouger, préparer
ses mouvements, poser délicatement la pointe du fer à souder (on appelle
ça une panne) et appliquer lentement la brasure à partir d'un petit fil en
alliage d'étain. C'est un peu comme un moment de méditation pour moi.
Ceci dit, j'ai bien du passer 3 heures pour réaliser le montage final. Et
même si j'adore ça, vers la fin j'avais tout de même hâte de terminer. Et
j'y suis parvenu!
Maintenant j'arrête de parler de moi. Je fini ce paragraphe en vous
laissant simplement admirer en image ma réalisation.
L'état de mon bureau après 3h de soudure ... oui oui, j'arrête de parler de moi. |
2. Liaison série et débogage
Nous voici désormais doté d'un magnifique programmeur pour nos attiny. Nous
pouvons commencer à écrire nos premières lignes de codes et les téléverser.
Mais bien que nous soyons de modestes développeurs de génie, personne n'est
à l'abris de faire quelques bogues. En général, lorsque j'écris un
programme, je place de nombreuses traces dans mon code pour afficher un
message lors du passage dans une section ou alors pour afficher les valeurs
des variables. Et quand je programme sur des ESP8266 ou des Arduino,
j'utilise la fonction "Serial.print". Cette fonction, s'appuie sur l'objet
(au sens programmation objet) Serial qui est associé directement au
matériel. En effet, ces plateformes disposent d'interfaces USB et donc
embarquent une puce qui va traduire en USB les messages envoyés par le
microcontrôleur dans le protocole UART. De manière très résumée, un
microcontrôleur va parler le langage série UART et un PC le langage série
USB. Il faut donc une puce entre les deux qui puisse faire la traduction.
Les Arduino et certaines plateformes ESP8266 embarquent ces puces que l'on
appelle des convertisseurs UART/USB. Mais les attiny eux, n'en ont pas.
L'objet "Serial" qui, comme nous venons de le dire, est associé au composant
matériel, ne sera donc pas utilisable (et s'il l'est ce ne sera pas un
fonctionnement identique). Nous allons donc devoir passer par un
intermédiaire pour que notre microcontrôleur qui ne demande qu'a s'exprimer
puisse être reçu et compris dans le moniteur série de notre PC.
Pour ceux qui souhaitent aller plus loin dans la compréhension des échanges série entre un microcontrôleur et un ordinateur, vous pouvez consulter mon article sur le sujet ICI.
2.1 La couche logicielle
Avant de regarder quel équipement nous allons pouvoir utiliser comme
convertisseur penchons nous sur l'aspect programmation.
A ce stade, je suppose que vous savez plus ou moins programmer un sketch
basique avec l'IDE Arduino et que vous savez téléverser ce dernier dans
l'attiny. Et je vais même supposer que pour ce téléversement vous avez
fabriqué le magnifique programmeur que je vous ai présenté dans le chapitre
précédent.
Comme je viens de le dire en introduction, pour envoyer (et recevoir) des
messages sur la liaison série nous n'allons pas pouvoir utiliser l'objet
"Serial" de manière simple, en connectant le microcontrôleur directement en
USB, comme nous le faisons avec un Arduino. Par conséquence la séquence
habituelle ci-dessous ne va pas fonctionner sur un attiny:
///////////////////////////////////Initialisation de la liaison
série
Serial.begin(SERIAL_BIT_RATE);
//Affiche message initial
Serial.println( "Serial: OK" );
Serial.begin(SERIAL_BIT_RATE);
//Affiche message initial
Serial.println( "Serial: OK" );
Toutefois, envoyer des données sur une liaison série ne consiste, après
tout, qu'a envoyer les bonnes impulsions électriques sur le bon fil. Bien
entendu ces impulsions doivent respecter certaines normes, mais à partir du
moment ou l'on est un microcontrôleur qui se respecte, que nous avons des
broches numériques et que nous savons envoyer des impulsions sur ces
dernières alors il n'y a pas de raisons que nous ne puissions pas les
utiliser pour envoyer des messages à la norme UART. Et vous l'aurez deviné,
notre attiny est un microcontrôleur qui se respecte (💪). En le programmant
correctement, il va donc pouvoir communiquer en UART en utilisant ses
broches. Nous allons regarder ça de plus près.
2.1.1 Trouver les librairies pour attiny
Dans les commentaires de mon article précédent, Bruno m'avait posé la
question de comment savoir quelles sont les librairies qui sont disponibles
pour l'attiny. C'est une très bonne question et selon moi il n'y a pas à ce
jour de réponse universelle.
Ce qu'il faut savoir, c'est que quand on ajoute la gestion d'une nouvelle
carte dans l'IDE Arduino , on va ajouter tout un ensemble de fichiers qui
vont apporter le code des fonction standard et ainsi permettre de compiler
un programme pour cette carte. Cet ensemble de fichiers s'appellent un
"core". Pour chaque carte on peut trouver plusieurs "core" différents,
réalisés par des développeurs différents et qui peuvent présenter des
différences entre eux. A la base,
chaque "core" est fait pour reprendre les instructions et les
librairies standard de l'Arduino. Sauf qu'il y a parfois de telles différences dans le fonctionnement du
matériel que les développeurs doivent parfois faire des choix
d'implémentation spécifique. L'exemple de la fonction Serial qui fonctionne
sur tous les arduino et qui est associé à la présence physique sur la carte
d'une puce UART est particulièrement parlant. Si je me décide de réaliser un
"core" pour pouvoir programmer un attiny, comment dois-je implémenter
"Serial" sachant que je n'ai pas de chipset UART, ni de broches TX, RX sur
le microcontrôleur cible ? Je pourrais tout simplement décider d'associer
"Serial" à deux broches de l'attiny que je désignerai de manière arbitraire
comme TX et RX . Ou alors je pourrais aussi décider de ne pas implémenter
l'objet Serial afin que le développeur choisisse lui même une autre
solution.
Avec cette longue explication et cet exemple, j'apporte une moitié de réponse à la question des librairies en disant:
En ce qui me concerne lorsque je me suis lancé dans la programmation des attiny je n'avais pas bien identifié cette notion de "core". Par défaut j'ai donc installé celui de Damellis qui est réputé pour générer les programmes les plus petits. Il existe également celui de SpenceKonde qui semble un peu plus documenté et propose en standard une librairie I2C et SPI. Vous trouverez plus d'informations la concernant ICI.
Avec cette longue explication et cet exemple, j'apporte une moitié de réponse à la question des librairies en disant:
Les librairies disponibles en standard, et le fonctionnement des
fonctions de base pour l'attiny dépendent du "core" que vous
utilisez.
En ce qui me concerne lorsque je me suis lancé dans la programmation des attiny je n'avais pas bien identifié cette notion de "core". Par défaut j'ai donc installé celui de Damellis qui est réputé pour générer les programmes les plus petits. Il existe également celui de SpenceKonde qui semble un peu plus documenté et propose en standard une librairie I2C et SPI. Vous trouverez plus d'informations la concernant ICI.
Pour rappel, si vous souhaitez ajouter la gestion d'une carte
supplémentaire dans votre IDE Arduino, vous devez aller dans le menu
<Fichier><Préférences>
et ajouter l'URL d'un fichier JSON dans le menu
<URL de gestionnaire de carte supplémentaire>. Ce fichier JSON va contenir l'ensemble des informations qui permettront
à l'IDE Arduino de télécharger les fichiers "core" pour cette nouvelle
carte. Si vous avez plusieurs URL dans cette sections, séparez chacune
d'entre elles par une virgule.
Voici les URL pour deux "core" différents permettant de compiler des programmes pour attiny:
Voici les URL pour deux "core" différents permettant de compiler des programmes pour attiny:
- Core Damellis: https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json
- Core SpenceKonde: http://drazzy.com/package_drazzy.com_index.json
Vous pouvez également aller dans le menu
<Outils><Type de carte><Gestionnaire de
carte>
et dans l'outils qui s'affiche, sélectionner la carte de votre choix.
Pour l'attiny, le "core" disponible est celui de Damellis (David A.
Mellis).
Le Core Damellis permettra en standard l'accès aux fonctions Arduino
suivantes:
pinMode()
digitalWrite()
digitalRead()
analogRead()
analogWrite()
shiftOut()
pulseIn()
millis()
micros()
delay()
delayMicroseconds()
SoftwareSerial ()
Un autre moyen d’obtenir des librairies de fonctions pour attiny, est
d'utiliser le gestionnaire de bibliothèque de l'IDE Arduino. Je suppose que vous savez tous que l'IDE dispose d'un outil simple et
performant qui permet de recherche sur la base de mots clés des librairies
et de les ajouter dans l'environnement de compilation afin qu'elles soient
disponibles pour nos programmes. On accède à cet outil directement dans
l'IDE dans par le menu
<Croquis><Inclure une bibliothèque><Gérer les
bibliothèques>:
Menu de l'IDE pour ajouter des librairies |
Ce menu lance un outil qui va permettre de faire une recherche dans un grand
nombre de librairies.
A ce jour, je ne sais pas encore comment fonctionne cet outil. Notamment s'il y a un dépôt quelque part et comment ces librairies sont mise à disposition pour tous les utilisateurs de l'IDE Arduino. S'il y en a parmi vous qui maîtrisent ce sujet n'hésitez pas à m'envoyer vos textes que j'ajouterai ici.
Il est très facile de faire une recherche par mot clé et lorsque l'on tape
"attiny" on reçoit une quantité assez importante réponses avec des
librairies dédiées pour attiny, comme "TinySuite", ou des librairies pour
d'autres cartes mais dont le fonctionnement est validé pour les attiny (ou
les microcontrôleur AVR).
Ecran du gestionnaire de bibliothèque de l'IDE Arduino |
Comme vous pouvez le voir sur l'écran ci-dessus, j'ai installé la
bibliothèque "TinySuite" qui apporte plusieurs fonctionnalités, comme une
librairie de gestion de la sortie série (hé hé ...).
Des librairies pour attiny sont disponibles dans le gestionnaire de
bibliothèque inclus dans l'IDE Arduino.
De nombreuses librairies pour attiny, couvrant de nombreuses
fonctionnalités, sont disponibles gratuitement sur internet.
2.1.2 Les librairies "serial"
Maintenant que nous savons comment nous procurer des librairies, je ne vais
pas faire durer le suspens plus longtemps car vous l'aurez compris, pour
transmettre des messages au format série UART avec l'attiny, nous allons
utiliser des librairies.
En fonction du "core" que vous utilisez, la classe "Serial" pourrait être
implémentée ou pas. Dans le core (Damellis) que j'utilise ce n'est pas le cas. Mais sachez que même si c'était le cas
pour vous, je vous déconseille de l'utiliser pour deux raisons:
- Vous n'auriez pas la maîtrise des broches par défaut qui sont utilisées.
- Si cette classe existe, elle est certainement qu'une simple couche supplémentaire, s'appuyant sur d'autres fonctions. Alors autant utiliser directement ces fonctions.
Il existe de nombreuses librairies qui fournissent au développeurs sur
attiny, les fonctions nécessaires pour gérer les communication série de
manière logicielle. Ces librairies peuvent être très différentes les unes
des autres. Certaines sont minimalistes et ne permettent que d'envoyer
quelques caractères mais n'utilisent que quelques ko de mémoire. D'autres
sont plus complètes et fournissent toutes les fonctions habituelles de
l'objet "Serial" de l'Arduino. D'autres encore sont implémentées pour gérer
les interruptions matériel de manière spécifiques afin de répondre à des
besoins plus avancés comme réaliser de la programmation asynchrone.
En ce qui me concerne j'en ai choisi deux que je vais tester afin
d'essayer de comparer s'il y a des différences:
SoftwareSerial: J'ai choisi cette librairie car elle se compile sans modification
de code sur beaucoup d'autres cartes que les attiny. De plus, elle est
incluse dans le core "Damellis" que j'utilise. Je n'aurais donc pas besoin
d'aller la chercher et de l'importer. Elle fournit des fonctionnalités
d’émission et de réception et elle permet d'utiliser les broches souhaitées
comme broches TX/RX.
Pour moi cette librairie est parfaite et c'est celle que j'utiliserais
autant que possible.
Le seul défaut que j'y vois pour le moment est la taille importante qu'elle
nécessite à la compilation. Le programme archi minimaliste ci-dessous occupe
2100 ko. Sachant que l'attiny45 n'est dispose que de 4096 cela laisse peut
de marge pour le reste du code. Par contre, sur l'attiny85, avec 8192 ko de
disponible, cela me semble suffisant pour mes besoins actuels.
#include <SoftwareSerial.h>
SoftwareSerial serial(PB2,PB1); //RX, TX
void setup() {
serial.begin( 19200 );
}
void loop() {
serial.println(F("loop") );
delay( 2000 );
}
TinySerial: J'ai choisie cette librairie pour me permettre de comparer avec
<SoftwareSerial>. Elle propose également des fonctions de
lecture/écriture et permet de personnaliser les broches TX/RX. Pour l'avoir
j'ai importé la bibliothèque TinySuite depuis le gestionnaire de
bibliothèque de l'IDE Arduino. Au niveau taille elle occupe quasiment la
même qu'avec SoftwareSerial: 2068ko pour un programme le plus basique
possible. Toutefois, la manière de déclarer la variable "serial" avec la
nécessité de donner une variable Timer et PinChange en
paramètres, laisse supposer qu'elle apportera d'autres fonctionnalités qui
peuvent être utiles.
#include <TinySerial.h>
#include <TinyPinChangeB.h>
#include <TinyTimer1Compare.h>
TinySerial serial(PB2, PB1, Timer1Compare, PinChangeB); //RX,TX
void setup() {
serial.begin( 19200 );
}
void loop() {
serial.println(F("loop") );
delay( 2000 );
}
#include <TinyPinChangeB.h>
#include <TinyTimer1Compare.h>
TinySerial serial(PB2, PB1, Timer1Compare, PinChangeB); //RX,TX
void setup() {
serial.begin( 19200 );
}
void loop() {
serial.println(F("loop") );
delay( 2000 );
}
Si vous recherchez une librairie qui occupe beaucoup moins de place mémoire, je vous laisse faire des recherches sur TinyDebugSerial.
Comparaison des deux librairies:
Comme vous pourrez le voir dans le code du programme que j'ai réalisé (dont vous pourrez retrouver l'intégralité ICI) il y a très peu de différences dans l'utilisation des deux librairies. Toutefois la librairie TinySerial m'a obligé de positionné un petit "delay" au moment de la lecture des caractère car il y en avait un qui n'était pas lu.
De plus, sur le plan des fréquences de connexion, les deux ont fonctionné de manière identiques. Par contre le bon fonctionnement de la liaison série dépend également de la fréquence de fonctionnement du MCU.
Voici le résultat de mes essais:
Vitesse laison série / Fréquence attiny => résultat
4800 bauds / 1 Mhz => OK
9600 bauds / 1 Mhz => Ne fonctionne pas.
9600 bauds / 1 Mhz => Ne fonctionne pas.
19200 bauds / 1 Mhz => Ne fonctionne pas.
57600 bauds / 8 Mhz => Instable
57600 bauds / 16 Mhz => OK
115200 bauds / 16 Mhz => OK
57600 bauds / 8 Mhz => Instable
57600 bauds / 16 Mhz => OK
115200 bauds / 16 Mhz => OK
2.1.3 Programme de test
Les petits exemples de code minimalistes que je vous ai donné ci-dessus montrent comment faire un programme qui envoi un message sur la liaison série. Dans les deux cas, RX est associé à PB2 et TX à PB1. Pour visualiser je vous redonne le plan de brochage des attiny25/45/85:
Faire des programmes minimalistes c'est bien, mais n'oublions pas qu'ici
nous sommes dans un blog de jardinier! Nous sommes ici pour creuser,
cultiver, semer ...
Alors bon, le minimalisme c'est pas trop notre truc.
Nous allons donc profiter de ce qui devrait être un simple exemple de programme montrant comment envoyer un commentaire sur la liaison série, pour aller bien plus loin et apprendre plein de choses.
Je vous propose que nous parlions de:
Nous allons donc profiter de ce qui devrait être un simple exemple de programme montrant comment envoyer un commentaire sur la liaison série, pour aller bien plus loin et apprendre plein de choses.
Je vous propose que nous parlions de:
- Compilation conditionnelle
- Reset / Reboot logiciel
- Lecture d'une chaîne de caractère sur la liaison série
- Attente non bloquante.
Si cela ne vous intéresse pas pour l'instant, vous pouvez passer directement
au paragraphe suivant.
Algorithme:
Le programme que nous allons réaliser va permettre de lire une chaîne de
caractère depuis la liaison série. Lorsque cette chaîne est reçue, le
programme va simplement l'afficher et afficher le nombre de caractères. Si
cette chaîne est le mot "reset", alors le programme devra provoquer un
"reset" du microcontrôleur. Et comme la patience ce n'est pas notre fort, si
aucun caractère n'est reçu pendant un temps donné, le programme devra nous
rappeler qu'il attend des caractères. Vous trouverez le code complet du
programme
ICI.
Compilation conditionnelle:
Comme nous souhaitons utiliser deux librairies différentes, c'est le moment
de regarder comment faire une compilation conditionnelle. Le pré-compilateur
C/C++ de l'IDE Arduino permet d'inclure des directives #if, #ifdef, #else,
#elif et #endif qui en fonction de la condition compile le code dans la
section ou l'ignore totalement.
Pour ce faire, j'ai introduit deux définitions avec chacune des valeurs
différentes. Ces définitions désignent la librairie <SoftwareSerial>
ou <TinySerial>. Ensuite j'ai défini une autre valeur nommée
SERIAL_LIBRARY qui indique avec quelle librairie nous souhaitons
compiler.
#define SOFTWARE_SERIAL 0
#define TINY_SERIAL 1
#define SERIAL_LIBRARY SOFTWARE_SERIAL
#define TINY_SERIAL 1
#define SERIAL_LIBRARY SOFTWARE_SERIAL
Ainsi ici, SERIAL_LIBRARY a la valeur SOFTWARE_SERIAL. Ceci indique que nous
souhaitons compiler avec <SoftwareSerial>. Si j'avais modifié le code
par:
#define SERIAL_LIBRARY TINY_SERIAL
Cela aurait indiqué que je souhaite compiler avec <TinySerial>.
Ensuite, à chaque portion de code spécifique, on va tester quelle librairie
est utilisée:
#if( SERIAL_LIBRARY == TINY_SERIAL )
#include <TinySerial.h>
#include <TinyTimer1Compare.h>
#include <TinyPinChangeB.h>
#elif( SERIAL_LIBRARY == SOFTWARE_SERIAL )
#include <SoftwareSerial.h>
#else
#error "SERIAL_LIBRARY: valeur incorrecte"
#endif
#include <TinySerial.h>
#include <TinyTimer1Compare.h>
#include <TinyPinChangeB.h>
#elif( SERIAL_LIBRARY == SOFTWARE_SERIAL )
#include <SoftwareSerial.h>
#else
#error "SERIAL_LIBRARY: valeur incorrecte"
#endif
Vous remarquerez la directive "#error" qui permet de générer un message d'erreur à la compilation.
Reset / Reboot logiciel:
Depuis que nous étudions les microcontrôleurs dans ce blog, nous avons déjà
vu comment faire un reset. Notamment avec les ESP8266, il faut simplement
générer une impulsion (à GND) sur la broche RESET et le MCU reboot. Mais
pour faire un reset (ou reboot) de manière logicielle c'est un peu moins
simple. Pour le moment j'ai identifié deux méthodes. La première consiste à
faire repartir le programme en cours depuis le début. En général, quand un
microcontrôleur reboot, il commence par exécuter l'instruction dans sa
mémoire située à l'adresse 0. On peut réaliser cela simplement en appelant
une fonction que l'on a "forcé" d'être à l'adresse 0. Voici ce que cela
donne:
void (*soft_reboot) (void) = 0;
void loop() {
//Appel de la fonction qui va provoquer le reset
soft_reboot();
}
void loop() {
//Appel de la fonction qui va provoquer le reset
soft_reboot();
}
Cette méthode fonctionne toutefois elle n'est pas idéale car toutes les
zones de la mémoire et les valeurs de certains registres ne vont pas être
remis à zéro proprement comme lorsque le microcontrôleur effectue un vrai
reset. Pour faire ça de manière plus sure, les microcontrôleurs disposent la
plupart du temps, d'une fonction appelée "Watch Dog Timer" (WDT). Son rôle
est justement, de déclencher une séquence complète de reboot. On lui indique
un temps de déclenchement et après ce temps, s'il n'est pas interrompu, le
WDT reboot le MCU. Je ne peux pas rentrer dans des détails plus complets
ici. Mais pour l'utiliser il faut appeler la fonction wdt_enable() qui se
trouve dans la librairie <avr/wdt.h>. Avant cela il faudra avoir pris
soins d'avoir remis à zéro les indicateurs d'état dans les registres du MCU
et bien sur de s’être assuré qu'il est bien désactivé. Cette séquence étant
un peu complexe, pour une fois je vais me contenter d'en écrire le code sans
rentrer dans les détails.
void setup() {
// On désactive le watch dog timer au cas ou il avait été activé.
cli(); // C'est mieux d'empêcher les interruptions quand on manipule les registres.
// Remet à zero le "reset flag" qui indique si le reset à été provoqué par le watch dog ou manuel (pulse sur le broche reset)
// MCUSR est le registre d'état du MCU.
// WDRF est le bit qui indique si le reset provient du WD
MCUSR &= ~(1<<WDRF);
wdt_disable(); // desactive wdt
sei(); // Autorise à nouveau les interruptions.
}
void soft_reboot(){
wdt_enable(WDTO_15MS);
while(1){}; //attente que le WDT se déclanche.
}
void loop() {
//Appel de la fonction qui va provoquer le reset
soft_reboot();
}
// On désactive le watch dog timer au cas ou il avait été activé.
cli(); // C'est mieux d'empêcher les interruptions quand on manipule les registres.
// Remet à zero le "reset flag" qui indique si le reset à été provoqué par le watch dog ou manuel (pulse sur le broche reset)
// MCUSR est le registre d'état du MCU.
// WDRF est le bit qui indique si le reset provient du WD
MCUSR &= ~(1<<WDRF);
wdt_disable(); // desactive wdt
sei(); // Autorise à nouveau les interruptions.
}
void soft_reboot(){
wdt_enable(WDTO_15MS);
while(1){}; //attente que le WDT se déclanche.
}
void loop() {
//Appel de la fonction qui va provoquer le reset
soft_reboot();
}
Lecture d'une chaîne de caractère sur la liaison série et attente non bloquante:
Pour l'attente non bloquante j'utilise la fonction millis(). Je vous laisse
regarder dans le code comment je procède. Pour la lecture d'une chaîne
sur la liaison série, il faut déclarer un buffer et tant qu'il y a des
caractères de présent, les lire et la ajouter en bout de buffer.
if (serial.available()) {
uint8_t index = 0;
le_buffer[ 0 ] = '\0';
while ( ( serial.available()> 0 ) && ( index <= ( TAILLE_BUFFER - 2 ) ) ){
le_buffer[ index++ ] = serial.read();}
uint8_t index = 0;
le_buffer[ 0 ] = '\0';
while ( ( serial.available()> 0 ) && ( index <= ( TAILLE_BUFFER - 2 ) ) ){
le_buffer[ index++ ] = serial.read();}
2.2 La passerelle physique
Après cette partie consacrée à l'aspect logiciel de la liaison série sur
l'attiny, nous allons maintenant regarder comment physiquement mettre en
relation les broches de notre petit microcontrôleur et le port USB du PC.
Il nous faut trouver un équipement qui puisse jouer le role de passerelle
physique mais aussi protocolaire, en traduisant les signaux UART dans la
norme USB.
J'ai deux solutions à vous proposer.
2.2.1 Convertisseur UART/USB
Le plus simple est de vous procurer un petit appareil qui embarque une puce
de conversion UART/USB et les connectiques USB + GPIO. On en trouve
facilement sur tous les sites qui vendent de l'électronique. Souvent il
suffit de rechercher "convertisseur UART USB".
Les puces de traduction sont le plus souvent soit à la
norme CH340G ou CP2102. L'une comme l'autre feront l'affaire. Il faudra juste installer le bon
driver sur votre ordinateur. Pour ma part j'ai essentiellement eu des CH340G
et jamais aucun problème.
En ce qui concerne la forme et l'interface GPIO, j'aime bien ceux qui
ressemblent aux images ci-dessus car il permettent très facilement de
connecter un module ESP01 pour le programmer. Celui de gauche est le plus
basique et vous imposera de réaliser une jonction entre le GPIO et le GND
pour passer l'ESP en mode programmation. Celui de droite, qui est la version
grand luxe ;-) mettra à votre disposition un bouton pour réaliser la
mise à GND de GPIO01.
Si vous souhaitez en savoir plus sur la réalisation de cette jonction et sur
la programmation des ESP01/ESP01s en utilisant ces convertisseurs, je vous
invite à parcourir mon article
ICI.
Dans l'univers de ces modules, vous pourrez également entendre parler de
FTDI ou de TTL. FTDI est une marque et TTL indique que le niveau bas dans le
protocole UART est à 0V et le niveau haut à 5V. La bonne manière de nomer
ces convertisseurs serait donc "Convertisseur UART TTL vers USB embarquant
un chipset de type CH340G (ou CP2012)".
Regardons comment on raccorde notre attiny au convertisseur:
Connexion convertisseur UART-USB et attiny |
2.2.2 Utilisation d'un arduino comme passerelle
Si vous ne souhaitez pas vous équiper d'un convertisseur mais que vous avez un Arduino sous la main alors ça devrait faire l'affaire. L'Arduino possède toutes les qualités pour jouer le rôle de convertisseur. Il dispose d'un chipset capable de convertir les signaux UART du CPU en USB et il possède la double connectique : ports GPIO et USB.Pour qu'il puisse fonctionner comme passerelle USB-UART il faut:
- Raccorder la broche simulant RX de l'attiny sur RX de l'Arduino.
- Raccorder la broche simulant TX de l'attiny sur TX de l'Arduino.
- Raccorder VCC de l'attiny sur +5V Arduino
- Raccorder GND de l'attiny sur GND Arduino
- Raccorder RST Arduino à GND Arduino
2.3 Conclusion
J'aime beaucoup les conclusions mais je déteste les fins. Alors j'ai trouvé
une astuce: faire des conclusions avant la fin! Nous arrivons donc à la
conclusion de ce chapitre.
Dans le premier chapitre nous avons vu comment nous construire un
programmateur digne de ce nom pour nos attiny.
Dans ce second chapitre nous avons commencé à voir comment programmer et
surtout comment nous doter des outils, logiciels et matériels, pour pouvoir
déboguer nos programmes et envoyer des traces sur notre moniteur série. Nous
allons donc pouvoir sereinement passer à la suite et essayer d'envoyer des
données depuis notre attiny vers notre serveur domotique.
3. Envoi de données vers domoticz
Lorsque j'ai débuté cet article, j'avais prévu dans ce chapitre d'étudier
l'échange de données entre un attiny et d'autres équipements tels qu'un
ordinateur, un Raspberry PI ou d'autres microcontrôleurs. Mais en cet
instant je me dis que le sujet est trop vaste et mériterait à lui seul
plusieurs articles complets. Alors comme le disait ma grand mère, je me
suis dit "dans la vie, il faut faire en premier les choses qui sont les
plus importantes". Et quelles sont les choses vraiment importantes dans la
vie ? Je suis sur que vous avez la réponse! c'est notre serveur domotique.
Alors dans ce chapitre nous allons voir comment ce petit attiny peut
envoyer simplement des données vers le serveur domoticz
(mais cela doit fonctionner quelle que soit votre solution domotique).
3.1 Le choix de la technologie de communication
Faire un choix est parfois quelque chose de difficile dans la vie. Mais
quand le choix concerne quelque chose d'aussi important que la technologie
d'échange de données entre un attiny et un serveur domoticz, cela devient
carrément cornélien. Nous allons donc procéder par élimination.
3.1.1 Choix du support
Le support est le média physique qui va permettre de mettre en relation
les deux équipements. L'objectif est de trouver un support qui permette de
relier un attiny et un Raspberry PI. Ma solution domotique tournant sur un
PI 3B+.
De manière native, l'attiny ne dispose que d'un port GPIO pour envoyer des
données. Le Raspberry 3B+ dispose d'une interface Ethernet, d'un port GPIO
et du wifi.
De plus, sur mon Raspberry PI, j'ai ajouté un équipement RFXCOM qui permet
de capter et émettre des signaux sur la longueur d'onde 433,92 Mhz. Il
s'agit d'un RFXtrx433E que vous pouvez trouver
ICI (ou
ICI en version XL
qui est l'identique que la E mais avec plus de capacités). J'ai aussi une
clé USB Zwave (comme
ICI).
Si j'ajoute les autres composants que j'ai à disposition, comme des
modules NRFL2401 ou des
ESP01s cela laisse un choix assez important de support:
- Ethernet
- GPIO
- wifi / Bluetooth
- RF 433Mhz
- RF 2,4Ghz
- Zwave
En ce qui concerne Ethernet et GPIO il s'agit de supports filaires. Si
j'utilise des attiny c'est pour fabriquer des petites sondes à placer un
peu partout. Donc dans un premier temps je vais écarter ces supports je ne
me fois pas tirer des câbles partout.
En ce qui concerne le wifi ou le RF 2,4Ghz, ce sont deux supports qui
consomment une quantité d'énergie assez importante. Ils seront
certainement adaptés à certains cas d'usages, mais dans un premier temps
je préfère me concentrer sur des supports qui me permettront de mettre en
place des objets connectés sur accu, donc à faible consommation.
En ce qui concerne le Zwave, je n'ai aucun module qui me permette
d’émettre sur ce support.
Par élimination il ne me reste donc plus que le RF433. Il s'agit d'un
très bon support car:
- Il est peu consommateur d'énergie
- Il existe une quantité de protocoles simples et standardisés pour émettre des données
- Les équipements qui utilisent ce support sont en général assez abordables financièrement
- On trouve facile des modules ultra simples qui permettent à un microcontrôleur d’émettre un signal sur cette fréquence. Ces modules se trouvent en général par paires: un récepteur et un émetteur.
- Et surtout me concernant, j'ai déjà un récepteur RF433 connecté à mon Raspberry et reconnu nativement par le serveur domoticz.
Les point négatifs ne sont pas très nombreux mais il y en a tout de
même:
- Portée limitée (une centaine de mètre dans les meilleures conditions, 3 ou 4 m dans les pires.
- Protocoles associés souvent peut sécurisés: tout le monde peu recevoir le message ou le copier.
- Protocoles associés souvent sans retours d'état.
- Fréquence très utilisée et possibilité d'avoir des erreurs dans les données transmises.
Malgré ces quelques défauts que nous pourrons essayer de corriger en
fonction des situations à venir que nous rencontrerons et de nos besoins,
le RF433 me semble le support le plus adapté pour les projets futurs. Nous
allons donc considérer que transmettre un message à notre serveur
domotique en utilisant cette longueur d'onde fait parti des bases
essentielles à apprendre en programmation de l'attiny.
3.1.2 Choix du protocole X10
Dans l'univers de la fréquence 433Mhz, il existe énormément de protocoles différents. De nombreux développeurs de sondes ont mis au point leur propres protocoles et chacun ont leurs complexité et leurs spécificités.
Dans le cadre de cet article, j'ai cherché à montrer que je pourrais
facilement faire communiquer l'attiny et le serveur domoticz. Il fallait
donc trouver un protocole simple, disposant d'une librairie facile à
intégrer, à utiliser et qui serait reconnu en standard par domoticz.
Il y a peut être plusieurs protocoles qui répondent à ces critères mais en
ce qui me concerne, après tout de même pas mal d'heures de recherches et
d'essais (manqués) j'ai croisé le protocole X10 et le X10 RF, son
adaptation à la porteuse 433,92Mhz .
Qu'est-ce que X10 RF ?
X10 est un protocole qui permet à un émetteur d'envoyer des trames
composées de bits vers un récepteur qui est constamment à l'écoute. A
l'origine (en 1975 ... ça ne nous rajeunit pas), ce protocole a été
développé pour de la transmission de données sur courant porteur de ligne
(CPL). En gros, pour que des objets raccordés à des prises électriques
dans une maison puissent recevoir des instructions de la part d'un
émetteur central. Et comme il pouvait y avoir plusieurs objets dans la
maison, le protocole a été conçu pour pouvoir donner un identifiant à
chacun d'eux.
Comment fonctionne le X10 RF ?
Nous n'allons pas passer de temps ici à détailler le fonctionnement du
protocole car vous me connaissez, il faudrait que nous creusions toujours
un peu plus pour comprendre comment fonctionne la modulation de fréquence
pour transmettre des bits, ainsi que toutes les subtilités liées à ce type
d'envois de données.
Je peux toutefois donner quelques éléments sur le protocole X10 RF
mais sans rentrer dans les détails:
- Une trame X10 est constituée:
- d'une en-tête de 8.8 ms de porteuse, suivi de 4.4 ms de silence
- De deux octets de données, soit 16 bits constitués de la manière suivante:
- Un code maison: 4 bits (une lettre de A à P)
- Un code unité : 4 bits (16 combinaison possibles).
- Un code maison: 4 bits
- Un code commande: 4 bits
- Chaque octet envoyé est suivi par le même octet mais inversé (complément binaire) afin de permettre un certain contrôle.
- La trame est envoyée plusieurs fois de suite. Souvent 5 fois espacé par 40 ms de silence entre chaque.
En regardant le protocole nous observons que la trame X10 nous permet d'identifier des équipements en associant deux codes. Le code appelé "maison" et le code appelé "unité".
- Maison est une lettre allant de A à P (16 possibilités)
- Unité est un chiffre allant de 1 à 16.
Ceci aura pour conséquence que sur une même installation, nous pourrons
gérer 16*16 = 256 équipements différents. Chacun sera identifié par son
couple unique (maison, unité).
3.1.3 La librairie x10rf
Comme le disait ma grand mère, il ne faut pas chercher à réinventer la roue. Et pour utiliser le protocole X10 c'est bien ce que je compte faire. Après mes recherches, j'ai trouvé pas mal de makers qui utilisent pour leurs montages la librairie "x10rf". Je vais donc également l'utiliser. Cette librairie fournit des fonctions pour envoyer des messages 433 Mhz en pilotant un module émetteur basique de type FS1000A. Nous dirons quelques mots un peu plus loin sur ce module et comment se le procurer. Les fonctions fournies envoient les trames de données dans un format correspondant au protocole X10 et permettent d'émuler des équipement reconnus en standard par le récepteur RFXCOM . En recevant ces trames, l'équipement sera également identifié dans domoticz.Les fonctions fournies par la librairie x10rf permettent d'émuler des objets de type:
- RFXmeter: compteur de mesures (type eau, gaz, ...)
- RFXSensor: sonde de température, humidité et pression.
- X10Switch: simulation d'un commutateur à deux états (ON / OFF ou Ouvert / Fermé).
- x10Security: Gamme d'équipements en relation avec la sécurité.
Le but ici n'est pas de rentrer dans l'étude de cette librairie mais simplement de l'utiliser pour envoyer une donnée à domoticz. Pour faire simple, je vais donc essayer de créer un interrupteur virtuel dans domoticz et de le piloter depuis l'attiny avec l'objet de type "X10Switch".
Récupération de la librairie x10rf:
On trouve plusieurs versions de la librairie. La plus ancienne et celle qui est le plus référencée dans les articles, est celle de "p2baron" qui se trouve ICI: https://github.com/p2baron/x10rf. Dans mon environnement, cette librairie n'a pas été compatible avec une compilation pour attiny.
Toutefois, une branche de développement parallèle a été ouverte par "pyrou". Cette dernière propose une version plus récente, qui apporte quelques corrections mineures et surtout qui se compile avec le core "Damellis" de l'attiny. Vous pouvez la trouver ICI: https://github.com/pyrou/X10RF-Arduino.
Installation de x10rf:
x10rf est une librairie constituée par deux fichiers. Un .h et un .cpp. Pour l'utiliser, soit vous l'installez normalement après avoir téléchargé le fichier ZIP, allez dans l'IDE Arduino et dans le menu:<Croquis> / <Inclure une bibliothèque> / <Ajouter la bibliothèque .ZIP>
Vous devriez vous un répéretoire \X10RF-Arduino-master qui s'est créé dans le répertoire où se trouvent vos librairies Arduino (par exemple Arduino\hardware\arduino\avr\libraries).
Sinon, vous pouvez à partir du fichier ZIP, extraire directement le dossier X10RF-Arduino-master\ dans le répertoire de votre choix, en vous étant assuré que ce dernier sera bien connu lors de la compilation.
Si vous ne souhaitez pas installer la librairie, vous pouvez extraire les deux fichier .cpp et .h en les plaçant directement dans le répertoire où se trouvera le code source de votre sketch. Mais si vous faites cela, dans votre sketch, vous devrez modifier le #include <x10rf.h> en #include "x10rf.h".
3.1.4 Configuration domoticz
Comme je le disais ci-dessus, dans le cadre de cet article, nous allons simplement essayer de piloter avec notre attiny, un interrupteur déclaré dans domoticz. Il va falloir déclarer ce switch en lui donnant les bons paramètres qui permettront ensuite de lui envoyer les commandes ON et OFF avec notre librairie X10.
Comme d'habitude il y a plusieurs méthodes pour créer cet interrupteur. La première est la plus simple mais elle suppose que la trame X10 ait déjà été envoyée en RF433 et reçue par le capteur RFXCOM. Si vous avez suivi la progression de cet article, nous n'en sommes pas encore là. Je vous l'indique tout de même pour l'avenir.
Pré-requis:
Avant toute chose, bien entendu, vérifiez que vous avez bien votre boitier RFXCOM de connecté et reconnu dans la liste des matériels domoticz. Les modèles RFXtrx433E ou RFXtrx433XL vont fonctionner tous les deux.
Ensuite vérifiez que le protocole X10 est bien activé dans les paramètres du RFXCOM. Pour cela allez dans domoticz, menu <Configuration>/<Matériel>. Pour accéder à la liste des protocoles reconnus, cliquez sur <Réglez le mode>.
Activation protocole X10 dans le RFXCOM |
Méthode d'appairage automatique:
Cette méthode est possible si l'équipement a déjà émis la trame X10.
Dans ce cas, si la trame et le protocole sont reconnus par le RFXCOM,
l'équipement doit apparaître, après quelques secondes, dans la liste des
dispositifs vu par domoticz. Prenons l'exemple d'un dispositif X10 ayant
pour code Maison: N et pour code unité: 1 ayant émis une commande ON.
Allez dans le menu
<Configuration>/<Dispositifs>
et suivez les étapes suivantes:
Une fois validé, vous pouvez vous rendre dans la page <Interrupteurs> de domoticz et vous verrez votre nouvel équipement. De base il est identifié comme un interrupteur ON/OFF mais en cliquant sur <Modifier> vous pourrez en changer le type pour, par exemple, en faire un détecteur d'ouverture de porte.
La seconde méthode va nous permettre d'ajouter un dispositif manuellement, avant que celui ci n'ait émis un signal et ne soit reconnu dans domoticz.
Pour cela, rendez vous dans la page <Interrupteurs> de domoticz et cliquez sur le bouton <Ajout Manuel> en haut à gauche.
- Affichez tous les dispositifs et classez les par ordre décroissant en fonction de la date de dernier contact. Vous devriez voir en tête de liste les équipements ayant émis un signal le plus récemment.
- Regardez si vous avez des équipements dont le "sous type" identifié est X10. Si vous ne voyez rien, attendez un peu, rafraîchissez l'affichage et si au bout de 2 minutes vous n'avez toujours rien, faites réémettre le signal.
- Vérifiez bien que le signal a été reçu par le RFXCOM.
- Recherchez l'ID de l'équipement émetteur. L'ID correspondra au code "maison". Dans notre cas nous avions choisi "N". C'est le code ASCII correspondant à la lettre qui s'affiche. En ASCII la lettre N est codée 78.
- La colonne Unit doit vous montrer le code unité de l’émetteur. Nous avions choisi 1.
- Lorsque vous êtes certain que la ligne correspond bien à l'équipement, il ne reste plus qu'à le déclarer dans domoticz en cliquant sur le petite flèche verte.
Une fenêtre va s'afficher pour vous demander de donner un nom au
dispositif. Nommez-le et validez en cliquant sur
<Ajouter un dispositif>. Ici j'ai donné le nom "Test_N1".
Une fois validé, vous pouvez vous rendre dans la page <Interrupteurs> de domoticz et vous verrez votre nouvel équipement. De base il est identifié comme un interrupteur ON/OFF mais en cliquant sur <Modifier> vous pourrez en changer le type pour, par exemple, en faire un détecteur d'ouverture de porte.
Méthode d'appairage manuel:
La seconde méthode va nous permettre d'ajouter un dispositif manuellement, avant que celui ci n'ait émis un signal et ne soit reconnu dans domoticz.
Pour cela, rendez vous dans la page <Interrupteurs> de domoticz et cliquez sur le bouton <Ajout Manuel> en haut à gauche.
Ensuite, remplissez le champs de la fenêtre qui apparaît:
Pour finaliser, validez en cliquant sur <Ajouter un dispositif>. C'est terminé! Normalement votre nouveau dispositif va apparaître dans la page <Interrupteurs> et dans la liste des dispositifs.
- Nom du périphérique: donnez le nom de votre choix.
- Type: sélectionnez X10 qui sera notre protocole.
- Code maison et code unité: donnez les codes que vous avez choisi. Dans mon cas j'ai mis A7.
Pour finaliser, validez en cliquant sur <Ajouter un dispositif>. C'est terminé! Normalement votre nouveau dispositif va apparaître dans la page <Interrupteurs> et dans la liste des dispositifs.
3.2 Matériel et montage sur breadboard
Bien! Tout se met en place progressivement. Nous avons installé la librairie et nous avons configuré domoticz pour que le serveur reconnaisse un nouvel équipement de type X10 dont les codes maison/unité sont A7 (bien entendu vous pouvez choisir autre chose, l'important c'est que cet identifiant soit unique). Nous allons maintenant réaliser un montage sur breadboard qui sera un prototype de ce que nous pourrons réaliser ultérieurement. Le cahier des charges minimal est le suivant:
- Utilisation d'un attiny85
- Utilisation d'un module low-cost émetteur 433Mhz de type FS1000A.
- Capacité d'émettre (et recevoir en option) des messages sur la liaison série avec notre ordinateur afin de mettre au point et déboguer le programme.
- Ajout d'une LED de contrôle du bon fonctionnement du sketch et d'une LED de controle d'envois de données en RF433.
3.2.1 Matériel nécessaire
Philosophie commerciale: Je ne suis pas actionnaire d'Amazon ou d'eBay. J'utilise Amazon pour la rapidité de livraison, le choix et surtout le service qu'ils fournissent en cas de problème. J'utilise eBay pour mes achats de petits matériel électronique pour les prix compétitifs mais quand je peux me permettre d'attendre deux mois une commande. Les liens que je vous donne pointent sur du matériel compatible avec mes montages, que je recommande et que j'ai en général acheté. Je choisi du matériel de bon rapport qualité/prix/service (livraison, SAV,...) Si vous faites un achat en passant par un de mes liens, la (minuscule) commission qui me sera versée ne nuira pas aux bénéfices des géant du e-Commerce et m'aidera à investir pour rédiger de nouveaux articles. Et si aucun matériel ne vous intéresse, vous pouvez mettre ce lien https://amzn.to/30xd8Ag dans vos favoris et l'utiliser quand vous aurez besoin de quelque chose sur Amazon.
Un GRAND merci à tous ceux qui ont joué le jeu et ceux d'entre vous
qui le joueront
Pour le serveur domotique, si vous ne l'avez pas encore, vous aurez besoin d'un Raspberry PI sur lequel va tourner domoticz. Pour l'installation je vous invite à parcourir mon article ICI. Un PI 3B+ suffira largement pour faire de la domotique et d'autres choses en même temps. Il aura l'avantage de moins consommer que le PI4. Par contre, si vous achetez un 4, vous aurez une interface 1G Ethernet et de l'USB 3.0. A vous de voir. Il vous faudra également un RFXCOM et là, sans hésiter, je vous conseille un RFXtrx433 XL (le lien sur eBay est ICI) plutôt qu'un E car pour le même prix le dernier propose bien plus de capacités.
Pour le montage coté émetteur, je suppose que vous avez tout le petit matériel nécessaire pour réaliser des montages sur breadboard. Sinon prenez un kit le plus complet possible comme ICI.
Il va également falloir se procurer des attiny et des émetteur RF433. En général ces derniers se vendent par paire émetteur + récepteur. Vous pourrez trouver des émetteurs seuls mais le gain sera quasiment nul et ça ne vaut pas la peine de se priver. Dans mes différents montages j'ai déjà abîmé certains de ces modules donc je vous recommande d'en prendre un lot d'au moins 5. Le petit nom donné à ces modules, pour l’émetteur est FS1000A. Sur eBay par 5 j'ai trouvé un lot qui revient à moins de 2€ la paire ICI. Sinon sur Amazon si vous êtes pressés de les recevoir, pour avoir un prix équivalent il faudra commander un lot de 10 comme ICI. On peut trouver aussi de petites antennes toutes faites pour ces modules. Elles améliorent nettement la portée et je vous conseille pour quelques euros d'en prendre un lot de 10 comme ICI.
3.2.2 Schéma de câblage
Nous allons maintenant connecter tout ce petit matériel afin de respecter notre cahier des charges. Je vais utiliser un Arduino nano comme passerelle UART-USB. Pour cela il ne faudra pas oublier de relier le RST au GND. Il me fournira aussi l'alimentation 5V pour l'attiny et le module FS1000ALe coeur de notre montage sera l'attiny. Nous allons utiliser les broches PB0 et PB1 pour la liaison série (RX et TX). Pour être compatible avec notre plateforme de programmation telle que nous l'avons construite en chapitre 1, nous allons connecter la LED de contrôle de fonctionnement du programme sur PB4.
Ensuite, pour la librairie "x10rf", il nous faut une broche qui va envoyer des données au module RF433 et une broche qui sera raccordée à une LED et utilisée par la librairie quand elle sera en train d'envoyer des données. Je vais choisir PB3 pour les données et PB2 pour la LED de contrôle.
Voici ce que cela donne:
Montage de test pour envoi trame X10 vers domoticz |
Et en photo:
3.3 Programme de test
Nous arrivons enfin à la fin de ce long parcours d'apprentissage et de
découvertes. Il ne nous reste plus qu'à écrire un programme qui envoie le
bon message et si nous ne nous sommes pas trompés nous devrions voir
directement le résultat au niveau de notre interrupteur déclaré dans
domoticz.
Dans un premier temps nous allons écrire un petit programme de test qui va
tourner en boucle pour faire passer l'interrupteur d'un état ON à OFF et
de OFF à ON. Ce programme sera uniquement l'occasion de regarder si nous
arrivons bien à compiler et utiliser la librairie x10rf. Et également à
valider que nous maîtrisons bien toute la chaîne de communication.
Dans un second temps je vais me servir du programme écrit au chapitre
précédent (ICI) qui permet d'envoyer un ordre de "reset" au microcontrôleur depuis la
liaison série, pour le faire évoluer. Le but étant qu'en plus du "reset"
on puisse entrer des ordres "on" et "off" et que cela pilote le changement
d'état de l'interrupteur dans l'interface domoticz.
3.3.1 Utilisation de x10rf
Si vous l'avez installé correctement, pour utiliser les fonctions de la
librairie x10rf il suffit d'ajouter en haut de votre programme la
directive d'inclusion classique:
#include <x10rf.h>
Ceci permet d'instancier une classe de type x10rf en créant une variable
de ce type:
x10rf myx10 = x10rf( TX, LED, REPETITIONS);
Avec:
- TX: la broche du microcontrôleur destinée à transmettre les données au module RF433. Dans notre montage il s'agira de la broche PB3
- LED: une broche du MCU sur laquelle sera connectée une LED qui clignotera lorsque des données seront envoyée au module RF433. Dans notre montage ce sera PB2. Si LED égale à 0 alors cela désactive la fonctionnalité (ceci pose d’ailleurs un petit problème si l'on souhaite utiliser la broche PB0).
- REPETITIONS: il s'agit d'un nombre qui va désigner le nombre de fois que la trame X10 devra être envoyée. Comme nous l'avons vu quand nous avons parlé du protocole X10, pour avoir moins de pertes de messages, il est prévu de le répéter un certain nombre de fois. En général ce nombre est 5.
Une fois déclaré, l'objet x10rf doit être initialisé dans la
fonction setup():
myx10.begin();
Et les différentes fonctions de la librairie sont utilisables par un simple appel. Nous allons utiliser x10Switch de la manière suivante:
myx10.x10Switch(MAISON,UNITE, ACTION);
Avec:
- MAISON et UNITE représentent les identifiants de l'équipement X10. Dans notre cas nous avions déclaré dans domoticz un interrupteur X10 dont les codes sont A et 7.
- ACTION: Représente l'action sur l'interrupteur. Dans notre cas ce sera soit "ON", soit "OFF". ON et OFF sont deux constantes définies dans x10rf.h
Voila, c'est tout ce qu'il y a à savoir. Regardons le code
maintenant.
3.3.2 Test x10Switch()
Voici le code du programme le plus simple du monde, qui ne fait qu'envoyer
une commande pour allumer (ON) et éteindre (OFF) l'interrupteur A7.
#include <SoftwareSerial.h>
#include <x10rf.h>
#define MAISON 'A'
#define UNITE 7
x10rf myx10 = x10rf( PB3, PB2,5);
SoftwareSerial serial(PB0,PB1); //RX, TX
int boucle = 0;
byte interrupteur = ON;
void setup() {
serial.begin( 19200 );
// Initialisation de l'emmetteur RF433
myx10.begin();
serial.println( "setup OK" );
}
void loop() {
serial.print( "loop " );
serial.println( ++boucle );
// Inversion de l'état ON ou OFF
if ( interrupteur == ON ) interrupteur = OFF;
else interrupteur = ON;
// x10Switch
myx10.x10Switch(MAISON , UNITE, interrupteur ); // Switch B4 on
delay(5000);
}
Voici le résultat sous domoticz:
3.3.3 Pilotage d'interrupteur via commandes sur liaison série
Je me suis amusé à adapter le programme écrit dans le chapitre 2.1.3 pour
en faire un outil qui permet de commander à distance notre interrupteur,
depuis la console série de l'IDE Arduino.
Je vous laisse découvrir le code ICI. Le mode d'emploi est simple: envoyez une commande via la liaison série. Les commandes possibles sont:
Je vous laisse découvrir le code ICI. Le mode d'emploi est simple: envoyez une commande via la liaison série. Les commandes possibles sont:
- reset: provoque un reboot du MCU
- on: bascule l'interrupteur sur ON
- off: bascule l'interrupteur sur OFF
4 Conclusion
Nous voici arrivé à la fin de cet
article. Additionné avec le précédent concernant les fondamentaux sur
l'attiny, nous avons maintenant l'ensemble des bases nécessaires pour
maîtriser ces merveilleux microcontrôleurs. Les attiny, avec notamment
l'attiny85, vont nous permettre de développer de manière significative
notre solution domotique DIY. Sa facilité de programmation avec l'IDE
Arduino, le grand nombre de librairies disponibles, sa quantité de mémoire
et surtout sa faible consommation, vont nous offrir des possibilités
infinies de constructions d'objets connectés. Et plutôt que d'acheter ces
objets tout fait dans le commerce, nous allons acquérir les connaissances
et les compétences pour les fabriquer nous même afin que chacun réponde
exactement à nos besoin spécifiques. Parce que nous sommes tous
spécifiques et que nous le valons bien!
4.1 Quelques liens
4.1.1 Des liens sur des librairies:
Programmer en mode asynchrone à l'aide de bibliothèques non bloquantes:http://p.loussouarn.free.fr/arduino/asynchrone/asynchrone.html
Utiliser la librairie <TinyOscCal> pour calibrer l'oscillateur interne des ATtiny84 et ATtiny85:
http://p.loussouarn.free.fr/arduino/exemple/PortSerieSurATtiny.html
Détails sur le protocole X10 RF:
http://liaison.mainguet.org/433MHz.htm
4.1.2 Des liens sur des cores:
Arduino-Tiny un "core" attiny pour l'IDE Arduino:https://code.google.com/archive/p/arduino-tiny/
Core de Spence Konde (alias Dr. Azzy):
https://github.com/SpenceKonde/ATTinyCore
4.1.3 Installer les librairies
https://www.arduino.cc/en/Guide/Libraries
https://www.astrolynx.com/Programmateur_ATTiny.html
https://www.astrolynx.com/Programmateur_ATTiny.html
4.2 Soutenez la blogoculture
Le plus simplement du monde, si vous avez un achat à faire sur Amazon,
accédez au site à partir de ce lien
(que vous pouvez ajouter dans vos favoris)
:
https://amzn.to/2weXW1i
toujours aussi bien développés, vos articles sont génial, merci
RépondreSupprimerBonjour, le voltage du condensateur 10uf est il important où est ce une valeur max admissible. Si je connecte un 10 uf en 16 v sur l’arduino , cela va t il faire des dégâts ?
RépondreSupprimerMerci