Encoder met knopaansluitschema. Hoe een roterende encoder te gebruiken in een microcontrollerproject

De KY-040 encodermodule is een mechanische rotatiehoeksensor; deze zet de rotatiehoek van een roterend object (bijvoorbeeld een as) om in elektrische signalen die 90 graden ten opzichte van elkaar zijn verschoven. Deze module heeft drie uitgangen: CLK, DT en SW. Signalen die 90 graden ten opzichte van elkaar zijn verschoven, verschijnen precies op de CLK- en DT-pinnen wanneer ze met de klok mee/tegen de klok in worden gedraaid. De SW-pin wordt gebruikt om de status van de centrale as van de encoder te verkrijgen, die werkt als een knop.

Dus, zonder in details te treden over het in-circuit-apparaat van de encoder (dit zal in een apart artikel worden besproken), laten we het verbinden met het Arduino Uno-bord. Aansluitschema voor de encodermodule in combinatie met een meercijferige zevensegmentindicator:

Het zal voor ons voldoende zijn om eenvoudigweg de toestand te ontleden van de signalen die aanleiding geven tot de CLK- en DT-pinnen; hiervoor is er een klein schakelschema dat laat zien hoe de signalen worden verschoven wanneer ze in de ene of de andere richting worden gedraaid.

Het diagram laat zien dat elke keer dat signaal A (pen van encoder CLK) van hoog naar laag gaat, de toestand van signaal B (pin van encoder DT) wordt gelezen. Als signaal B een hoog signaalniveau geeft, betekent dit dat de encoder met de klok mee draait. Als signaal B een laag signaalniveau geeft wanneer signaal A van laag naar hoog niveau overgaat, betekent dit dat de encoder tegen de klok in draait. Door beide signalen in het programma te lezen, kunt u de draairichting bepalen; ook kunt u bij het tellen van signaal B-pulsen de programma-pulsenteller verhogen of verlagen.

Om signalen A en B te lezen, evenals signalen van de centrale as van de encoder (ik wil u eraan herinneren dat deze werkt als een knop), kunt u het hieronder beschreven ontwerp gebruiken. Dit ontwerp kan in een schets worden ingebouwd en er verschillende functionaliteiten aan worden toegevoegd, alles wordt alleen beperkt door de wens en verbeeldingskracht van de ontwikkelaar. Het lichaam van de structuur is vrij goed becommentarieerd; in de toekomst kunt u opmerkingen verwijderen om de tekst van de schets te vereenvoudigen. Het ontwerp voor het lezen en omzetten van encodersignalen in bruikbare gegevens:

//Tijdelijke variabelen voor het opslaan van signaalniveaus //ontvangen van de encoder unsigned char encoder_A, encoder_B, encoder_A_prev; //Variabele voor het bijhouden van knopdrukken - //de centrale as van de statische bool SW_State = false; void setup() ( // Voorlopige instellingen // Variabele declaraties // Initialisatie van poorten, enz. ) void loop() ( // CLK aangesloten op pin 3 op het Arduino-bord // DT aangesloten op pin 4 op het Arduino-bord / / We lezen de waarden van de encoderuitgangen //En slaan ze op in variabelen encoder_A = digitalRead(3); encoder_B = digitalRead(4); //Als het niveau van signaal A laag is, //en in de vorige cyclus it was high if(!encoder_A && encoder_A_prev) ( //Als het signaalniveau B hoog is if(encoder_B) ( //Dit betekent dat de rotatie met de klok mee plaatsvindt //Hier kunt u een ophogingsbewerking invoegen //Hier kunt u een van de volgende invoegen uw eigen //gegevensverwerkingsbewerkingen in de gewenste richting) //Als het signaalniveau te laag is anders ( //Dus de rotatie vindt tegen de klok in plaats //Hier kunt u een decrement-bewerking invoegen //Hier kunt u uw eigen bewerking invoegen // gegevensverwerkingsbewerkingen in de gewenste richting) ) //Het is absoluut noodzakelijk om de status van het huidige signaalniveau A op te slaan // om deze waarde te gebruiken in de volgende scancyclus van het programma encoder_A_prev = encoder_A; //We werken met de centrale as van de encoder - een knop //Dit stukje code vormt een soort flip-flop-trigger //Lees de waarde van pin 2 op het Arduino-bord //waaraan het SW-contact van de encoder zit is verbonden //Als de centrale as wordt ingedrukt, zal het SW-signaal een laag niveau hebben if(!digitalRead(2)) ( //Als de SW_State-variabele is ingesteld op false, stel deze dan in op true if(!SW_State) ( / /En onthoud de status SW_State = true; ) //En omgekeerd: als de variabele SW_State is ingesteld op true , //zet deze dan terug naar false else ( //En onthoud de status SW_State = false; ) ) )

