Ce billet est en cours de rédaction.

1. Introduction

Au moyen d'un Arduino, un boîtier d'assistance au démarrage sera mis au point. Pour ce faire, il sera nécessaire d'analyser en temps réel les signaux émis par différents capteurs situés sur le moteur et d'actionner un moteur pas à pas pour réguler le régime du moteur pendant et juste après le démarrage.

1.1. Capteurs

Traditionnellement, le régime d'un moteur est exprimé en RPM (Rotations Par Minute). Une conversion (division par 60) est donc nécessaire pour considérer le régime du point de vue de l'électronique :

1'400 RPM ≈  24 Hz  régime au ralenti
2'400 RPM =  40 Hz  régime au sol
4'600 RPM ≈  80 Hz  régime de croisière
5'800 RPM ≈ 100 Hz  régime maximal

1.1.1. Principe des capteurs électro-magnétique

1.1.2. Capteur à dents

1.1.3. Capteur compte-tours

2. Matériel et méthodes

2.1. Enregistrement des capteurs

Un oscilloscope Rigol DS1052E (permettant des enregistrements à 50 MHz, mais modifié pour fonctionner à 100 MHz) a été utilisé pour enregistrer les signaux émis par les différents capteurs du moteur directement sur le moteur en marche.

2.2. Boîtier d'assistance au démarrage

Le boîtier est basé sur un Arduino Uno.

2.2.1. Gestion des potentiels

Les mesures des signaux produits par les capteurs ont montré des pics de ±64 V. Il est impensable d'alimenter directement les pins du microcontrôleur avec une telle tension.

Un diviseur de tension a donc été mis en place pour ramener ces différences de potentiel à des valeurs supportables pour l'Arduino.

Par mesure de sécurité, un courant de 100 V en sortie du moteur a été considéré pour un courant de 2 V en entrée du microcontrôleur. L'intensité a été plafonnée à 2 mA, au moyen d'une résistance globale de 50 kΩ calculée grâce à la loi de Ohm :

U = R * I <=> 100 V = 50 kΩ * 2 mA

Quant à la puissance électrique dissipée par les différents composants, il est important de vérifier qu'elle n'excède pas leur spécifications.

En particulier, les éléments critiques du circuit sont ici les résistances de 10 kΩ utilisées qui sont spécifiées pour 1/6 W = 167 mW, la puissance électrique maximale qu'elles sont sensées dissiper (effet Joule) avant de se dégrader.

W = R * I^2 = U^2 / R <=> (2 V * 2 V ) / 10 kΩ = 0.4 mW

Pas de problème, donc, ce d'autant qu'il s'agit d'un courant pulsé et non pas d'un courant continu.

2.3. Analyse des signaux

Les enregistrements enregistrés au format WFM au pied de l'avion avec l'oscilloscope ont été relus (au chaud) grâce au programme WFM Reader.

Un portage sous Mac — réalisé grâce à Wineskin Winery — fut nécessaire pour pouvoir réaliser ce travail sous Mac.

2.3.1. Détermination du régime

Plusieurs méthodes peuvent être envisagées, deux ont été testées. Elles ont en commun l'utilisation les interruptions disponibles sur l'Arduino Uno pour obtenir la meilleure précision :

// SENSOR_INTERRUPT=0 on SENSOR_PIN=2
void setup() {
  attachInterrupt(SENSOR_INTERRUPT, onRisingInput, RISING);
}

Avec cette méthode, l'arduino appellera automatiquement la fonction "onRisingInput()" à chaque fois qu'il notera un flanc montant sur la pin 2.

2.3.1.1. Première version

La première idée (suggérée sur cette page) pour l'implémentation de "onRisingInput()" a consisté à compter les appels :

volatile unsigned int risingCounter = 0;
void onRisingInput() {
  risingCounter++;
}

puis à attendre que le compteur ait atteint une valeur suffisante (par exemple 20 coups) pour diviser le temps écoulé pour obtenir une fréquence.

void loop() {
   static unsigned long previousTime = micros();

   // une mise à jour tous les 20 coups pour plus de précision
   if (risingCounter >= 20) { 
     noInterrupts();
     unsigned long elapsedTime = micros() - previousTime;
     float freq = (1000000.0*risingCounter) / elapsedTime;
     previousTime = micros();
     interrupts();
   }
 }

