Utiliser des capteurs à effet Hall BLDC comme codeurs de position – 3e partie

Utiliser un microcontrôleur Teensy 3.5 pour calculer la position, la direction et la distance

Les informations suivantes sont destinées à faciliter l'interprétation de la sortie logique des capteurs Hall afin de déterminer la position, la direction et la vitesse. Même si la sortie peut être utilisée pour la commutation de moteurs, cet aspect du fonctionnement des moteurs BLDC n'est pas abordé ici.

Consultez la 1re partie et la 2e partie de cette série d'articles de blog pour avoir une vue d'ensemble du projet jusqu'ici.

Présentation

Lorsque les trois sorties de capteurs à effet Hall dans un BLDC sont transmises à un microcontrôleur, les signaux peuvent être traités comme un codeur à trois canaux. Les données peuvent être affichées ou utilisées pour déterminer un nombre d'impulsions, le sens de rotation et le nombre moyen de tours par minute (tr/min). Le nombre moyen de tours par minute est établi pour créer une progression régulière des valeurs affichées.

Carte de développement PJRC Teensy 3.5

La carte de développement PJRC Teensy 3.5 de SparkFun (1568-1464-ND) présente suffisamment d'interruptions numériques pour prendre en charge les trois entrées de signal provenant des capteurs Hall. Elle est fournie avec des embases soudées. La carte Teensy 3.5 est suffisamment puissante pour exécuter de nombreuses tâches supplémentaires grâce à des canaux E/S supplémentaires et peut être utilisée pour l'enregistrement de données au moyen de la carte SD intégrée.

Figure 1 : Carte d'évaluation Teensy 3.5 de SparkFun Electronics. (Source de l'image : SparkFun Electronics)

Montage d'essai de la sortie de capteur et de la carte PJRC Teensy 3.5

En utilisant un montage d'essai (438-1045-ND ou modèle similaire), positionnez la carte Teensy 3.5 avec le connecteur USB à droite et les broches de l'embase supérieure insérées dans la première rangée de trous du montage d'essai au-dessus de la séparation (Figure 2). Cela permet d'avoir de la place pour la connexion des sorties de capteurs à l'E/S de la carte Teensy.

Figure 2 : Montage d'essai avec carte de développement Teensy 3.5 et fils de raccordement. (Source de l'image : DigiKey Electronics)