Hieronder ziet u een schets voor het verwerken van encodersignalen en het weergeven van de tellerwaarde op het display. Deze schets bevat een ingebouwd ontwerp voor het lezen en omzetten van encodersignalen, zoals hierboven beschreven.

#include "LedControl.h" /* * We verbinden de LedControl.h-bibliotheek * en creëren een object van de LedControl-klasse * in dit geval moet een 7-segment display met een MAX72xx-driver * als volgt op het Arduino-bord worden aangesloten : * Arduino -> Displaymodule MAX72xx * Arduino -> Displaymodule MAX72xx * Arduino -> Displaymodule MAX72xx * Arduino -> Displaymodule MAX72xx * Arduino -> Displaymodule MAX72xx * Arduino -> Encodermodule * Arduino -> Encodermodule * Arduino -> Encodermodule */ LedControl lc = LedControl(12, 11, 10, 1); // Geef de poortadressen een naam op het Arduino-bord const int Dir = 4; const int Stap = 3; const int Schakelaar = 2; //Counter - variabele om de tellerwaarde op te slaan statisch lang Counter = 0; //SW_State - triggervlag voor het volgen van het indrukken van de statische bool van de centrale as SW_State = false; //Tijdelijke variabelen voor het opslaan van encodersignaalniveaus unsigned char encoder_A, encoder_B, encoder_A_prev; void setup() ( //Het apparaat (7-segmentdisplay) wordt uit de slaapmodus gehaald lc.shutdown(0, false); //Stel de helderheid van het display in op 8 //Totaal mogelijke helderheidsmodi van 0 tot 15 lc. setIntensity(0,8); //Wis het display lc.clearDisplay(0); //Configureer de poorten voor de encoder pinMode(Dir, INPUT); pinMode(Step, INPUT); pinMode(Switch, INPUT); ) void loop() ( // Lees de waarden van de encoderuitgangen //En sla ze op in variabelen encoder_A = digitalRead(Step); encoder_B = digitalRead(Dir); //Als het niveau van signaal A laag is, //en in de vorige cyclus was het hoog if(!encoder_A && encoder_A_prev) ( //Als het signaalniveau B hoog is if(encoder_B) ( //Dit betekent dat de rotatie met de klok mee plaatsvindt //Onze voorwaarde: //Als de tellerwaarde groter is dan of gelijk aan het maximale aantal if(Counter >= 99999999) ( //Reset de tellerwaarde Counter = 0; ) else ( //Anders, verhoog met één bij elke klik Counter ++; ) ) //Als het signaalniveau B is laag anders ( //Dit betekent dat de rotatie tegen de klok in is //Als de tellerwaarde kleiner is dan of gelijk is aan nul if(Counter<= 0) { //проинициализировать значение максимальным числом Counter = 99999999; } else { //Иначе декрементировать при каждом щелчке на единицу Counter --; } } } //Обязательно нужно сохранить состояние текущего уровня сигнала А //для использования этого значения в следующем цикле сканирования программы encoder_A_prev = encoder_A; //Работаем с центральной осью энкодера - кнопкой //Этот кусок кода образует собой как бы перекидной триггер //Считываем значение пина 2 на плате Arduino //которомый проименован как Switch //Если центральная ось нажата - то сигнал Switch будет иметь низкий уровень if(!digitalRead(Switch)) { //Если переменная SW_State установлена в false то установить её в true if(!SW_State) { //И запомнить состояние SW_State = true; } //И наоборот - если переменная SW_State установлена в true, //то сбросить её в false else { //И запомнить состояние SW_State = false; } } //Часть программы которая заполняет разряды //семисегментного дисплея значением счетчика long intCounter = Counter; int divCounter; for(int i = 0; i < 8; i ++) { divCounter = intCounter % 10; intCounter = intCounter / 10; if(intCounter == 0 && SW_State) { if(divCounter == 0) { if(i == 0) { lc.setChar(0, 0, "0", false); } else { lc.setChar(0, i, " ", false); } } else { lc.setDigit(0, i, divCounter, false); } } else { lc.setDigit(0, i, divCounter, false); } } }

Video van hoe het werkt:


We hopen dat je het materiaal in dit artikel leuk vond; laat je vragen, suggesties en kritiek achter in de reacties hieronder.

  • Industriële optische encoders gebruiken in Arduino
Schakel javascript in om reacties te laten werken.