Logique… mais inopérant, car la mise à jour du régime est alors fonction du régime : à 10 Hz, une mise à jour est réalisée toutes les 2 secondes, à 100 Hz, ce sont cinq mises à jour par seconde.

2.3.1.2. Deuxième version

La solution est venue de la réponse #4 à une question dans un forum.

"Retrolefty" y suggère de ne prendre en compte qu'un intervalle entre deux flancs montants à la fois :

volatile unsigned long risingInterval;

void onRisingInput() {
   static unsigned long startTime;
   static byte firstRise = 1;
   unsigned long now = micros();

   if (firstRise) {
      startTime = now;
      firstRise = 0;
    } else {
      risingInterval = now - startTime;
      first = 1;     
    }
}

Le code de la fonction "onRisingInput()" est un peu plus long, ce qui pourrait problème car pendant son exécution, l'Arduino ne fait rien d'autre (l'appel est bloquant). Avec un appel de fonction, trois affectations, une comparaison et zéro ou une soustraction par appel, les instructions restent peu nombreuses.

D'ailleurs, avec une précision à la microseconde ("micros()"), les résultats sont convaincants entre 10 Hz et 10 kHz, ce qui couvre largement les besoins de cette application.

Dans le loop, il ne reste plus qu'à utiliser l'intervalle. L'implémentation est d'autant plus efficace qu'il est inutile de désactiver les interruptions car une seule opération est suffisante pour calculer la fréquence instantanée :

void loop() {
  float freq = 1000000.0/risingInterval;
  delay(100);
}

Le délai introduit dans le loop permet de contrôler la fréquence de rafraîchissement du régime moteur. Avec 100 ms, presque 10 mises à jour par seconde sont calculées, indépendamment du régime moteur.

2.3.1.1. Lissage du régime moteur

Le défaut majeur de cette solution est sa fragilité : la lecture erronée d'un seul intervalle entre deux flancs montant (quelle qu'en soit l'origine) pourrait conduire à une mauvaise décision dans le code Arduino.

Pour contrer cet dépendance à une mesure unique, une moyenne mobile a été introduite. L'implémentation fait appel à un "tableau circulaire".

float averageFrequency(float value) {
  static float frequencies[] = {0.0, 0.0, 0.0, 0.0, 0.0};
  static unsigned short runningIndex = 0;

  frequencies[runningIndex] = value;
  runningIndex = (runningIndex + 1) % 5;

  return (frequencies[0] + frequencies[1] +  frequencies[2] + frequencies[3] +  frequencies[4]) / 5;
}

Une moyenne sur 5 valeurs a empiriquement été choisie.

Le code de "loop()" se résume donc à un code simple, élégant, fiable et indépendant du régime moteur :

void loop() {
  float freq = averageFrequency(1000000.0/risingInterval);
  delay(100);
}

2.4. Motorisation

À définir.

2.5. Tests

Le fait d'interagir avec un moteur d'avion implique qu'il ne soit pas possible de disposer en tout temps du matériel pour les tests. Il a donc été nécessaire de mettre en place un "mock-up", une tricherie qui fait croire à l'Arduino qu'il a affaire à un moteur d'avion.

Pour ce faire, un générateur d'onde arbitraires Rigol DG-4062 a été configuré pour simuler les impulsions normalement transmises par les capteurs.

2.5.1. Détection du régime

Channel 1 + 2
mode : pulse
freq : de 10 Hz (ralenti) à 100 Hz (régime max)

Channel 1
Vpp : +10 V
offset : +5 VDC
duty : 0.5 %

Channel 2
Vpp : -10 V
offset : -5 VDC
duty : 99.5 %

mockup-pre-diviseur-tension.bmp

Figure 2.1 — Signal émis par le générateur d'ondes arbitraires pour simuler les pics du capteur de régime. Enregistrement réalisé avant le diviseur de tension. Les pics mesurent ±5.2 V. À comparer avec la Figure 3.2.

mockup-post-diviseur-tension.bmp

Figure 2.2 — Signal émis par le générateur d'ondes arbitraires pour simuler les pics du capteur de régime. Enregistrement réalisé après le diviseur de tension. Notez la diminution du rapport signal / bruit par rapport à la Figure 2.1. Les pics mesurent ±100 mV.

2.5.1. Simulation des accélérations

Utilisation du mode sweep du générateur d'ondes :

mode : sinus
phase : 180°
Vpp : +10 V
offset : -5 V
wait : 1 s
sweep : 3 s
wait : 1 s
return : 200 ms

3. Résultats

3.1. Enregistrements des signaux des capteurs

Différents signaux émis par les capteurs du moteur ont été enregistrés.

Les traces montrent des pics négatifs puis positifs d'une amplitude totale de ??? V.

20131223-enregistrement.jpg

Figure 3.1 — L'oscilloscope DS-1052E raccordé au moteur Rotax 912 ULS de l'AvidFlyer HB-YMX. Cliché pris le 23 décembre 2013 à l'aéroport de Lausanne Blécherette.

3.1.1. Compte-tours

Une impulsion par tour est produite. Elle a été lue directement à l'entrée du compte-tours du tableau de bord.

03_-_compte-tours_-_regime-isole.png

Figure 3.2 — Enregistrement du signal entrant dans le compte-tours au régime de croisière.

3.1.2. Capteur à dents

Le signal émis par le disque denté a été enregistré dans trois conditions différentes :

3.1.2.1. En l'absence de combustion, entraîné par le seul démarreur électrique.

Les 23 dents engendrent 23 pics, suivis d'une absence de pic : la 24e dent absente marquant le tour complet.

Un cycle complet dure quelques 160 ms et les pics mesurent un peu plus de 8 V.

01_-_capteur_-_demarreur-sans-combustion-detail.bmp

Figure 3.3 — Enregistrement du signal issu du capteur à dents. Le moteur est entraîné par le démarreur en l'absence d'injection d'essence, il n'y a pas d'explosion. Notez l'effet des compressions des cylindres qui ralentissent la rotation, induisant un espacement des pics et une diminution de leur amplitude.

Les 7 premiers pics plus intenses et plus proches correspondent au déplacement rapide des deux pistons ; les 5 suivants correspondent au moment de la combustion d'une paire de cylindres. On pourrait presque entendre le tchuf-tchuf du moteur sur le point de démarrer.

En absence d'injection, le moteur ne démarre pas à proprement parler : il n'y a pas de combustion.

3.1.2.2. Au ralenti (600 RPM)

02_-_capteur_-_ralenti.bmp

Figure 3.4 — Enregistrement issu du compteur à dents, moteur allumé, régime au ralenti. Notez la diminution des fluctuations engendrées par la combustion avant la moitié et la fin d'un cylce (c.f. Figure 3.3).

Les mêmes observations peuvent être faites. Les combustions des paires de cylindres lissent les crêtes, mais les pics sont facilement identifiables, particulièrement la dent manquante.

Un cycle complet dure 35 ms avec des pics à ±22 V, environ.

3.1.2.3. Au régime de croisière (2500 RPM)

03_-_capteur_-_regime.bmp

Figure 3.5 — Enregistrement issu du compteur à dents, moteur allumé, régime de croisière. À comparer avec la Figure 3.4.

Pas de surprises avec le régime de croisière : tout reste stable avec une amplitude et une fréquence supérieures.

Un cycle complet dure 22 ms avec des pics de ±35 V.

3.2. Montage du boîtier

schema-boitier.png

Figure 3.6 — Schéma (temporaire) du montage électrique du boîtier d'aide au démarrage. La LED1 est utilisée pour le débuggage en permettant la visualisation du régime tel que perçu par le boîtier. Les résistances R1 et R2 forment le diviseur de tension. L'interrupteur général S2 est secondé par l'interrupteur S1 qui désactive la motorisation de la poignée des gazes.

4. Discussion

- Analyser de façon critique dans la perspective d'un futur projet :
  - les résultats
  - les méthodes utilisées
  - les apprentissages réalisés
  - les difficultés rencontrées 

5. Conclusion

- Répondre à la question : "Et maintenant ?"
- Ouvrir vers de nouvelles directions
- Suggérer des considérations qui vont au-delà du travail réalisé ici