Créer un nouveau projet Arduino avec VSCode

Dans un article précédent, la configuration de VSCode pour développer sur Arduino avait été présentée. Si son utilisation pour des projet existant est relativement aisée, il se trouve que la création d'un nouveau projet à partir de zéro nécessite quelques étapes indispensables pour que cela fonctionne. La description de ces étapes est l'objet du present article.

Pré-requis

Création d'un répertoire pour le nouveau projet

La première étape est de créer un répertoire pour le projet. En effet, VSCode ne dispose pas d'une commande de menu du style « Nouveau Projet ». La pratique est la suivante :
  • Connecter l'Arduino cible sur le PC de développement.
  • Lancer VSCode sur le PC de développement.
  • Dans VSCOde, lancer la commande de menu File/Open Folder...
  • Dans la boîte de dialogue Open Folder, se positionner dans le répertoire qui contient les projets Arduino. Ce peut être C:\Users\[UserName]\Documents\Arduino, où [UserName] doit être remplacé par l'identifiant de l'utilisateur du PC.
  • Toujours dans la boîte  de dialogue Open Folder, cliquer le menu Nouveau dossier
  • Un nouveau dossier a été créé dans la boîte de dialogue. Donner un nom à ce dossier : MonProjet.
  • Sélectionner ce nouveau dossier et cliquer le bouton [Sélectionner un dossier].
  • Lancer la commande File/Save Workspace As...
  • Dans la boîte de dialogue Save Workspace, donner un nom au projet. En principe, il s'agit du même nom que le nouveau dossier, à savoir MonProjet pour l'exemple.
  • Valider en cliquant le bouton [Save] de la boîte de dialogue Save Workspace.
L'intérêt de créer un espace de travail VSCode pour un projet est que celui-ci peut contenir plusieurs sous-répertoires, chacun relatif à un aspect particulier du projet. Par exemple, un projet peut contenir le développement de plusieurs bibliothèques pour l'Arduino, et des aspects pas forcément techniquement liés au code hébergé sur le micro-contrôleur, comme une site web ou une interface Windows pour piloter le micro-contrôleur à distance.

Configurer le répertoire comme une application Arduino

Cette configuration concerne soit le répertoire principal du projet, soit un sous-répertoire si le projet comprend plusieurs aspects autres que ceux relatifs au code hébergé sur le micro-contrôleur.
La configuration en question procède du même principe que ce qui a été décrit dans l'article intitulé « Utiliser Visual Studio Code pour développer sur Arduino ». A savoir, paramétrer les caractéristiques du micro-controleur cible.
  • Dans la barre de menu de VSCode, cliquer la commande View/Command Palette... (Shift+Ctrl+P).
  • Derrière le prompt >, taper Arduino. Toutes les commandes de l'extension Arduino apparaissent dans une liste.
  • Choisir la commande Arduino: Initialize. Cela permet de créer le programme principal de l'application. Ce programme contient les fonctions setup() et loop(), les deux points d'entrée d'un programme Arduino.
  • Par défaut, VSCode propose comme nom du programme principal app.ino. Par convention, ce programme doit avoir le même nom que le répertoire du projet avec l'extension .ino. Taper MonProjet.ino.
  • Dans la barre d'état en bas de la fenêtre de VSCode, cliquer sur Select Board
    Dans la combo Selected board, choisir le micro-contrôleur cible (pour l'exemple, choisir Arduino Uno).
  • Dans la barre d'état en bas de la fenêtre de VSCode, cliquer sur Select Serial Port.
    Choisir le port utilisé (COM9 dans l'exemple).
  • Dans la barre d'état de VSCode, cliquer sur Select Programmer
    Choisir le programmateur associé au micro-contrôleur cible (pour l'exemple choisir ArduinoISP.org).
Lorsque la configuration est terminée, les éléments de configuration doivent s'afficher dans la barre d'état de VSCode.

Fichier de configuration du projet

Dans tous les projets VSCode, les fichiers de configuration se trouvent dans un répertoire spécial nommé .vscode. Les fichiers qu'il contient doivent être au format JSON. Lors de l'étape précédente, la configuration du  projet pour Arduino a créé deux fichiers de configuration : arduino.json et c_cpp_properties.json.

Ficher arduino.json

Ce fichier contient les paramètres de l'extension Arduino, parmi lesquelles les caractéristiques du micro-contrôleur cible.  
{
    "board": "arduino:avr:uno",
    "port": "COM9",
    "programmer": "ArduinoISP.org",
    "sketch": "MonProjet.ino"
}
  • Les paramètres board, port et programmer correspondent aux caractéristiques du micro-contrôleur cible configuré dans l'étape précédente.
  • Le paramètre sketch définit le programme principal de l'application Arduino qui est embarquée sur le micro-contrôleur. Par convention, son nom est le même que le répertoire qui le contient et son extension est .ino (MonProjet.ino dans l'exemple).

Fichier c_cpp_properties.json

Ce fichier contient les paramètre de l'extension C/C++, parmi lesquelles la liste des chemins pour trouver les fichiers include .h de C et C++. Le projet ayant été configuré pour Arduino, les chemins de recherche ont été adaptés pour aller chercher le fichiers .h dans les répertoires d'installation de l'IDE Arduino. C'est pourquoi, bien qu'il ne soit plus utilisé pour programmer le projet, son installation est indispensable pour utiliser VSCode.
Par défaut, le contenu de c_cpp_properties.json est le suivant. Il conviendra d'y ajouter tous les chemins supplémentaires nécessaires pour que le préprocesseur et le compilateur C/C++ y retrouvent tous les fichiers de définition .h des fonctions utilisées dans le code.
{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "C:\\Program Files (x86)\\Arduino\\tools\\**",
                "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\**"
            ],
            "forcedInclude": [
                "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino\\Arduino.h"
            ],
            "intelliSenseMode": "msvc-x64",
            "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.27.29110/bin/Hostx64/x64/cl.exe",
            "cStandard": "c11",
            "cppStandard": "c++17"
        }
    ],
    "version": 4
}
  • Le paramètre configurations est un tableau qui peut contenir plusieurs configurations différentes. Cela permet à une équipe de développeurs, qui n'utiliseraient pas tous le même PC, de développement de disposer, pour un même projet commun, de leur configuration respective. Dans l'exemple ci dessus, il n'y a qu'une configuration nommée Win32 de définie.
  • Chaque configuration doit avoir un nom défini par le paramètre name
  • Le paramètre includePath est un tableau contenant la liste des répertoires qui seront explorés par le préprocesseur pour y retrouver les fichiers de définition .h des fonctions utilisées dans le code.
    Cette liste n'est pas définitive et devra être régulièrement mise à jour, selon les projets, pour y ajouter de nouveaux chemins de recherche en fonctions de bibliothèques externes utilisées.
  • Le paramètre forcedInclude est un tableau contenant la liste des fichiers à inclure systématiquement dans tous les fichiers de code du projet. Cela évite d'avoir, par exemple, à écrire la directive #include <Arduino.h> normalement obligatoire dans chaque fichier de code d'une application Arduino. Ce que fait par défaut l'IDE Arduino, mais pas VSCode qui peut être utiliser pour développer en C++ des applications pour d'autres environnements où celle-ci serait inutile. 
  • Les autres paramètres correspondent au compilateur C/C++ utilisé. Ici, il s'agit du compilateur MSVC de Visual Studio 2019.

Programmation du fichier principal de l'application

Le fichier principal de l'application est le fichier qui contient les point d'entrée du programme. Par convention, son nom est le même que le répertoire qui le contient et son extension est .ino.
Il doit contenir obligatoirement les deux fonctions qui servent de point d'entrée d'un programme Arduino :
  • La fonction setup() qui est invoquée une seule fois au démarrage du programme. Elle est dédiée aux actions d'initialisation des différents composants de l'application.
  • La fonction loop() qui est invoquée plusieurs fois en boucle, comme son nom le suggère. Elle constitue le fonctionnement normal réccurent de l'application.
Comme avec l'IDE Arduino, le squelette de l'application peut être généré automatiquement par VSCode dans le projet grâce à la commande de la palette (menu View/Command Palette...Arduino: Initialize. Mais il peut être également créé manuellement :
  • Dans VScode, lancer la commande de menu File/New File. Un onglet Untitled-1 est créé.
  • Dans VSCode, lancer la commande de menu File/Save As... pour donner un nom au fichier. Par convention, celui-ci étant créé dans le répertoire principal MonProjet, son nom doit être MonProjet.ino.
Pour tester, le plus simple est de reprendre le code de l'exemple de base Arduino. Celui-ci permet de faire clignoter la diode orange de la carte du micro-controleur (qui, pour info, correspond à la pin digitale n°13).
void setup()
{
    pinMode(LED_BUILTIN, OUTPUT);
}


void loop()
{
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);

}

