Nous allons voir quelques programmes de complexité croissante, apprendre au robot à aller droit, à obéir à ses capteurs. Vous devez avoir quelques connaissance de C/Arduino (if, while, for, fonctions). Pour un cours C temps réel dérivé du MOOC EPFL "Comprendre les Microprocesseurs", voir Coursera LC1..7
Comprenez que digitalWrite
est une invention géniale d'Arduino pour cacher la structure interne des registres. Mais pour nous c'est le vélo d'enfant à 2 roues d'équilibrage. On peut aller partout aussi bien qu'un vélo, on risque moins de tomber, mais pour continuer, il faut un vrai vélo, et si on se passionne, il y a encore des options.
Notre objectif est d'apprendre à écrire des programmes lisible et compatible C, avec des définitions claires et des fonctions bien choisies et bien nommées. On verra que le #define
, ignoré par Arduino, est un élément clé pour bien documenter.
Rappelons le câblage du Xbot et les noms des signaux . Pour ce PORTD, les no de pins sont les même que les numéro de bits |
Comparons trois programmes qui font la même chose: éviter un obstacle en reculant et tournant. Vous pouvez faire du copie-collé ou trouver tous les programmes de cette doc ici
|
|
Le programme détaille ce qu'il faut faire.
On ne gére plus des pins, mais les bits du port 8 bits, et on définit à l'avance les combinaisons de bits qui font avancer, tourner, etc. Il faut des opérations logiques pour ne pas peturber les bits 0 et 1 du PORTD.
C'est expliqué ici , mais c'est comme le digitalWrite, on peut utiliser sans bien compendre.
|
|
On voit que le programme est beaucoup plus clair
Les définitions sont "encapsulées" dans un fichier XBotDef.h
que l'on charge avec le menu Arduino "sketch" "Add file", si le dossier qui contient le .ino ne contient pas déjà le .h. - une règle de cuisine de plus!
|
|
Les définitions, le set-up doivent être avant le programme. En quelques lignes, on voit maintanant qu'il y a une ressource Xbot que l'on initialise avec XbotSetup. Comment cela se fait dans le détail ne nous intéresse plus; on veut tester les obstacles et réagir.
L'IDE Arduino présente bien cette information. On peut éditer les fichier inclus. Le compilateur travaille sur les fichiers tampons montrés sur l'écran. Ne pas oublier de sauver fréquemment avec l'icône ▼ (ou mode automatique dans "Preferences". |
A noter que les fichiers inclus peuvent très bien être écrits avec les fonctions Arduino, c'est le cas du programme EvitObstacleIncludeA.ino
sur le .zip. Remarquez que Avance(), etc y est alors une fonction. Un #define est possible, mais peu efficace dans ce cas. Le programme principal est identique, c'est tout l'avantage des fichiers inclus. Comparez la taille de ces 2 programmes!
Le programme principal ne doit pas dépendre du matériel et du type de compilateur. Notre programme principal ne sait rien du robot si ce n'est qu'il avanc, tourne et détecte des obstacles. Mais nous avons mal documenté en disant qu'il recule de 0.3 secondes. Ce n'est pas valable pour un autre robot! Il aurait fallu écrire DelRecule et déclarer au début du programmes, avec les déclarations matérielles
#define DelRecule 300 // pour le Xbot qui est très rapide
C'est en écrivant des programmes plus riches, en changeant de robot, de compilateur, que l'on comprend bien cette nécessité d'une bonne structuration des programmes.
Recommendation: Toujours, toujours avant de modifier un programme qui marche, donner un nouveau nom au fichier, aussi explicite que possible. A début de chaque programme testé, décrire le comportement voulu, l'algorithme, la date, l'auteur.
On remarque que face à certains obstacle, le robot alterne à l'infini. Une amélioration est de changer la durée de la rotation. S'il tourne plus longtemps à droite qu'à gauche le robot va se décaler et a plus de chance de quitter l'obstacle.
Plus efficace, c'est de compter les obstacles et tous le 5 par exemple faire une pirouette.
Facile de déclarer un compteur et l'incrémenter dans chaque "if". Mais ou tester? Une solution est dans la boucle loop avec un if (programme complet sous EvitObstacleCompte.ino)
On pourrait aussi dire "tant que le compteur est inférieur à x" on fait rien de spécial.
|
|
On remarque dans la 2e colonne que l'on appelle des fonctions (mises dans le fichier inclu) pour faciliter la lecture.du programme principal. Dans le programme, on veut éviter les obstacle. Comment? Reculer. C'est un autre niveau de réflexion qui se définit dans des fonctions - que faire pour reculer. Une fois les fonctions bien définies et adaptées, on les mets dans un #include.
Une fonction est une action, son nom commence par un verbe. Les fonctions commencent par une majuscules (sauf les fonctions Arduino comme delay) et les variables par une majuscules.
Attention, Arduino n'accèpte pas les minuscules accentuées dans les programmes et réagit stupidement!
void EviterObsD () { //on recule et tourne |
|
A vous d'écrire le programme de test pour ces deux fonctions. Vous reprenez un programme, vous le renommez, vous ajoutez les fonctions ou dans le programme principal, ou dans le #include si c'est une fonction qui retrouvera souvent son utilité.
Le #include est parfois délicat à gérer, voir Utilisation des #include sous Arduino
Jouons avec des vitesses en tout-ou-rien avant de passer au PWM du prochain chapitre.
Dessiner un polygone
Suivre un mur concave
Suivre un mur convexe
Contourner l'extrémité d'une paroi
Modifier la vitesse
Corriger pour une ligne droite
Tracer une spirale
Le Diduibot est prévu pour ajouter facilement sur le connecteur avant des capteurs de suivi de ligne, suivi de lumière, distance, et un affichage Oled et/ou 4 digits, sans fils de câblage peu fiables.
Voir Modules capteurs pour Xbot
jdn 170815