Positioneren met een hall-sensor

Gepost door Jeroen Vreuls op woensdag 10 november 2021 22:40

Inleiding

Hall-sensoren worden voor veel doeleinden gebruikt onder andere in de industrie, automotive en medisch.

  • Industrie: detectie van snelheid en omwentelingen per minuut (RPM), toerenteller, teller opnemer, debietmeting, borstelloze gelijkstroom (DC), motorcommutatie, motor en ventilatorregeling, robotica controle, het meten van stroom, hoekmeting, enzovoort.
  • Automotive: positie van een nokkenas bepalen, het meten of een wiel gaat blokkeren (ABS) bij het remmen, bij ontstekingssystemen van een brandstofmotor, cabriodak positie, elektrische raamlift.
  • Medisch: motorassemblages operatiekamer, controle medicatieafgifte.

Positioneren van een as

Ik ga een hall-sensor gebruiken voor het positioneren van een as. Meestal wordt dit met een encoder gedaan, maar het kan ook met een hall-sensor. Alleen moet er wel een flinke vertraging achter de motor zitten. Alleen de motoras ermee positioneren gaat niet werken, omdat dat met één hall-sensor totaal niet precies is. Dan kun je in principe alleen 360 graden halen, maar zet je achter de motor een grote vertraging dan wordt het een ander verhaal. Dat heb ik in het voorbeeld ook gedaan en dan wordt het vrij precies, hoe groter de vertraging is hoe beter het is.

Honeywell SS411-T3Honeywell SS411-T3

De hall-sensor die gebruikt is, is van het bipolaire type. Dat wil zeggen dat de sensor geset en gereset wordt door de noord en zuidkant van een magneet. De magneet is een rond type met een noord- en zuidkant, deze magneet is op de motoras gemonteerd.

Het is een sensor van Honeywell, de SS411-T3. De voeding van de sensor heeft een vrij groot voedingsspanningsbereik, tussen de 3,8 en 30 V DC. De sensor mag continu 20 mA sinken met een absoluut maximum van 50 mA.

In het voorbeeld gaan we de sensor met 5 V DC voeden. De sensor wordt gevoed uit de controllerprint en de uitgang van de sensor komt direct op een ingang van de controllerprint.

Zoals je kunt zien is pin 1 de plus, pin 2 is de massa en pin 3 is de uitgang van de sensor.

Het principeschemaHet principeschema

In het principeschema zie je dat de sensor en de motor gekoppeld zijn. De sensor is een sink type, dat wil zeggen dat de belasting naar de GND getrokken wordt, dit wordt gedaan middels een pull-up weerstand van 1 kΩ aan 5 V DC. Op deze manier is de uitgang van de sensor hoog en dus ook de ingang van de controller. Als nu de magneet langs de sensor draait, zal de sensor uitgang laag en weer hoog worden. Hierdoor komt er dus een blokgolf op de ingang van de controller te staan. En daar kan in de software bijvoorbeeld weer mee geteld worden om naar een bepaalde positie te gaan.

Hieronder een voorbeeld van de blokgolf.

De blokgolfDe blokgolf

Je kunt zien dat als de motor langzaam draait de frequentie van het uitgangssignaal lager is dan bij een hoger toerental. Op deze manier kun je dus bijvoorbeeld ook het toerental van de motor meten en constant houden bij zwaardere belastingen.

De motor

De hall-sensor zit achterop de motor gemonteerd. De motor moet dan wel een doorlopende as hebben, anders wordt het moeilijk monteren. Het printje is vast gesoldeerd op de motoraansluitingen, daar zit ook de bedrading op gemonteerd voor de motor en de hall-sensor. Daar komen dus vijf draden af. Deze motor had ik nog liggen en wilde daar eens mee experimenteren. Ik heb wel de standaard hall-sensor vervangen voor de SS411-T3, omdat de oude sensor stuk was.

Motor met sensorprintMotor met sensorprint

Hier kun je zien hoe het een en ander gemonteerd is op de motor. De magneet zit in een kunststof huisje en is op de as gelijmd. Op het printje zit ook een connector (hier niet getekend) waar de bedrading op zit.