In dit artikel leert u wat een encoder is, waarom deze nodig is en hoe u deze kunt verbinden met een microcontroller. Als je ooit een moderne wasmachine, magnetron of audiosysteem hebt gebruikt, heb je hoogstwaarschijnlijk zonder dat je het wist al met een encoder te maken gehad. De meeste moderne stereosystemen voor thuis en in de auto gebruiken bijvoorbeeld encoders om het audiovolume aan te passen.
Een encoder of rotatiehoeksensor is een elektromechanisch apparaat dat is ontworpen om de hoekpositie van een as of as om te zetten in elektrische signalen. Er zijn twee hoofdtypen encoders: incrementeel en absoluut.
Bij het draaien genereert de incrementele encoder pulsen, waarvan het aantal evenredig is met de rotatiehoek. Door het aantal van deze pulsen te tellen, krijgen we de rotatiehoek van de encoderas ten opzichte van de beginpositie. Dit type encoder genereert geen uitgangspulsen wanneer de as in rust is. Incrementele encoders worden veel gebruikt in industriële besturingen, huishoudelijke apparaten en muziekapparatuur.
Een absolute encoder produceert een unieke code voor elke positie van zijn as. In tegenstelling tot een incrementele encoder heeft deze geen teller nodig; de rotatiehoek is altijd bekend. Een absolute encoder genereert een signaal wanneer de as draait en wanneer deze in rust is. Een absolute encoder verliest geen informatie over zijn positie wanneer de stroom uitvalt en hoeft niet terug te keren naar zijn oorspronkelijke positie. Dit type encoders wordt gebruikt in industriële apparatuur - robotica, werktuigmachines, transportlijnen.
Ik wil het graag hebben over het koppelen van een incrementele mechanische encoder aan een microcontroller. Om dit te doen, heb ik een incrementele encoder van Bourns gekocht - PEC12-4220F-S0024. Hier is de decodering van de naam volgens het gegevensblad: PEC12 – model, 4 – verticale positie van de draden, 2 – 24 stoppers, 20 – schachtlengte in mm, S – aanwezigheid van een knop, 0024 – 24 pulsen per omwenteling.

Het heeft 5 pinnen. 2 pinnen op de foto links zijn de knoppinnen, 3 pinnen op de foto rechts zijn de encoderpinnen. Hiervan zijn er 2 signaal- en 1 algemeen. Hij zit in het midden. Het encoderaansluitschema verschilt niet van het aansluiten van conventionele knoppen. We verbinden de signaalpinnen van de encoder met elke invoer-/uitvoerpoort van de microcontroller. We plaatsen de gemeenschappelijke uitgang van de encoder op de grond. Ter bescherming tegen contactstuiteren zou het een goed idee zijn om nog een paar keramische condensatoren toe te voegen met een waarde van enkele nanofarads. We configureren de microcontroller-pinnen in het programma als ingangen en zetten de pull-up-weerstanden aan. Externe exemplaren kunnen worden gebruikt.

Wanneer de encoderknop stilstaat, zijn er logische eenheden aan de ingangen van de microcontroller. Wanneer aan de encoderknop wordt gedraaid, verschijnen er twee rechthoekige signalen op de pinnen van de microcontroller, ten opzichte van elkaar verschoven. De draairichting van de encoderas bepaalt welk signaal naar het andere leidt. Onderstaande figuur toont mogelijke signaalopties voor een ideaal geval.


Binnenin de encoder bevinden zich contacten die, wanneer ze worden gedraaid, sluiten of openen. Dit proces gaat uiteraard gepaard met stuiteren, dus echte signalen kunnen er zo uitzien.


De signalen zijn afkomstig van een oude encoder, ingeschakeld zonder filtercondensatoren.


Het cis als volgt. De encoder polling-functie wordt gestart in de timer-interrupt-handler. Het leest de logische niveaus die aanwezig zijn op de pinnen van de microcontroller waarmee de encoder is verbonden en schrijft deze naar een tijdelijke variabele. Binnen een functie bevindt zich een statische variabele (een variabele die zijn waarde behoudt wanneer de functie wordt afgesloten) die de reeks voorgaande toestanden opslaat. Met behulp van een bitmasker extraheert de microcontroller de laatste toestand uit deze variabele en vergelijkt deze met de huidige toestand om te bepalen of er veranderingen zijn opgetreden. Als de toestanden gelijk zijn, eindigt de functie; als ze verschillend zijn, wordt de waarde van de statische variabele met 2 bits naar links verschoven en wordt de huidige toestand naar de “vrijgekomen” ruimte geschreven. Als de encoderas draait, slaat de functie dus voortdurend een bepaalde herhalende codereeks op. Wanneer u naar rechts draait, is dit 11100001. Wanneer u naar links draait, is dit 11010010. Met behulp van deze reeksen begrijpt de microcontroller in welke richting de rotatie plaatsvindt.

