1 Notions de Base: Apprendre À Programmer Avec Le Learncbot Sur Arduino/Diduino
1 Notions de Base: Apprendre À Programmer Avec Le Learncbot Sur Arduino/Diduino
1 Notions de Base: Apprendre À Programmer Avec Le Learncbot Sur Arduino/Diduino
com
www.didel.com/coursera/LC1.pdf
1 Notions de base
Notre but est de montrer comment un micro-contrôleur
interagit avec son environnement.
Vous avez une carte Arduino ou Diduino, vous avez
chargé l'environnement et vu comment clignoter une
led et lire un poussoir.
Allons plus loin avec le LearnCbot, un shield super-
efficace pour apprendre à programmer en C,
comprendre les timers internes, quelques capteurs et
se préparer à des applications robotique ou autre en
temps réel.
A noter que vous pouvez faire les exercices et devoirs sans matériel. Vous modifierez les programmes en
vérifiant seulement que la compilation est correcte et en soumettant vos devoirs, vous saurez que le
programme s'exécute correctement. Vous perdez la dimension "temps réel", si importante avec les
microcontrôleurs, .. et le plaisir d'interagir directement avec des poussoirs et des leds !
Allumer la led L1 peut s'écrire maintenant digitalWrite (L1,1);, mais on est encore au niveau
du langage de notre machine : il faut un 1 (5V) pour allumer, dans d'autres montages il faut un 0.
Définissons ce câblage et utilisons des instructions fonctionnelles avec un nom clair: L1On; L1Off;
#define Led1On digitalWrite (L1,1) // Allume
#define Led1Off digitalWrite (L1,0) // Eteint
Attention, l'instruction dans une macro ne se termine pas par un ;
Le programme qui clignote va avoir maintenant une partie principale compréhensible par tous, et
une partie définitions et mise en route qui nécessite d'avoir compris le câblage. Mais une fois
compris, nommé et défini ce câblage, plus besoin d'y réfléchir.
//LcCligno2.ino clignoter la led L1 sur la pin 4
#define L1 4
#define Led1On digitalWrite (L1,1) // Allume
#define Led1Off digitalWrite (L1,0) // Eteint
void setup() {
pinMode (L1,1);
}
void loop () {
Led1On; delay (500);
Led1Off; delay (500);
}
1.6 Constantes
Dans le programmes précédent, si on veut un clignotement plus rapide, il faut changer deux
instruction pour modifier la constante 500. Il faut définir cette constante au début du programme;
c'est un paramètre qui agit dans le programme.
//LcCligno3.ino
. . . définitions et set-up comme avant
#define DemiPer 500
void loop () {
Led1On; delay (DemiPer);
Led1Off; delay (DemiPer);
}
Il faut ajouter une ligne, mais quand on lit le programme, on voit ce que signifie le contenu des( ).
1.7 Variables
Une variable est une case mémoire 8 bit (type byte ou char) 16 bits (type int) et il y a d'autres
types. On expliquera chaque type quand on en aura besoin.
La valeur du délai peut être une variable, et dans ce cas on ne peut pas utiliser un #define. On
déclare :
int demiPer; // la minuscule au début montre que c'est une variable et pas une constante
ce qui réserve en mémoire une case de 16 bits "vide" (le compilateur mets en général la valeur
zéro). On peut donner une valeur initiale en écrivant
int demiPer = 100;
C'est important de bien distinguer les variables et les constantes. Une bonne habitude est d'avoir la
première lettre d'une variable en minuscule et les constantes toute en majuscule. Pour une raison
de lisibilité, nous n'avons pas écrit, quand DemiPer était une constante, DEMIPER ou DEMI_PER.
Un puriste du langage C l'aurait fait !
Attention aux minuscules et majuscules demiPer et une variable, DimiPer est une constante, mais
le C ne vérifie rien.
//LcCligno4.ino
. . . définitions et set-up comme avant
unsigned int demiPer = 100; // on commence avec 0.1 seconde
void loop () {
Led1On; delay (demiPer);
Led1Off; delay (demiPer);
demiPer--;
}
Donc la période va diminuer 99, 98... A partir de 20ms (50Hz) on ne voit plus le clignotement et à
zéro, cela s'arrête! Non cela ne s'arrête pas s'il n'y a pas un test spécial. La variable 16 bits a passé
à sa valeur maximum, comme le compteur d'une voiture neuve qui ferait un km en arrière et
afficherait 999'999 km.
Le délai a passé à 65335 (216-1, la led se ralumera dans 65 secondes et cela mettra des jours avant
de repasser par un clignotement rapide.
1.11 Le haut-parleur
Le HP est sur la pin1, qui est utilisée pour les transferts série, mais cela ne gêne pas, il fait des
bruits pendant la programmations et les transferts série. Un interrupteur sur le LCbot permet de
désactiver ce bruit, parfois gênant.
On a vu comment faire clignoter une led, utilisez des microsecondes avec le haut-parleur et
changez naturellement le no de pin..
Quand on lit une pin, on se pose la question "quel est son état ?"
digitalRead (P1) est un état binaire, 0 ou 1, vrai ou faux.
Il faut maintenant tenir compte du câblage. Le poussoir, comme c'est le plus souvent le cas, est
câblé pour court-circuiter une résistance tirage ("pull-up") et imposer 0V sur l'entrée du processeur.
Si on ne pèse pas, la résistance pull-up impose du 5V.
Donc pour allumer la L1 quand on presse P1, il faut écrire :
if (digitalRead(P1) == 0) {
digitalWrite (L1,1)
}
Attention aux parenthèses : Le compilateur repère un if (condition) et la condition est
digitalRead (P1)==0 avec un point d'interrogation sous-entendu.
Est-ce vrai ou faux ?
Si on presse, digitalRead (P1)==0 est vrai (valeur 1).
Si on ne presse pas la condition est fausse (valeur 0). On voit le risque de confusion entre états
électriques et états logiques.
Quand on écrit le programme, on doit penser l'état du poussoir, pressé ou relâché, 1 ou 0, vrai ou
faux, on ou off. Ce qui nous a conduit à définir :
#define Pous1On (digitalRead (P1)==0) // électriquement actif à 0V
#define Pous1Off (digitalRead (P1)==1) // électriquement actif à 5V
Dans le set-up, il faut ajouter la direction du poussoir :
void setup() {
pinMode (P1,INPUT);
pinMode (L1,OUTPUT);
}
Ce que fait le programme devient très lisible:
if (Pous1On) { Led1On; }
if (Pous1Off) { Led1Off; }
Si le bloc d'instructions à exécuter est plus complexe, il faut éclater les accolades.
if (Pous1On) {
Led1On;
}
if (Pous1Off) {
Led1Off;
}
Si vous testez une autre carte ou le poussoir est actif à 1 ou les leds actives à zéro, il suffit de
changer les définitions, et rien dans le programme. De plus, le programme est maintenant écrit en C
et pas en Arduino; en adaptant les définitions, il tournera sur une carte qui a un compilateur C sans
les fonctions spécifiques à Arduino ou Energia
//LcCopy.ino Copie P1 sur L1
#define L1 4
#define Led1On digitalWrite (L1,1) // Allume
#define Led1Off digitalWrite (L1,0) // Eteint
#define P1 2
#define Pous1On (digitalRead (P1)==0) // actif à 0V
#define Pous1Off (digitalRead (P1)==1) // actif à 5V
void setup() {
pinMode (P1,INPUT);
pinMode (L1,OUTPUT);
}
void loop () {
if (Pous1On) {
Led1On;
}
if (Pous1Off) {
Led1Off;
}
}
Modifiez le programme LcCopy pour que la led1 reste allumée pendant 2 secondes au moins.
Modifiez le programme LcCopy pour que la led1 reste allumée pendant 2 secondes exactement,
même si on presse plus longtemps. Créez les programmes
1.13 Résumé
Une condition est une variable booléenne avec deux valeurs 0 (faux) et 1 (vrai).
Une variable 8 ou 16 bits peut être vue comme une variable booléenne avec deux états : faux si
égal à 0, vrai si différent de zéro.
Dans une instruction conditionnelle, si la condition est vraie, une ou plusieurs instructions sont
exécutées. Elles doivent être mises entre accolade; pour la clarté des programmes et réduire le
risque d'erreur, l'accolade fermée doit être alignées avec l'instruction conditionnelle.
Le menu "Outils" - "Auto format" (raccourci "Ctlr-T") sous Arduino formate avec l'accolade sous
l'instruction. L'usage d'espace et de retours à la ligne est assez libre avec le C.
Remarque: Les tutoriels Arduino raisonnent avec les états électriques, et dans le programme, il faut sans
cesse se souvenir "le bouton est pressé, je vois un zéro". Editez les programmes que vous trouvez en
ajoutant des #define pour qu'il soient plus clairs !
Un programme bien documenté n'est pas un programme qui répète sur chaque ligne ce que fait l'instruction !
Il définit des noms clairs et fait apparaître des blocs d'instruction dont la fonctionnalité est commentée avant le
bloc, si elle n'est pas évidente.
jdn 140426/150410/151017