Motor met vertragingMotor met vertraging

Zoals je kunt zien is het een drietraps planetaire vertraging met een verhouding van 110,592 : 1. Hoe ik daar aan komen ben leg ik hieronder uit. Het zonnewiel van de eerste trap zit op de motoras en het zonnewiel van de tweede trap wordt aangedreven door de satellietdrager van de eerste trap. De satellietdrager van de derde trap drijft de uitgaande as van de planetaire vertraging aan.

Omdat ik deze motor had liggen, wist ik niet wat de vertraging was. Dus dat werd tanden tellen. Ik had het ook met de hall-sensor kunnen doen, kijken hoeveel pulsen er nodig waren voor één omwenteling van de uitgaande as van de vertraging. Maar dan had ik eerst de software moeten schrijven, en via een display had ik het dan kunnen zien. Maar je kunt het ook uitrekenen als je het aantal tanden weet.

Er is een formule hoe je uit kunt rekenen hoeveel tanden de tandring heeft, die hoef je dus niet te tellen. Maar dan moet je wel het aantal tanden van het zonnetandwiel en het aantal tanden van de satelliet tandwielen weten.

Die formule is:
T_t = T_z + 2 \times T_s

Berekening planetaire vertragingBerekening planetaire vertraging

Tt is dus het aantal tanden op de tandring die berekend kan worden, Tz is het aantal tanden op het zonnetandwiel en Ts is het aantal tanden op de satelliet tandwielen.

Het zonnetandwiel heeft 15 tanden en het satelliet tandwiel heeft 21 tanden. Dan wordt de berekening als volgt: 15 + 2 x 21 = 57. De tandring heeft dus 57 tanden, deze berekening klopt altijd. Als je het aantal tanden van het zonnetandwiel en van het satelliet tandwiel maar weet.

Nu we het aantal tanden weten, kunnen we ook de vertraging van het planetaire tandwielstelsel uit rekenen. Ook daar is weer een formule voor:
1 + \frac{T_t}{T_z}
Dit is voor één trap.

Volgens de formule krijgen we dan: 57 : 15 = 3,8 + 1 = 4,8. Maar deze planetaire vertraging heeft drie trappen. Dan wordt het dus 4,8³ = 110,592. De totale vertraging is dus 110,592 : 1 en daar kun je redelijk mee positioneren in combinatie met een hall-sensor.

We weten dat de hall-sensor één puls per omwenteling van de motoras geeft, nu kunnen we ook uitrekenen hoeveel graden de uitgaande as van de vertraging verdraaid bij één puls. Een omwenteling van de motoras = 360° : 110,592 = 3,255° per puls. Dat is dus redelijk precies, als het nog nauwkeuriger moet is er dus nog een grotere vertraging nodig. Je zou nog een extra vertraging kunnen maken met een tandriem en tandriemwielen. Met bijvoorbeeld een extra verhouding van 3 : 1 kom je dan uit op 3 x 110,255 = 330,765. Dan wordt het aantal graden wat de uitgaande as verdraaid, 360° : 330,765 = 1,088°. Maar voor het voorbeeld is alleen de planetaire vertraging gebruikt en dat is redelijk nauwkeurig.

Hoewel we het niet gaan gebruiken, is een voorbeeld om het toerental te controleren ook wel leuk. Stel de motor draait 5 Hz, dan geeft de hall-sensor dus 5 pulsen per seconden. Dan draait de motor dus 5 x 60 = 300 toeren per minuut. De motor is een 12 V DC type en op 12 V DC draait de motor (via de motorregelaar) ± 57 Hz, dan is het toerental van de motor dus 57 x 60 = 3420 toeren per minuut. De uitgaande as van de vertraging draait nu met een toerental van 3420 : 110,592 = 30,92 toeren per minuut. En bij 5 Hz is dat 300 : 110,592 = 2,71 toeren per minuut.

Op deze manier kun je dus het toerental berekenen. En met de juiste software kun je het toerental controleren en constant houden bij zwaardere belastingen, maar dat gaan we nu niet bespreken.

De regelaar