De broncode voor het werken met de encoder kan worden gedownload. Het archief bevat twee bestanden: encoder.h en encoder.c. De header specificeert de poort- en pinnummers waarop de encoder is aangesloten, de constanten LEFT_SPIN en RIGHT_SPIN. Ook worden daar functieprototypes beschreven. Het C-bestand bevat de implementatie van de functies.


void InitEncoder(void)– initialiseert de poortpinnen.

ongeldig PollEncoder(ongeldig)
– Pollt de encoder één keer. Als rotatie wordt gedetecteerd, schrijft het een van de constanten in de buffer; als dat niet het geval is, wordt het eenvoudigweg afgesloten.

niet-ondertekende char GetStateEncoder(ongeldig)
– retourneert de inhoud van de buffer en wist deze.

Meestal poll ik de encoder met een frequentie van ~ 4 kHz. Als het pollen langzamer gaat, slaat de microcontroller pulsen over als de encoderknop snel wordt gedraaid. Als de encoder wordt gebruikt om een ​​lineair variërende waarde in te stellen, bijvoorbeeld om de tijd in uren in te stellen, dan is het handig om de getallen 255 en 1 te gebruiken als respectievelijk de constanten LEFT_SPIN en RIGHT_SPIN. In de encodersignaalprocessor worden deze getallen eenvoudigweg opgeteld bij de ingestelde waarde. Bij het optellen met 1 wordt de waarde met 1 verhoogd, bij het optellen met 255 neemt deze af met 1. Dit is uiteraard relevant als deze waarde één byte is. Welnu, in principe kunnen de constanten LEFT_SPIN en RIGHT_SPIN willekeurig worden gekozen, het belangrijkste is om de handler correct te schrijven. Dat is alles.

Broncode voor het werken met de encoder.

Eindelijk heb ik deze prachtige spinner en nu wil ik je vertellen hoe je ermee kunt werken. Mijn encoder (EC12E24204A9) is ongeveer zo:

De encoder heeft drie contacten: Common, A en B. Common is meestal altijd verbonden met aarde en de andere twee met eventuele pinnen van de microcontroller. Klemmen A en B moeten worden aangesloten op de positieve voeding via weerstanden van ongeveer 10 kOhm om valse positieven door interferentie te voorkomen. Ik zou het gebruik van een interne aanscherping van de microcontroller niet aanbevelen. Ze is erg zwak. Om het werk te demonstreren hangen we nog 8 LED's op. (let op: als mega16, mega32 en ouder worden gebruikt, moet jtag uitgeschakeld zijn, anders gaat de helft van de LED's niet branden)
We kregen dus het volgende diagram:


We draaien de encoderknop naar rechts - het licht loopt naar rechts. We draaien naar links - het licht loopt naar links. Hoe werkt een encoder? We komen er wel achter. Er is niets ingewikkelds. Laten we naar de onderstaande grafieken kijken.
Wanneer de encoder in één richting wordt gedraaid, ziet het signaal er als volgt uit:

Aan een ander:

De vraag rijst: hoe kan de microcontroller de draairichting van de encoder onderscheiden?

Er zijn twee populaire polling-algoritmen voor encoders:

  • Pollen met behulp van interrupts
  • Poll met vergelijking van de vorige status van de encoder en de huidige

Elk van deze onderzoeksmethoden heeft zijn eigen nadelen en voordelen. Ik heb beide geprobeerd en heb gekozen voor de tweede methode. Pollen met behulp van interrupts is goed omdat het een onmiddellijke reactie kan geven op het draaien van de encoderknop. Maar er is ook een ernstig nadeel. Zoals contactbounce. Om het te onderdrukken kun je natuurlijk verschillende software en hardware gebruiken, maar dat vond ik niet erg. Laten we het tweede polling-algoritme eens nader bekijken. Tijdens bedrijf leest de microcontroller continu gegevens van de pinnen waaraan de encoder hangt en vergelijkt wat hij leest met het resultaat van de vorige meting. Afhankelijk van het resultaat van het vergelijken van toestanden trekt het programma conclusies over de draairichting. Het programma heeft opmerkingen, ik denk dat deze voldoende zullen zijn om het algoritme te begrijpen. Als u vragen heeft, kunt u deze, zoals altijd, stellen in de reacties.

Kortom, encoders kunnen hoekverplaatsingstransducers worden genoemd. Ze dienen om de rotatiehoek van een rotatieobject, bijvoorbeeld de as van een mechanisme, om te zetten in een elektrisch stroomsignaal. In dit geval wordt niet alleen de rotatiehoek van de as bepaald, maar ook de draairichting ervan, evenals de rotatiesnelheid en de huidige positie ten opzichte van de oorspronkelijke positie.

