Operácie

Snímanie polohy optickým enkodérom: Rozdiel medzi revíziami

Zo stránky SensorWiki

StudentMIPS (diskusia | príspevky)
StudentMIPS (diskusia | príspevky)
 
(7 medziľahlých úprav od rovnakého používateľa nie je zobrazených.)
Riadok 4: Riadok 4:
== Zadanie ==
== Zadanie ==


Cieľom projektu je snímanie polohy natočenia optickým rotačným enkóderom, a túto polohu vypísať sériovú komunikáciu na počítač.  
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:"doskanano.jpg"|300px|thumb|center|PinOut dosky Arduino nano.]]
[[Obrázok:"doskanano.jpg"|300px|thumb|center|PinOut dosky Arduino nano.]]
Riadok 19: Riadok 19:
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.
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:encoder.webp|400px|thumb|center|LPD3806-600BM.]]
[[Súbor:encoderCapla.webp|400px|thumb|center|LPD3806-600BM.]]


Nezabudnite doplniť schému zapojenia! V texte by ste mali opísať základné veci zo zapojenia, samotná schéma nie je dostačujúci opis.
Schéma zapojenia


[[Súbor:GeminiAI-image2.jpg|400px|thumb|center|Schéma zapojenia.]]
[[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 toto a toto, základné funkcie sú takéto a voláma ich tuto...  
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ť:
Výpis kódu je nižšie...
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="AVR C-code"><syntaxhighlight  lang="c++" style="background: LightYellow;">
 
<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;


int main(void)
{
  unsigned int measuredValue;


  while (1)
#define BAUD 9600
  {
    /*  relax  */ 
  }


  return(0);
 
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--;
}
}
}


</syntaxhighlight ></tab>
// External Interrupt 1 (INT1) Handler (PD3)
<tab name="filename.h"><syntaxhighlight lang="c++" style="background: LightYellow;">
ISR(INT1_vect) {
#include <avr/io.h>
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


void adc_init(void);                                   // A/D converter initialization
while (1) {
if (temp != counter) {
temp = counter;
printf("natocenie: %ld\r",counter);
}
}


unsigned int adc_read(char a_pin);
return 0;
}
</syntaxhighlight ></tab>
</syntaxhighlight ></tab>
</tabs>
</tabs>


Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x ''zdrojaky.zip'':


Zdrojový kód: [[Médiá:projektMenoPriezvisko.zip|zdrojaky.zip]]
Zdrojový kód: [[Médiá:CaplaLukas.zip|zdrojaky.zip]]


=== Overenie ===
=== Overenie ===


Ako ste overili funkciu, napríklad... Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia.
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.
Na konci uvádzame fotku hotového zariadenia.  


[[Súbor:GeminiAI-image1.jpg|400px|thumb|center|Aplikácia.]]
[[Súbor:CaplaZapojenie.jpg|400px|thumb|center|Hotové zariadenie/zapojenie.]]


'''Video:'''
'''Video:'''
<center><youtube>D0UnqGm_miA</youtube></center>
<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č.

PinOut dosky Arduino nano.

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.

LPD3806-600BM.

Schéma zapojenia

Schéma zapojenia.

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

Signály 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.

Hotové zariadenie/zapojenie.

Video:



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