In het principeschema staat ook een regelaar getekend, daar heb ik deze voor gebruikt.

Schema van de regelaarSchema van de regelaar

Dit schema is al vaker gebruikt in andere artikelen. De gebruikte transistoren zijn hier de TIP142 en de TIP147, dat is voor deze motor zwaar genoeg.

Hieronder het aansluitschema van de regelaar.

Aansluitschema van de regelaarAansluitschema van de regelaar

De regelaar kan op verschillende manieren aan gestuurd worden, zie hieronder. De poorten die je ziet, zitten op de print van de regelaar. Dit kun je in het schema van de regelaar zien.

De aansturingDe aansturing

De software

We gaan nu naar de software kijken.

Het programma is gemaakt in PIC-BASIC en de gebruikte controller is een PIC16F887. De controller draait hier op 10 MHz. Dit is een controller die ik veel gebruik voor het testen en aansturen van diverse zaken. En ik gebruik de controller dan ook bij veel artikelen.

'*  Name    : POSITIE REGELING MET HALL-SENSOR.                                     
'*  Author  : H.van Zwieten.                                    
'*  Notice  : Copyright (c) 2021 H.v.Z.                         
'*          : All Rights Reserved                               
'*  Date    : 16-10-2021                                        
'*  Version : 1.0                                               
'*  Notes   : 360 GRADEN VAN DE UITGAANDE AS VAN DE VERTRAGING-
'*  Notes   : IS 110.592 PULSEN VAN DE HALL-SENSOR.                                                  
'*  Notes   : IN HET VOORBEELD MAAKT DE AS 10 ROTATIES.

Device 16F887                     ; Processor type

Xtal 10                           ; Kristal 10Mhz

Asm                               ; Config settings  HS_OSC
CONFIG_REQ            
__CONFIG _CONFIG1, HS_OSC & WDT_OFF & DEBUG_OFF & FCMEN_OFF & LVP_OFF & IESO_OFF & BOR_OFF & CPD_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON 
__CONFIG _CONFIG2, WRT_OFF & BOR40V 
EndAsm
All_Digital true                  ; Alle poorten digitaal

Declare Adin_Res = 8              ; resolutie 8 bits
Declare Adin_Tad = frc            ; set RC osc
Declare Adin_Stime = 50           ; sample tijd 5

Declare LCD_RSPin PORTD.2         ; Reset display poort D.2
Declare LCD_ENPin PORTD.3         ; Enable display poort D.3
Declare LCD_DTPin PORTD.4         ; Data display poort D.4 t/m D.7

Declare CCP1_Pin PORTC.2          ; HPWM Uitgang

Symbol FREQUENTIE = 10000         ; HPWM frequentie 10KHz

Symbol PULS = PORTA.1             ; Ingang hall-sensor

Symbol S1 = PORTE.0               ; Ingang vrijgave
Symbol S2 = PORTE.1               ; Ingang as op nul zetten

Symbol WAARDE_POSITIE = 1106      ; Waarde positie as ingeven

Symbol RECHTS   = PORTC.0         ; Uitgang motor rechtsom
Symbol LINKS    = PORTC.1         ; Uitgang motor linksom
Symbol PULS_LED = PORTE.2         ; Uitgang puls-led

Dim WAARDE As Word                ; Variabele waarde positie

Dim TEL_BIT As Byte               ; variabele tel-bit

Dim TOEREN As Byte                ; Variabele toerental motor

Cls                               ; Wis display

DelayMS 1000                      ; Pauze 1 seconden

Clear                             ; Wis geheugen

         ;543210                  ; Hulpregel poort A
PORTA  = %000000                  ; Maak poort A laag
TRISA  = %111111                  ; Poort_A I/O

         ;543210                  ; Hulpregel poort B
PORTB  = %000000                  ; Maak poort B laag
TRISB  = %000000                  ; Poort_B I/O

         ;76543210                ; Hulpregel poort C
PORTC  = %00000000                ; Maak poort C laag
TRISC  = %00000000                ; Poort_C I/O

         ;76543210                ; Hulpregel poort D
