Introduction à la programmation
Introduction¶
"Un voyage de mille lieues commence toujours par un premier pas." – Lao Tseu
Le langage de programmation¶
Arduino utilise un langage de programmation spécifique appelé "Arduino Language" ou "Arduino C++".
Le langage Arduino est basé sur le langage C++, avec des modifications et des extensions spécifiques pour permettre une utilisation facile des fonctionnalités du microcontrôleur Arduino. Il est donc recommandé de connaître les bases du langage C++ avant de se lancer dans la programmation Arduino.
Note
Si vous avez déjà programmé en C# ou Java, vous verrez que le langage Arduino est très proche de ces langages. C'est d'ailleurs pour cette raison que le langage Arduino est souvent utilisé pour initier les débutants à la programmation embarquée.
Exemples¶
Voici quelques exemples de structures de base du langage Arduino :
- Déclaration de variables :
- Structures de contrôle de flux :
- Fonctions :
Il existe également de nombreuses fonctions prédéfinies dans le langage Arduino qui permettent d'interagir avec le microcontrôleur et ses périphériques (lecture et écriture sur les pins, gestion de l'horloge, gestion de la communication série, etc.).
Comment programmer un Arduino¶
Voici la structure de base d'un programme Arduino :
Le programme Arduino comporte deux fonctions de base obligatoire : setup et loop.
La fonction setup est exécutée une seule fois au démarrage du programme. On y met généralement le code de configuration, comme la définition des pin de sortie ou l'initialisation de certains paramètres.
La fonction loop est exécutée en boucle, c'est-à-dire qu'elle est répétée indéfiniment. C'est là que se trouve le code principal du programme.
Voici un exemple de programme Arduino simple qui fait clignoter une LED toutes les secondes :
La fonction setup¶
La fonction setup est exécutée une seule fois au démarrage du programme Arduino, avant la boucle infinie de la fonction loop.
Elle est généralement utilisée pour mettre en place l'environnement de travail du programme, c'est-à-dire pour configurer les paramètres et les dispositifs nécessaires au bon fonctionnement du programme.
Voici quelques exemples d'utilisations possibles de la fonction setup :
- Définition des modes d'entrée/sortie des pins du microcontrôleur Arduino : en utilisant la fonction
pinMode, on peut indiquer si une pin doit être utilisée en entrée (par exemple pour lire une valeur provenant d'un bouton ou autre capteur) ou en sortie (par exemple pour envoyer une tension à une LED). - Initialisation de paramètres et de variables : la fonction
setupest souvent utilisée pour initialiser des variables qui seront utilisées tout au long du programme, comme des compteurs ou des variables de configuration. - Configuration de périphériques externes : si le programme utilise des périphériques tels que des écrans LCD, des modules WiFi ou des capteurs, la fonction
setuppeut être utilisée pour configurer ces périphériques et les mettre en place pour l'utilisation ultérieure.
Voici un exemple de programme Arduino qui utilise la fonction setup pour définir le mode de la pin 13 en sortie et initialiser une variable de comptage à 0 :
Question : De quelle façon, nous pourrions améliorer ce programme pour qu'il soit plus facile à maintenir?
Indice
Si l'on doit modifier la broche de la LED ou de la durée de l'attente que devrons-nous faire?
La fonction loop¶
La fonction loop est exécutée en boucle, c'est-à-dire qu'elle est répétée indéfiniment. C'est là que se trouve le code principal du programme.
Cette boucle est très pratique dans les programmes Arduino car elle permet de mettre en place des actions qui sont répétées de manière périodique, comme la lecture de données sensorielles, l'affichage de données sur un écran ou encore la commande de dispositifs tels que des moteurs ou des LED.
Perle de culture
Les microcontrôleurs doivent tous avoir une fonction similaire à
looppour fonctionner. Si vous ne mettez pas de fonctionloopdans votre programme, le microcontrôleur ne fera rien.Ainsi, on pourrait retrouver quelques choses comme ça dans le code d'un microcontrôleur :
Cycle de vie d'un programme Arduino¶
📌 Explications du diagramme :¶
- Démarrage :
- L'Arduino est alimenté et initialise son matériel.
-
Il charge ensuite le programme stocké en mémoire.
-
setup() (exécuté une seule fois) :
- Configuration des broches (
pinMode(),Serial.begin(), etc.). -
Initialisation des variables, capteurs, moteurs, etc.
-
loop() (exécuté en continu) :
- Contient le programme principal qui tourne en boucle infinie tant que l'Arduino est sous tension.
- Permet de réagir aux événements, de lire des capteurs, de contrôler des actionneurs, etc.
Les principaux types de données¶
Le langage Arduino, basé sur le C++, offre plusieurs types de données adaptés aux contraintes des microcontrôleurs. Voici un tableau des principaux types disponibles :
| Type | Description | Limite Inférieure | Limite Supérieure |
|---|---|---|---|
int |
Entier signé 16 bits (sur Arduino Uno) | -32,768 | 32,767 |
unsigned int |
Entier non signé 16 bits | 0 | 65,535 |
long |
Entier signé 32 bits | -2,147,483,648 | 2,147,483,647 |
unsigned long |
Entier non signé 32 bits | 0 | 4,294,967,295 |
float |
Nombre à virgule flottante (32 bits) | ≈ -3.4 × 10³⁸ | ≈ 3.4 × 10³⁸ |
double |
Identique à float sur Arduino AVR |
(32 bits) | (Idem float) |
char |
Caractère unique (8 bits) | -128 | 127 |
bool |
Valeur booléenne (true ou false) |
false (0) |
true (1) |
⚠ Attention : Sur les cartes basées sur des microcontrôleurs AVR (comme l’Arduino Mega),
doubleest identique àfloat(32 bits). Sur d’autres plateformes (ESP32, ARM),doublepeut être en 64 bits.
🛠 Déclaration et utilisation¶
Voici un exemple de déclaration de variables utilisant ces types :
Comparaison des types et exemples d'utilisation¶
| Type | Taille (octets) | Exemples d'utilisation |
|---|---|---|
int |
2 | Compteur, indicateur d'état numérique |
unsigned int |
2 | Index, compteur sans valeur négative |
long |
4 | Stocker des temps longs (millis(), micros()) |
unsigned long |
4 | Horodatage, gestion de délais (millis(), micros()) |
float |
4 | Stockage de mesures précises (température, tension, etc.) |
double |
4 (ou 8) | Calculs scientifiques sur certaines cartes |
char |
1 | Stockage de caractères ('A', 'Z', '\n') |
bool |
1 | Gestion d’états (true ou false) |
Étant programmé pour un appareil très limité en ressource, il est important de choisir le type de données le plus adapté pour stocker vos données, afin de maximiser l'efficacité et la précision de votre programme. Par exemple, il n'est pas recommandé d'utiliser un type float pour stocker des nombres entiers, car cela peut entraîner une perte de précision. De même, il est préférable d'utiliser un type long ou unsigned long pour stocker des nombres très grands, plutôt que de dépasser la limite supérieure du type int.
⚠ Précision et limitations du type float¶
Le type float est utile pour les calculs à virgule flottante, mais il a une précision limitée (7 chiffres significatifs). Il utilise une représentation binaire, ce qui peut entraîner des erreurs d'arrondi.
🔥 Problèmes de conversion float → int¶
Il est donc important de prendre en compte ces limitations lors de l'utilisation du type float dans vos programmes Arduino.
📌 Les variables en Arduino¶
Une variable est un espace mémoire utilisé pour stocker une valeur. En programmation Arduino, les variables permettent de manipuler des données dynamiquement et sont essentielles à l'exécution des programmes.
📍 La portée des variables¶
La portée d’une variable définit où elle est accessible dans le programme. On distingue trois types principaux :
1️⃣ Variables globales¶
✅ Définition :
- Déclarées en dehors de toutes les fonctions.
- Accessibles partout dans le programme.
- Conservent leur valeur pendant toute l’exécution du programme.
📌 Exemple :
⚠ Attention : Un usage excessif peut rendre le programme difficile à déboguer.
2️⃣ Variables locales¶
✅ Définition :
- Déclarées à l’intérieur d’une fonction.
- Inaccessibles en dehors de cette fonction.
- Réinitialisées à chaque appel de la fonction.
📌 Exemple :
3️⃣ Variables statiques¶
✅ Définition :
- Déclarées dans une fonction avec
static. - Conservent leur valeur entre les appels de la fonction.
- Accessibles uniquement dans la fonction où elles sont déclarées.
📌 Exemple :
🔄 Illustration de la portée des variables¶
Le programme ci-dessous met en évidence l’évolution des variables locales, globales et statiques.
📌 Exemple détaillé :
📝 Explication des résultats attendus :
| Type de variable | Évolution |
|---|---|
variableGlobale |
Incrémente à chaque cycle de loop() |
compteurStatique |
Incrémente à chaque appel de fonctionAvecStatique() |
compteurLocal |
Reste à 1 à chaque appel (réinitialisé) |
🔘 Application pratique des variables statiques¶
Un exemple concret : compter le nombre de pressions sur un bouton sans utiliser de variable globale.
📌 Exemple avec bouton :
✅ Bonnes pratiques¶
- Privilégier les variables locales pour éviter les conflits et améliorer la clarté du code.
- Utiliser
staticquand une valeur doit être conservée entre appels sans être globale. - Limiter les variables globales aux cas où elles sont vraiment nécessaires (ex. : timers, état général).
Wokwi - Simulateur Arduino¶
Il existe plusieurs sites qui permettent de simuler une partie des fonctionnalités de l'Arduino. Toutefois, je préconise Wokwi. Il est gratuit, il est en ligne, il est simple d'utilisation et il est très complet.
Plusieurs de mes captures d'écran proviendront de Wokwi.
Simuler un projet sur un simulateur avant d'effectuer les branchements physiques permet de s'assurer que notre code fonctionne.
Créer un projet¶
Pour créer un projet, il suffit d'aller dans le bas de la page dans la section "Start from scratch" et de cliquer sur la carte Arduino que l'on souhaite utiliser. Dans notre cas, il s'agira du Arduino Mega.
Exercice - Premier projet¶
- Si ce n'est déjà fait, créez un compte GitHub.
- Connectez-vous à Wokwi avec votre compte GitHub.
- À partir du logiciel Arduino IDE, ouvrir le projet exemple "Blink".
- Créez un nouveau projet nommé
c01_ex01et choisissez le typeArduino Mega. - Collez le projet "Blink" dans le nouveau projet Wokwi.
- Exécutez le projet.
- Modifiez les valeurs de timing pour d'autres valeurs et exécutez le projet.
Exercices¶
Recherches¶
Dans le but de vous habituer à faire des recherches sur Google, j'ai expressément mis des questions où l'information n'est pas directement dans ce document.
- Dans certains exemples de code, on retrouve des noms de variable tout en majuscule. Pour quelle raison?
- Dans nos cas d'utilisation, quelles sont les valeurs des variables
HIGH,LOWetLED_BUILTIN? - Que fait la fonction
delay()? - Que fait la fonction
pinMode()? - Combien de mémoire RAM possède le Arduino Mega?
Questions¶
- Quelle est la différence entre une variable locale et une variable globale?
- Quel type de variable est-il préférable d'utiliser pour stocker le temps en milliseconde?
- Si je veux partager une variable entre les fonctions, quelle sera la portée de la variable que devrais-je prendre?
- Si je veux conserver la valeur d'une variable à l'intérieur d'une même fonction, quelle sera la portée de la variable que devrais-je prendre?
- À l'intérieur d'une fonction, si la valeur d'une variable doit être réinitialiser à chaque fois et elle n'est pas utile à l'extérieur de la dite fonction, quelle sera la portée de la variable?
- Quelle est la différence entre une variable statique et une variable globale?
- Quelle est la différence entre une variable locale et une variable statique?
- Nommez une utilité pour une variable locale.
- Nommez une utilité pour une variable statique.
- Nommez une utilité pour une variable globale.
Réponses
- Une variable locale est déclarée à l'intérieur d'une fonction et n'est pas accessible à l'extérieur de la fonction. Une variable globale est déclarée à l'extérieur de toute fonction et est accessible à l'extérieur de toutes les fonctions.
unsigned long- Variable globale
- Variable statique
- Variable locale
- Une variable statique conserve sa valeur entre les exécutions d'une fonction et n'est pas accessible aux autres fonctions. Une variable globale est accessible à l'extérieur de toutes les fonctions.
- Une variable locale est déclarée à l'intérieur d'une fonction, n'est pas accessible à l'extérieur de la fonction et elle est réinitialisée à chaque exécution de la fonction. Une variable statique est déclarée à l'intérieur d'une fonction et conserve sa valeur entre les exécutions de la fonction.
- Exemple : Avoir une variable qui sert à incrémenter un compteur.
- Exemple : Conserver la valeur du temps entre les exécutions d'une fonction. Conserver l'état d'une LED entre les exécutions d'une fonction.
- Exemple : Conserver l'heure globale du système. Conserver l'état d'un composant pour l'ensemble du système.
Programmation¶
- Modifiez le programme "Blink" pour faire clignoter la LED 5 fois par seconde.
- Modifiez le programme "Fade" pour faire réagir la LED qui est intégrée sur le Arduino.
- Modifiez le programme "Fade" pour faire graduer la LED plus rapidement.
Défi¶
- Créez un programme qui fait clignoter la LED 2 fois dans une seconde. Ensuite, faire un graduation 100% vers 0% sur 1 seconde. Et recommencer.