Encoders zijn het populairst geworden bij gebruik in precisiebewegingssystemen, in machinefabrieken, in productiecomplexen die gebruik maken van robotica, in meetapparatuur die nauwkeurige metingen van kantelingen, draaiingen, rotaties en hoeken vereist.

Typen en werkingsprincipe

Encoders zijn rotatiesensoren. De eenvoudigste sensor heeft een handvat dat met de klok mee of tegen de klok in kan worden gedraaid. Afhankelijk van de draaihoek en richting wordt een digitaal signaal afgegeven, dat informeert over de positie van de hendel of in welke richting deze is gedraaid.

Voor een dergelijke encoder, weergegeven in de figuur, kan de hendel ook als knop worden gebruikt. Dit is een hulpfunctie van een specifiek type encoder.

Op basis van het type gegevensuitvoer worden encoders in twee grote groepen verdeeld:
  1. Absoluut.
  2. Toenemend.
Absolute encoders

Bij een absolute encoder wordt de gehele rotatiecirkel verdeeld in een bepaald aantal sectoren, meestal van dezelfde grootte. Deze sectoren zijn genummerd. Tijdens bedrijf geeft de encoder het nummer weer van de sector waarin deze zich momenteel bevindt. Daarom heet het absoluut. Met dit type encoder kun je altijd bepalen onder welke hoek ten opzichte van de nulsector de encoder op een bepaald moment wordt geroteerd, dat wil zeggen dat hij bij rotatie de waarden van de sectornummers produceert, tot aan de maximale waarde. Daarna gaat het terug naar nul.

Als de encoderas in de andere richting wordt gedraaid, begint deze tegengestelde waarden te produceren. In ons geval gebruikt het vijf pinnen om rotatiewaarden uit te voeren.

Dit algoritme heeft zijn nadelen. Tabel 1 toont de volgorde van de uitgangswaarden van de n-de encoder. Het is de moeite waard om aandacht te besteden aan de laatste twee regels, de overgang van 127 naar 128.

tafel 1

Absoluut alle stukjes veranderen hier. In een ideale encoder veranderen ze allemaal tegelijkertijd en zijn er geen problemen. In bijna een echte encoder veranderen de bits snel, maar niet tegelijkertijd. En op een gegeven moment blijkt de uitvoer van de encoder een volkomen willekeurige waarde te zijn. Omdat alle bits veranderen, zal de encoder een willekeurige waarde hebben, van nul tot allemaal enen.

Rechts ziet u een voorbeeld van zo'n schakelaar. Wat zou dit kunnen betekenen? Laten we eens kijken naar een voorbeeld. De microcontroller gebruikt een motor om de as aan te sturen en deze in een bepaalde hoek te draaien. Op een gegeven moment, bij het overschakelen van cel 127 naar cel 128, ontvangt het een bepaalde willekeurige waarde. De controller concludeert dat de as zich op een compleet andere plaats bevindt, in tegenstelling tot de werkelijke locatie, en begint deze in een andere richting te draaien, met een andere snelheid, enz.

Na een bepaalde tijd ontvangt de microcontroller de juiste waarde en begint te proberen de as te stoppen en in de juiste richting te draaien. Dit proces kan lang duren, op voorwaarde dat een dergelijke fout vaak voorkomt. Dergelijke fouten zijn onregelmatig en vrij moeilijk te berekenen.

Grijze code

Het hierboven beschreven probleem wordt opgelost door een Gray-code te introduceren. Een kenmerk van de Gray-code is dat wanneer de encoder naar één wordt geschakeld, de waarde van de Gray-code ook met één verandert. Er verandert slechts één type. Dit is te zien in Tabel 2 in de vergelijking tussen binaire code en Gray-code.

tafel 2

De eerste twee regels zijn hetzelfde, maar al in de tweede regel is het middelste bit veranderd. Dan verandert er ook een stukje. Het is ook vermeldenswaard dat de laatste en eerste Gray-code één bit verschillen, wat betekent dat de Gray-code in een lus terecht kan komen.

Het voordeel van deze code is dat de hierboven besproken fout niet mogelijk is. Een van de nadelen is dat de microcontroller de Gray-code naar binaire code moet converteren om te begrijpen in welke positie de absolute encoder zich bevindt.

Incrementele encoders

Het volgende type is de incrementele encoder, die een eenvoudiger structuur heeft. Maar tegelijkertijd laat hij niet de specifieke locatie van zijn hok zien. Het toont alleen de draairichting en het aantal rotatieverdelingen moet door de microcontroller worden geteld.