PORTD  = %00000000                ; Maak poort D laag
TRISD  = %00000000                ; Poort_D I/O

         ;210                     ; Hulpregel poort E 
PORTE  = %000                     ; Maak poort E laag
TRISE  = %011                     ; Poort_E I/O

         ;76543210                ; Hulpregel analoog
ADCON0 = %00000001                ; ADCON0 register 8 bit analoog

         ;76543210                ; Hulpregel analoog
;ADCON1 = %10000000               ; ADCON1 register 10 bit analoog

         ;543210                  ; Hulpregel analoog poort_B
;ANSELH = %000000                 ; ANSEL register analoog poort_B

;-------------------------------------------------
; PROGRAMMA TEST POSITIE REGELING MET HALL-SENSOR.
;-------------------------------------------------

RECHTS   = 0
LINKS    = 0

START:


    Print At 1,1, Dec4 WAARDE

    TOEREN = ADIn 0
    
    HPWM 1,TOEREN,FREQUENTIE

    If S1 = 1 Then
       GoTo RUN_RECHTS
    EndIf
    
    If S2 = 1 Then
       RECHTS = 1
       Else RECHTS = 0
    EndIf

GoTo START

RUN_RECHTS:


    LINKS = 0
    RECHTS = 1
    
    TOEREN = ADIn 0

    If PULS = 1 Then
       TEL_BIT = 1
       PULS_LED = 0
    EndIf 

    If PULS = 0 Then
       If TEL_BIT = 1 Then
          WAARDE = WAARDE + 1
          TEL_BIT = 0
          PULS_LED = 1
          Print At 1,1, Dec4 WAARDE
       EndIf
    EndIf
   
    If WAARDE > = WAARDE_POSITIE Then
       Cls
       GoTo RUN_LINKS
    EndIf
    
    If S1 = 0 Then
       GoTo RESET_WAARDE
    EndIf
    
    HPWM 1,TOEREN,FREQUENTIE

GoTo RUN_RECHTS: 

RUN_LINKS:


    RECHTS = 0
    LINKS = 1

    TOEREN = ADIn 0

    If PULS = 1 Then
       TEL_BIT = 1
       PULS_LED = 0
    EndIf 

    If PULS = 0 Then
       If TEL_BIT = 1 Then
          WAARDE = WAARDE - 1
          TEL_BIT = 0
          PULS_LED = 1
          Print At 1,1, Dec4 WAARDE
       EndIf
    EndIf
    
    If WAARDE < 1 Then
       Cls
       GoTo RUN_RECHTS
    EndIf
    
    If S1 = 0 Then
       GoTo RESET_WAARDE
    EndIf
    
    HPWM 1,TOEREN,FREQUENTIE

GoTo RUN_LINKS: 

RESET_WAARDE:


    Print At 1,1, Dec4 WAARDE
    Cls
    
    RECHTS = 0
    LINKS = 0
    WAARDE = 0
    
    GoTo START
    
GoTo RESET_WAARDE

End

Zoals je kunt zien zijn er een paar schakelaars toegevoegd om de motor te bedienen. Deze schakelaars staan niet in het principe schema. Met S1 kun je de motor starten en stoppen. Met S2 kun je de as in een bepaalde positie zetten of de as op het nulpunt zetten. Er zit ook een potmeter op de controller aangesloten om het toerental van de motor te regelen.

Er zit voor de test ook een display op de controller aangesloten om de binnenkomende pulsen te controleren. Verder zijn er vier uitgangen gebruikt, twee voor de richting (linksom en rechtsom), één voor het PWM-signaal (om het toerental van de motor te regelen) en één voor de puls LED (als controle voor de puls die van de hall-sensor). De PWM-frequentie staat op 10 KHz ingesteld.

Bij WAARDE_POSITIE is het getal 1106 ingevuld. We weten dat de motor 110,592 omwentelingen moet maken voor één rotatie van de uitgaande as van de planetaire vertraging, dus om er tien te maken krijgen we 10 x 110,592 = 1105,92. Afgerond maken we daar 1106 van omdat de controller met hele getallen werkt.

