JA.ENG
FICHE JA-ENG / PROJET·RÉF P-01·DOC DEEP-DIVE·PAGE 01 / 01
P-01 · Embarqué · 2017 — 2018 · JCDecaux

Contrôleur moteur de vélo à assistance électrique.

Développement complet du logiciel embarqué d'un contrôleur moteur pour vélo à assistance électrique urbain — architecture temps réel, C++ embarqué, logique d'assistance sur mesure, chez JCDecaux.

Période2017 → 2018
RôleLogiciel embarqué complet
ÉquipeSolo
PérimètreFirmware → outils PC → maquette
Lecture~ 6 min
STM32C++FreeRTOSCAN busQtCapteur pédalier
fig. 1 · contrôleur moteur STM32 + maquette de test

fig. 1Vélo'v électrique — Métropole de Lyon, le vélo à assistance électrique en libre-service équipé du contrôleur développé chez JCDecaux.

##

Une architecture distribuée à trois cartes

§ 01

Dans le cadre d'un projet de vélo à assistance électrique destiné à un usage urbain, j'ai été en charge de l'intégralité du logiciel embarqué du contrôleur moteur. J'étais seul responsable de cette partie du projet, depuis les choix d'architecture firmware jusqu'à la mise au point fonctionnelle.

Le système reposait sur une architecture distribuée autour de trois cartes électroniques : le contrôleur moteur, une carte batterie équipée d'un BMS, et une carte dédiée à l'interface utilisateur intégrant un afficheur et des boutons. Le contrôleur moteur, basé sur un microcontrôleur STM32, constituait le cœur décisionnel du système.

fig. 2 · architecture distribuée — trois cartes sur un bus partagéP-01.ARCH
MOTEURContrôleur moteurSTM32 · C++FreeRTOSCapteur pédalierLogique d'assistanceÉNERGIECarte batterieBMSAlimentation moteurIHMCarte afficheurAfficheur + boutonsRemontée des défautsBus CANdéfauts & états
##

Une architecture temps réel orientée sécurité et confort

§ 02

Le logiciel embarqué devait répondre à des contraintes temps réel strictes. L'action sur un frein devait provoquer une coupure immédiate de l'alimentation du moteur, sans latence perceptible. De la même manière, l'assistance devait s'interrompre à 25 km/h, conformément à la réglementation.

Plutôt que de procéder à une coupure brutale, j'ai choisi d'implémenter une réduction progressive de l'assistance à l'approche de cette limite. L'objectif était d'éviter les à-coups et de préserver une sensation de conduite naturelle, même dans les phases transitoires.

Le logiciel s'appuyait sur FreeRTOS, tel que recommandé par ST pour les microcontrôleurs STM32 à l'époque, ce qui m'a permis de structurer le système autour de tâches clairement identifiées et de garantir la réactivité des fonctions critiques.

##

Choix du C++ embarqué : une décision structurante

§ 03

J'ai fait le choix de développer l'ensemble du firmware en C++, une première dans l'entreprise pour un projet embarqué de ce type. Cette décision n'était pas motivée par un besoin de sophistication du langage, mais par une volonté très pragmatique : mieux structurer le code et le rendre plus lisible et plus accessible pour un futur ingénieur amené à reprendre le projet.

Le C++ m'a permis d'introduire une encapsulation claire des responsabilités, de définir des interfaces explicites entre les différents sous-systèmes, et d'isoler les dépendances matérielles. Contrairement à certaines idées reçues, les compilateurs récents se sont révélés parfaitement capables d'optimiser efficacement ce code, sans pénalité notable en termes de performances ou de consommation de ressources.

Avec le recul, ce choix s'est avéré pertinent : il a contribué à une meilleure maintenabilité et à une compréhension plus rapide du fonctionnement global du système.

##

Abstraction matérielle et pilotage moteur

§ 04

Le pilotage du moteur reposait sur une bibliothèque ST fournie, utilisée comme une boîte noire. Afin de préserver la cohérence de l'architecture, j'ai volontairement encapsulé cette bibliothèque derrière une couche logicielle dédiée. Cette approche a permis de contenir la complexité liée à cette dépendance et d'éviter que le reste du code ne soit structuré autour de contraintes imposées par la bibliothèque.

