Bonjour!
Ce qui suit est un petit projet pour créer une girouette pour bateau. Je l'ai déjà écrit
en C pour une carte TI, recyclage d'un autre programme pour mesurer des distances. Vous
le trouverez facilement en cherchant "girouette". Comme la carte utilisée n'est plus en
vente, je porte l'ensemble sur une carte récente. Et comme la dernière fois il n'y avait
pas d'affichage, je vais ajouter un affichage tout-à-fait standard.
0. Avant propos
0.1. Le choix du sujet
Je suis conscient que parler de C++ à des électroniciens est un sujet à guerre de
religion. Alors précisons dès maintenant: mon but n'est pas de discréditer ceux qui font
du C ou de l'assembleur, mais simplement de présenter une autre approche à ceux qui
n'y ont jamais touché. Ou même à ceux qui font du C mais n'ont jamais eu la curiosité
de voir ce que fait C++. Un bit étant un bit, qu'il soit écrit en C, C++ ou en assembleur,
qu'il soit sur un système embarqué, qu'il vienne d'un mac ou d'un pc, c'est toujours un
bit, alors il n'y a pas lieu de s'entr'engueuler sur le sujet, il y a juste plusieurs approches.
J'ai choisi un sujet simple, avec peu d'éléments, que n'importe qui peut construire.
J'utilise une carte bon marché, et en ce qui concerne le soft, j'utilise IAR.
La version gratuite est limitée à 4K d'exécutable. J'ai l'impression que cela
suffira largement. Si ce n'est pas le cas, il y a un compilateur chez Texas qui va
jusqu'à 8k ou 32, je ne sais plus, en version gratuite. Et si ce compilateur est configuré
en option gcc, je crois que c'est totalement gratuit. On verra si le projet grossit
un peu trop...
0.2. Fiabilité
Inutile de me dire que le code n'est pas "professionnel", il s'agit d'un exemple.
Ce code n'a pas de "ceintures de sécurité". Exemple: quand on initialise un capteur,
on doit d'habitude vérifier qu'il est bien initialisé. Mais ici, ce n'est pas le but.
Donc je n'appelle que la fonction init(), et je ne teste pas, je ne fais que supposer
que c'est fait. Mais ça rend le code plus court, donc plus clair. La plupart du temps,
le fonctionnement sera irréprochable.
0.3. Courtoisie
Dernier point, un peu de courtoisie serait bienvenue. Ceci est redondant parce que c'est
déjà dans la charte, mais je rappelle que je ne suis pas payé pour écrire ceci, au
contraire, j'ai même payé les composants. Alors plutôt que de dire: "je suis l'expert,
le fait que tu écrives de cette façon montre que tu n'a rien compris", comme récemment,
je préfèrerais "cette solution fonctionne, mais il serait avantageux de faire xxx xxxx
pour la raison suivante: <explication détaillée de cette raison>". Et bien sûr, quand on
fait une suggestion, on ne reste pas les mains dans les poches. Il est donc préférable
de la tester sur le même hard (qui ne vous coûtera pas grand chose) et de poster le code
avec les modifications. Dans ce cas, je serai évidemment ravi d'accueillir toute critique
courtoise, étayée, fondée et construite. S'il n'y a rien de tout cela, il est préférable
de ne pas commenter, surtout que comme je suis assez primaire, j'ai tendance à répondre
sèchement quand on vient me les briser (d'autant que je n'en ai pas d'autres). Ce serait
dommage. Bon, au boulot!
1. Plan de travail
Je pars du principe que le lecteur a des notions de programmation en C, sait ce qu'est
un pointeur, une fonction, un préprocesseur, et a déjà écrit quelques programmes.
Je vais repartir du programme posté précédemment, avec modification pour qu'il fonctionne
sur une carte très bon marché (1/2 ~ 1/3 d'Arduino uno pour quelque chose de bien plus
puissnat. Je parlerai ensuite de découpage de code en sous-ensembles (modules), puis je
passerai petit à petit à un programme en C++, ce qui me permettra de rétablir les
contre-vérités suivantes:
- Mélanger C et C++ est dénaturé
Je vais vous montrer que cela fonctionne très bien ensemble
- C++ n'est pas portable et est en plus dépendant du processeur.
J'ai déjà dit récemment pourquoi c'est portable, voir ANSI C++.
- C++ ne peut pas travailler intimement avec le hardware
Je vais montrer que, au contraire, c'est prévu pour cela.
- C++ n'apporte strictement rien, C++ est une démarche inappropriée, etc,etc...
Je montrerai ce que cela apporte. Qu'on aime ou pas est une autre chose.
2. Le hardware
J'ai choisi une carte LaunchPad de Texas, avec un F5529. Le 5529 a 128k de flash, 8k
de RAM et peut fonctionner à 25 MHz. Avec en plus une petite section de flash utilisateur
(512 bytes, je crois) qui permet de stocker des données persistentes (survivant à une
coupure d'alimentation). Mais ce programme utilisera peut-être 1~2% des capacités de la carte.
- J'ai pris un LCD tout-venant, un 4x20 caractères. Je préfère les graphiques, mais
il faut reconnaître que la mise en oeuvre est plus simple.
Voici une photo du hard. Carte LaunchPad, LCD, potentiomètre pour le contraste, et
bien sûr, capteur magnétique.
02Elements.jpg
Un petit inventaire des pattes disponibles sur la carte Launchpad. Je m'aperçois que
je l'ai écrit à la façon japonaise: un petit rond signifie oui, une croix signifie non.
C'est simple pour s'en souvenir: o = oui ou OK, x comme quand le prof de math faisait
une grande croix rouge sur un devoir. Ça ne vous rappelle pas la prépa?
Bref, il y avait un seul port complet, le port 3 pour les données du LCD (1). Le port 4
peut être utilisé pour le SPI, et quelques signaux du port 1 pour les commandes du LCD.
01PinList.png
(1) Il est possible d'utiliser le LCD par demi-bytes. J'ai câblé le port complet, c'est
plus simple à gérer.
Les noms des pattes sont sérigraphiés sur la carte. Donc par exemple si vous voulez
câbler MISO, vous verrez dans la table qu'il correspond a port 4, bit 2, et sur la carte,
vous trouverez P4.2.
Une photo du câblage. Tout au plus une 20 aine de fils. Mais il manque encore le
capteur qui n'est pas câblé. Je le ferai plus tard.
03Connections.jpg
Voilà une photo du hard, incomplet. Il reste à câbler le capteur. J'ai écrit un pilote
de LCD vite fait, mais tellement vite fait que j'y mettrai un peu d'ordre avant de le
lâcher, histoire que l'on ne me jetât pas trop de pierres, elles viennent déjà assez
facilement même sans ça.
04Result.jpg
3. Aperçu des étapes suivantes
3.1 Dans le deuxième étape, je vais (essayer de) vous présenter un programme complet
qui lit les données et les affiche. En C. De cette manière, on part de quelque chose
que la plupart des programmeurs en embarqué connaissent.
3.2 Dans la 3ème étape, je vais introduire l'encapsulation, le groupement de données
relatives à une même unité, par exemple le LCD ou le capteur. La classe LCD sera
créée, et aussi des méthodes surchargées (overloaded), qui permettent d'utiliser
les mêmes noms de fonctions avec des paramètres différents.
3.3 Dans la 4ème étape, je vais essayer de mettre un autre LCD pour montrer qu'il
est possible de créer une classe unique LCD qui gère les deux types. Introduction
de l'héritage (inheritance). Des méthodes virtuelles.
Voilà. J'arrête pour ce soir...
À suivre...
Pascal
-----