In het programma maakt de uitgaande as van de planetaire vertraging eerst tien omwentelingen naar rechts en daarna tien omwentelingen naar links.

Voor het tellen van de binnen komende pulsen is er een TEL_BIT aangemaakt, deze bit wordt hoog gezet als er een puls binnen komt. Als de puls weg is en de tel-bit is nog één, dan wordt de WAARDE met één opgehoogd. Als de WAARDE is opgehoogd, dan wordt de TEL_BIT weer op nul gezet totdat de volgende puls weer binnen komt. Bij het linksom draaien gebeurt precies hetzelfde, maar dan wordt de WAARDE tekens met één verlaagd.

De WAARDE wordt vergeleken met de ingegeven waarde bij WAARDE_POSITIE, als de WAARDE groter is of gelijk aan de WAARDE_POSITIE gaat de motor de andere kant op draaien.

WAARDE_POSITIE is nu een vast gegeven, die zou je ook variabel kunnen maken met bijvoorbeeld een tweede potmeter of met een paar drukknoppen om de waarde te verhogen of om de waarde te verlagen. Je zou het ook in combinatie met Profilab-Expert kunnen doen en daar ga ik ook een voorbeeld mee maken. Dan kun je de waardes serieel naar de controller sturen via Profilab.

Besturing met Profilab-Expert

Nu gaan we de besturing via Profilab-Expert doen, in combinatie met de controller. We gaan de waardes ingeven via de seriële poort, via RX en TX dus. We hebben drie waardes om in te geven, dat is ingave positie, ingave toeren en ingave herhaling. Dan hebben we nog de knop start zendwaarde, de resetknop en de knop afsluiten.

Profilab frontplaatProfilab frontplaat

Je ziet drie ingave velden, ingave positie, ingave toeren en ingave herhaling. Bij ingave positie geef je het aantal pulsen in voor de verdraaiing van de as, bij ingave toeren geef je het toerental van de motor op en bij ingave herhaling geef je het aantal herhalingen op. Er is alleen één maar, de waarde die verzonden kan worden door de compoort-module is tussen de 0 en 255. Dat is voor de positie veel te weinig, maar daar is wel een foefje voor. Later in het schema van Profilab zal ik meer uitleggen daarover.

Dan zien we nog een veld staan met "klaar" erin, als het aantal herhalingen bereikt is gaat dat veld knipperen. Als er dan op de resetknop gedrukt wordt kun je weer een waarde verzenden.

Dan is er nog een teller waar het aantal herhalingen op getoond wordt, bij iedere herhaling wordt de teller met één opgehoogd.

Met de knop afsluiten wordt het programma gestopt.

Grote waarden verzenden

Ik had het hierboven over dat je maar tot een waarde van 255 kon verzenden via de compoort-module, maar door wat berekeningen uit te voeren kan er een veel grotere waarde verzonden worden.

Grote waarden verzenden via de compoort-moduleGrote waarden verzenden via de compoort-module

Ik geef eerst een voorbeeld met een klein getal.

Bij ingave NE1 geef je bijvoorbeeld een waarde van 5 in, die wordt gedeeld door 100 (FW1). Dan verschijnt er op de uitgang van DIV1 dus een waarde van 5 : 100 = 0,05. Die waarde komt op de ingang van MATH1 en SUB1 te staan. Bij de uitgang van MATH1 is de waarde ook 0,05, die wordt weer vermenigvuldigt door MUL1 x FW2. Dan krijg je dus 0,05 x 100 = 5. De berekening van SUB1 is als volgt, de waarde bij E0 = 0.05 en de waarde bij E1 = 0.05. De waarde op de uitgang van SUB1 wordt dus 0,05 - 0.05 = 0. Als er nu dus op de knop verzenden T1 gedrukt wordt, dan wordt eerst de waarde 0 verzonden en dan waarde 5. Dat wordt later in het programma van de controller weer omgezet, maar dat komt later aan bod.

We gaan nu kijken naar een waarde groter dan 255.

Bij ingave NE1 geef je bijvoorbeeld een waarde van 1000 in, die wordt gedeeld door 100 (FW1). Dan verschijnt er op de uitgang van DIV1 dus een waarde van 1000 : 100 = 10. Die waarde komt op de ingang van MATH1 en SUB1 te staan. Bij de uitgang van MATH1 is de waarde nu 0, die wordt weer vermenigvuldigd door MUL1 x FW2. Dan krijg je dus 0 x 100 = 0. De berekening van SUB1 is als volgt, de waarde bij E0 = 10 en de waarde bij E1 = 0. De waarde op de uitgang van SUB1 wordt dus 10 - 0 = 10. Als er nu dus op de knop verzenden T1 gedrukt wordt, dan wordt eerst de waarde 10 verzonden en dan waarde 0. Ook dat wordt later in het programma van de controller weer omgezet.

Op deze manier kun je dus makkelijk grote waardes verzenden via de compoort-modules $CS1 en $CS2. De tijd tussen de twee waardes verzenden loopt via monoflop MF1. De tijd tussen het verzenden staat hier op 0,05 seconden, die tijd is wel afhankelijk van de gebruikte baudrate.

Het Profilab schema

We gaan nu naar het schema kijken van het Profilab programma.

Het Profilab schemaHet Profilab schema

Zoals je kunt zien in het schema, kun je nu drie waardes serieel verzenden (positie, toeren en herhaling), zoals besproken bij de frontplaat. Voor de terugmelding, de waardes die vanuit de controller verzonden worden van de teller en de blokkering van de verzendknop, is de compoort-module CRB4 toegevoegd. DAC1 zet de digitale waarde om in een analoge waarde. Die waardes worden vergeleken door AVG1 en AVG2. Zodra waarde 10 verzonden wordt door de controller, wordt de teller met één opgehoogd.

Als de waarde 20 verzonden wordt door de controller, dan wordt RS1 geset en laat de tekst klaar op de frontplaat knipperen. Ook kan er nu geen data verzonden worden via de compoort. Na een reset van T2 kan dat weer wel. Dit is zo'n beetje de werking van het Profilab programma.

De software van de controller voor Profilab

We gaan nu naar het programma van de controller kijken.

'*  Name    : POSITIE REGELING MET HALL-SENSOR EN PROFILAB.                                      
'*  Author  : H. van Zwieten                                    
'*  Notice  : Copyright (c) 2021 H.v.Z.                         
'*          : All Rights Reserved                               
'*  Date    : 21-10-2021                                        
'*  Version : 1.0                                               
'*  Notes   : POORT C.7 = RX EN POORT C.6 = TX BIJ GEBRUIK HSERIAL.
                                                  
Device 16F887                               ; Processor type

Xtal 10                                     ; Kristal 10Mhz

Asm                                         ; Config settings
CONFIG_REQ            
__CONFIG _CONFIG1, HS_OSC & WDT_OFF & DEBUG_OFF & FCMEN_OFF & LVP_OFF & IESO_OFF & BOR_OFF & CPD_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON 
__CONFIG _CONFIG2, WRT_OFF & BOR40V 
EndAsm
   
All_Digital true                            ; Alle poorten digitaal

Declare Adin_Res = 8                        ; resolutie 8 bits
Declare Adin_Tad = frc                      ; set RC osc
Declare Adin_Stime = 50                     ; sample tijd 5

Declare LCD_RSPin PORTD.2                   ; Reset display poort D.2
Declare LCD_ENPin PORTD.3                   ; Enable display poort D.3
Declare LCD_DTPin PORTD.4                   ; Data display poort D.4 t/m D.7
Declare LCD_Lines 2                         ; Twee lijns display

Declare Hserial_Baud 9600                   ; Set baudrate op 9600
Declare Hserial_RCSTA %10010000             ; Register instelling
Declare Hserial_TXSTA %10100110             ; Register instelling 
Declare Hserial_Clear = On                  ; Reset buffer bij een overflow 

Declare CCP1_Pin PORTC.2                    ; HPWM 1 op poort C.2

Symbol FREQUENTIE = 10000                   ; HPWM frequentie 10KHz

Symbol PULS = PORTA.1                       ; Ingang hall-sensor