Een incrementele encoder heeft een set strips die standaard met aarde zijn verbonden en die, wanneer ze worden gedraaid, verbindingen maken en verbreken. Het resultaat is het signaal dat in de figuur wordt weergegeven (vergelijkbaar met een blokgolf). De encoder heeft twee van dergelijke cirkelvormige strips. De strips worden met een kwart verschoven, en de signalen worden ook met een kwart verschoven. Dit is belangrijk omdat je hiermee de draairichting kunt bepalen.

Het circuit van een incrementele encoder kan worden weergegeven in de rechter figuur. De knoppen geven periodieke verbindingen van de encoder met aarde aan. Omdat de encoder intern niet met een logische eenheid is verbonden, is het noodzakelijk om de logische eenheden onafhankelijk van buitenaf via weerstanden naar de encoderuitgang te trekken. In dit geval, wanneer geen van de poten van de encoder met aarde is verbonden, zal er een logische poten op de poten zitten.

Als de encoder een been met de grond heeft verbonden, heeft dit been een logische nul. In een stille toestand is de uitvoer van de encoder logisch. Wanneer u de encoder in welke richting dan ook draait, wordt eerst de ene pin met aarde verbonden en vervolgens de andere. Vervolgens worden deze pinnen op hun beurt losgekoppeld van de aarde en wordt er opnieuw een logische eenheid op gevormd.

De draairichting kan worden bepaald door welke van de terminals het eerst met de grond was verbonden. Bij het tellen van volledige cycli kunt u het aantal klikken tellen dat de encoder draait.

In feite heeft de encoder vier statussen:
  1. Twee eenheden.
  2. Nul en één.
  3. Nul en nul.
  4. Eén en nul.

Drie toestanden die niet gelijk zijn aan één zijn onstabiel en de encoder kan zich daar niet in bevinden. Veel microcontrollers implementeren de functie van het tellen van beurten met behulp van timers die specifieke ingangen hebben. De timer telt op hardwareniveau hoeveel klikken en in welke richting de encoder is gedraaid, en geeft de waarde weer. Dat wil zeggen, de teller verhoogt een getal.

Door dit aantal te wijzigen, kunt u bepalen hoeveel klikken de encoder heeft gedraaid. Aan de hand van het aantal klikken kun je de draaihoek bepalen. De encoder heeft ook contactbounce, wat signaalanalyse bemoeilijkt.

Optische encoders

Een dergelijke converter is gemaakt in de vorm van een schijf die op een as is bevestigd en is gemaakt van glas. De optische rotatiesensor verschilt van andere typen doordat deze een extra optische array heeft die beweegt wanneer de as wordt gedraaid. Tegelijkertijd zet het het koppel om in een lichtstroom, die vervolgens wordt opgevangen door een fotosensor.

De optische converter onthoudt rotatiehoeken. In dit geval komt elke individuele positie overeen met een speciale digitale code, die samen met het aantal omwentelingen de meeteenheid van de sensor vormt. De encoder wordt aangesloten en werkt op dezelfde manier als een incrementele encoder.

Afhankelijk van de aard van hun functioneren, zijn ze onderverdeeld in fotovoltaïsch En magnetisch . Het werkingsprincipe van magnetisch is gebaseerd op het gebruik van , dat voor het eerst werd ontdekt in 1879. In dit geval treedt er alleen een potentiaalverschil op als een gelijkstroomdraad in een magnetisch veld wordt geplaatst.

In termen van nauwkeurigheid en resolutie-eigenschappen is het magnetische type sensor inferieur aan de foto-elektrische sensor, maar het is eenvoudiger van ontwerp en minder veeleisend voor de bedrijfsomstandigheden en de ruimte. Een magnetische encoder is een apparaat dat de doorgang van de magnetische pool van een magneet tijdens rotatie detecteert, gelegen naast het gevoelige element. Zenderinformatie wordt uitgedrukt in digitale code.

Foto-elektrische encoder is een sensor die werkt volgens het foto-elektrische principe. Dit effect wordt waargenomen wanneer een stof wordt blootgesteld aan licht. Dit principe werd ontdekt in 1887. Bij het bedienen van een dergelijke sensor wordt de lichtstraal voortdurend omgezet in een elektrisch stroomsignaal.

Analogen van de foto-elektrische encoder zijn opto-elektronische, optische en. Deze sensoren zijn gevoeliger voor productiekenmerken, werking en andere factoren in vergelijking met andere modellen. Dit wordt echter gerechtvaardigd door hun grotere nauwkeurigheid, in tegenstelling tot hun concurrenten.

Iedereen is vast wel eens een encoder tegengekomen in het dagelijks leven. In autoradio's worden ze bijvoorbeeld gebruikt om het volume te regelen. Of bij computermuizen: een scrollwiel.

