Inhoudsopgave:

Hoe de draairichting van een digitale draaischakelaar te interpreteren met een PIC - Ajarnpa
Hoe de draairichting van een digitale draaischakelaar te interpreteren met een PIC - Ajarnpa

Video: Hoe de draairichting van een digitale draaischakelaar te interpreteren met een PIC - Ajarnpa

Video: Hoe de draairichting van een digitale draaischakelaar te interpreteren met een PIC - Ajarnpa
Video: Werken met de multimeter - uw Eltra toolkit 2024, Juli-
Anonim
Hoe de draairichting van een digitale draaischakelaar te interpreteren met een PIC
Hoe de draairichting van een digitale draaischakelaar te interpreteren met een PIC

Het doel van deze Instructable is om te illustreren hoe een digitale (kwadratuur gecodeerde) draaischakelaar met een microcontroller kan worden gekoppeld. Maak je geen zorgen, ik zal uitleggen wat quadrature coded voor ons betekent. Met deze interface en de bijbehorende software kan de microcontroller de draairichting herkennen voor elke beweging van de ene pal naar de andere. Ik heb onlangs dit type schakelaar gebruikt in een microcontrollerproject waarbij een drukinstelpunt moest worden ingevoerd met behulp van een knop met 16 pallen in plaats van omhoog/omlaag-knoppen. Het idee was om de gebruiker de gewenste druk te laten "inbellen". Als gevolg hiervan moesten we een softwareroutine ontwikkelen om de positie-informatie van de schakelaar te krijgen en de rotatierichting af te leiden om het drukinstelpunt voor het hoofdsysteem te verhogen of te verlagen. In deze Instructable zal ik de fysieke interface behandelen tot de microcontroller, de werkingstheorie voor de draaischakelaar, de werkingstheorie voor de software en de deductieroutine. Ten slotte zal ik je mijn toepassing van de aftrekroutine laten zien. Naarmate we verder komen, zal ik proberen de dingen enigszins generiek te houden, zodat het idee op zoveel mogelijk platforms kan worden toegepast, maar ik zal ook delen wat ik heb gedaan, zodat u een specifieke toepassing kunt zien.

Stap 1: Onderdelen

Onderdelen
Onderdelen

Om dit te implementeren, heb je nodig: Een draaischakelaar (kwadratuurgecodeerd) Trekweerstanden Geschikt microcontrollerplatform Voor mijn project heb ik een Grayhill 61C22-01-04-02 optische encoder gebruikt. Het datablad voor de draaischakelaar vraagt om 8,2k ohm pull-up weerstanden op de twee datalijnen die van de schakelaar komen. U wilt het gegevensblad controleren van de encoder die u wilt gebruiken. De draaischakelaar die ik gebruikte is ook te bestellen met een axiale drukknopschakelaar. Het is een handige functie voor het vastleggen van geselecteerde selecties, enz., maar ik zal de interface hier niet bespreken. Ik heb een "geschikt microcontrollerplatform" vermeld omdat dit (denk ik) op meer dan één platform kan worden geïmplementeerd. Ik heb veel mensen gezien die andere microcontrollers gebruiken voor Instructables, dus ik wil ook de algemene aanpak laten zien. Ik heb alle code in PIC Basic Pro geschreven voor gebruik met een Microchip PIC16F877A. Echt, het belangrijkste dat je op de microcontroller nodig hebt, is de mogelijkheid om te onderbreken wanneer er een logische verandering is op een van de twee pinnen. Op de PIC16F877A wordt dit de PORTB change interrupt genoemd. Er kunnen andere namen voor zijn op andere controllers. Deze microcontroller-interrupt-functie maakt deel uit van wat deze implementatie zo elegant maakt.

Stap 2: Hardware-interface

Hardware-interface
Hardware-interface