Symbol S1 = PORTE.0                         ; Ingang invoer / reset ingave
Symbol S2 = PORTE.1                         ; Ingang As op nul zetten

Symbol RECHTS   = PORTC.0                   ; Uitgang motor rechtsom
Symbol LINKS    = PORTC.1                   ; Uitgang motor linksom
Symbol PULS_LED = PORTE.2                   ; Uitgang puls-led

Dim POSITIE As Word                         ; Variabele positie
                                    
Dim TOEREN As Byte                          ; Variabele toerental motor

Dim HERHALING As Byte                       ; Variabele herhaling

Dim DATA_1 As Byte                          ; Variabele data-1

Dim DATA_2 As Byte                          ; Variabele data-2

Dim TEL_BIT As Byte                         ; variabele tel-bit

Dim WAARDE As Word                          ; variabele waarde

Dim TELLER As Byte                          ; Variabele teller

Cls                                         ; Wis display

DelayMS 1000                                ; Pauze 1 sec 

Clear                                       ; Wis geheugen

         ;543210                            ; Hulpregel poort A
PORTA  = %000000                            ; Maak poort A laag
TRISA  = %111111                            ; Poort_A I/O

         ;543210                            ; Hulpregel poort B
PORTB  = %000000                            ; Maak poort B laag
TRISB  = %111111                            ; Poort_B I/O

         ;76543210                          ; Hulpregel poort C
PORTC  = %00000000                          ; Maak poort C laag
TRISC  = %00000000                          ; Poort_C I/O

         ;76543210                          ; Hulpregel poort D
PORTD  = %00000000                          ; Maak poort D laag
TRISD  = %00000000                          ; Poort_D I/O

         ;210                               ; Hulpregel poort E 
PORTE  = %000                               ; Maak poort E laag
TRISE  = %011                               ; Poort_E I/O

         ;76543210                          ; Hulpregel analoog
;ADCON0 = %00000001                         ; ADCON0 register analoog 8 bit

         ;76543210                          ; Hupregel analoog
;ADCON1 = %10000000                         ; ADCON1 register analoog 10 bit

         ;76543210                          ; Hulpregel analoog poort_B
;ANSELH = %00000000                         ; ANSEL register analoog poort_B

;--------------------------------------------------------------
; TEST PROGRAMMA POSITIE REGELING MET HALL-SENSOR EN PROFILAB.
;--------------------------------------------------------------

POSITIE = 0
TOEREN = 0
HERHALING = 0
DATA_1 = 0
DATA_2 = 0
TEL_BIT = 0
WAARDE = 0
TELLER = 0
RECHTS = 0
LINKS = 0

AS_NULLEN:


    Print At 1,1, "AS OP NUL ZETTEN"
    
    If S2 = 1 Then
       RECHTS = 1
       LINKS = 0
       HPWM 1,100,FREQUENTIE
    EndIf
    
    If S2 = 0 Then
       RECHTS = 0
       LINKS = 0
       HPWM 1,0,FREQUENTIE
    EndIf
    
    If S1 = 1 Then
       GoTo INVOER
    EndIf
    
GoTo AS_NULLEN
        
INVOER:


    Cls

    HSerIn [DATA_1, DATA_2, TOEREN, HERHALING] 
    
    POSITIE = ((DATA_1 * 100) + DATA_2)
    
    Print At 1,1, Dec5, POSITIE
    
    Print At 1,7, Dec3, TOEREN
    
    Print At 1,11, Dec3, HERHALING 
    
    DelayMS 2000
    
    GoTo RUN_RECHTS
    
GoTo INVOER

RUN_RECHTS:


    LINKS = 0
    RECHTS = 1
    
    Print At 2,1, Dec4 WAARDE

    If PULS = 1 Then
       TEL_BIT = 1
       PULS_LED = 0
    EndIf 

    If PULS = 0 Then
       If TEL_BIT = 1 Then
          WAARDE = WAARDE + 1
          TEL_BIT = 0
          PULS_LED = 1
       EndIf
    EndIf
    
    If WAARDE > = POSITIE Then
       LINKS = 0
       RECHTS = 0
       DelayMS 1000
       GoTo RUN_LINKS
    EndIf
    
    If S1 = 1 Then
       HERHALING = 0
       GoTo RESET_INGAVE
    EndIf
    
    HPWM 1,TOEREN,FREQUENTIE
     
