Vous êtes sur la page 1sur 3

Accueil Cours Exercices Ressources À propos

Cours > Système embarqué > Transmission numérique > Collecte de données sur Arduino

Collecte de données
Une fois que l'on a réussi à communiquer avec les capteurs, depuis l'Arduino, pour obtenir le résultat de leurs
mesures, plusieurs questions se posent par rapport à ce que l'on va effectivement collecter comme données.
Cette phase va préparer l'étape de communication de la chaine de transmission, en déterminant quelles seront
les données transmises par l'Arduino vers l'extérieur.
Navigation

Agrégation de données Introduction


Chaine d'information
La première chose qu'il faut évidemment faire, c'est d'agréger les données qui proviennent des différents Transmission du signal
capteurs. Il s'agit de toutes les stocker dans une seule et même structure, pour pouvoir les manipuler en une LM35/DHT11
seule entité. On ajoute typiquement un timestamp à une telle structure, c'est-à-dire une information permettant Collecte de données
d'identifier à quel moment les données ont été mesurées.

Dans le sketch, il faut d'abord définir une nouvelle structure qui va permettre d'agréger les différentes données.
Elle va contenir quatre champs pour stocker le timestamp et les données des capteurs.

1 typedef struct {
2 unsigned long timestamp;
3 float temperature;
4 byte humidity;
5 bool soundDetected;
6 } measure;

On prévoit également une fonction createMeasure pour créer un nouvel agrégat à partir des mesures
individuelles. Concernant le timestamp, il n'y a pas moyen de connaitre l'heure actuelle sur l'Arduino sans lui
connecter une horloge externe. On va donc simplement utiliser la fonction prédéfinie millis qui donne le nombre
de millisecondes écoulées depuis que le sketch a été démarré sur l'Arduino. On ne pourra donc pas savoir quand
la mesure a été faite dans l'absolu, mais uniquement en relatif, par rapport au démarrage du sketch.

1 measure createMeasure(float t, byte h, bool s) {


2 measure m { millis(), t, h, s };
3 return m;
4 }

Prise de mesure

Maintenant que l'on est capable de rassembler des mesures provenant de plusieurs capteurs, il faut déterminer
quand ils seront interrogés et s'ils le seront tous en même temps et à même fréquence, ou non. La figure 17
montre les transferts de données entre les différents éléments de notre système. On a d'abord la deuxième étape
de la chaine de transmission qui ramène les mesures faites par les capteurs vers l'Arduino, qui les collecte et
traite. Vient ensuite la troisième étape qui va transférer les données agrégées par l'Arduino vers une Raspberry
Pi.

Figure 17. Les données collectées par les capteurs sont collectées par l'Arduino qui les traite et agrège, avant
qu'elles soient récupérées par la Raspberry Pi.

Chacune des quatre transmissions de données présentées sur la figure 17 peut se faire à son propre rythme. Par
exemple, on pourrait prendre une mesure de la température toutes les quinze secondes, de l'humidité relative
toutes les dix minutes, et vérifier si le niveau sonore dépasse le seuil configuré toutes les secondes. Les données
agrégées seraient ensuite communiquées à la Raspberry Pi une fois par minute.

Une des tâches qui doit être réalisée sur l'Arduino est donc la coordination de tous ces flux de données. Cette
carte électronique n'offrant pas de support permettant d'exécuter plusieurs tâches en parallèle, il va falloir tout
réaliser dans la même fonction boucle principale. Ce que l'on va dès lors faire, c'est exécuter un code toutes les
secondes et, à l'aide de tests, vérifier s'il faut soit interroger un capteur, soit envoyer les dernières mesures vers la
Raspberry Pi.
1 int tick = 0;
2 float temperature;
3 byte humidity;
4 bool soundDetected;
5
6 void loop() {
7 if (tick % 15 == 0) {
8 temperature = getTemperature();
9 }
10 if (tick % 600 == 0) {
11 humidity = getHumidity();
12 }
13 soundDetected = isSoundDetected();
14
15 if (tick % 60 == 0) {
16 measure m = createMeasure(temperature, humidity, soundDetected);
17 sendMeasure(m);
18 }
19
20 tick++;
21 delay(1000);
22 }

Dans ce sketch, on mémorise donc la dernière mesure qui a été faite par chacun des capteurs, dans les trois
variables globales temperature, humidity et soundDetected. La variable tick, incrémentée de un toutes les
secondes, permet de gérer les demandes de mesure aux capteurs. Les données agrégées sont envoyées à la
Raspberry Pi toutes les minutes, grâce à la fonction sendMeasure.

Historique

Les fréquences des différentes transmissions de données n'étant pas les mêmes, certaines demandes de mesure
faites dans le sketch présenté plus haut sont clairement inutiles. Puisqu'il ne faut envoyer les données agrégées
qu'une seule fois par minute à la Raspberry Pi, les capteurs pourraient également n'être interrogés que toutes les
minutes.

Néanmoins, il se peut qu'il soit nécessaire de prendre certaines mesures plus souvent que d'autres, même si elles
sont communiquées à la Raspberry Pi moins régulièrement. Il faut donc que l'Arduino envoie un historique des
mesures faites depuis la dernière communication Arduino-Raspberry Pi. Le principal avantage de cette façon de
procéder est que toutes les données mesurées seront communiquées à la Raspberry Pi, qui pourra ensuite les
traiter et les analyser. Le principal désavantage est l'alourdissement de la communication Arduino-Raspberry Pi,
dû à l'augmentation de la quantité de données transférées.

Voyons ce que cela impliquerait comme modifications sur le sketch, si on voulait transférer l'historique pour la
température. La première chose à adapter est la structure définissant une mesure. Comme on prend une mesure
de température toutes les quinze secondes, il faut en mémoriser quatre, puisque les transferts vers la Raspberry
Pi se font une fois par minute. Il faut également modifier la fonction createMeasure.

1 typedef struct {
2 unsigned long timestamp;
3 float temperature[4];
4 byte humidity;
5 bool soundDetected;
6 } measure;
7
8 measure createMeasure(float t[4], byte h, bool s) {
9 measure m;
10 memcpy(m.temperature, t, 4 * sizeof(float));
11 m.humidity = h;
12 m.soundDetected = s;
13 return m;
14 }

Enfin, il faut modifier la manière de stocker les températures récupérées du capteur. Elles seront stockées dans
les cases successives du tableau temperature, une des variables globales que l'on a modifiée.

1 int tick = 0;
2 float temperature[4];
3 byte humidity;
4 bool soundDetected;
5
6 void loop() {
7 if (tick % 15 == 0) {
8 temperature[tick % 4] = getTemperature();
9 }
10
11 // [...]
12 }

Moyenne de mesures

Une autre façon de faire, pour prendre en compte plusieurs mesures, mais tout en ne les communiquant pas
toutes, consiste à calculer une moyenne de plusieurs mesures. L'idée est de n'envoyer à la Raspberry Pi, toutes
les minutes, que la moyenne des mesures qui ont été réalisées depuis la dernière fois qu'elle a reçu des données
de l'Arduino. Tout d'abord, on va reprendre les définitions initiales de la structure measure et de la fonction
createMeasure, présentées à la section 2.4.1. Ensuite, il faut adapter la fonction boucle principale, pour qu'elle
calcule la somme des quatre dernières mesures de température et la divise par quatre au moment de
communiquer les informations à la Raspberry Pi.

1 int tick = 0;
2 float sumTemperature;
3 byte humidity;
4 bool soundDetected;
5
6 void loop() {
7 if (tick % 15 == 0) {
8 sumTemperature += getTemperature();
9 }
10 if (tick % 600 == 0) {
11 humidity = getHumidity();
12 }
13 soundDetected = isSoundDetected();
14
15 if (tick % 60 == 0) {
16 measure m = createMeasure(sumTemperature / 4, humidity, soundDetected);
17 sendMeasure(m);
18
19 sumTemperature = 0;
20 }
21
22 tick++;
23 delay(1000);
24 }

 Précédent Suivant 

UKO, 2000–2021. Suivez-nous :

Vous aimerez peut-être aussi