Een "eenvoudige" oplossing zou zijn om een "single pole-16 throw" schakelaar te hebben met 16 aansluitingen naar de microcontroller. Elke schakeluitgang zou dan worden vastgemaakt aan een pin op de microcontroller, zodat elke positie van de wijzerplaat door de microcontroller kan worden gecontroleerd. Dit is een overmatig gebruik van I/O-pinnen. Het wordt nog erger als we meer dan 16 posities (detents) beschikbaar willen hebben op de switch. Elke extra positie op de schakelaar zou een extra invoer naar de microcontroller vereisen. Dit wordt al snel een zeer inefficiënt gebruik van ingangen op een microcontroller. Betreed de schoonheid van de draaischakelaar. De draaischakelaar heeft slechts twee uitgangen naar de microcontroller die op het gegevensblad als A en B wordt vermeld. Er zijn slechts vier mogelijke logische niveaus die deze lijnen kunnen aannemen: AB = 00, 01, 10 en 11. Dit vermindert het aantal invoerlijnen dat u moet gebruiken om de schakelaar op de microcontroller aan te sluiten aanzienlijk. Daarom hebben we het aantal invoerregels teruggebracht tot slechts twee. Wat nu? Het lijkt erop dat we echt 16 verschillende statussen nodig hebben, maar deze nieuwe schakelaar heeft er maar vier. Hebben we onszelf in de voet geschoten? Nee. Lees verder. We zullen een klein beetje van de theorie achter de werking van de draaischakelaar behandelen om uit te leggen.

Stap 3: Hardwaretheorie van de werking

Hardware theorie van de werking
Hardware theorie van de werking
Hardware theorie van de werking
Hardware theorie van de werking
Hardware theorie van de werking
Hardware theorie van de werking

Rotatierichtingsdetectie is mogelijk met behulp van de eerder genoemde "single pole-16 throw"-schakelaar, maar het gebruikt veel ingangen op de microcontroller. Het gebruik van de draaischakelaar vermindert het aantal ingangen naar de microcontroller, maar nu moeten we de signalen die van de schakelaar komen interpreteren en deze vertalen naar een draairichting. Ik zei eerder dat de schakelaar kwadratuurgecodeerd was. Dit is ook een van de belangrijkste elegantie van deze oplossing. Dit betekent dat er een 2-bits code is die de schakelaar geeft die overeenkomt met de positie van de schakelaar. U denkt misschien: "Als er een 2-bits invoer naar de microcontroller is, hoe vertegenwoordigen we dan alle 16 posities?" Dat is een goede vraag. We vertegenwoordigen ze niet allemaal. We hoeven alleen de relatieve posities van de knop te kennen, zodat we de draairichting kunnen bepalen. De absolute positie van de knop is niet relevant. Voor rechtsom draaien wordt de code die de schakelaar geeft om de vier aanslagen herhaald en is grijs gecodeerd. Grijs gecodeerd betekent dat er slechts één bitverandering is voor elke positieverandering. In plaats van dat de AB-invoer optelt voor rotatie met de klok mee in binair als volgt: 00, 01, 10, 11, verandert het als volgt: 00, 10, 11, 01. Merk op dat voor het laatste patroon er slechts één invoer verandert tussen stelt. De waarden tegen de klok in voor de AB-invoer naar de microcontroller zien er als volgt uit: 00, 01, 11, 10. Dit is gewoon het omgekeerde van het patroon met de klok mee, waarbij AB = 00 als eerste wordt vermeld. Bekijk de diagrammen voor een meer visuele uitleg.

Stap 4: Softwaretheorie van werking

Software Theorie van Werking
Software Theorie van Werking