GoTo RUN_RECHTS

RUN_LINKS: 


    RECHTS = 0
    LINKS = 1

    Print At 2,1, Dec4 WAARDE

    If PULS = 1 Then
       TEL_BIT = 1
       PULS_LED = 0
    EndIf 

    If PULS = 0 Then
       If TEL_BIT = 1 Then
          WAARDE = WAARDE - 1
          TEL_BIT = 0
          PULS_LED = 1
       EndIf
    EndIf
    
    If S1 = 1 Then
       HERHALING = 0
       GoTo RESET_INGAVE
    EndIf
    
    If WAARDE < 1 Then
       LINKS = 0
       RECHTS = 0
       DelayMS 1000
       GoTo RESET_INGAVE
    EndIf
    
    HPWM 1,TOEREN,FREQUENTIE
       
GoTo RUN_LINKS

RESET_INGAVE:


    RECHTS = 0
    LINKS = 0
    WAARDE = 0
    
    TELLER = TELLER + 1
    
    HSerOut [10]
    DelayMS 100
    HSerOut [0]
   
    If TELLER > = HERHALING Then
       HSerOut [20]
       DelayMS 100
       HSerOut [0]
       TELLER = 0
       TOEREN = 0
       HPWM 1,TOEREN,FREQUENTIE
       GoTo INVOER
    EndIf
    
    DelayMS 1000

    GoTo RUN_RECHTS
    
GoTo RESET_INGAVE

End

Zoals je kunt zien is er wel wat veranderd ten opzichte van het eerste programma. In het vorige voorbeeld hadden we twee schakelaars (S1 en S2), één schakelaar was voor de vrijgave en één schakelaar om de as op nul te zetten. Deze twee schakelaars blijven, alleen S1 krijgt een andere functie. S1 krijgt de functie invoer / reset ingave. Ook kun je zien dat er wat variabelen bijgekomen zijn en dat de declaratie voor de seriële poort is toegevoegd. De baudrate staat op de standaard waarde van 9600 baud.

Het begint met AS_NULLEN, dat gebeurt met schakelaar S2. Hier heeft Profilab dus niets mee te maken, dat gebeurt helemaal buiten Profilab om.

Onder INVOER kun je zie dat DATA_1, DATA_2, TOEREN en HERHALING binnenkomen, verstuurd door Profilab. DATA_1 en DATA_2 bevatten de waarde voor de positie van de as, deze waardes worden in de variabele POSITIE gezet. Dat gebeurt door deze formule: POSITIE = (DATA_1 * 100) + DATA_2. Hier kun je zien hoe die twee waardes weer samen gevoegd worden als de waarde groter is dan 255 zoals eerder uitgelegd onder grote waardes verzenden.

Onder RESET_INGAVE kun je zien dat de waardes 10 en 20 verzonden worden, als de voorwaarden kloppen. In die lus wordt de teller iedere keer met één opgehoogd, als de teller opgehoogd is wordt de waarde 10 verzonden door de controller. Ook wordt in die zelfde lus de teller stand vergeleken met het ingegeven aantal herhalingen. Als die waarde groter of gelijk is aan de ingegeven waarde, dan wordt de waarde 20 verzonden door de controller.

De ontvangen waardes verzonden door Profilab worden ook op een display getoond, op deze manier kun je controleren of ontvangen waardes kloppen met de verzonden waardes. Want serieel blijft toch wel een beetje een dingetje, het werkt wel of het werkt niet.

Dit was het weer zo'n beetje, maar zoals je gezien hebt is het goed mogelijk om de positie van een as te bepalen met een hall-sensor. Zolang de vertraging achter de motor maar groot genoeg is, is dit het geval dan is het geen probleem. Zo'n hall-sensor wordt vaak gebruikt voor dit soort doeleinden zoals beschreven in het begin van het artikel.