Compilation et vérification du code

Pour compiler, il suffit de cliquer l'icone , qui lance la commande Arduino: Verify (Alt+Ctrl+R). Celle-ci est située en haut à droite de la barre de titre de l'onglet MonProjet.ino.

Préciser les paramètres de compilation

En principe, les opérations précédentes ayant été scrupuleusement effectuées, la compilation ne devrait générer aucune erreur.
Cependant, il se peut que des erreurs soient détectées. Celles-ci sont listées dans la fenêtre Problems en bas de VSCode.
La plupart du temps, il s'agit d'erreur de syntaxe, les plus courantes étant l'oubli d'un point-virgule terminal ou un défaut d'apairage des parenthèses, crochets ou accolades.
Mais, lors de la création d'un nouveau projet Arduino, il est possible que les erreurs suivantes soient constatées :
  • Erreurs #include détectées. Mettez à jour includePath. Les tildes sont désactivés pour cette unité de traduction (C:\Users\Moi\Documents\Arduino\MonProjet\MonProjet.ino).
  • Impossible d'ouvrir le fichier source "avr/pgmspace.h" (dependency of "C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h").
Comme on le voit sur la figure ci-dessus, l'erreur est attribuée à la déclaration de la fonction setup(). Ce qui peut être déroutant pour en détecter l'origine. En fait, l'erreur est causée, comme l'indique les messages, par un défaut de dépendance des fichiers de déclaration .h. En réalité, l'erreur apparaît à l'intérieur du fichier Arduino.h dont l'inclusion est implicite du fait de sa présence dans le paragraphe forcedInclude du fichier de configuration c_cpp_properties.json. En effet, le fichier Arduino.h sollicite le fichier pgmspace.h par une directive #include. Car ce fichier se trouve dans le répertoire C:\Program Files (x86)\Arduino\hardware\tools\avr\avr\include\avr qui ne fait pas partie de la liste des répertoires de recherche du préprocesseur C/C++ énumérés dans le paragraphe includePath du fichier de configuration c_cpp_properties.json.
Pour corriger cette erreur, il suffit donc d'ajouter le chemin de recherche C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr\\**, en n'oubliant pas la virgule de séparation avec l'item précédent.
{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "C:\\Program Files (x86)\\Arduino\\tools\\**",
                "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\**",
                "C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr\\**"

            ],
            "forcedInclude": [
                "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino\\Arduino.h"
            ],
            "intelliSenseMode": "msvc-x64",
            "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.27.29110/bin/Hostx64/x64/cl.exe",
            "cStandard": "c11",
            "cppStandard": "c++17"
        }
    ],
    "version": 4
}

Préciser les paramètres de compilation

Pour un projet important, surtout lorsqu'il est écrit en C++, il est d'une bonne pratique d'isoler le code dans plusieurs fichiers .cpp, en principe un par classe, et de créer le fichier de définition .h à part.
Par ailleurs, un projet peut faire référence à des bibliothèques de code relatives à des composants électroniques particuliers. Ces bibliothèques sont enregistrées dans le sous répertoire libraries du répertoires Arduino qui contient les projets pour Arduino. Ces bibliothèques fournissent également des fichiers de définition .h à inclure dans le code des applications qui les utilisent.
Aussi est-il d'une bonne pratique que de prévoir les chemins de recherche correspondants dans le paragraphe includePath du fichier de configuration c_cpp_properties.json :
{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceRoot}",
                "C:\\Program Files (x86)\\Arduino\\tools\\**",
                "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\**",
                "C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr\\**",
                 "C:\\Users\\Moi\\Documents\\Arduino\\libraries\\**"

            ],
            "forcedInclude": [
                "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino\\Arduino.h"
            ],
            "intelliSenseMode": "msvc-x64",
            "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.27.29110/bin/Hostx64/x64/cl.exe",
            "cStandard": "c11",
            "cppStandard": "c++17"
        }
    ],
    "version": 4
}

Conclusion