Met hun hulp is het erg handig om het menu te organiseren. Ik ken gevallen waarin, op een zeer serieus en duur apparaat, alle controle wordt georganiseerd met behulp van slechts één encoder. Op dezelfde manier was er in de oudheid een telefoonmodel waarbij alle bedieningselementen ook met slechts één wiel waren georganiseerd.

Allereerst zijn er verschillende soorten encoders; degene die in dit artikel wordt besproken, is mechanisch incrementeel. Pec12-4220f-s0024 werd als proefpersoon gebruikt. Uiterlijk lijkt het op een variabele weerstand, maar in tegenstelling tot een weerstand heeft hij geen begrenzers, d.w.z. kan eindeloos in elke richting draaien.

Het resultaat van zo'n apparaat is een binaire Gray-code. Dit kan worden verkregen door de toestand van de benen te analyseren waarop pulsen van de encoder aankomen.

Laten we nu alles in meer detail bekijken. Elektrisch gezien bestaat het uit 2 knoppen zonder vergrendeling, wanneer we beginnen te draaien werken ze om de beurt - eerst één, daarna de tweede. Afhankelijk van in welke richting we draaien, wordt een van de knoppen eerder of later geactiveerd. Om erachter te komen in welke staat deze knoppen zich bevinden, moeten de pootjes van de poort (waarop de encoder is aangesloten) omhoog worden getrokken naar de “+” voeding.

Bij een gedemonteerde encoder behoort 1/3 van het gebied tot het 1e contact, 1/3 tot het 2e contact, het dichte gebied is gebruikelijk. Wanneer de schuifcontacten de geïsoleerde gebieden (zwart) raken, is een klikkend geluid hoorbaar. Op dit moment bevindt de encoder zich in een stabiele toestand wanneer beide knoppen open zijn. Er zullen houtblokken op de bakboordbenen staan ​​(staat 11).

Zodra we in welke richting dan ook beginnen te draaien, sluit een van de contacten zich naar de aarde. Log 0 zal verschijnen op deze etappe, log 1 zal nog steeds verschijnen op de tweede etappe (status 01). Als we doorgaan met roteren, verschijnt log0 (status 00) op het tweede been. Vervolgens verdwijnt het contact op het eerste been (toestand 10) en uiteindelijk keert de encoder terug naar een stabiele toestand (11). Die. Er zijn 4 statuswijzigingen per klik. Het timingdiagram ziet er als volgt uit:

Bij het draaien in de tegenovergestelde richting blijft het idee hetzelfde, alleen de tweede poot gaat als eerste dicht.

Als we deze toestanden in het binaire systeem uitschrijven en ze omzetten naar decimalen, krijgen we de volgende volgorde (voor rotatie in één richting):
11=3
01=1
00=0
10=2

Bij draaien in de tegenovergestelde richting:
11=3
10=2
00=0
01=1

Nu moet nog worden begrepen hoe deze waarden moeten worden verwerkt. Laten we zeggen dat de encoder is aangesloten op de poortpinnen B0 en B1. We moeten deze benen lezen. Er is een behoorlijk slimme manier, maar eerst moeten we de logische en (&) werking begrijpen.

Het resultaat is alleen gelijk aan één als beide getallen gelijk zijn aan 1, d.w.z. het resultaat van de bewerking 1&1 zal gelijk zijn aan 1. Daarom is 1&0=0, 0&0=0, 0&1=0.

Logisch en zal ons helpen alleen de benen die ons interesseren van de hele haven te isoleren. Die. bediening x=0b00000011 & PINB; zal ons in staat stellen om in de variabele “x” de toestand van de eerste twee benen te lezen, ongeacht wat zich op de overige benen bevindt. Het getal 0b00000011 kan worden omgezet naar hexadecimaal 0x3.

Nu hebben we alle benodigde kennis om firmware te schrijven. Taak: verhoog/verlaag de Vol-variabele met behulp van een encoder, geef het resultaat weer op het LCD-scherm.

