BLDC hall-sensors als positie-encoders gebruiken - Deel 3
Een Teensy 3.5 microcontroller gebruiken om positie, richting en afstand te berekenen
De volgende informatie is bedoeld om te helpen bij het interpreteren van de logische uitgang van hall-sensors voor het bepalen van positie, richting en snelheid. Hoewel de uitgang ook kan worden gebruikt voor motor-commutatie, wordt dat aspect van de werking van BLDC-motoren hier niet uitgelegd.
Zie Deel 1 en Deel 2 van deze reeks blogs om dit project tot aan hier opnieuw te bekijken.
Overzicht
Als de drie sensorsignalen van een Hall-sensor in een BLDC naar een microcontroller worden gevoed, kunnen ze worden verwerkt als een driekanaals encoder. De gegevens kunnen worden weergegeven of gebruikt om een pulstelling, de rotatierichting en het gemiddelde aantal omwentelingen per minuut (RPM) te bepalen. Het RPM wordt gemiddeld om een soepele vooruitgang in de weergegeven waarden te creëren.
PJRC Teensy 3.5 Ontwikkelingsbord
Het PJRC Teensy 3.5 ontwikkelingsbord van SparkFun (1568-1464-ND) heeft meer dan voldoende digitale interrupts voor de drie signaalingangen van de hall-sensors en heeft voorgesoldeerde stiftlijsten. De Teensy 3.5 is krachtig genoeg om veel extra taken uit te kunnen voeren, dankzij een groot aantal extra I/O-kanalen en kan worden gebruikt voor datalogging met de ingebouwde SD-kaart.
Afbeelding 1: Het Teensy 3.5 evaluatiebord van SparkFun Electronics. (Bron afbeelding: SparkFun Electronics)
Sensoruitgang en PJRC Teensy 3.5 op een breadboard
Gebruik een breadboard (438-1045-ND of dergelijke) en plaats de Teensy 3.5 met de USB-connector naar rechts en de bovenste stiftlijstpennen in de eerste rij breadboard-gaten boven de partitie (Afbeelding 2). Dit geeft ruimte voor het aansluiten van de sensoruitgangen op de Teensy I/O.
Afbeelding 2: Breadboard met Teensy 3.5 ontwikkelingsbord en draadbrugverbindingen. (Bron afbeelding: DigiKey)
Gebruik massieve draadbruggen (BKWK-3-ND) voor alle breadboard-verbindingen. Sluit de positieve (+) aansluiting van een voeding van 5 V, 1 A aan op de bovenste of onderste positieve voedingsrail van het breadboard; sluit dan de negatieve (-) voedingsaansluiting aan op de bovenste of onderste negatieve voedingsrail. Sluit de positieve (rood) en negatieve (zwart) aansluitingen van de hall-sensorconnector aan op respectievelijk de positieve en negatieve rail van het breadboard; sluit dan de drie sensoraansluitingen van de connector aan op de Teensy 3.5 op pinnen 2, 3 en 4 in willekeurige volgorde.
De sensoruitgang is actief laag wat betekent dat de uitgang wanneer getriggerd, met de negatieve stroomrail is verbonden. Wanneer hij niet getriggerd is, moet de sensoruitgang 'omhoog worden getrokken' naar de positieve stroomrail om twee gedefinieerde toestanden te bewerkstelligen. Installeer drie 4 KΩ – 8 KΩ weerstanden in het breadboard. Deze worden gebruikt om sensoruitvoer 'omhoog te trekken' (Afbeelding 2).
Sluit de Teensy 3.5 aan op een computer met een Micro-USB-B naar standaard A-kabel.
Software
De Teensy 3.5 is compatibel met het Arduino Integrated Development Environment (IDE) voor programmeringsdoeleinden. De IDE- en Teensyduino-add-ons zijn online verkrijgbaar. Volg de installatieprocedures op https://www.pjrc.com/teensy/td_download.html om door te gaan.
De onderstaande programmeringsvoorbeeldcode gebruikt drie hardware-interrupts om veranderingen van de hall-sensoruitgangen te bewaken (stijgende en vallende randen). Als er een interrupt optreedt, worden de verstreken-tijdklok van de Teensy 3.5 en twee van de drie ingangspinnen gelezen. De sensorwaarden worden vergeleken om de rotatierichting te bepalen en dan worden andere berekeningen gemaakt om het aantal pulsen en het gemiddelde RPM te bepalen. De tijd tussen interrupts wordt berekend door de huidige klokwaarde te vergelijken met de opgeslagen klokwaarde van het vorige interrupt.
Er zijn vier waarden beschikbaar om serieel te printen in de void loop. Plaats of verwijder commentaar op coderegels om de seriële printfunctie te deactiveren of te activeren; download de code dan naar de Teensy en lanceer de seriële monitor om de live-data te zien. Laat de BLDC-motor draaien om de veranderingen in de waarden van de printmonitor te bekijken.
Let op: Seriële printfuncties vertragen de microcontroller. De I/O-interrupts veroorzaken het stoppen en omhoog springen van de weergegeven waarden omdat het seriële printproces per definitie steeds wordt onderbroken als een ingangspin van status verandert. Controleer of alle seriële printfuncties van de code in commentaar zijn veranderd en zijn gedeactiveerd als de weergavefunctie niet wordt gebruikt.
Copy/* 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 functie (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; }
Let op: Programmateurs kunnen in de verleiding komen om herhaalde interruptfunctiecode af te scheiden in een aanvullende functie om het algehele programma te vereenvoudigen. Dat kan er echter toe leiden dat de aanvullende functie wordt onderbroken en dat de waardeveranderingen tussen berekeningen datafouten opleveren. Zoals we al gezien hebben in de breadboarding-stappen en in de code, heeft de volgorde van de sensoringangen alleen invloed op het bepalen van de rotatierichting. Verwijder het commentaar van de seriële-printregel met betrekking tot de variabele "direct" om de waarde op de monitor te zien. Controleer of de waarde 1 of -1 blijft, afhankelijk van de richting waarin je het wiel draait. Als de waarde afwijkt, wissel dan de "CW" en "CCW" om in de ternaire code in de bijbehorende interruptfunctie om de uitgang te corrigeren.
Samenvatting
De BLDC Hall-sensors zijn nu geconfigureerd als een driekanaals encoder met lage resolutie die nauwkeurige gegevens kan leveren om te helpen bij navigatie en wielpositiedetectie zonder dat hun primaire motorbesturingsfunctie wordt beperkt. Sommige BLDC-controllers gebruiken alleen back-EMF voor het bepalen van de positie van spoel en magneet zodat de uitgangen van de Hall-sensors volledig beschikbaar zijn voor navigatie en positiedetectie. De sensors zijn hoe dan ook van meer waarde voor de gebruiker dan alleen motorbesturing.
Aanvullend documentatiemateriaal:
Arduino IDE: http://www.arduino.cc/en/Main/Software
Teensyduino: https://www.pjrc.com/teensy/td_145/TeensyduinoInstall.exe
Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.
Visit TechForum




