Bibliothèques et débogage

bibliothèques

Définition

Une bibliothèque permet de mettre à disposition du programmeur des fonctions pré-écrites. On parle de fonctions haut-niveau. Par exemple dans la bibliothèque math.h (incluse par défaut dans tout programme Arduino) on trouvera des fonctions telles que sin() et cos() qui calculent le sinus ou le cosinus d’un angle exprimé en radiant.

La bibliothèque peut aussi être un pilote (driver) pour un composant que l’on veut interfacer avec la carte Arduino. Par exemple la bibliothèque LiquidCrystal pilote automatiquement un afficheur cristaux liquides de 2 lignes 16 caractères.

L’intérêt d’une telle bibliothèque est qu’on n’a pas à connaitre la manière dont l’afficheur est commandé pour l’utiliser. C’est la bibliothèque qui va prendre en charge la génération des signaux électriques (horloge, données..) pour piloter l’afficheur en fonction de la nature de la fonction.

Utilisation d’une bibliothèque dans un programme.

 Dans l’interface de développement (IDE) Arduino c’est on ne peut plus simple : depuis le menu « Croquis » sélectionner « Inclure une bibliothèque » puis la sélectionner dans la liste déroulante.

On voit alors apparaitre une directive de type « #include… » dans le programme

Dans l’exemple ci-dessus, on a importé  la bibliothèque LiquidCrystal.

Il faut souvent lire la documentation de la bibliothèque pour connaitre la manière de l’utiliser

Par exemple la bibliothèque LiquidCrystal expose les méthodes (ou fonctions) suivantes :

Fonctions d’initialisation

Fonctions de gestion de l’écran

Fonctions de positionnement du curseur

Fonctions modifiant l’aspect du curseur

 

Fonctions d’écriture

Fonctions de contrôle du mode d’affichage

Fonction de création de caractère personnalisé

createChar()

En général il faut initialiser la bibliothèque en instanciant un objet c’est-à-dire en créant une variable du type correspondant à l’objet.

Explication : dans le cas d’une variable simple on la crée en écrivant :

int valeur = 3;

On instancie un objet simple  de type Int (entier) auquel on affecte la valeur 3.
Pour un objet plus complexe on procède de manière analogue :

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

On créer ici un objet « lcd » de type LiquidCrystal, de plus on passe en paramètres les numéros de broches de l’Arduino permettant la connexion avec l’afficheur (voir la documentation de la bibliothèque)

Remarque : la création d’objet (que ce soit de simples variables ou des objets complexes) revient à faire des réservations d’espace mémoire et fournir des valeurs initiales.

L’appel des fonctions liées à l’objet se fait en indiquant le nom de l’objet suivi d’un « . » (point) suivi lui-même du nom de la fonction.

exemple

lcd.begin(16, 2); // initialise l’afficheur: 16 caractères, 2 lignes
lcd.print("hello, world!"); // affiche un message.

En général une bibliothèque est fournie avec des exemples d’utilisation. On y accède depuis le menu « Fichiers » puis « Exemples » enfin on choisit l’exemple dans la bibliothèque qui nous intéresse.

Installation d’une bibliothèque

Pour installer une bibliothèque il faut fermer l’IDE Arduino.

L’installation d’une bibliothèque est simple : il faut la copier dans le dossier « Libraries » contenu dans le dossier Arduino de l’utilisateur (« chemin de l’utilisateur »/documents/Arduino). Les bibliothèques « natives » c’est dire fournies d’office avec Arduino sont localisées dans « dossier d’installation d’Arduino »/libraries. Les bibliothèques natives contiennent par exemple Ethernt, Firmata,Keyboard, LiquidCrystal, Stepper, Wifi…

En général le dossier de la bibliothèque contient les éléments suivants :

  • Les fichiers codes de la bibliothèque (LiquidCrystal.h et LiquidCristal.cpp)
  • Un fichier texte keywords.txt permetaant la coloration syntaxique
  • Un dossier « examples » contenant lui-même des sous dossiers nommés avec le nom des exemples.