De routine die de draairichting afleidt, is interrupt-gedreven. De microcontroller die u selecteert, moet in staat zijn om te onderbreken wanneer er een wijziging is op een van (ten minste) twee pinnen wanneer de onderbreking is ingeschakeld. Dit wordt de PORTB change interrupt op de PIC16F877A genoemd. Telkens wanneer de schakelaar wordt gedraaid, wordt de microcontroller onderbroken en wordt de uitvoering van het programma naar de Interrupt Service Routine (ISR) gestuurd. De ISR zal snel achterhalen op welke manier de schakelaar is gedraaid, een juiste vlag instellen en snel terugkeren naar het hoofdprogramma. Dit moet snel gebeuren voor het geval de gebruiker de schakelaar erg snel draait. We weten dat het grijs gecodeerde AB-patroon zich elke vier posities herhaalt, dus als we de routine laten werken voor overgangen tussen die vier posities, zal het voor alle andere werken. Merk op dat er in een cyclus met vier posities vier randen zijn. Een stijgende flank en een dalende flank voor zowel de A-ingang als de B-ingang. De microprocessor wordt onderbroken telkens als er een rand is, wat betekent dat de microcontroller wordt onderbroken wanneer aan de knop wordt gedraaid. Als gevolg hiervan moet de ISR uitzoeken op welke manier de knop is gedraaid. Om ons te helpen erachter te komen hoe we dit moeten doen, gaan we naar de golfvorm voor rotatie met de klok mee. Merk op dat elke keer dat A een rand heeft, zijn nieuwe waarde altijd anders is dan die van B. Wanneer de knop van positie 1 naar 2 gaat, gaat A over van logisch-0 naar logisch-1. B is nog steeds 0 voor deze overgang en komt niet overeen met de nieuwe waarde van A. Als de knop van positie 3 naar 4 gaat, heeft A een dalende flank terwijl B op logisch-1 blijft. Merk nogmaals op dat B en de nieuwe waarde van A verschillend zijn. Op dit moment kunnen we zien dat elke keer dat A de onderbreking veroorzaakt tijdens rotatie met de klok mee, de nieuwe waarde ervan verschilt van die van B. Laten we eens kijken naar B om te zien wat er gebeurt. B heeft een stijgende flank wanneer de schakelaar van positie 2 naar 3 gaat. Hier is de nieuwe waarde van B hetzelfde als A. Kijkend naar de laatst overgebleven flank voor rechtsom draaien, heeft B een dalende flank die van positie 4 naar 5 beweegt. (Positie 5 is hetzelfde als positie 1.) De nieuwe waarde van B is ook hier hetzelfde als A! We kunnen nu wat aftrekken! Als A de interrupt veroorzaakt en de nieuwe waarde van A is anders dan die van B, dan was de rotatie met de klok mee. Bovendien, als B de onderbreking veroorzaakt en de nieuwe waarde van B is hetzelfde als A, dan was de rotatie met de klok mee. Laten we snel het geval van rotatie tegen de klok in onderzoeken. Net als rotatie met de klok mee, veroorzaakt rotatie tegen de klok in vier onderbrekingen in één cyclus: twee voor ingang A en twee voor ingang B. Ingang A heeft een stijgende flank wanneer de knop van positie 4 naar 3 beweegt en een dalende flank die van positie 2 naar 1 beweegt Wanneer de knop van positie 4 naar 3 beweegt, is de nieuwe waarde van A gelijk aan de waarde van B. Merk op dat wanneer A van positie 2 naar 1 beweegt, zijn nieuwe waarde ook dezelfde is als die van B. Nu kunnen we zien dat wanneer A de interrupt veroorzaakt en zijn nieuwe waarde overeenkomt met die van B, de rotatie tegen de klok in was. Snel kijken we naar input B om alles te verifiëren. B zal een onderbreking veroorzaken wanneer de knop van positie 5 (wat hetzelfde is als 1) naar 4 beweegt en wanneer de knop van positie 3 naar 2 beweegt. In beide gevallen komt de nieuwe waarde van B niet overeen met de bestaande waarde van A, wat het tegenovergestelde is van de gevallen waarin B de onderbreking veroorzaakt voor rotatie met de klok mee. Dit is goed nieuws. Alles verloopt zoals het hoort. Om samen te vatten, als A de onderbreking veroorzaakt en de nieuwe waarde ervan komt niet overeen met de waarde van B of als B de onderbreking veroorzaakt en de nieuwe waarde van B komt overeen met de waarde van A, dan weten we dat er een rotatie met de klok mee was. We kunnen de andere gevallen controleren op rotatie tegen de klok in in de software of we kunnen aannemen dat omdat het geen rotatie met de klok mee was, het tegen de klok in was. Mijn routine maakte gewoon de veronderstelling.

