Snímanie polohy optickým enkodérom: Rozdiel medzi revíziami
Zo stránky SensorWiki
Vytvorená stránka „Záverečný projekt predmetu MIPS / LS2025 - '''Meno Priezvisko''' == Zadanie == Sem príde text zadania, ak bolo len voľne formulované, rozpíšte ho podrobnejšie 400px|thumb|center|Vývojová doska ACROB. '''Literatúra:''' * [http://ap.urpi.fei.stuba.sk/sensorwiki/index.php/Acrob_technical_description Dokumentácia k doske Acrob] * [http://www.humanbenchmark.com/tests/reactiontime/index.php Vyskúšajte si zmerať reakciu on-line]…“ |
|||
(14 medziľahlých úprav od 2 ďalších používateľov nie je zobrazených) | |||
Riadok 1: | Riadok 1: | ||
Záverečný projekt predmetu MIPS / LS2025 - ''' | Záverečný projekt predmetu MIPS / LS2025 - '''Lukáš Čapla''' | ||
== Zadanie == | == Zadanie == | ||
Cieľom projektu je snímanie polohy natočenia optickým rotačným enkóderom, a túto polohu vypísať cez sériovú komunikáciu na počítač. | |||
[[Obrázok: | [[Obrázok:"doskanano.jpg"|300px|thumb|center|PinOut dosky Arduino nano.]] | ||
'''Literatúra:''' | '''Literatúra:''' | ||
* [ | * [https://practicalusage.com/arduino-using-a-rotary-encoder Blog o fungovaní rotačného enkóderu] | ||
Riadok 17: | Riadok 17: | ||
== Analýza a opis riešenia == | == Analýza a opis riešenia == | ||
V zadaní použijeme optický rotačný enkodér (LPD3806-600BM Rotary Encoder 600 Pulse NPN) teda 600 pulzov na jednu otáčku hriadeľa. | |||
[[Súbor: | [[Súbor:encoderCapla.webp|400px|thumb|center|LPD3806-600BM.]] | ||
Schéma zapojenia | |||
[[Súbor: | [[Súbor:CaplaProficad.jpg|400px|thumb|center|Schéma zapojenia.]] | ||
Signály A a B rotačného enkóderu. | |||
[[Súbor:rotaryencodersignals.jpg|400px|thumb|center|Signály rotačného enkóderu.]] | |||
zdroj: https://www.makerguides.com/quadrature-rotary-encoder-with-arduino/ | |||
=== Algoritmus a program === | === Algoritmus a program === | ||
Algoritmus programu využíva | Algoritmus programu využíva prerušenia, pretože inak by sa mohlo stať, že niektoré signály procesor nespracuje. Teda použijeme piny PD2 a PD3 ako vstupy so zapnutými prerušeniami v sledovaní nábežnej hrany, čo je veľmi výhodné aj využiť, keďže princíp činnosti by sa dal vtedy opísať: | ||
ak signál A PD2 (INT0) prejde z 0 do 1, teda nábežná hrana sig. A a zároveň signál B nadobudne hodnotu 1, jedná sa o smer po smeru hodinových ručičiek teda inkrementujeme premennú counter, z obrázku signálov vyššie je zrejmé, že ak točíme hriadeľ opačným smerom, postup signálov sa jednoducho vymení, a teda pracujeme s prerušením signálu B PD3. | |||
Použitý enkodér má 600 impulzov na otáčku, čo znamená 600 nábežných hrán na jednom kanáli (napríklad A) za jednu úplnú otáčku. Keďže v tomto programe spracovávame nábežné hrany na oboch kanáloch A aj B, dostávame dvojnásobok impulzov – teda 1200 impulzov na otáčku (Counts Per Revolution, CPR). Ide o tzv. 2x kvadratúrne dekódovanie. Keby sme sledovali aj zostupné hrany (falling edge), bolo by možné dosiahnuť až 4x dekódovanie a teda 2400 impulzov na otáčku. | |||
Ďalej sa v hlavnom programe len vypisuje aktuálne natočenie hriadeľa cez UART sériovú linku na počítač, teda využívame knižnicu uart.h ako na cvičeniach. | |||
<tabs> | <tabs> | ||
<tab name=" | |||
<tab name="main.h"><syntaxhighlight lang="c++" style="background: LightYellow;"> | |||
#include <avr/io.h> | #include <avr/io.h> | ||
#include <avr/interrupt.h> | |||
#include <stdio.h> | |||
#include "uart.h" | |||
#include <util/delay.h> | |||
volatile long counter = 0; | |||
volatile long temp = 0; | |||
#define BAUD 9600 | |||
FILE mystdout = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE); | |||
// External Interrupt 0 (INT0) Handler (PD2) | |||
ISR(INT0_vect) { | |||
if (!(PIND & (1 << PIND3))) { | |||
counter++; | |||
} else { | |||
counter--; | |||
} | |||
} | |||
// External Interrupt 1 (INT1) Handler (PD3) | |||
ISR(INT1_vect) { | |||
if (!(PIND & (1 << PIND2))) { | |||
counter--; | |||
} else { | |||
counter++; | |||
} | |||
} | } | ||
int main(void) { | |||
uart_init(); // Uart init | |||
stdout = &mystdout; | |||
// Set PD2 and PD3 as inputs with pull-up | |||
DDRD &= ~((1 << DDD2) | (1 << DDD3)); // Inputs | |||
PORTD |= (1 << PORTD2) | (1 << PORTD3); // Enable pull-up resistors | |||
uart_init(); | |||
// Enable external interrupts on INT0 and INT1 on rising edge | |||
EICRA |= (1 << ISC01) | (1 << ISC00); // INT0: Rising edge | |||
EICRA |= (1 << ISC11) | (1 << ISC10); // INT1: Rising edge | |||
EIMSK |= (1 << INT0) | (1 << INT1); // Enable INT0 and INT1 | |||
sei(); // Enable global interrupts | |||
while (1) { | |||
if (temp != counter) { | |||
temp = counter; | |||
printf("natocenie: %ld\r",counter); | |||
} | |||
} | |||
return 0; | |||
} | |||
</syntaxhighlight ></tab> | </syntaxhighlight ></tab> | ||
</tabs> | </tabs> | ||
Zdrojový kód: [[Médiá: | Zdrojový kód: [[Médiá:CaplaLukas.zip|zdrojaky.zip]] | ||
=== Overenie === | === Overenie === | ||
Funkciu sme overili pomocou seriového terminálu https://libhal.github.io/web-serial/ a teda ako je možné vidieť na videu, natočením hriadeľa snímame počet pulzov, čo by sme mohli následne previesť na stupne prípadne radiány, to by záviselo od konkrétneho použitia tohto typu senzoru, samozrejme môžeme takisto pracovať aj v týchto arbitrárnych číslach. | |||
[[Súbor: | [[Súbor:CaplaZapojenie.jpg|400px|thumb|center|Hotové zariadenie/zapojenie.]] | ||
'''Video:''' | '''Video:''' | ||
<center><youtube> | <center><youtube>IL0pBf987gY</youtube></center> | ||
Aktuálna revízia z 20:58, 15. máj 2025
Záverečný projekt predmetu MIPS / LS2025 - Lukáš Čapla
Zadanie
Cieľom projektu je snímanie polohy natočenia optickým rotačným enkóderom, a túto polohu vypísať cez sériovú komunikáciu na počítač.

Literatúra:
Analýza a opis riešenia
V zadaní použijeme optický rotačný enkodér (LPD3806-600BM Rotary Encoder 600 Pulse NPN) teda 600 pulzov na jednu otáčku hriadeľa.

Schéma zapojenia

Signály A a B rotačného enkóderu.

zdroj: https://www.makerguides.com/quadrature-rotary-encoder-with-arduino/
Algoritmus a program
Algoritmus programu využíva prerušenia, pretože inak by sa mohlo stať, že niektoré signály procesor nespracuje. Teda použijeme piny PD2 a PD3 ako vstupy so zapnutými prerušeniami v sledovaní nábežnej hrany, čo je veľmi výhodné aj využiť, keďže princíp činnosti by sa dal vtedy opísať: ak signál A PD2 (INT0) prejde z 0 do 1, teda nábežná hrana sig. A a zároveň signál B nadobudne hodnotu 1, jedná sa o smer po smeru hodinových ručičiek teda inkrementujeme premennú counter, z obrázku signálov vyššie je zrejmé, že ak točíme hriadeľ opačným smerom, postup signálov sa jednoducho vymení, a teda pracujeme s prerušením signálu B PD3.
Použitý enkodér má 600 impulzov na otáčku, čo znamená 600 nábežných hrán na jednom kanáli (napríklad A) za jednu úplnú otáčku. Keďže v tomto programe spracovávame nábežné hrany na oboch kanáloch A aj B, dostávame dvojnásobok impulzov – teda 1200 impulzov na otáčku (Counts Per Revolution, CPR). Ide o tzv. 2x kvadratúrne dekódovanie. Keby sme sledovali aj zostupné hrany (falling edge), bolo by možné dosiahnuť až 4x dekódovanie a teda 2400 impulzov na otáčku.
Ďalej sa v hlavnom programe len vypisuje aktuálne natočenie hriadeľa cez UART sériovú linku na počítač, teda využívame knižnicu uart.h ako na cvičeniach.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include "uart.h"
#include <util/delay.h>
volatile long counter = 0;
volatile long temp = 0;
#define BAUD 9600
FILE mystdout = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);
// External Interrupt 0 (INT0) Handler (PD2)
ISR(INT0_vect) {
if (!(PIND & (1 << PIND3))) {
counter++;
} else {
counter--;
}
}
// External Interrupt 1 (INT1) Handler (PD3)
ISR(INT1_vect) {
if (!(PIND & (1 << PIND2))) {
counter--;
} else {
counter++;
}
}
int main(void) {
uart_init(); // Uart init
stdout = &mystdout;
// Set PD2 and PD3 as inputs with pull-up
DDRD &= ~((1 << DDD2) | (1 << DDD3)); // Inputs
PORTD |= (1 << PORTD2) | (1 << PORTD3); // Enable pull-up resistors
uart_init();
// Enable external interrupts on INT0 and INT1 on rising edge
EICRA |= (1 << ISC01) | (1 << ISC00); // INT0: Rising edge
EICRA |= (1 << ISC11) | (1 << ISC10); // INT1: Rising edge
EIMSK |= (1 << INT0) | (1 << INT1); // Enable INT0 and INT1
sei(); // Enable global interrupts
while (1) {
if (temp != counter) {
temp = counter;
printf("natocenie: %ld\r",counter);
}
}
return 0;
}
Zdrojový kód: zdrojaky.zip
Overenie
Funkciu sme overili pomocou seriového terminálu https://libhal.github.io/web-serial/ a teda ako je možné vidieť na videu, natočením hriadeľa snímame počet pulzov, čo by sme mohli následne previesť na stupne prípadne radiány, to by záviselo od konkrétneho použitia tohto typu senzoru, samozrejme môžeme takisto pracovať aj v týchto arbitrárnych číslach.

Video:
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.