Utilisez des fils de raccordement pleins (BKWK-3-ND) pour réaliser toutes les connexions du montage d'essai. Connectez la sortie positive (+) d'une alimentation de 5 V, 1 A au rail d'alimentation positif supérieur ou inférieur du montage d'essai, puis connectez la sortie négative (-) au rail d'alimentation négatif supérieur ou inférieur. Connectez respectivement les sorties positive (rouge) et négative (noire) du connecteur de capteur Hall aux rails positif et négatif du montage d'essai, puis connectez les trois sorties de capteurs du connecteur à la carte Teensy 3.5, aux broches 2, 3 et 4 (dans n'importe quel ordre).

La sortie de capteur est active basse, c'est-à-dire qu'en cas de déclenchement, la sortie est connectée au rail d'alimentation négatif. En l'absence de déclenchement, une excursion haute de la sortie de capteur doit être effectuée vers le rail positif pour établir deux états logiques définis. Insérez trois résistances 4 kΩ – 8 kΩ dans le montage d'essai afin de les utiliser comme résistances d'excursion haute pour la sortie de capteur (Figure 2).

Connectez la carte Teensy 3.5 à un ordinateur au moyen d'un câble USB micro B vers USB standard A.

Logiciel

La carte Teensy 3.5 est compatible avec l'environnement de développement intégré (IDE) Arduino à des fins de programmation. L'IDE et le module d'extension Teensyduino sont disponibles en ligne. Suivez les procédures d'installation indiquées sur le site https://www.pjrc.com/teensy/td_download.html pour continuer.

Le code de programmation d'exemple ci-dessous utilise trois interruptions matérielles pour surveiller toute modification (fronts de montée et de descente) des sorties de capteurs Hall. Lorsqu'une interruption se produit, la lecture de l'horloge de temps écoulé de la carte Teensy 3.5 et de deux des trois broches d'entrée est effectuée. Les valeurs des capteurs sont comparées pour déterminer le sens de rotation, puis d'autres calculs sont effectués pour déterminer le nombre d'impulsions et le nombre moyen de tours par minute. Le temps entre les interruptions est calculé en comparant la valeur d'horloge actuelle à la valeur d'horloge stockée lors de l'interruption précédente.

Quatre valeurs sont disponibles pour la fonction serial print (impression caractère par caractère) à l'intérieur de la fonction void loop. Ajoutez ou supprimez des commentaires aux lignes de code pour activer ou désactiver la fonction serial print, puis téléchargez le code sur la carte Teensy et lancez le moniteur série pour voir les données en direct. Faites tourner le moteur BLDC pour observer les modifications des valeurs dans le moniteur d'impression.

Remarque : les fonctions serial print ralentissent le microcontrôleur. Les interruptions E/S provoquent une interruption et un saut des valeurs affichées car, par définition, le processus d'impression caractère par caractère est interrompu chaque fois qu'une broche d'entrée change d'état. Si la fonction d'affichage n'est pas utilisée, assurez-vous de supprimer les commentaires des fonctions serial print.

Copier/* BLDC Hall Sensor read and calculation program for Teensy 3.5 in the Arduino IDE (Ver.1). DigiKey*/ /***************************** Variables *********************************/ #define CW 1 // Assign a value to represent clock wise rotation #define CCW -1 // Assign a value to represent counter-clock wise rotation bool HSU_Val = digitalRead(2); // Set the U sensor value as boolean and read initial state bool HSV_Val = digitalRead(3); // Set the V sensor value as boolean and read initial state bool HSW_Val = digitalRead(4); // Set the W sensor value as boolean and read initial state int direct = 1; // Integer variable to store BLDC rotation direction int pulseCount; // Integer variable to store the pulse count float startTime; // Float variable to store the start time of the current interrupt float prevTime; // Float variable to store the start time of the previous interrupt float pulseTimeW; // Float variable to store the elapsed time between interrupts for hall sensor W float pulseTimeU; // Float variable to store the elapsed time between interrupts for hall sensor U float pulseTimeV; // Float variable to store the elapsed time between interrupts for hall sensor V float AvPulseTime; // Float variable to store the average elapsed time between all interrupts float PPM; // Float variable to store calculated pulses per minute float RPM; // Float variable to store calculated revolutions per minute /***************************** Setup *********************************/ void setup() { // Set digital pins 2, 3 and 4 as inputs pinMode(2, INPUT); pinMode(3, INPUT); pinMode(4, INPUT); // Set digital pins 2, 3 and 4 as interrupts that trigger on rising and falling edge changes. Call a function (i.e. HallSensorU) on change attachInterrupt(digitalPinToInterrupt(2), HallSensorU, CHANGE); attachInterrupt(digitalPinToInterrupt(3), HallSensorV, CHANGE); attachInterrupt(digitalPinToInterrupt(4), HallSensorW, CHANGE); // Initialize the print monitor and set baud rate to 9600 Serial.begin(9600); } /*************************** Main Loop ******************************/ void loop() { if ((millis() - prevTime) > 600) RPM = 0; // Zero out RPM variable if wheel is stopped //Serial.print(HSU_Val); Serial.print(HSV_Val); Serial.println(HSW_Val); // Display Hall Sensor Values //Serial.println(direct); // Display direction of rotation //Serial.println(pulseCount); // Display the pulse count Serial.println(RPM); // Display revolutions per minute } /************************ Interrupt Functions ***************************/ void HallSensorW() { startTime = millis(); // Set startTime to current microcontroller elapsed time value HSW_Val = digitalRead(4); // Read the current W hall sensor value HSV_Val = digitalRead(3); // Read the current V (or U) hall sensor value direct = (HSW_Val == HSV_Val) ? CW : CCW; // Determine rotation direction (ternary if statement) pulseCount = pulseCount + (1 * direct); // Add 1 to the pulse count pulseTimeW = startTime - prevTime; // Calculate the current time between pulses AvPulseTime = ((pulseTimeW + pulseTimeU + pulseTimeV)/3); // Calculate the average time time between pulses PPM = (1000 / AvPulseTime) * 60; // Calculate the pulses per min (1000 millis in 1 second) RPM = PPM / 90; // Calculate revs per minute based on 90 pulses per rev prevTime = startTime; // Remember the start time for the next interrupt } void HallSensorV() { startTime = millis(); HSV_Val = digitalRead(3); HSU_Val = digitalRead(2); // Read the current U (or W) hall sensor value direct = (HSV_Val == HSU_Val) ? CW : CCW; pulseCount = pulseCount + (1 * direct); pulseTimeV = startTime - prevTime; AvPulseTime = ((pulseTimeW + pulseTimeU + pulseTimeV)/3); PPM = (1000 / AvPulseTime) * 60; RPM = PPM / 90; prevTime = startTime; } void HallSensorU() { startTime = millis(); HSU_Val = digitalRead(2); HSW_Val = digitalRead(4); // Read the current W (or V) hall sensor value direct = (HSU_Val == HSW_Val) ? CW : CCW; pulseCount = pulseCount + (1 * direct); pulseTimeU = startTime - prevTime; AvPulseTime = ((pulseTimeW + pulseTimeU + pulseTimeV)/3); PPM = (1000 / AvPulseTime) * 60; RPM = PPM / 90; prevTime = startTime; } 

Remarque : les programmeurs peuvent être tentés de fragmenter le code de fonction d'interruption répétitive en une fonction supplémentaire pour simplifier le programme dans son ensemble. Cette opération peut provoquer l'interruption de la fonction supplémentaire et la modification des valeurs entre les calculs, ce qui peut entraîner des erreurs de données. Comme il a été indiqué dans les étapes relatives au montage d'essai et dans le code, l'ordre des entrées de capteur a un effet uniquement sur la détermination du sens de rotation. Supprimez les commentaires de la ligne de fonction serial print associée à la variable « direct » pour voir la valeur dans le moniteur d'affichage. Vérifiez que la valeur reste 1 ou -1 en fonction du sens dans lequel vous faites tourner la roue. En cas d'écart, inversez les valeurs « CW » et « CCW » dans le code ternaire dans la fonction d'interruption correspondante pour corriger la sortie.

Résumé

Les capteurs Hall BLDC sont maintenant configurés sous forme de codeur à trois canaux basse résolution, capable de fournir des données exactes pour faciliter la navigation et la détection de position de roue sans entraver la fonction principale de commande du moteur. Certains contrôleurs BLDC utilisent uniquement la force contre-électromotrice pour déterminer la position de la bobine et de l'aimant, laissant les sorties de capteurs Hall uniquement à la navigation et à la détection de position. Dans tous les cas, les capteurs ont plus de valeur pour l'utilisateur que la simple commande du moteur.

Ressources supplémentaires :

IDE Arduino : http://www.arduino.cc/en/Main/Software

Teensyduino : https://www.pjrc.com/teensy/td_145/TeensyduinoInstall.exe

À propos de l'auteur

Image of Don Johanneck

Don Johanneck, développeur de contenu technique chez DigiKey, travaille dans l'entreprise depuis 2014. Occupant ce poste depuis peu, il est responsable de la rédaction des descriptions vidéo et du contenu produit. Don a obtenu sa licence en sciences appliquées en technologies électroniques et systèmes automatisés du Northland Community & Technical College dans le cadre du programme de bourses de DigiKey. Il aime le radiomodélisme, la restauration de machines anciennes et le bricolage.

More posts by Don Johanneck
 TechForum

Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.

Visit TechForum