Stap 5: Software

Software
Software
Software
Software

Ik heb de ingebouwde interrupts in PIC Basic Pro niet gebruikt. Ik heb een paar bestanden gebruikt die ik in mijn code van Darrel Taylor heb opgenomen om de routine aan te sturen. Dit is waar een enorme eer aan Darrel thuishoort! De bestanden zijn gratis. Bezoek gewoon zijn website voor meer informatie, andere toepassingen en om de bestanden te downloaden. U kunt dit deel overslaan als u geen PIC gebruikt met Darrel Taylor-interrupts. Stel zo nodig de interrupts in op het platform dat u gebruikt. Om de Darrel Taylor (DT)-interrupts in te stellen, moet u twee dingen doen: 1.) Voeg de bestanden DT_INTS-14.bas en ReEnterPBP.bas toe aan uw code.2.) Kopieer en plak dit in uw code. ASMINT_LIST macro;IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _ISR, PBP, ja endm INT_CREATEENDASMVoer tabbladen en spaties in, zoals de afbeelding aan het einde van de Instructable, zodat je de dingen een beetje gemakkelijker in je code kunt zien. U moet het enigszins aanpassen om aan uw behoeften te voldoen. Vervang onder Label ISR door de naam van de subroutine die uw ISR is. Vergeet het onderstrepingsteken niet! Je hebt het nodig! Om de interrupts te laten werken, zijn er nog twee dingen die je moet doen: 1.) Schrijf de ISR. Je schrijft dit net zoals je een PBP-subroutine zou schrijven, behalve dat je @INT_RETURN aan het einde van de subroutine moet invoegen in plaats van RETURN. Dit zal de interrupt bevestigen en de uitvoering van het programma terugbrengen naar waar het was gebleven in de hoofdlus. Binnen de ISR moet u de interrupt-vlag wissen, zodat uw programma niet verstrikt raakt in een recursieve interrupt. Gewoon PORTB lezen is alles wat je hoeft te doen om de interruptvlag op de PIC16F877A te wissen. Elke verschillende microcontroller heeft een andere manier om interruptvlaggen te wissen. Controleer het gegevensblad van uw microcontroller.2.) Wanneer u het punt in uw code bereikt waarop u de onderbreking wilt inschakelen, gebruikt u deze regel code:@ INT_ENABLE RBC_INTAls u de onderbreking wilt uitschakelen, gebruikt u gewoon:@ INT_DISABLE RBC_INTEr is veel van dingen verpakt in wat ik net heb behandeld, dus ik zal het snel samenvatten. Tot nu toe zou je programma er ongeveer zo uit moeten zien:; Elke benodigde setup of codeINCLUDE "DT_INTS-14.bas"INCLUDE "ReEnterPBP.bas"ASMINT_LIST macro;IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _myISR, PBP, ja endm INT_CREATEENDASM; Elke andere benodigde instelling of code@ INT_ENABLE RBC_INT; Code die moet weten in welke richting de knop draait@ INT_DISABLE RBC_INT; Andere codeEND; Einde van programmamyISR:;ISR-code hier @ INT_RETURN (Interrupt Handler Set Up Table) Ik denk dat dit is waar iedereen die geen PIC of DT-interrupts gebruikt, weer kan meedoen. Nu moeten we de ISR daadwerkelijk schrijven, zodat de microcontroller weet in welke richting de knop draait. Bedenk uit het gedeelte over softwaretheorie dat we de draairichting kunnen afleiden als we de invoer kennen die de onderbreking heeft veroorzaakt, de nieuwe waarde en de waarde van de andere invoer. Hier is de pseudocode: Lees PORTB in een scratchvariabele om de interruptvlag te wissenControleer of A de interrupt heeft veroorzaakt. Indien waar, vergelijk A en B. Controleer indien verschillend, indien verschillend, Het was rechtsom draaien. Anders was het linksom EndifControleer of B de onderbreking veroorzaakte. Indien waar, vergelijk A en B Controleer of verschillend, indien hetzelfde, Het was rechtsom draaien Anders was het linksom EndifReturn from interruptHoe weten we of een wijziging op A of B de interrupt veroorzaakte? Het ontdekken van de nieuwe waarde van de gewijzigde invoer en de andere (onveranderde) invoer is eenvoudig omdat we ze in de ISR kunnen lezen. We moeten weten wat de staat van elk was voordat de uitvoering naar de ISR wordt gestuurd. Dit gebeurt in de hoofdroutine. De hoofdroutine zit en wacht op een bytevariabele die we CWflag hebben genoemd om op 1 te worden ingesteld of door de ISR op 0 te worden gewist. Na elke bevestigde verandering van de knop of als er geen knopactiviteit is, wordt de variabele ingesteld op 5 om een inactieve toestand aan te geven. Als de vlag wordt ingesteld of wordt gewist, verhoogt of verlaagt de hoofdroutine de instelpuntdruk onmiddellijk op de juiste manier op basis van de rotatie en stelt vervolgens de CWflag-variabele weer in op 5 omdat de knop nu weer inactief is. Aangezien de belangrijkste routine het controleren van de CW-vlag is, documenteert het ook de status van de A- en B-draaischakelaarwaarden. Dit is heel eenvoudig en ziet er zo uit:oldA = AoldB = BEr is hier echt niets superchiques. Voeg gewoon die twee regels toe aan het begin van de lus die de CW-vlag controleert op rotatie. We werken alleen de logische waarden van de invoer van de draaiknop in de increment/decrement-lus in de hoofdroutine bij, zodat we kunnen zien welke invoer de interrupt veroorzaakte wanneer de ISR wordt uitgevoerd. Hier is de ISR-code:ABverander: scratch = PORTB ' Lees PORTB om de interruptvlag te wissen ' Als A de interrupt veroorzaakt, controleer dan B op de draairichting IF oldA != A THEN ' Als A en B verschillend zijn, was het rechtsom draaien IF A != B THEN GOTO CW ' Anders was het een rotatie tegen de klok in ELSE GOTO CCW ENDIF ENDIF ' Als B de onderbreking veroorzaakt, controleer dan A op de draairichting IF oldB != B THEN ' Als A en B hetzelfde zijn, is het was rechtsom draaien IF A == B THEN GOTO CW ' Anders was het linksom draaien ELSE GOTO CCW ENDIF ENDIFCW: CWflag = 1@ INT_RETURNCCW: CWflag = 0@ INT_RETURNI heeft de ISR-code in een AB_ISR.bas-bestand opgenomen omdat de tabbladen in de code worden niet weergegeven zoals ze zouden moeten. Omdat de ISR nu de oude waarden voor ingangen A en B heeft, kan deze bepalen welke ingang de onderbreking heeft veroorzaakt, deze vergelijken met de andere (onveranderde) ingang en de richting bepalen van rotatie. Het enige dat u hoeft te doen, is de CW-vlag controleren om te zien in welke richting de knop is gedraaid (als dat het geval is) en een teller, instelpunt of wat u maar wilt of nodig heeft verhogen of verlagen. Ik hoop dat dit helpt en niet te veel is geweest verwarrend. Dit type interface is vooral handig als uw systeem al interrupts gebruikt, omdat dit nog maar één interrupt is om toe te voegen. Genieten van!

Aanbevolen: