Fonction Arduino : créer et appeler des fonctions en C
Fonctions Arduino : portée, DRY, code lisible, éviter les globales. 20 exercices corrigés.
Illustration générée par IA
Fonctions Arduino : portée, DRY, code lisible, éviter les globales. 20 exercices corrigés.
Quand ton programme robotique grandit, il devient difficile à lire : beaucoup de if, beaucoup de répétitions, et des constantes un peu partout. Les fonctions servent à :
etatVeille(), alerteIntrusion()DRY = ne pas répéter la même information à plusieurs endroits.
Exemple : si tu écris 2 fois "Mon message", tu risques d’en modifier une et pas l’autre. En robotique, ça crée des bugs difficiles à comprendre.
Bonne pratique : une seule source :
const char* message = "Mon message";
En robotique, trop de globales = programme difficile à raisonner. On garde des globales pour les états nécessaires, et on passe le reste en paramètres.
loop():
lire capteur
si intrusion -> alerteIntrusion()
sinon -> etatVeille()
Exercice 1 — Écris une fonction void etatVeille() qui affiche VEILLE sur Serial. Simple
void etatVeille() {
Serial.println("VEILLE");
}
Exercice 2 — Écris void alerteIntrusion() qui affiche ALERTE et joue un “bip” simulé (Serial.println("bip")). Simple
void alerteIntrusion() {
Serial.println("ALERTE");
Serial.println("bip");
}
Exercice 3 — Appelle etatVeille() dans setup() (après Serial.begin). Simple
void etatVeille() { Serial.println("VEILLE"); }
void setup() {
Serial.begin(9600);
etatVeille();
}
void loop() {}
Exercice 4 — DRY : déclare const int DIST_STOP = 15; et utilise-la dans une fonction bool isStop(int d). Simple
const int DIST_STOP = 15;
bool isStop(int d) { return d <= DIST_STOP; }
Exercice 5 — Écris int absInt(int v) (valeur absolue) et utilise-la pour un seuil d’intrusion. Simple
int absInt(int v) { return v < 0 ? -v : v; }
Exercice 6 — Écris bool intrusion(int ref, int mesure, int seuil) qui renvoie true si abs(mesure-ref) > seuil. Intermédiaire
int absInt(int v) { return v < 0 ? -v : v; }
bool intrusion(int ref, int mesure, int seuil) {
return absInt(mesure - ref) > seuil;
}
Exercice 7 — Évite une globale : crée void showCounter(int n) au lieu d’accéder directement à intrusions. Intermédiaire
void showCounter(int n) {
Serial.print("intrusions=");
Serial.println(n);
}
Exercice 8 — Écris void etatVeille(int nbr_intrusion) qui affiche un visage/texte simulé différent selon le compteur (si 0 : OK, sinon : attention). Intermédiaire
void etatVeille(int nbr_intrusion) {
if (nbr_intrusion == 0) Serial.println("OK");
else Serial.println("ATTENTION");
}
Exercice 9 — Explique en commentaire : pourquoi passer nbr_intrusion en paramètre peut aider la pédagogie même si la variable est globale. Intermédiaire
// Pédagogie : on voit quelles infos la fonction utilise (comme f(x)) ;
// bonne pratique : moins dépendre de variables globales rend le code plus testable et lisible.
Exercice 10 — Écris une fonction unsigned long periodFromDistance(int d) qui renvoie 1000ms si 35..69, 250ms si <35, sinon 100ms. Intermédiaire
unsigned long periodFromDistance(int d) {
if (d >= 70) return 100;
if (d >= 35) return 1000;
return 250;
}
Exercice 11 — Écris bool every(unsigned long period, unsigned long* last) (timer générique). Avancé
bool every(unsigned long period, unsigned long* last) {
unsigned long now = millis();
if (now - *last >= period) { *last = now; return true; }
return false;
}
Exercice 12 — Crée une fonction int readDistanceFake() qui renvoie une distance qui descend de 70 à 0 puis remonte (simulation). Avancé
int readDistanceFake() {
static int d = 70;
static int step = -1;
d += step;
if (d <= 0) { d = 0; step = 1; }
if (d >= 70) { d = 70; step = -1; }
return d;
}
Exercice 13 — Écris void radarTick(int distance_cm) qui affiche bip si distance < 70 (sinon rien). Avancé
void radarTick(int distance_cm) {
if (distance_cm < 70) Serial.println("bip");
}
Exercice 14 — Mini-architecture : dans loop, lis la distance, calcule period, puis si every(period) alors radarTick. Avancé
unsigned long last = 0;bool every(unsigned long period, unsigned long* last) { unsigned long now = millis(); if (now - *last >= period) { *last = now; return true; } return false; }
unsigned long periodFromDistance(int d) { if (d >= 70) return 100; if (d >= 35) return 1000; return 250; }
int readDistanceFake() { static int d = 70; d—; if (d < 0) d = 70; return d; }
void setup() { Serial.begin(9600); } void loop() { int d = readDistanceFake(); unsigned long p = periodFromDistance(d); if (every(p, &last) && d < 70) Serial.println(“bip”); }
Exercice 15 — Écris une fonction void logKV(const char* k, int v) et utilise-la pour logger distance. Avancé
void logKV(const char* k, int v) {
Serial.print(k);
Serial.print('=');
Serial.println(v);
}
Exercice 16 — DRY : crée const int SEUIL = 3; et utilise-le dans 2 endroits (intrusion + alerte) sans recopier le 3. Avancé
const int SEUIL = 3;
int absInt(int v) { return v < 0 ? -v : v; }
bool intrusion(int ref, int mesure) { return absInt(mesure - ref) > SEUIL; }
Exercice 17 — Explique en commentaire ce que veut dire “modularité”. Avancé
// Modularité : découper un programme en blocs/fonctions indépendants et réutilisables,
// chacun avec une responsabilité claire.
Exercice 18 — Crée une fonction int vitesseFromDistance(int d) qui renvoie 0 si d<=15, 80 si d>=50, sinon 30. Avancé
int vitesseFromDistance(int d) {
if (d <= 15) return 0;
if (d >= 50) return 80;
return 30;
}
Exercice 19 — Ajoute une fonction void drive(int v) qui simule l’envoi vitesse moteur (Serial.println(v)). Avancé
void drive(int v) {
Serial.print("drive=");
Serial.println(v);
}
Exercice 20 — Mini-projet : dans loop, lis une distance simulée, calcule la vitesse via vitesseFromDistance, puis appelle drive(v) toutes les 200 ms (non-bloquant). Avancé
unsigned long last = 0; bool every(unsigned long p, unsigned long* last) { unsigned long now = millis(); if (now - *last >= p) { *last = now; return true; } return false; } int vitesseFromDistance(int d) { if (d <= 15) return 0; if (d >= 50) return 80; return 30; } int readDistanceFake() { static int d = 70; d--; if (d < 0) d = 70; return d; } void drive(int v) { Serial.print("drive="); Serial.println(v); }
void setup() { Serial.begin(9600); } void loop() { if (every(200, &last)) { int d = readDistanceFake(); int v = vitesseFromDistance(d); drive(v); } }
Vous hésitez entre deux modèles ou vous avez besoin d'aide sur un montage ? Écrivez-nous, nous vous répondons rapidement par e-mail.