Le courant moteur est la mesure qui révèle un roulement qui frotte, un bobinage en court-circuit ou une voie d'ESC défaillante sur un banc de moteurs brushless, à condition que la valeur soit juste. Apprenez à choisir une méthode de mesure du courant, dimensionner un shunt pour un moniteur INA228, régler l'échantillonnage pour que la moyenne et les crêtes aient un sens, et enregistrer les deux avec des limites dans une procédure TofuPilot.
Quatre façons de mesurer le courant d'un moteur
Un banc de moteurs de drone dispose en général de quatre lectures de courant. Elles ne se valent pas.
| Méthode | Résolution typique | Bande passante | Étalonnée | Par moteur | Usage |
|---|---|---|---|---|---|
| Shunt + INA228 (I2C, 20 bits) | 0,3 à 0,7 mA avec un shunt de 0,5 à 1 mOhm | Fixée par le temps de conversion (50 µs à 4,12 ms) | Oui, par la tolérance du shunt et l'erreur de gain de l'INA228 | Oui, un shunt par entrée DC | Limites pass/fail |
| Capteur de courant à effet Hall | Dizaines de mA, limitée par l'offset et le bruit | Dizaines à centaines de kHz | Offset qui dérive avec la température et la rémanence | Oui | Isolation galvanique, transitoires rapides |
| Courant de télémétrie de l'ESC | Champ de 0,01 A, précision réelle inconnue | Une trame par moteur et par cycle d'interrogation | Non | Oui | Recoupement, diagnostic terrain |
| Relecture de l'alimentation de banc | Affichage de 1 à 10 mA | Quelques lectures par seconde | Oui, mais moyennée | Non, total de toutes les charges | Contrôle de cohérence du total |
Un shunt lu par un moniteur de précision est la seule option à la fois étalonnée, assez rapide et attribuable à un moteur. Un capteur à effet Hall l'emporte quand il faut une isolation ou la forme d'onde d'un transitoire inférieur à la milliseconde, au prix d'un offset à remettre à zéro avant chaque run. La télémétrie de l'ESC et la relecture de l'alimentation donnent du contexte, pas des mesures sur lesquelles poser des limites.
Sur un ESC 4-en-1, il y a une seule entrée DC pour quatre moteurs. Un shunt sur cette entrée mesure la somme. Pour attribuer le courant à un moteur, faites tourner un moteur à la fois, ou placez le shunt entre l'alimentation et un ESC à une seule voie. Les courants de phase entre ESC et moteur sont des formes d'onde de commutation alternatives, et ce n'est pas là que se place un shunt DC.
Connaître la plage de courant avant de choisir les composants
La plage fixe la valeur du shunt, sa puissance nominale et la gamme du moniteur. Valeurs d'exemple mesurées sur un moteur de taille 3115, 1250 KV (12N14P), sur un bus 6S avec un ESC BLHeli_32 :
| Gaz | Vitesse | Courant sans hélice |
|---|---|---|
| 3 % | ralenti | environ 0,1 A |
| 25 % | 8 350 tr/min | 0,65 A |
| 70 % | 22 600 tr/min | 2,65 A |
| 100 % | 31 000 tr/min | 3,5 à 4,5 A |
Avec une hélice, le même moteur consomme des dizaines d'ampères. Pour une hélice typique en 6S, 60 à 80 A plein gaz est une estimation raisonnable, pas une valeur mesurée. Dimensionnez pour le cas avec hélice si le banc doit un jour en recevoir une, et vérifiez que la résolution couvre toujours les 0,1 A du ralenti.
Dimensionner le shunt
Trois grandeurs décident du shunt : la tension pleine échelle du moniteur, la puissance dissipée dans le shunt et la résolution à faible courant.
L'INA228 mesure la tension différentielle du shunt avec un ADC delta-sigma 20 bits. Dans sa gamme par défaut (ADCRANGE = 0), la pleine échelle est de ±163,84 mV et le LSB de 312,5 nV. L'entrée de tension de bus accepte jusqu'à 85 V, donc une batterie 6S (25,2 V pleine charge) est largement couverte, côté haut comme côté bas.
V_shunt = I x R must stay below 163.84 mV at I_maxP_shunt = I^2 x R shunt power rating >= 2 x P_shuntI_lsb = 312.5 nV / R current resolutionV_burden = I x R voltage the motor no longer seesAppliqué à une crête de 80 A et à un ESC de 100 A :
| Shunt | V à 80 A | P à 80 A | P à 100 A | Résolution | Courant max avant saturation |
|---|---|---|---|---|---|
| 0,5 mOhm | 40 mV | 3,2 W | 5 W | 0,625 mA | 327 A |
| 1 mOhm | 80 mV | 6,4 W | 10 W | 0,3125 mA | 163 A |
| 2 mOhm | 160 mV | 12,8 W | 20 W | 0,156 mA | 81,9 A |
Le shunt de 2 mOhm sature au premier transitoire au-dessus de 82 A et dissipe plus de chaleur qu'un petit shunt ne peut en évacuer. Le shunt de 0,5 mOhm garde une dissipation faible, résout encore le courant de ralenti de 0,1 A à mieux que 1 %, et coûte 40 mV de chute à 80 A, soit 0,18 % d'un bus nominal de 22,2 V. Pour un banc qui ne reçoit jamais d'hélice, un shunt de 5 mOhm donne 25 mV à 5 A pour 0,125 W.
Trois détails décident si la valeur inscrite sur le shunt est celle que vous obtenez :
- Utilisez un shunt quatre fils et des lignes de mesure Kelvin. À 0,5 mOhm, 0,1 mOhm de résistance de soudure ou de contact vissé dans le chemin de mesure fait 20 % d'erreur. Les lignes de mesure vont aux bornes de mesure dédiées, jamais aux cosses de puissance.
- Tenez compte du coefficient de température. Un shunt qui chauffe de 25 °C à 85 °C avec un TCR de 50 ppm/°C varie de 0,3 %. Choisissez un alliage à faible TCR et montez le shunt là où il peut évacuer sa chaleur.
- Faites cheminer la paire de mesure ensemble. Torsadez-la et éloignez-la des fils de phase du moteur, qui portent les fronts de commutation de l'ESC.
Choisir la cadence, le moyennage et ce que signifie une crête
Le courant absorbé par un ESC n'est pas une valeur continue. Il porte une ondulation à la fréquence PWM de l'ESC (des dizaines de kHz), et des transitoires à chaque changement de gaz, parce que le moteur a besoin d'un couple supplémentaire pour accélérer son rotor et son hélice. Trois réglages de l'INA228 décident de ce que vous voyez :
- Temps de conversion (VSHCT, 50 µs à 4,12 ms par conversion). L'ADC delta-sigma intègre sur cette fenêtre, donc l'ondulation PWM se moyenne à l'intérieur d'une conversion.
- Nombre de moyennes (AVG, 1 à 1024 conversions). Le circuit moyenne en interne avant de mettre à jour le registre de résultat.
- Cadence de lecture. L'interrogation I2C depuis Python atteint au mieux quelques centaines de lectures par seconde, avec la gigue du système d'exploitation.
| Objectif | VSHCT | AVG | Période de mise à jour (shunt et bus) | Résultat |
|---|---|---|---|---|
| Courant moyen à gaz constant | 540 µs | 16 | environ 17 ms | Bruit faible, ondulation et pics courts moyennés |
| Transitoires d'accélération visibles | 150 µs | 1 | environ 0,3 ms, limitée par la cadence de lecture | Échantillons plus bruités, crêtes de quelques dizaines de ms capturées |
| Événements inférieurs à la milliseconde | Pas l'INA228 | Sonde à effet Hall sur oscilloscope |
La période de mise à jour est VSHCT x AVG pour chaque voie activée, additionnées : 2 x 540 µs x 16 = 17,3 ms avec shunt et bus convertis. Une crête enregistrée avec ce réglage est la plus haute moyenne sur 17 ms, pas la crête instantanée. C'est la bonne grandeur pour une limite thermique ou de dimensionnement d'alimentation, et la mauvaise pour une limite de contrainte des MOSFET. Indiquez laquelle dans la description de la mesure.
N'interrogez pas plus vite que la mise à jour du registre. Relire la même valeur n'apporte aucune information, et interroger plus lentement que la mise à jour sans moyennage saute des données entre deux lectures, ce qui peut faire passer une ondulation pour un pic ou masquer un vrai pic.
Étape 1 : écrire le plug INA228
Le plug possède le bus I2C et renvoie des nombres et des listes simples. Cet exemple utilise smbus2 sur un hôte Linux doté d'un bus I2C (un ordinateur monocarte, ou un adaptateur USB-I2C exposé en /dev/i2c-N) :
smbus2>=0.4plugs/ina228.py60 lines
import timefrom smbus2 import SMBusREG_CONFIG = 0x00REG_ADC_CONFIG = 0x01REG_VSHUNT = 0x04REG_VBUS = 0x05VSHUNT_LSB = 312.5e-9 # V, ADCRANGE = 0 (+/-163,84 mV)VBUS_LSB = 195.3125e-6 # V# Codes de temps de conversion pour VBUSCT / VSHCT / VTCTCT_CODES = {50: 0, 84: 1, 150: 2, 280: 3, 540: 4, 1052: 5, 2074: 6, 4120: 7}AVG_CODES = {1: 0, 4: 1, 16: 2, 64: 3, 128: 4, 256: 5, 512: 6, 1024: 7}MODE_CONT_SHUNT_BUS = 0xBclass INA228: def __init__(self, bus, address, shunt_ohm): self.address = address self.shunt_ohm = shunt_ohm self.i2c = SMBus(bus) self.i2c.write_i2c_block_data(self.address, REG_CONFIG, [0x80, 0x00]) # reset time.sleep(0.01) self.configure(540, 16) def __del__(self): if hasattr(self, "i2c"): self.i2c.close() def configure(self, conversion_us, averages): ct = CT_CODES[conversion_us] value = (MODE_CONT_SHUNT_BUS << 12) | (ct << 9) | (ct << 6) | (ct << 3) | AVG_CODES[averages] self.i2c.write_i2c_block_data(self.address, REG_ADC_CONFIG, [value >> 8, value & 0xFF]) # Période de mise à jour d'un résultat shunt + bus, sert à cadencer l'échantillonnage self.period_s = 2 * conversion_us * 1e-6 * averages def _read20(self, register, signed): b = self.i2c.read_i2c_block_data(self.address, register, 3) raw = ((b[0] << 16) | (b[1] << 8) | b[2]) >> 4 if signed and raw & 0x80000: raw -= 1 << 20 return raw def read_current(self): return self._read20(REG_VSHUNT, True) * VSHUNT_LSB / self.shunt_ohm def read_bus_voltage(self): return self._read20(REG_VBUS, False) * VBUS_LSB def sample_current(self, duration_s): """Renvoie [times_s, currents_a] échantillonnés au rythme du registre.""" times, currents = [], [] t0 = time.monotonic() while (now := time.monotonic() - t0) < duration_s: times.append(round(now, 4)) currents.append(self.read_current()) time.sleep(self.period_s) return [times, currents]Le courant est calculé à partir du registre de tension shunt et de la valeur du shunt, ce qui garde l'étalonnage dans un seul nombre visible. L'INA228 peut aussi calculer le courant en interne avec son registre SHUNT_CAL. Les deux donnent le même résultat ; la forme directe est plus facile à auditer.
Déclarez-le avec son bus, son adresse et la valeur du shunt dans with:, pour qu'un autre poste ou un shunt remplacé soit un changement de configuration, pas de code :
procedure.yaml21 lines
name: Motor Current Checkversion: 0.1.0execution: workers: 1plugs: - name: Current Monitor key: current_monitor python: plugs.ina228:INA228 scope: station with: bus: 1 address: 0x40 shunt_ohm: 0.0005 - name: Motor Driver key: motor python: plugs.motor:MotorDriver scope: station with: port: /dev/ttyACM0workers: 1 compte sur un banc moteur. TofuPilot exécute par défaut les phases indépendantes en parallèle, et deux phases qui pilotent le même moteur ou lisent le même bus I2C en même temps donnent des résultats sans valeur. Le plug motor est ce qui règle les gaz sur votre banc, par exemple un microcontrôleur qui génère du DShot via un port série USB.
Étape 2 : enregistrer courant moyen et crête avec des limites
Enregistrez les échantillons comme une mesure multidimensionnelle, pour que le dashboard affiche la courbe, et posez les limites sur des agrégations de cette courbe :
procedure.yaml43 lines
main: - name: Current at 25 % Throttle key: current_25 python: phases.current:hold_and_measure timeout: 30s with: throttle_pct: 25 settle_s: 2.0 measure_s: 3.0 measurements: - name: Motor Current 25 % key: motor_current description: INA228, VSHCT 540 us, AVG 16. Peak is the highest 17 ms average. x_axis: legend: Time unit: s y_axis: - legend: Current key: current unit: A aggregations: - type: mean validators: - operator: ">=" expected_value: 0.5 - operator: "<=" expected_value: 0.8 - type: max validators: - operator: "<=" expected_value: 1.2 - name: Bus Voltage key: bus_voltage unit: V validators: - operator: ">=" expected_value: 21.0 - operator: "<=" expected_value: 25.5teardown: - name: Stop Motor python: phases.current:stop_motorLa fenêtre de 0,5 à 0,8 A encadre les 0,65 A mesurés sur un moteur sans hélice. Ce sont des valeurs d'exemple : fixez les vôtres à partir d'un lot de moteurs connus bons, puis resserrez-les avec le Cpk que le dashboard calcule pour la mesure.
phases/current.py22 lines
import timedef hold_and_measure(motor, current_monitor, measurements, log, throttle_pct, settle_s, measure_s): motor.ramp_to(throttle_pct) # Laisser passer le transitoire d'accélération avant de mesurer le courant établi time.sleep(settle_s) times, currents = current_monitor.sample_current(measure_s) measurements.motor_current.x_axis = times measurements.motor_current.y_axis.current = currents aggs = measurements.motor_current.y_axis.current.aggregations aggs.mean = sum(currents) / len(currents) aggs.max = max(currents) measurements.bus_voltage = current_monitor.read_bus_voltage() log.info(f"{len(currents)} samples, mean {aggs.mean:.3f} A, max {aggs.max:.3f} A")def stop_motor(motor): motor.ramp_to(0)La phase de teardown s'exécute même quand une limite échoue ou que la phase dépasse son timeout, donc le moteur revient toujours à zéro. C'est une commodité, pas une fonction de sécurité : le banc a toujours besoin d'un arrêt d'urgence câblé qui coupe la puissance.
Chaque run enregistre alors la courbe, la moyenne, le maximum et la tension de bus avec le numéro de série du moteur. Sur le dashboard, un courant moyen qui monte lentement sur un lot de production désigne les roulements ou les aimants avant que la limite ne soit franchie.
Pourquoi le courant de télémétrie de l'ESC n'est pas une mesure
Les ESC BLHeli_32 renvoient le courant dans leur trame de télémétrie avec un champ de 0,01 A. La résolution du champ ne dit rien de la précision :
- La mesure de l'ESC n'est pas étalonnée unité par unité. Un ESC 4-en-1 mesure le courant avec son propre shunt de faible valeur ou la chute dans les MOSFET, mise à l'échelle par une constante du firmware. Deux ESC du même modèle ne lisent pas la même valeur.
- L'offset domine à faible courant. Sans hélice, le moteur consomme 0,1 à 4,5 A, soit le bas d'une gamme de capteur de 100 A. Des lectures de 0,00 A au ralenti sont courantes.
- La cadence est faible. La télémétrie est demandée un moteur à la fois, donc chaque moteur ne reçoit une trame fraîche qu'une fois par cycle d'interrogation.
Enregistrez le courant de l'ESC comme une mesure distincte sans limites serrées, à côté de la valeur de l'INA228. Un écart important entre les deux signale un problème de câblage ou d'ESC ; il ne décide pas du pass ou du fail.
Pièges courants
Brancher les lignes de mesure sur les cosses de puissance. La résistance de contact entre dans le shunt. Utilisez les bornes Kelvin.
Dimensionner le shunt pour le banc sans hélice, puis monter une hélice. Un shunt de 10 mOhm qui lisait proprement 5 A sature à 16 A et dissipe 64 W à 80 A.
Laisser les phases en parallèle. Deux phases qui commandent le moteur en même temps ruinent les deux lectures. Réglez workers: 1 ou chaînez les phases avec depends_on.
Mesurer pendant le transitoire d'accélération. Une moyenne qui inclut la montée en vitesse n'est pas un courant établi. Attendez la stabilisation.
Appeler crête une moyenne sur 17 ms sans le dire. Écrivez la fenêtre de moyennage dans la description de la mesure.
Poser des limites sur le courant de télémétrie de l'ESC. Il n'est pas étalonné et reste grossier à faible courant. Servez-vous-en pour recouper.
Points clés
- Un shunt câblé en Kelvin et lu par un INA228 est la référence pour le courant moteur ; capteurs Hall, télémétrie d'ESC et relecture d'alimentation sont secondaires.
- Dimensionnez le shunt avec V = I x R sous 163,84 mV, P = I^2 x R avec une marge de puissance de 2x, et une résolution de 312,5 nV / R.
- Le temps de conversion et le moyennage décident si vous enregistrez une moyenne ou une crête, et ce que « crête » veut dire.
- Enregistrez la courbe comme mesure multidimensionnelle, avec des agrégations mean et max qui portent les limites.
- Exécutez les phases moteur une à la fois et arrêtez le moteur en teardown.
Pour une vue d'ensemble des bancs de test de moteurs et d'actionneurs, consultez Motor and Actuator Testing with TofuPilot.
