Operácie

Snímanie polohy optickým enkodérom

Zo stránky SensorWiki

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.