Vous êtes-vous déjà dit que la partie « collecte de données » d’une chaîne de données était une partie relativement simple d’un projet ? Dans cette série d’articles, nous expliquons pourquoi, selon nous, c’est une partie plus importante et complexe qu’il n’y paraît. Pour cela, nous nous appuyons sur un projet que nous avons réalisé, nommé DataRider. Ce projet nous a poussé à nous questionner sur la qualité et la quantité de données dont nous avions besoin, ainsi que sur l’organisation du code nécessaire pour avoir des performances optimales au niveau de notre collecte puis au niveau de notre chaîne de données. C’est parti pour un retour d’expérience sur tous les défis rencontrés !
Matinée IA & Cloud de Confiance
DataRider est un projet autour de courses de petites voitures électriques. Deux modes de jeu sont proposés à des joueurs et des joueuses : gagner des courses en allant le plus vite possible (premier mode de jeu) ou gagner en ayant la meilleure écoconduite, c’est-à-dire la plus basse consommation électrique (deuxième mode de jeu).
Pour pouvoir proposer un tel jeu et communiquer leur classement aux personnes qui participent, nous avons besoin de collecter les données des courses.
Nous présentons, dans ce premier article, la mise en place initiale de la collecte de données, ainsi que le premier défi que nous avons rencontré : la nécessité de trouver un moyen d’augmenter la fréquence de production de nos données afin de ne pas manquer d’informations importantes sur la localisation des voitures pendant les courses.
Retrouvez tous nos articles qui parlent également de ce projet :
- [Data Rider] Booster Mario Kart à l’IoT et à l’IA – Étape 1 : collecter les données IoT en temps réel
- [Data Rider] Booster Mario Kart à l’IoT et à l’IA – Étape 2 : la donnée en temps réel, du capteur au Dashboard
- [Data Rider] Booster Mario Kart à l’IoT et à l’IA – Étape 3 : écoconduite et consommation électrique
1. Lister et définir les données à collecter
Pour réaliser notre première collecte de données, nous avons tout d’abord défini les grandeurs dont nous avions besoin pour analyser les courses de voitures.
Il nous fallait ainsi collecter simultanément :
- Les données de position des voitures, renvoyées par des capteurs de position jalonnant le circuit,
- Les données de tension et d’intensité pour chaque voiture, afin d’établir ensuite la consommation électrique de chaque voiture.
Pour une voiture donnée, les données brutes ont donc l’allure suivante :
Une ligne complète de données, qui contient les données des deux voitures du circuit, se présente alors comme suit :
2. Mise en place de la collecte à partir des capteurs et du code Arduino
La collecte se fait à partir de capteurs physiques, utilisés de façon classique en électronique. Ces capteurs sont ensuite reliés, de façon filaire, à une carte Arduino MEGA.
Ci-dessous se trouvent les différents capteurs que nous utilisons.
- Capteurs de localisation
Pour la localisation, des capteurs à effet Hall détectent le passage des aimants collés sur les roues arrière des voitures.
Après paramétrage des PIN de l’Arduino, on lit de façon directe, grâce au script Arduino, les PINA (voiture 1) et PINC (voiture 2) de la carte Arduino pour obtenir les données de localisation.
![[Data Rider] Capteur de tension](https://blog.businessdecision.com/wp-content/uploads/2025/05/4-data-rider-REX-capteurs-tension.jpg)
- Capteurs de tension
Les deux capteurs (un capteur par voie) effectuent, de façon analogique, un pont diviseur et renvoient la tension entre le pôle moins du circuit et un des deux rails de la voiture. La lecture se fait de façon directe sur l’Arduino, via la fonction de lecture native analogRead().
![[Data Rider] Capteur d'intensité](https://blog.businessdecision.com/wp-content/uploads/2025/05/5-data-rider-REX-capteurs-intensite.jpg)
- Capteurs d’intensité
Il s’agit de capteurs « ACS712 ». Ils fonctionnent avec la librairie Arduino du même nom, « ACS712 », qui propose des fonctions de lecture de l’intensité. On utilise une des fonctions de la librairie pour lire l’intensité : mA_DC(). L’argument de cette fonction indique combien de points sont pris avant de renvoyer une valeur moyenne d’intensité. Le moyennage est nécessaire pour une lecture d’intensité correcte car le signal est très bruité.
La boucle de lecture de l’Arduino est présentée ci-dessous (valeurs exemples indiquées). Elle envoie un message dans le câble USB à chaque itération :
![[Data Rider] Boucle de lecture de l'Arduino](https://blog.businessdecision.com/wp-content/uploads/2025/05/6-data-rider-REX-boucle-arduino-1024x343.jpg)
Le message envoyé dans cet exemple est le suivant : « 254 ;14.77 ;233.4 ;255 ;6.77 ;185.56 ».
Notre collecte de données est fin prête ! Nous lançons notre script et réalisons nos premiers tests.
3. Analyse de cette première phase de collecte
La collecte est fonctionnelle, nous obtenons les lignes de données souhaitées. Bonne nouvelle, à première vue ! Nous effectuons alors quelques courses de voitures et constatons… que le passage des voitures devant certains capteurs de localisation n’est pas pris en compte dans la collecte de données. En réalité, nous manquons même les signaux de beaucoup de capteurs de localisation. Ils semblent parfois très bien fonctionner, et parfois pas du tout…
Que se passe-t-il ?
Après vérification du bon fonctionnement des capteurs, des fils de transmission, de l’émission et de la réception, nous entamons quelques réflexions supplémentaires et arrivons à l’hypothèse suivante :
Les voitures semblent parfois passer trop rapidement devant les capteurs de localisation et le signal ne parvient pas à être récupéré de façon fiable et systématique. Il est parfois récupéré, notamment quand la voiture ne va pas trop vite, mais parfois pas, quand les voitures passent trop rapidement devant les capteurs.
Comment faire pour régler ce problème sans changer les capteurs (car, nous allons le voir, le problème ne vient pas des capteurs) ?
Il est temps ici de vous donner quelques précisions supplémentaires sur notre chaîne de collecte des données.
4. Quelques précisions sur la chaîne de données
La chaîne de captation de données au complet se présente de la façon suivante :
![[Data Rider] Chaîne de captation de données](https://blog.businessdecision.com/wp-content/uploads/2025/05/7-data-rider-REX-chaine-captation-donnees-1024x354.jpg)
La donnée est captée et envoyée à l’Arduino. Ce dernier réalise en permanence une boucle (while loop) pour lire l’état des capteurs, remettre les données dans un format lisible et les envoyer sous forme de String dans un câble USB branché à un ordinateur. Un script python de l’ordinateur vient alors lire le port USB où arrive le câble. Le script python est lui aussi une boucle : après lecture d’une ligne, cette dernière est gardée si elle est valide (parfois des lignes avec données alphanumériques invalides ou un nombre de données invalides arrivent et sont donc rejetées), puis un timestamp est ajouté et enfin la ligne est envoyée vers un flux Kafka qui fait le lien avec la suite du traitement (partie ETL).
Notons que dans cette chaîne, nous disposons d’une information qui va être cruciale pour notre analyse : le timestamp des lignes de données.
5. Analyse de la fréquence des données collectées
Grâce à l’information du timestamp, nous pouvons voir que les lignes de données sont envoyées toutes les 6 millisecondes environ.
Notre hypothèse est que cette fréquence est trop faible : si une voiture passe devant un capteur de localisation en moins de 6 millisecondes, la donnée n’est purement et simplement pas « vue ». Cela arrive car les voitures vont en moyenne autour de 2,5 mètres par seconde et les capteurs à effet Hall (capteurs de localisation) font quelques millimètres de large, ce qui laisse un temps de passage devant un capteur de quelques millisecondes.
Quel est l’élément qui, avant tout autre, détermine la fréquence d’envoi des lignes de données ? C’est le code Arduino, qui est le producteur des lignes données. En effet, si le code Arduino met 6 millisecondes à :
- lire les capteurs de tension,
- lire les capteurs d’intensité,
- lire les capteurs de localisation,
- mettre en forme et assembler les données dans une ligne,
- envoyer la ligne dans le câble USB,
- revenir au début de ces étapes
alors il y a 6 millisecondes entre deux moments de lecture des capteurs de localisation, ou encore 6 millisecondes entre deux envois de lignes de données (ou 6 millisecondes entre n’importe quelle étape de la boucle et l’itération suivante de cette même étape).
Sur le schéma ci-dessous, chaque point en noir représente un moment où la fonction « lire la donnée du capteur de localisation » est appelée dans le script Arduino. Δt correspond au temps d’une itération de la boucle de l’Arduino, entre deux opérations de lecture.
![[Data Rider] Itération de la boucle de l'Arduino](https://blog.businessdecision.com/wp-content/uploads/2025/05/8-data-rider-REX-iteration-boucle-arduino-1024x353.jpg)
Le schéma permet de comprendre pourquoi nous manquons certaines données de localisation : si la voiture passe trop rapidement devant un jalon (exemple : jalon « 253 » sur le schéma), alors une fréquence d’acquisition trop faible présente le risque de ne pas échantillonner au moment où la voiture passe devant le capteur. Le jalon correspondant (ici le « 253 ») n’est alors pas « vu ».
Nous cherchons donc à augmenter la fréquence d’acquisition des données ou, formulé autrement, à diminuer le temps qui sépare deux lectures de données. Les deux grandeurs sont reliées par la formule suivante :
![[Data Rider] Fréquence d'acquisition des données](https://blog.businessdecision.com/wp-content/uploads/2025/05/9-data-rider-REX-frequence-acquisition-donnees.jpg)
6. Retrait de la captation de l’intensité
Nous constatons lors de nos tests que la fonction de lecture de l’intensité, mA_DC(), ralentit considérablement la boucle de l’Arduino, à cause du fait qu’elle moyenne sur plusieurs points.
Ce n’est pas le cas des fonctions AnalogRead() (captation des données de tension) et PINA / PINC (captation des données de localisation), qui, elles, sont beaucoup plus rapides.
Nous décidons donc d’enlever la lecture de l’intensité, et de retrouver l’intensité de façon théorique grâce à une loi d’Ohm (I = U/R, avec R la résistance des voitures).
Il est moins précis de retrouver l’intensité de façon théorique que de la mesurer car il y a une incertitude sur la constance de la résistance des voitures. En effet, des effets inductifs et capacitifs font que la loi d’Ohm est ici une approximation. Néanmoins, pour pouvoir avancer, nous prenons le parti de réaliser cette approximation, au moins dans un premier temps.
Nous voici donc prêts à tester un nouveau format de collecte de données, qui ne fait plus intervenir que la localisation des voitures et la tension à leurs bornes.
![[Data Rider] Boucle de l'Arduino](https://blog.businessdecision.com/wp-content/uploads/2025/05/10-data-rider-REX-boucle-de-arduino.jpg)
7. Nouveau format pour la collecte de données
Pour rappel, l’ancien format des lignes était le suivant :
![[Data Rider] Ancien format des lignes de collectes de données](https://blog.businessdecision.com/wp-content/uploads/2025/05/11-data-rider-REX-ancien-format-lignes-1024x224.jpg)
Le nouveau format, sans l’intensité, est désormais celui ci-dessous :
![[Data Rider] Nouveau format des lignes de collectes de données](https://blog.businessdecision.com/wp-content/uploads/2025/05/12-data-rider-REX-nouveau-format-lignes.jpg)
À nouveau, nous examinons la durée moyenne entre l’acquisition de deux lignes… Environ 2 millisecondes ! Nous gagnons un facteur 3 en termes de latence entre deux lignes données, et nous manquons beaucoup moins de jalons sur les signaux de localisation des voitures ! Ce n’est pas encore parfait, mais nous captons suffisamment de données pour globalement identifier les positions des voitures et nous décidons de revenir plus tard sur l’amélioration de ce code à paraître. (Cet article donnera des données chiffrées sur les performances).
Pour continuer le projet et pour le faire avancer, nous nous concentrons alors sur une nouvelle partie : le traitement de nos données dans l’ETL (Extract, Transform, Load). Pourquoi la prochaine étape de cette série d’articles consiste-t-elle à parler de la partie ETL ? Après tout, ce retour d’expérience ne concerne-t-il pas le périmètre de la collecte des données, et non de l’ETL ? En réalité, le développement des opérations à effectuer dans l’ETL nous a mené à une réflexion qui nous a poussés, à nouveau, à modifier la façon dont nous choisissons de collecter les données.
Prochaine étape de la collecte de données IoT : l’étude des opérations à réaliser dans l’ETL et l’influence sur les choix de collecte. À suivre…
>> Retrouvez toute notre actu en temps réel en nous suivant sur LinkedIn <<
Votre adresse de messagerie est uniquement utilisée par Business & Decision, responsable de traitement, aux fins de traitement de votre demande et d’envoi de toute communication de Business & Decision en relation avec votre demande uniquement. En savoir plus sur la gestion de vos données et vos droits.