Plus globalement, j'ai mis en place des couches d'abstraction matérielle pour les capteurs et les actionneurs, ainsi que des machines à états pour modéliser les différents modes de fonctionnement du système. Cette organisation permettait d'envisager le remplacement de capteurs ou d'actionneurs avec un impact logiciel limité.

##

Capteur pédalier : de la mesure brute à la donnée exploitable

§ 05

Le capteur de pédalier fournissait plusieurs informations brutes : un capteur de couple mesuré sur une seule pédale, ainsi qu'un capteur incrémental à quadrature de phase, complété par un top tour.

Plutôt que d'exposer directement ces données au reste du système, j'ai conçu une abstraction logicielle par fusion de données, dont le rôle était de produire des grandeurs exploitables par la logique métier : un couple filtré par moyenne glissante, une vitesse de pédalage stable, et un angle de pédalier cohérent et continu. Cette approche permettait à la fois de lisser les imperfections de la mesure et d'isoler la complexité du capteur dans une couche dédiée, rendant le reste du logiciel plus simple, plus lisible et plus évolutif.

##

Une logique d'assistance centrée sur l'effort

§ 06

À partir du couple mesuré, de la vitesse de pédalage et du niveau d'assistance demandé par l'utilisateur, j'ai conçu et implémenté l'intégralité de la logique de pilotage du moteur. Mon constat, issu de l'expérience utilisateur de nombreux vélos à assistance électrique d'entrée de gamme, est que l'assistance est souvent mal perçue : trop brutale, peu cohérente, et déconnectée de l'effort réel du cycliste.

J'ai donc adopté une approche différente : pour moi, un niveau d'assistance ne doit pas correspondre à une simple amplification du couple, mais à un niveau d'effort cible que le cycliste doit fournir. L'asservissement du moteur a été conçu de manière à maintenir cet effort aussi constant que possible — s'affranchissant ainsi des variations liées à l'environnement (pente, vent, charge, état de la batterie) sans avoir besoin de les mesurer explicitement. Le comportement du vélo reste ainsi cohérent, prévisible et confortable, quelles que soient les conditions extérieures.

##

Communication CAN et gestion des défauts

§ 07

La communication entre le contrôleur moteur, le BMS batterie et la carte afficheur reposait sur un bus CAN. Les informations de défauts, qu'elles concernent les capteurs, la batterie ou le système lui-même, étaient transmises à la carte afficheur afin d'informer l'utilisateur.

Même sans être responsable de l'architecture système globale, j'ai conçu la partie firmware de manière à isoler la communication CAN de la logique métier, et à garantir un comportement sûr en cas d'anomalie ou de perte de communication.

##

Outils de mise au point et maquette de test

§ 08

Pour accompagner le développement et la mise au point du système, j'ai développé deux outils logiciels sur PC.

Interface graphique Qt
Dialogue avec le contrôleur via bus CAN — visualisation temps réel des états et capteurs, ajustement de paramètres, pilotage manuel d'actionneurs.
Outil ligne de commande
Analyse des trames CAN, avec décodage lisible en console — efficace pour comprendre le comportement du système dans des situations complexes.

Afin de développer et valider le logiciel indépendamment de l'intégration finale sur le vélo, j'ai également conçu une maquette sur table représentant les principaux composants du système : moteur, capteur de pédalier et capteurs de frein.

Cette maquette m'a permis de tester la logique d'assistance, les réactions temps réel et les scénarios de défaut dans un environnement maîtrisé, tout en accélérant fortement les phases de mise au point. Elle a joué un rôle clé dans la compréhension fine du comportement du système et dans la validation progressive des choix d'architecture logicielle.

##

Regard rétrospectif

§ 09

Ce projet a renforcé ma conviction que, même sur des systèmes embarqués contraints, les choix d'architecture logicielle sont déterminants.

Une abstraction bien pensée, une structuration claire et des outils adaptés permettent non seulement de répondre aux exigences fonctionnelles, mais aussi de produire un système plus robuste, plus compréhensible et plus durable.

Il illustre aussi l'intérêt d'une approche pragmatique du C++ embarqué, utilisée non pour sa sophistication, mais comme un levier de clarté et de maintenabilité.