Le nom des exemples doit être le même que le dossier qui les contient . Par exemple le dossier  « HelloWorld » contient « HelloWorld.ino »

débogage

L’IDE Arduino ne possède pas d’outils tels qu’exécution en mode pas à pas, mode trace, visualisation des registres…

Il faut user de stratagèmes pour déboguer un programme. Le plus simple est d’utiliser le moniteur série et d’y faire afficher les valeurs de variables, les résultats de calculs…

Pour utiliser le moniteur il faut initialiser la liaison série. Puis à chaque fois qu’on désire afficher une valeur, il faut appeler la fonction « print » ou « println »

/* Blink without Delay*/
// set pin numbers:
const int ledPin =  13;      // the number of the LED pin
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated
long interval = 1000;           // interval at which to blink (milliseconds)
void setup() { 
    pinMode(ledPin, OUTPUT);       // set the digital pin as output:
    // -------------------- débogage ----------------------------//
    //  initialisation de la liaison série 
    // la ligne suivante pourra être commentée pour le passage en production
    Serial.begin(9600);
    //-------------------- fin débogage -------------------------//
}
void loop()
{
    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis > interval) 
    {   
        // -------------------- débogage ----------------------------//
        // affichage de la valeur de CurrentMillis
        // la ligne suivante pourra être commentée pour le passage en production
        Serial.print("time: "); Serial.println(currentMillis,DEC); 
        //-------------------- fin débogage -------------------------//
        previousMillis = currentMillis;    // save the last time you blinked the LED 
        if (ledState == LOW)// if the LED is off turn it on and vice-versa
            ledState = HIGH;
        else
            ledState = LOW;

        // -------------------- débogage ----------------------------//
        // affichage de la valeur de ledState
        // la ligne suivante pourra être commentée pour le passage en production
        Serial.print("led state: "); Serial.println(ledState);  
        //-------------------- fin débogage -------------------------//   
        digitalWrite(ledPin, ledState); // set the LED with the ledState of the variable
    }
}

 

La fonction Serial.begin(9600); initialise la liaison série à un débit de 9600 bauds

Les fonctions Serial.print et Serial.println sont deux fonctions similaires : elles affichent des données sur la liaison série. À la différence de print, println affiche les données sur le port série suivi d’un caractère de “retour de chariot” (ASCII 13, or ‘\r’) et un caractère de “nouvelle ligne” (ASCII 10, or ‘\n’).

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

 

Serial.print(78); // affiche "78"
Serial.print(1.23456); // affiche "1.23"
Serial.print(byte(78)); // affiche "N" (dont la valeur ASCII est 78)
Serial.print('N'); // affiche "N"
Serial.print("Hello world."); // affiche "Hello world." 

Un second paramètre optionnel (format) spécifie :

  • pour les nombres entiers, la base à utiliser. Les valeurs autorisées sont BYTE, 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 à virgules (float), le paramètre précise le nombre de décimales après la virgule à utiliser.
Serial.print(78, BYTE); // affiche "N"
Serial.print(78, BIN) ; // affiche  "1001110"
Serial.print(78, OCT); // affiche "116"
Serial.print(78, DEC); // affiche "78"
Serial.print(78, HEX); // affiche "4E"
Serial.println(1.23456, 0); // affiche "1"
Serial.println(1.23456, 2); // affiche "1.23"

 

Lorsqu’on compile et qu’on lance le progamme, il faut appuyer sur l’icône « Serial Monitor »  dans l’IDE Arduino on voit alors une fenêtre qui s’ouvre et qui affiche les informations demandées dans le programme

À noter que le débit du moniteur doit être ajusté avec le débit de la liaison série ( 9600 baud)

En visualisant les variables et en plaçant des espions aux bons endroits du programme on se sort de quasiment toutes les situations.