STM32 premier pas et prise en main logiciel
STM32 — Premiers pas et prise en main logicielle
Cette page présente une prise en main progressive de l’environnement STM32 utilisé pour le projet Mini-Bee. Elle explique comment installer l’environnement logiciel, réaliser les premiers exercices Arduino/STM32, puis comprendre le rôle de la carte Nucleo, des BluePills, du bus CAN et des modules de puissance L298N dans l’architecture FCU.
L’objectif n’est pas de tout documenter, mais de donner une base claire, lisible et directement réutilisable par les futurs contributeurs du projet.
1. Objectif de la page
Cette page sert de point d’entrée pour les étudiants, ingénieurs ou contributeurs qui découvrent la partie logicielle STM32 du projet Mini-Bee.
Elle permet de comprendre :
- comment préparer l’environnement de développement ;
- comment programmer une carte STM32 Nucleo avec l’IDE Arduino ;
- comment tester les entrées/sorties de base ;
- comment lire un joystick analogique ou numérique ;
- comment piloter un moteur à courant continu via un pont en H ;
- comment utiliser un bus CAN pour connecter la carte principale aux modules moteurs ;
- comment cette prise en main s’intègre dans le Flight Control Unit du Mini-Bee.
Idée clé : la STM32 Nucleo joue le rôle de contrôleur principal. Elle lit les consignes pilote, traite les informations capteurs et envoie des ordres aux modules moteurs.
2. Contexte Mini-Bee et Flight Control Unit
Le Mini-Bee est un multicoptère hybride VTOL développé comme plateforme collaborative de recherche et de prototypage.
Dans l’architecture FCU étudiée, la carte STM32 Nucleo agit comme le cerveau de commande. Elle reçoit les consignes de pilotage, prépare les ordres moteurs et coordonne les modules déportés.
Le projet vise à rendre le Mini-Bee contrôlable et stabilisable sur les trois axes principaux :
- Roll : roulis ;
- Pitch : tangage ;
- Yaw : lacet.
La soutenance ESTACA rappelle que l’objectif final du FCU Mini-Bee est de rendre le prototype contrôlable et stabilisable en trois axes grâce à une nouvelle architecture de contrôle distribuée.
3. Matériel principal utilisé
| Élément | Rôle dans la maquette | Point important |
|---|---|---|
| STM32 Nucleo F446RE | Carte maître du système | Lit les consignes, prépare les ordres et pilote la communication |
| BluePill STM32F103C8T6 | Carte esclave locale | Reçoit les ordres et génère les signaux moteur localement |
| SN65HVD230 | Transceiver CAN | Permet la communication différentielle CAN en 3,3 V |
| L298N | Pont en H de puissance | Alimente et contrôle le sens de rotation des moteurs DC |
| Moteurs DC | Actionneurs de la maquette | Permettent de visualiser les commandes moteurs |
| Joystick / potentiomètre | Interface de commande | Sert à générer des consignes pilote simples |
center|650px|thumb|Carte STM32 Nucleo F446RE utilisée comme contrôleur principal de la maquette.
4. Installation de l’environnement logiciel
La première étape consiste à préparer l’IDE Arduino pour programmer la carte STM32.
4.1 Installer les bibliothèques STM32
La carte d’extension X-NUCLEO-IKS01A2 est compatible avec l’écosystème Arduino. Une bibliothèque dédiée permet d’utiliser les capteurs et les fonctions associées dans l’IDE.
Étapes recommandées :
- Télécharger la bibliothèque STM32duino X-NUCLEO-IKS01A2 au format ZIP.
- Ouvrir l’IDE Arduino.
- Aller dans Croquis > Inclure une bibliothèque > Ajouter la bibliothèque .ZIP.
- Sélectionner directement le fichier ZIP sans le décompresser.
- Vérifier que la bibliothèque apparaît bien dans la liste des bibliothèques disponibles.
Attention : ne pas décompresser le fichier ZIP avant import dans Arduino IDE. L’IDE attend l’archive complète.
center|850px|thumb|Installation de la bibliothèque STM32duino X-NUCLEO-IKS01A2 dans l’IDE Arduino.
4.2 Ajouter le gestionnaire de cartes STM32
Dans les préférences Arduino, ajouter l’URL du gestionnaire de cartes STM32duino. Puis ouvrir le gestionnaire de cartes et installer les paquets STM32.
Ensuite, configurer la carte :
| Paramètre Arduino IDE | Valeur à sélectionner |
|---|---|
| Board | Nucleo-64 |
| Board part number | Nucleo F446RE |
| Port | Port série correspondant à la carte branchée |
| Upload method | Valeur par défaut adaptée à la Nucleo |
center|750px|thumb|Configuration de la carte Nucleo-64 / Nucleo F446RE dans l’IDE Arduino.
5. Premier exercice : clignotement d’une LED
Le clignotement d’une LED est l’exercice de base pour valider :
- le branchement ;
- le téléversement du code ;
- la configuration d’une sortie numérique ;
- le retour d’information dans le moniteur série.
5.1 Câblage
Connecter une LED sur la broche D13 / PA5 de la Nucleo.
Prévoir :
- une LED ;
- une résistance de 220 Ω ;
- une connexion vers GND ;
- un fil entre D13 / PA5 et l’anode de la LED.
center|700px|thumb|Premier montage LED sur breadboard avec la carte STM32 Nucleo.
5.2 Code de test
<syntaxhighlight lang="cpp">
- define LED_PIN PA5
- define BLINK_DELAY 500
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
Serial.println("LED blink test started");
}
void loop() {
digitalWrite(LED_PIN, HIGH);
Serial.println("LED: ON");
delay(BLINK_DELAY);
digitalWrite(LED_PIN, LOW);
Serial.println("LED: OFF");
delay(BLINK_DELAY);
} </syntaxhighlight>
5.3 Résultat attendu
La LED doit s’allumer et s’éteindre toutes les 500 ms. Le moniteur série doit afficher alternativement :
<syntaxhighlight lang="text"> LED: ON LED: OFF </syntaxhighlight>
Ce test valide que la carte est reconnue, que le programme est chargé correctement et que la sortie numérique fonctionne.
6. Lecture d’un joystick numérique
Le joystick numérique est utilisé comme une série d’interrupteurs logiques.
Il permet de détecter des états simples :
- direction activée ;
- bouton pressé ;
- position de repos.
6.1 Broches utilisées
| Fonction | Broche STM32 | Remarque |
|---|---|---|
| Axe X | PA0 | Entrée numérique |
| Axe Y | PA1 | Entrée numérique |
| Bouton | PB2 | Entrée numérique avec pull-up |
| VCC | 3.3 V | Alimentation logique |
| GND | GND | Masse commune |
<syntaxhighlight lang="cpp">
- define PIN_X PA0
- define PIN_Y PA1
- define PIN_BTN PB2
void setup() {
Serial.begin(115200);
pinMode(PIN_X, INPUT_PULLUP);
pinMode(PIN_Y, INPUT_PULLUP);
pinMode(PIN_BTN, INPUT_PULLUP);
Serial.println("Digital joystick test ready");
}
void loop() {
int stateX = digitalRead(PIN_X); int stateY = digitalRead(PIN_Y); int stateBtn = digitalRead(PIN_BTN);
if (stateX == LOW && stateY == HIGH) {
Serial.println("Position detected: upper right");
}
if (stateBtn == LOW) {
Serial.println("Button pressed");
}
delay(200);
} </syntaxhighlight>
center|650px|thumb|Montage d’un joystick sur la carte Nucleo pour lire des états numériques.
7. Lecture d’un joystick analogique
Le joystick analogique est plus adapté au pilotage progressif du Mini-Bee.
Contrairement au joystick numérique, il ne donne pas seulement un état ON/OFF. Il fournit une valeur proportionnelle à l’inclinaison.
7.1 Principe
Les axes X et Y sont lus par les entrées analogiques de la STM32.
Sur STM32, la lecture analogique peut être effectuée sur une résolution élevée. Dans les exercices, les valeurs sont exploitées pour détecter des zones :
- centre ;
- gauche / droite ;
- haut / bas.
7.2 Exemple de code
<syntaxhighlight lang="cpp">
- define JOYSTICK_X_PIN PA0
- define JOYSTICK_Y_PIN PA1
void setup() {
Serial.begin(115200);
pinMode(JOYSTICK_X_PIN, INPUT);
pinMode(JOYSTICK_Y_PIN, INPUT);
Serial.println("Analog joystick ready");
}
void loop() {
int x = analogRead(JOYSTICK_X_PIN); int y = analogRead(JOYSTICK_Y_PIN);
Serial.print("X: ");
Serial.print(x);
Serial.print(" | Y: ");
Serial.println(y);
if (x > 600) {
Serial.println("Action: right");
} else if (x < 400) {
Serial.println("Action: left");
}
if (y > 600) {
Serial.println("Action: up");
} else if (y < 400) {
Serial.println("Action: down");
}
delay(200);
} </syntaxhighlight>
Lien avec le Mini-Bee : le joystick analogique est indispensable pour générer une consigne proportionnelle. Il permet de piloter progressivement la poussée, l’orientation ou la vitesse angulaire.
8. Pilotage de moteurs avec un pont en H
La carte STM32 ne peut pas alimenter directement les moteurs. Il faut utiliser un composant de puissance.
Dans les exercices, deux approches apparaissent :
- L293D pour les premiers tests pédagogiques ;
- L298N pour la maquette Mini-Bee.
Le principe reste le même : le pont en H permet d’inverser la polarité appliquée au moteur, donc de changer son sens de rotation.
8.1 Logique de commande
| IN1 | IN2 | Résultat moteur |
|---|---|---|
| HIGH | LOW | Rotation sens A |
| LOW | HIGH | Rotation sens B |
| LOW | LOW | Arrêt |
| HIGH | HIGH | Arrêt / freinage selon montage |
8.2 Exemple simple
<syntaxhighlight lang="cpp"> const int motorPin1 = 5; const int motorPin2 = 6; const int motorPin3 = 10; const int motorPin4 = 9;
void setup() {
pinMode(motorPin1, OUTPUT); pinMode(motorPin2, OUTPUT); pinMode(motorPin3, OUTPUT); pinMode(motorPin4, OUTPUT);
}
void loop() {
digitalWrite(motorPin1, HIGH); digitalWrite(motorPin2, LOW); digitalWrite(motorPin3, LOW); digitalWrite(motorPin4, LOW); delay(2000);
digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, HIGH); delay(2000);
digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, LOW); digitalWrite(motorPin3, HIGH); digitalWrite(motorPin4, LOW); delay(2000);
digitalWrite(motorPin3, LOW); digitalWrite(motorPin4, HIGH); delay(2000);
digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, LOW); digitalWrite(motorPin3, LOW); digitalWrite(motorPin4, LOW);
} </syntaxhighlight>
center|700px|thumb|Montage de test moteur avec module de puissance et carte STM32.
9. Potentiomètre et jauge de poussée
Le potentiomètre permet de simuler une commande de puissance.
Dans le rapport d’exercices, il est utilisé pour allumer progressivement une, deux puis trois LED. Ce montage représente une jauge simplifiée de régime moteur.
9.1 Principe
- Potentiomètre faible : aucune LED allumée.
- Potentiomètre moyen : une ou deux LED allumées.
- Potentiomètre maximum : trois LED allumées.
9.2 Exemple de code
<syntaxhighlight lang="cpp">
- define POT_PIN A0
- define LED1 D2
- define LED2 D3
- define LED3 D4
void setup() {
Serial.begin(115200);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
Serial.println("Throttle gauge ready");
}
void loop() {
int value = analogRead(POT_PIN);
if (value < 50) {
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
} else if (value < 2000) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
} else if (value < 4000) {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, LOW);
} else {
digitalWrite(LED1, HIGH);
digitalWrite(LED2, HIGH);
digitalWrite(LED3, HIGH);
}
Serial.print("Potentiometer value: ");
Serial.println(value);
delay(100);
} </syntaxhighlight>
10. Bus CAN : pourquoi l’utiliser ?
Le bus CAN est utilisé pour faire communiquer la carte principale STM32 Nucleo avec les modules moteurs.
Il présente plusieurs avantages pour la maquette :
- réduction du câblage ;
- meilleure robustesse face aux parasites ;
- communication différentielle sur CAN_H et CAN_L ;
- architecture multipoint ;
- possibilité d’ajouter des modules sans refaire toute l’architecture ;
- priorité des messages grâce aux identifiants CAN.
Pourquoi le CAN est important : les moteurs et les modules de puissance génèrent des perturbations électriques. Le bus CAN est mieux adapté qu’une liaison simple ou qu’un câblage en étoile pour une maquette distribuée.
11. Test CAN en mode loopback
Le mode loopback permet de vérifier que le contrôleur CAN fonctionne sans dépendre immédiatement d’un autre module.
Le test consiste à :
- configurer les broches D14 / D15 ;
- initialiser le CAN à 500 kbps ;
- envoyer une trame ;
- recevoir la même trame en retour ;
- afficher le résultat dans le moniteur série.
11.1 Paramètres principaux
| Paramètre | Valeur utilisée |
|---|---|
| TX | D14 / PB9 |
| RX | D15 / PB8 |
| Débit | 500 kbps |
| Mode | Loopback |
| Identifiant de test | 0x123 |
11.2 Résultat attendu
Le moniteur série doit afficher une réception de données.
Exemple :
<syntaxhighlight lang="text"> SUCCESS: CAN uses D14/D15 Sending... RECEIVED! Data: 1 2 3 4 </syntaxhighlight>
12. Architecture distribuée de la maquette
L’architecture retenue sépare la commande et la puissance.
La STM32 Nucleo ne pilote pas directement tous les moteurs. Elle envoie des ordres à des BluePills, qui pilotent localement les modules L298N.
12.1 Chaîne fonctionnelle
Joystick / capteurs
↓
STM32 Nucleo F446RE
↓ Bus CAN
SN65HVD230
↓
BluePill STM32F103
↓ PWM + direction
L298N
↓
Moteurs DC
12.2 Rôle de chaque niveau
| Niveau | Fonction |
|---|---|
| STM32 Nucleo | Décision, consigne, stratégie de vol, coordination |
| Bus CAN | Transport fiable des messages vers les modules |
| BluePill | Exécution locale, génération PWM, pilotage moteur |
| L298N | Amplification de puissance et inversion de sens |
| Moteurs | Action physique observable sur la maquette |
center|900px|thumb|Schéma de principe de l’architecture STM32, CAN, BluePill et L298N.
13. Exemple de branchements maquette
Les documents de référence indiquent une organisation répétable par branche moteur.
13.1 STM32 vers CAN principal
- TX / D1 de la STM32 vers TX du CAN principal.
- RX / D0 de la STM32 vers RX du CAN principal.
- GND de la STM32 vers GND du CAN principal.
- 3.3 V de la STM32 vers 3.3 V du CAN principal.
13.2 CAN principal vers modules CAN
Pour chaque branche :
- CANH vers CANH ;
- CANL vers CANL.
13.3 CAN vers BluePill
- CANTX vers A7 de la BluePill.
- CANRX vers B1 de la BluePill.
13.4 BluePill vers L298N
- B8 vers ENA.
- B7 vers IN1.
- B6 vers IN2.
- B5 vers IN3.
- B4 vers IN4.
- B3 vers ENB.
13.5 L298N vers moteurs
- OUT1 / OUT2 vers le premier moteur DC.
- OUT3 / OUT4 vers le second moteur DC.
center|750px|thumb|Montage physique de la maquette avec STM32, CAN, BluePill, L298N et moteurs DC.
14. Exemple de code maître STM32
Ce code illustre le principe : la STM32 envoie une consigne de vitesse à plusieurs BluePills via le bus CAN.
<syntaxhighlight lang="cpp">
- define HAL_CAN_MODULE_ENABLED
- include <STM32_CAN.h>
STM32_CAN Can1(CAN1, ALT);
void setup() {
Serial.begin(115200);
Can1.begin();
Can1.setBaudRate(500000);
Serial.println("Mini-Bee master ready");
}
void loop() {
static uint8_t speed = 0; static bool increasing = true;
for (int id = 0x101; id <= 0x104; id++) {
CAN_message_t msg;
msg.id = id;
msg.len = 2;
msg.buf[0] = speed;
msg.buf[1] = speed;
Can1.write(msg);
}
if (increasing) {
speed += 5;
} else {
speed -= 5;
}
if (speed >= 250 || speed <= 0) {
increasing = !increasing;
}
delay(50);
} </syntaxhighlight>
15. Exemple de code BluePill esclave
Chaque BluePill possède un identifiant unique. Elle ne traite que les messages CAN qui lui sont destinés.
<syntaxhighlight lang="cpp">
- include <STM32_CAN.h>
- define NODE_ID 0x101
- define ENA_PIN PB8
- define IN1_PIN PB7
- define IN2_PIN PB6
- define IN3_PIN PB5
- define IN4_PIN PB4
- define ENB_PIN PB3
STM32_CAN Can1(CAN1, DEF);
void setup() {
pinMode(ENA_PIN, OUTPUT); pinMode(IN1_PIN, OUTPUT); pinMode(IN2_PIN, OUTPUT); pinMode(ENB_PIN, OUTPUT); pinMode(IN3_PIN, OUTPUT); pinMode(IN4_PIN, OUTPUT);
Can1.begin(); Can1.setBaudRate(500000); Can1.setFilter(0, NODE_ID, 0x7FF);
}
void driveMotors(uint8_t spd1, uint8_t spd2) {
analogWrite(ENA_PIN, spd1); digitalWrite(IN1_PIN, HIGH); digitalWrite(IN2_PIN, LOW);
analogWrite(ENB_PIN, spd2); digitalWrite(IN3_PIN, HIGH); digitalWrite(IN4_PIN, LOW);
}
void loop() {
CAN_message_t msg_rx;
if (Can1.read(msg_rx)) {
if (msg_rx.id == NODE_ID) {
driveMotors(msg_rx.buf[0], msg_rx.buf[1]);
}
}
} </syntaxhighlight>
16. Lien avec les futures lois de commande
Ces exercices ne sont pas seulement pédagogiques. Ils préparent directement la logique du Flight Control Unit.
| Exercice | Compétence acquise | Application FCU |
|---|---|---|
| LED | Sortie numérique | Signal d’état, diagnostic, alerte |
| Joystick numérique | Lecture d’ordre simple | Boutons, modes, commandes discrètes |
| Joystick analogique | Lecture proportionnelle | Consigne pilote progressive |
| Potentiomètre | Lecture ADC | Simulation de throttle ou jauge de poussée |
| Pont en H | Commande moteur | Sens, vitesse, arrêt moteur |
| CAN loopback | Communication robuste | Validation du bus de commande |
| CAN + L298N | Ordre numérique vers action moteur | Architecture distribuée Mini-Bee |
17. Bonnes pratiques de démarrage
Avant de lancer un test moteur :
- vérifier le câblage GND commun ;
- vérifier les alimentations 3.3 V, 5 V et puissance moteur ;
- tester d’abord sans hélice ;
- limiter la vitesse au début ;
- utiliser le moniteur série ;
- documenter chaque branche moteur ;
- numéroter les BluePills ;
- noter les identifiants CAN ;
- conserver une version du code stable avant modification.
Sécurité : les tests moteurs doivent être réalisés sans hélices lors des premières validations. Une erreur de code, de sens moteur ou de câblage peut déclencher un mouvement imprévu.
18. Perspectives pour la suite
La prise en main logicielle STM32 ouvre la voie aux travaux suivants :
- intégration complète du bus CAN sur toutes les branches ;
- validation de la commande moteur distribuée ;
- synchronisation des moteurs ;
- lecture des capteurs inertiels ;
- intégration d’un correcteur PID ;
- stabilisation roll / pitch / yaw ;
- test des cas de vol : décollage, stationnaire, montée, descente, virage et arrêt d’urgence.
Le travail réalisé constitue donc une base de reprise pour les futurs groupes. Il permet de passer d’exercices simples à une architecture de contrôle réellement exploitable sur la maquette Mini-Bee.
19. Visuels recommandés pour cette page
| Visuel | Source recommandée | Utilisation dans la page |
|---|---|---|
| Capture installation bibliothèque STM32duino | Rapport codes et exercices, page installation | Section 4 |
| Configuration Nucleo-64 / F446RE dans Arduino IDE | Rapport codes et exercices, page configuration | Section 4.2 |
| Montage LED + breadboard | Rapport codes et exercices, exercice LED | Section 5 |
| Montage joystick | Rapport codes et exercices, exercice joystick | Section 6 |
| Transceiver CAN SN65HVD230 | Rapport codes et exercices, section bus CAN | Section 10 |
| BluePill | Rapport codes et exercices, section BluePill | Section 12 |
| L298N | Rapport codes et exercices, section L298N | Section 8 ou 12 |
| Schéma de branchement maquette | Rapport codes et exercices, montage maquette | Section 13 |
| Architecture FCU | Soutenance FCU Mini-Bee | Section 2 ou 12 |
20. Conclusion
La STM32 est le point d’entrée logiciel du Flight Control Unit Mini-Bee.
En partant d’exercices simples — LED, joystick, potentiomètre, moteur — on construit progressivement les briques nécessaires à une architecture de vol distribuée :
- acquisition des consignes ;
- traitement logiciel ;
- communication CAN ;
- délégation locale aux BluePills ;
- pilotage de puissance par L298N ;
- commande synchronisée des moteurs.
Cette progression rend le système compréhensible, testable et améliorable. Elle facilite la reprise du projet par de nouveaux contributeurs et prépare les prochaines étapes de stabilisation du Mini-Bee.