Toutes ces opérations effectuées, il est possible de procéder à la compilation définitive et au téléchargement du programme sur le micro-contrôleur. Pour cela il, il suffit de cliquer l'icône, qui lance la commande Arduino: Upload (Alt+Ctrl+U). Le résultat de la compilation s'affiche dans l'onglet Output, dans la partie inférieure de VSCode.
Le croquis utilise 924 octets (2%) de l'espace de stockage de programmes. Le maximum est de 32256 octets.
Les variables globales utilisent 9 octets (0%) de mémoire dynamique, ce qui laisse 2039 octets pour les variables locales. Le maximum est de 2048 octets.
Téléversement...
DEBUG StatusLogger Stopping LoggerContext[name=af3868, org.apache.logging.log4j.core.LoggerContext@5a729f]
DEBUG StatusLogger Stopping LoggerContext[name=af3868, org.apache.logging.log4j.core.LoggerContext@5a729f]...
TRACE StatusLogger Unregistering 1 MBeans: [org.apache.logging.log4j2:type=af3868]
TRACE StatusLogger Unregistering 1 MBeans: [org.apache.logging.log4j2:type=af3868,component=StatusLogger]
TRACE StatusLogger Unregistering 1 MBeans: [org.apache.logging.log4j2:type=af3868,component=ContextSelector]
TRACE StatusLogger Unregistering 1 MBeans: [org.apache.logging.log4j2:type=af3868,component=Loggers,name=]
TRACE StatusLogger Unregistering 2 MBeans: [org.apache.logging.log4j2:type=af3868,component=Appenders,name=RollingFile, org.apache.logging.log4j2:type=af3868,component=Appenders,name=Console]
TRACE StatusLogger Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=af3868,component=AsyncAppenders,name=*'
TRACE StatusLogger Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=af3868,component=AsyncLoggerRingBuffer'
TRACE StatusLogger Unregistering but no MBeans found matching 'org.apache.logging.log4j2:type=af3868,component=Loggers,name=*,subtype=RingBuffer'
TRACE StatusLogger Stopping XmlConfiguration[location=jar:file:/C:/Program%20Files%20(x86)/Arduino/lib/pde.jar!/log4j2.xml]...
TRACE StatusLogger XmlConfiguration notified 2 ReliabilityStrategies that config will be stopped.
TRACE StatusLogger XmlConfiguration stopping 1 LoggerConfigs.
TRACE StatusLogger XmlConfiguration stopping root LoggerConfig.
TRACE StatusLogger XmlConfiguration notifying ReliabilityStrategies that appenders will be stopped.
TRACE StatusLogger XmlConfiguration stopping remaining Appenders.
DEBUG StatusLogger Shutting down RollingFileManager C:\Users\framboise\AppData\Local\Arduino15/logs/application.log
DEBUG StatusLogger Shutting down RollingFileManager C:\Users\framboise\AppData\Local\Arduino15/logs/application.log
DEBUG StatusLogger All asynchronous threads have terminated
DEBUG StatusLogger RollingFileManager shutdown completed with status true
DEBUG StatusLogger Shut down RollingFileManager C:\Users\framboise\AppData\Local\Arduino15/logs/application.log, all resources released: true
DEBUG StatusLogger Appender RollingFile stopped with status true
DEBUG StatusLogger Shutting down OutputStreamManager SYSTEM_ERR.false.false
DEBUG StatusLogger Shut down OutputStreamManager SYSTEM_ERR.false.false, all resources released: true
DEBUG StatusLogger Appender Console stopped with status true
TRACE StatusLogger XmlConfiguration stopped 2 remaining Appenders.
TRACE StatusLogger XmlConfiguration cleaning Appenders from 2 LoggerConfigs.
DEBUG StatusLogger Stopped XmlConfiguration[location=jar:file:/C:/Program%20Files%20(x86)/Arduino/lib/pde.jar!/log4j2.xml] OK
DEBUG StatusLogger Stopped LoggerContext[name=af3868, org.apache.logging.log4j.core.LoggerContext@5a729f] with status true
[Done] Uploaded the sketch: MonProjet.ino
De fait, la petite diode orange de la carte Arduino se met à clignoter.

Commentaires

Posts les plus consultés de ce blog

Afficheur à LED 7 segments (classe SegmentLedDisplay)

Piloter un clavier matriciel sur le bus I2C avec un PCF8574

Utiliser Visual Studio Code pour développer sur Arduino