#erbij betrekken int NieuweState, OudeState, Vol, upState, downState; #asm.equ __lcd_port= 0x12; PORTD #endasm #include #erbij betrekken interrupt [ TIM1_COMPA] void timer1_compa_isr(void ) ( NewState= PINB & 0b00000011 ; if (NewState!= OldState) ( switch (OldState) ( case 2 : ( if (NewState == 3 ) upState++; if (NewState == 0 ) downState++ ; break ; ) case 0 : ( if (NewState == 2 ) upState++; if (NewState == 1 ) downState++; break ; ) case 1 : ( if (NewState == 0 ) upState++; if (NewState == 3 ) downState++ ; break ; ) geval 3: ( if (NewState == 1 ) upState++; if (NewState == 2 ) downState++; break ; ) ) OldState= NewState; ) TCNT1H= 0x00 ; TCNT1L= 0x00 ; ) void main(void ) ( char lcd_buf[17] ; // Initialisatie van invoer-/uitvoerpoorten// Poort B-initialisatie // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // Staat7=T Staat6=T Staat5=T Staat4=T Staat3=T Staat2=T Staat1=P Staat0=P POORTB= 0x03; DDRB= 0x00; // Timer/teller 1 initialisatie// Klokbron: Systeemklok // Klokwaarde: 1000.000 kHz // Modus: CTC top=OCR1A // OC1A-uitgang: Discon. // OC1B-uitvoer: Discon. // Ruisonderdrukking: Uit // Invoeropname op dalende rand // Timer 1 Overlooponderbreking: Uit // Invoeropname onderbreken: Uit // Vergelijk een wedstrijdonderbreking: Aan // Vergelijk B Match Interrupt: Uit TCCR1A= 0x00; TCCR1B= 0x0A; TCNT1H= 0x00; TCNT1L= 0x00; ICR1H= 0x00 ; ICR1L= 0x00; OCR1AH= 0x03; OCR1AL= 0xE8; OCR1BH= 0x00; OCR1BL= 0x00; // Timer(s)/teller(s) Initialisatie onderbreken TIMSK= 0x10; // Globaal inschakelen interrupts #asm("sei") lcd_init(8 ); while (1 ) ( if (upState >= 4 ) ( Vol++; upState = 0 ; ) if (downState >= 4 ) ( Vol--; downState = 0 ; ) sprintf (lcd_buf, "vol=%d" , Vol) ; lcd_gotoxy(0 , 0 ) ; lcd_clear() ; lcd_puts(lcd_buf) ; ) ; )

#erbij betrekken int NieuweState,OudeState,Vol,upState,downState; #asm .equ __lcd_port=0x12 ;POORTD #endasm #include #erbij betrekken interrupt void timer1_compa_isr(void) ( NewState=PINB & 0b00000011; if(NewState!=OldState) ( switch(OldState) ( case 2: ( if(NewState == 3) upState++; if(NewState == 0) downState++; break; ) case 0: ( if(NewState == 2) upState++; if(NewState == 1) downState++; break; ) case 1: ( if(NewState == 0) upState++; if(NewState == 3) downState++; break; ) geval 3: ( if(NewState == 1) upState++; if(NewState == 2) downState++; break; ) ) OldState=NewState; ) TCNT1H=0x00; TCNT1L=0x00; ) void main(void) ( char lcd_buf; // Initialisatie van invoer-/uitvoerpoorten // Initialisatie van poort B // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4 =T State3=T State2=T State1=P State0=P PORTB=0x03; DDRB=0x00; // Initialisatie timer/teller 1 // Klokbron: systeemklok // Klokwaarde: 1000.000 kHz // Modus: CTC top=OCR1A // OC1A-uitgang: Discon. // OC1B-uitgang: Discon. // Ruisonderdrukking: Uit // Invoeropname op dalende flank // Timer 1 Overflow Interrupt: Uit // Invoeropname Onderbreking: Uit // Vergelijk een match Onderbreken: Aan // Vergelijk B Match Onderbreken: Uit TCCR1A=0x00; TCCR1B=0x0A; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x03; OCR1AL=0xE8; OCR1BH=0x00; OCR1BL=0x00; // Timer(s)/teller(s) Interrupt(s) initialisatie TIMSK=0x10; // Globale enable interrupts #asm("sei") lcd_init(8); while (1) ( if (upState >= 4) ( Vol++; upState = 0; ) if (downState >= 4) ( Vol--; downState = 0; ) sprintf(lcd_buf,"vol=%d",Vol) ; lcd_gotoxy(0,0); lcd_clear(); lcd_puts(lcd_buf); ); )

Ter verduidelijking: timer 1 is geconfigureerd om 1000 keer per seconde te flitsen, met de regel NewState=PINB & 0b00000011; We lezen de stand van pin 0 en 1 van poort B. if(NewState!=OldState) als de status niet is veranderd, is er geen rotatie.
Als de status is veranderd, bepaalt de schakelconstructie in welke richting de rotatie is uitgevoerd, afhankelijk hiervan neemt de waarde van de downState (links) of upState (rechts) variabele toe.

Van een klik tot de volgende klik zijn er 4 statusveranderingen, dus we veranderen de Vol-variabele eens per 4 pulsen. We tonen het ook op het display. Firmware beschikbaar