Manuel de laboratoire pour contrôleurs embarqués

Utilisation du langage C et de la plateforme Arduino


précédentsommairesuivant

VIII. Hello Arduino

VIII-A. Installation

Une raison pour laquelle le système Arduino a été choisi pour ce cours est son faible coût. Le logiciel est gratuit et les cartes de développement sont disponibles pour moins de 30 €. Si vous avez déjà installé le logiciel Arduino sur votre ordinateur ou si vous n'avez pas l'intention de le faire, passez au chapitre suivant sur l'« EDI ».

Pour l'installation, allez d'abord tout simplement sur le site http://arduino.cc/en/Main/Software et téléchargez la dernière version du logiciel compatible avec votre système d'exploitation. Il est disponible pour Windows, Mac et Linux. Pour Windows, le logiciel est compressé dans un fichier zip. Il doit être décompressé avec un programme tel que WinZip. Une fois décompressé, exécutez simplement le fichier d'installation. Cela installera tous les fichiers nécessaires en un rien de temps. Il n'y a qu'un seul problème qui survient au moment de l'installation des pilotes (ou drivers) de la carte. Une fois que le logiciel est installé, branchez votre carte Arduino avec un câble USB-A vers USB-B. À un moment donné, Windows vous informera qu'il a trouvé un nouveau composant et qu'il recherche son driver. Si vous sélectionnez « détails », Windows affichera quelque chose comme ceci (Windows 7) :

Image non disponible

Le problème est que Windows n'est pas capable de trouver le pilote et vous informe de la manière suivante :

Image non disponible

Ne vous inquiétez pas, vous pouvez installer les pilotes manuellement. Le processus varie un peu entre Windows XP, Vista et Windows 7, mais il va généralement comme suit. D'abord, ouvrez le gestionnaire de périphériques (via Panneau de configuration >> Système et sécurité >> Système). Descendez jusqu'à l'élément « Ports ». Vous devriez voir une entrée de type « Arduino R3 (COM 1) » (vous pouvez également trouver « Matériel inconnu » au lieu de « Ports »). Sélectionnez-la et allez vers l'onglet « Pilotes ». Cliquez sur « Mise à jour / Installation du pilote ». Parcourez la liste jusqu'à trouver votre pilote. Il devrait se trouver dans le dossier « drivers » du dossier d'installation du logiciel Arduino. Pour la carte UNO, il devrait se nommer « Arduino Uno R3.inf ». Sélectionnez-le et laissez Windows l'installer. Si vous avez des difficultés, un guide décrit l'installation étape par étape : https://www.arduino.cc/en/Guide/Windows#


Note de la rédaction
Sous Windows 7 et les versions ultérieures, avec les dernières versions de l'EDI, le problème évoqué ne devrait pas se produire. En revanche, ce qui peut se passer est que si vous débranchez la carte puis la rebranchez ou si vous changez de port USB, Windows réinstallera les pilotes et affectera un nouveau port COM à la carte ! Pensez à toujours vérifier dans l'EDI le port COM dédié à la carte Arduino utilisée avant le téléversement du programme.

Note de la rédaction
L'installation sous Linux est tout aussi simple. Téléchargez le fichier tar.xz correspondant à votre système. Décompressez-le dans le dossier de votre choix puis lancez l'installation en exécutant le script install.
Cependant, pour que la communication entre l'EDI et l'Arduino s'opère convenablement, vous devez modifier les droits sur les ports série. Sans cette opération, vous êtes obligé de lancer l'EDI en mode administrateur (via sudo). Pour débloquer le port série sur lequel l'Arduino est connecté, procédez comme suit :
$ sudo usermod -aG dialout votre_login
Source : http://www.leunen.com/linux/2012/11/autoriser-lacces-aux-ports-series-sous-ubuntudebian/

VIII-B. EDI Arduino

Une fois la carte installée, il est temps d'ouvrir l'EDI Arduino. Il est assez simple comparé aux autres systèmes de développement en C.

Image non disponible

Vous verrez un simple éditeur de texte avec les habituelles fonctions de copier-couper-coller. La zone noire en dessous de l'éditeur est dédiée aux messages du compilateur ou téléverseur. Autrement dit, c'est là où les erreurs du compilateur apparaissent avec les messages d'états. Le contenu des menus « Fichier » et « Édition » est tout ce qu'il y a de classique. Le menu « Outils » est particulièrement important.

Image non disponible

Les deux plus importants items sont « Type de carte » (à partir duquel vous sélectionnez votre carte) et « Port » (à partir duquel vous sélectionnez le port COM où votre carte est connectée). Ne pas configurer cela correctement conduira à une programmation infructueuse de votre carte. Notez que la carte et le port COM sélectionnés sont affichés en bas à droite de la fenêtre de l'EDI.

Il y a une simple barre d'outils sous le menu. Le premier item (symbole check) est appelé « Vérifier » et sert à compiler votre code. Le second item (flèche à droite) téléverse le code vers la carte cible. Les autres boutons servent à ouvrir et enregistrer les fichiers.

VIII-C. Codage

D'ordinaire, tout le code sera contenu dans un seul fichier. Quand vous créez un nouveau projet, ou « sketch » dans Arduino, un nouveau dossier sera créé pour lui. Contrairement aux fichiers sources en C, les sketches Arduino utilisent l'extension « .ino » en lieu et place de « .c ». De plus, le point d'entrée habituel main() n'est pas utilisé. En substance, le système Arduino a écrit le main() à votre place pour ressembler à quelque chose comme ça :

 
Sélectionnez
void main()
{
  init();
  setup();
  while(1)
    loop(); 
}

La première fonction appelée est là où l'initialisation des différents systèmes se produit comme l'allocation, le préréglage des horloges, le système de conversion analogique-numérique (ADC), etc. Tout ceci est déjà écrit pour vous. Les deux autres appels, setup() et loop(), sont pour vous. setup() est votre fonction d'initialisation (c.-à-d. les choses que vous devez faire juste une fois au démarrage) et loop() est la partie qui sera répétée indéfiniment. Vous allez donc commencer à coder avec quelque chose qui ressemble au code suivant :

 
Sélectionnez
void setup() {

}

void loop() {

}

Une des difficultés avec la programmation embarquée est que vous n'avez pas de console pour les entrées et les sorties via scanf() et printf(). Normalement, un programme embarqué n'a pas besoin de ça mais cela reste très utile quand il s'agit de déboguer un programme. Sans printf(), comment insérer des points d'arrêt dans le programme pour tester la progression, les valeurs, etc. ? Une des astuces est de simplement allumer une LED à un endroit spécifique dans le programme.

La carte Arduino possède une petite LED montée en surface de la carte et connectée à l'un de ses ports dans ce but. Bien que pratique, ceci est limité, ainsi une seconde et plus puissante méthode implique une communication bidirectionnelle avec l'ordinateur hôte. Avec l'Arduino, ceci peut se faire avec la bibliothèque Serial. L'EDI inclut un « Moniteur Série » dans le menu « Outils ». Le sélectionner ouvrira une fenêtre. Vous pouvez l'utiliser pour envoyer des données vers la carte ou recevoir des données provenant de la carte.

Regardons un exemple de communication via le Moniteur Série. Premièrement, considérez l'écriture de données de la carte vers l'hôte. Voici un programme « Hello World » :

 
Sélectionnez
void setup() 
{
  Serial.begin(9600);
}
void loop() 
{
  Serial.print("Hello World\n");
  delay(1000);
}

Dans la fonction setup(), nous ouvrons le port série et nous fixons la vitesse de communication à 9600 bauds (vitesse plus ou moins standardisée pour l'Arduino) en utilisant la fonction Serial.begin(). Il y a la fonction complémentaire Serial.end() si vous décidez d'utiliser les connecteurs dédiés pour la communication série pour d'autres objectifs. Notez que tous les appels vers des fonctions de cette bibliothèque débutent par le nom de la bibliothèque. La fonction loop() écrit votre message en utilisant Serial.print() et attend environ 1 seconde en utilisant la fonction delay(), l'argument de celle-ci étant en millisecondes.

La carte UNO ne possède qu'un seul port série matériel que l'on retrouve sur les connecteurs 0 (Rx) et 1 (Tx). Ce port est utilisé lors des échanges grâce à la classe Serial et également lors du téléversement. Il faut donc faire attention aux conflits si vous désirez connecter des périphériques sur ces connecteurs. Si vous avez besoin de plusieurs ports série, il reste la solution des ports séries virtuels avec quelques limitations ou passer par une carte Arduino comme la Mega qui possède trois ports séries matériels.
En savoir plus sur les ports série virtuels :
https://www.arduino.cc/en/Reference/SoftwareSerial

Une fois la fonction loop() exécutée, le programme retourne dans la fonction principale main(), qui rappelle aussitôt la fonction loop(), et ce indéfiniment. Votre message est affiché une seconde fois, puis une troisième fois et ainsi de suite.

Tapez le morceau de code précédent, compilez et téléversez-le dans la carte. Une fois fait, ouvrez le Moniteur Série et observez la sortie. Toutes les secondes, vous devez voir le message « Hello World » s'afficher encore et encore.

C'est tout ce que le programme du microcontrôleur fait. Pas très utile en soi, mais la possibilité d'afficher un message sur l'hôte est très utile une fois que nous le maîtrisons.

Habituez-vous à utiliser la documentation en ligne. Deux bons points de départ sont la page « Reference » à l'adresse http://arduino.cc/en/Reference/HomePage et la page « Tutorial » (tutoriel) à la page http://arduino.cc/en/Tutorial/HomePage.


La référence inclut des informations sur tous les opérateurs et fonctions disponibles dans le système Arduino. Les tutoriels donnent des informations sur des concepts de programmation et des idées. Par exemple, voici la copie (traduite) de l'aide en ligne sur la fonction Serial.print().

Serial.print()

Description

Affiche les données sur le port série au format ASCII. Cette commande peut prendre plusieurs formes. Les nombres sont affichés en utilisant le caractère ASCII de chaque chiffre. Les nombres flottants sont affichés de la même façon, avec, par défaut, deux chiffres après la virgule. Les octets sont envoyés comme de simples caractères. Les caractères et les chaînes sont envoyés tels quels.

Exemples

  • Serial.print(78) donne « 78 »
  • Serial.print(1.23456) donne « 1.23 »
  • Serial.print('N') donne « N »
  • Serial.print("Hello world.") donne « Hello world. »

Un second et optionnel paramètre spécifie la base (format) à utiliser ; les valeurs permises sont BIN (binaire ou base 2), OCT (octal ou base 8), DEC (décimal ou base 10), HEX (hexadécimal ou base 16). Pour les nombres à virgule flottante, ce paramètre spécifie le nombre de décimales à afficher. Par exemple :

  • Serial.print(78, BIN) donne « 1001110 »
  • Serial.print(78, OCT) donne « 116 »
  • Serial.print(78, DEC) donne « 78 »
  • Serial.print(78, HEX) donne « 4E »
  • Serial.println(1.23456, 0) donne « 1 »
  • Serial.println(1.23456, 2) donne « 1.23 »
  • Serial.println(1.23456, 4) donne « 1.2346 »

Vous pouvez exploiter les chaînes de caractères avec Serial.print() directement depuis la mémoire Flash où elles restent stockées en passant les chaînes avec F(). Par exemple :

Serial.print(F("Hello World"))

Pour envoyer un octet, utilisez Serial.write().

Syntaxe

  • Serial.print(val)
  • Serial.print(val, format)

Paramètres

  • val : la valeur à afficher. Tout type de donnée.
  • format : spécifie la base du nombre (pour des entiers) ou le nombre de décimales (pour les nombres à virgule flottante).

Retour

la taille (entier long) : print() retourne le nombre d'octets écrits bien que la lecture de ce nombre soit optionnelle.

/**** Fin de la copie de la documentation de référence. ****/

Ce qui est bien avec cette fonction est le paramètre optionnel qui vous permet de spécifier le format de l'information. La possibilité d'afficher des valeurs en hexadécimal ou en binaire est particulièrement pratique, par exemple pour examiner les valeurs des bits. Modifiez votre programme tel qu'il est présenté ci-dessous, compilez et téléversez.

 
Sélectionnez
void setup() 
{
  int i = 27;  // essayer différentes valeur

  Serial.begin(9600);

  // println est équivalent à print avec un saut de ligne
  Serial.println(i, DEC);
  Serial.println(i, BIN);
  Serial.println(i, HEX);
}

void loop() 
{  
  // rien à faire ici
}

Moins commun mais qui reste utile de temps en temps pour le débogage est la possibilité de passer des valeurs au programme. La fenêtre du Moniteur Série possède un champ de saisie en haut associé avec un bouton « Envoyer ». Les fonctions de la classe Serial les plus intéressantes sont Serial.available(), Serial.parseFloat() et Serial.parseInt() :

Serial.available()
Description
Récupère le nombre d'octets (caractères) disponibles pour la lecture sur le port série. Ce sont des données déjà arrivées et stockées dans le buffer de réception du port série (qui contient 64 octets). La fonction available() est héritée de la classe utilitaire Stream.
Syntaxe
Serial.available()
Paramètres
aucun
Retour
le nombre d'octets disponibles pour la lecture.

Serial.parseFloat()
Description
Serial.parseFloat() retourne le premier nombre flottant valide contenu dans le buffer série. Les caractères qui ne sont pas des nombres (ou le signe -) sont ignorés. ParseFloat() se termine par le premier caractère qui n'est pas un nombre à virgule flottante. La fonction parseFloat() est héritée de la classe utilitaire Stream.
Syntaxe
Serial.parseFloat()
Paramètres
aucun
Retour
flottant
/**** Fin de la copie de la documentation de référence. ****/

Serial.parseInt() est similaire à Serial.parseFloat() mais retourne une valeur entière au lieu d'une valeur à virgule flottante. Ces deux fonctions analysent la chaîne d'entrée et commencent par supprimer les caractères non numériques. Dès qu'un numéral est trouvé, elles continuent de regarder les caractères dans la chaîne jusqu'à trouver un non numéral. Ensuite, les codes ASCII numéraux sont traduits en valeur entière (ou en flottant selon le cas). Notez qu'il est possible d'envoyer plusieurs valeurs en même temps.

Voici un exemple sur la façon dont elles pourraient être utilisées pour créer un convertisseur décimal vers hexadécimal. Entrez ce bout de code, compilez et téléversez.

 
Sélectionnez
int i1, i2; // variables globales pour mémoriser les données

void setup() 
{
  Serial.begin(9600); 
}
void loop() 
{
  
  // Nouvelles données disponibles ?
  if (Serial.available() > 0) 
  {
    i1 = Serial.parseInt(); 
    i2 = Serial.parseInt();
  // 
  // Réaffiche ce que vous avez tapé mais en hexa

    Serial.println("En hexa, cela donne : ");
    Serial.println(i1, HEX);
    Serial.println(i2, HEX);
  }
}

Une fois le programme téléversé, ouvrez le Moniteur Série et entrez « 10␣27 » dans le champ de texte en haut et cliquez ensuite sur le bouton « Envoyer » à côté (vous pouvez aussi appuyer sur la touche « Entrée » de votre clavier). Le résultat devrait être :

 
Sélectionnez
En hexa, cela donne : 
A
1B

Vous pouvez aussi bien essayer avec d'autres valeurs. Si vous entrez seulement une valeur, i2 sera considéré comme un 0. Si vous entrez plusieurs valeurs, de multiples retours vont se succéder. Essayer les deux possibilités avant de continuer.

Si vous entrez un nombre négatif, quelque chose d'intéressant va se produire. Essayez en tapant « -1␣-2 ». Que voyez-vous et pourquoi ?

Maintenant que vous avez des connaissances basiques sur l'EDI et que vous savez comment créer un simple texte pour débogage, nous pouvons passer à l'examen de la lecture et de l'écriture sur des circuits externes.


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Licence Creative Commons
Le contenu de cet article est rédigé par James M. Fiore et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2013 Developpez.com.