ATtiny13 a rotacny enkoder

C,C++,C#

Moderátori: psichac, Moderátori

kuboo
Okoloidúci
Okoloidúci
Príspevky: 6
Dátum registrácie: 26 Jún 2013, 19:46

ATtiny13 a rotacny enkoder

Príspevok od používateľa kuboo » 26 Jún 2013, 20:11

Ahojte, s AVRkami este len zacinam a pokusam sa rozchodit opticky rotacny enkoder s procesorom ATtiny13. Na procesor su cez odpory pripojede 4 ledky na pinoch PB0-PB3, na piny PB4 a PB5 je priamo pripojeny rotacny enkoder. Chcem napisat program, ktory rozsvieti ledku na pine PB0 ak sa enkoder otaca jednym smerom a ledku na pine PB3 ak sa otaca druhym smerom. Inspiroval som sa zdrojovym kodom zo stranky http://stackoverflow.com/questions/3473 ... controller . Cele sa to vsak chova velmi zvlastne. Ledka na pine PB0 pri otacani enkodera nesvieti, rozsvieti sa len niekedy po dotoceni enkodera a ledka na pine PB4 nerobi nic. Ked som sa pokusal hladat chybu a rozne modifikovat kod, nechal som hned na zaciatku este rozsvietit ledky na pinoch PB1 a PB2. Tie by mali svietit stale, oni vsak svietia len vtedy ak svieti aj dioda PB0. Nemam uz absolutne ziadne tusenie kde hladat chybu. Nevedeli by ste ma niekto usmernit co robim zle ? Prichadza do uvahy teoreticky aj problem s napajanim ? To je realizovane len s pomocou programatora z usb portu.

Prikladam este pouzity kod:

Kód: Vybrať všetko

#include <avr/io.h>

#define LED_1 PB0
#define LED_2 PB1
#define LED_3 PB2
#define LED_4 PB3

#define SIGNAL_A (PINB & (1<<PB4))
#define SIGNAL_B (PINB & (1<<PB5)) 

int main(void){
	
	uint8_t dir = 0;
	uint8_t smer = 0;
	
	DDRB = 0b00001111;

	PORTB |= (1<<LED_2);
	PORTB |= (1<<LED_3);
	
	while(1){			
		if (dir == 0) {
			if (SIGNAL_A & (!SIGNAL_B)) {
				dir = 2;
			} else if(SIGNAL_B & (!SIGNAL_A)) {
				dir = 4;
			} else {
				dir = 0;
			}	
		} else if (dir == 2){
			if (SIGNAL_A & (!SIGNAL_B)) {
				dir = 2;
			} else if ((!SIGNAL_A) & (!SIGNAL_B)) {
				smer = 0;
				dir = 0;
			} else {
				dir = 0;
			}
		} else if (dir == 4) {
			if (SIGNAL_B & (!SIGNAL_A)) {
				dir = 4;
			} else if ((!SIGNAL_A) & (!SIGNAL_B)) {
				smer = 1;
				dir = 0;
			} else {
				dir = 0;
			}
		} else if (SIGNAL_B & SIGNAL_A) {
			dir = 0;
		}
		
		if (smer == 0) {
			PORTB |= (1<<LED_1);
			PORTB &= ~(1<<LED_4);
		} else {
			PORTB |= (1<<LED_4);
			PORTB &= ~(1<< LED_1);
		}

	}
		
	return 0;
}
0

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: ATtiny13 a rotacny enkoder

Príspevok od používateľa peterple » 28 Jún 2013, 20:34

Ahoj,
ani sa príliš nečudujem že sa to spáva čudne. Veď sa tam každým testom číta vždy nový stav zo vstupov. Ja som asemblerista a moje riešenie je máličko iné a veľmi jednoduché. Jeden zo signálov je privedený na prerušovací vstup ktorý je nastavený tak aby reagoval na hranu (nábežnú alebo dobežnú, to je jedno). Ak nastane prerušenie stačí pozrieť druhý vstup a smer otáčania sa určí podľa jeho logickej hodnoty. Sú to iba dve inštrukcie procesora.
Píšeš že začínaš. Možno si si zobral príliš náročnú úlohu. Skús na začiatok urobiť kód ktorý len bude kopírovať logický stav jedného signálu z enkódera na LED. Pri otáčaní hociktorým smerom by mala blikať. Ak sa ti to podarí budeš vedieť že hw je asi zapojený OK a môžeš pokročiť o krok ďalej. Kód ti tu naschváľ nenapíšem lebo kopírovaním programčekov z webu sa toho veľa nenaučíš. Keby si mal problém s kopírovaním, hoď sem kód čo si vymyslel a poradím ako na to.
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

kuboo
Okoloidúci
Okoloidúci
Príspevky: 6
Dátum registrácie: 26 Jún 2013, 19:46

Re: ATtiny13 a rotacny enkoder

Príspevok od používateľa kuboo » 01 Júl 2013, 19:14

Cita sa tam stale dookola novy stav zo vstupov, no prave na to je tam ta premenna dir. Vdaka nej je mozne zistit ze pri predchadzajucim citani bolo na vstupe to iste, teda nedoslo k zmene vstupu a program pokracuje dalsim testovanim. A az ked sa vstup zmeni vtedy sa nieco vykonava a prgram s aposuva dalej. Mne sa zda ze by ten kod mohol fugnovat :-) ak nie tak preco ?

Hral som sa s tym dalej a naozaj to vyzera na slabe napajanie. Skusim zohnat nejaky zdroj a vyskusam to este raz. Ano viem ze tento problem sa riesi celkom jednoducho cez prerusenie. Asi to tak nakoniec aj spravim. Priblizne kolko preruseni sa sekundu by bolo schopne vykonat AVRko beziace na 20 mhz ?
0

Používateľov profilový obrázok
petersno
Ultimate člen
Ultimate člen
Príspevky: 2774
Dátum registrácie: 06 Aug 2011, 00:00
Bydlisko: ba
Vek: 63

Re: ATtiny13 a rotacny enkoder

Príspevok od používateľa petersno » 01 Júl 2013, 20:49

pri citani enkoderu mimo isr ti vzdy vyjde vysledny kod vacsi a zlozitejsi, pretoze musis osetrovat stavy, ktore pri isr riesi hardware. hlavne osetri zakmity. enkoder sa na fore riesil uz niekolko krat, skus pozriet. jedno ci pic ci avr, princip je rovnaky.
limity poctu preruseni enkoderom urcite neohrozis :wink:
0

kuboo
Okoloidúci
Okoloidúci
Príspevky: 6
Dátum registrácie: 26 Jún 2013, 19:46

Re: ATtiny13 a rotacny enkoder

Príspevok od používateľa kuboo » 01 Júl 2013, 21:10

Zakmity je potrebne riesit len pri mechanickych enkoderoch nie ? :-)

Snazim sa nieco nove naucit no zaroven aj poskladat vec, ktoru chcem realne pouzit. Je fakt ze enkoder sa nebude otacat rychlo (vecsinou do 1 otacky za sekundu), no ma 1024 krokov na jednu otacku. Zvladne to vsak aj viac otacok za sekundu ?
0

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: ATtiny13 a rotacny enkoder

Príspevok od používateľa peterple » 01 Júl 2013, 21:28

no ja som mal na mysli toto:

Kód: Vybrať všetko

if (SIGNAL_A & (!SIGNAL_B))
je to tam niekoľko krát a zakaždým sa načíta nová informácia zo vstupu. Pomedzi je pár ďalších inštrukcií A nedokážem odhadnúť koľko to časovo koštuje. Na tej orig stránke píše že do nízkych frekvencií to stačí. Píšeš že máš optický snímač. Koľko dáva impulzov na otáčku. Môj dáva 2048. Tam by so zákmitmi nemal byť problém ale kto vie. Minimálne by som urobil toto:

Kód: Vybrať všetko

uint8_t temp_PINB = 0;

temp_PINB = PINB;
a potom testoval tú pomocnú premennú miesto PINB.

Ako si prišiel na to že máš problém s napájaním? To kopírovanie si skúšal? Blikala ti LED? Kontroloval si logickou sondou či sú slušné impulzy na jedvotlivých výstupoch snímača. Ideálne nejakou čo vie počítať impulzy.

Čo sa týka prerušenia tak datasheet hovorí:
The interrupt execution response for all the enabled AVR interrupts is four clock cycles
minimum. After four clock cycles, the program vector address for the actual interrupt
handling routine is executed. During this 4-clock cycle period, the Program Counter is
pushed onto the Stack. The vector is normally a jump to the interrupt routine, and this
jump takes three clock cycles. If an interrupt occurs during execution of a multi-cycle
instruction, this instruction is completed before the interrupt is served. If an interrupt
occurs when the MCU is in sleep mode, the interrupt execution response time is
increased by four clock cycles. This increase comes in addition to the start-up time from
the selected sleep mode.
A return from an interrupt handling routine takes four clock cycles. During these four
clock cycles, the Program Counter (2 bytes) is popped back from the Stack, the Stack
Pointer is incremented by 2, and the I-bit in SREG is set.
teda 4 cykly na uloženie PC do zásobníka. 3 cykly na skok na rutinu. Pri návrate 4 cykly. Plus čo si tam napíšes sám do obsluhy. Keby si chcel len určiť smer tak sú to dve inštrukcie. To je dohromady približne 14 inštrukcii. Koľko to zvládne prerušení pri 20Mhz si spočítaj sám (veľa).
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

kuboo
Okoloidúci
Okoloidúci
Príspevky: 6
Dátum registrácie: 26 Jún 2013, 19:46

Re: ATtiny13 a rotacny enkoder

Príspevok od používateľa kuboo » 04 Júl 2013, 22:47

Nakoniec to nebol problem so zdrojom, takze kod bude zly. Idem to vyskusat rozbehnut cez prerusenie. Velka vdaka za reakcie :-).
0

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: ATtiny13 a rotacny enkoder

Príspevok od používateľa peterple » 04 Júl 2013, 23:00

Ako si prišiel na to, že nie je problém zo zdrojom?
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

kuboo
Okoloidúci
Okoloidúci
Príspevky: 6
Dátum registrácie: 26 Jún 2013, 19:46

Re: ATtiny13 a rotacny enkoder

Príspevok od používateľa kuboo » 05 Júl 2013, 19:55

Pozical som si externy zdroj na ktorom sa spravalo vsetko rovnako ako pri napajani s programatora ;-). A tiez som premeral signaly z enkodera ktore boli ok :-).
0

peterple
Ultimate člen
Ultimate člen
Príspevky: 2328
Dátum registrácie: 25 Jún 2013, 21:06
Bydlisko: Krajné
Vek: 57
Kontaktovať používateľa:

Re: ATtiny13 a rotacny enkoder

Príspevok od používateľa peterple » 05 Júl 2013, 22:44

no povedzme, že zdrojom to teda nie je. Čo si zistil pri meraní signálov. Záver, že sú OK mi nič nehovorí. Opäť klasická otázka ako si na to prišiel? Čím si to meral, čo si nameral? Generuje sa ti prerušenie keď otáčaš snímačom? Alebo ešte študuješ ako povoliť prerušenie? A hlavne už s skúsil kopírovať stav vstupu enkódera na výstup LED? Podľa mňa je to zásadná vec, ak toto bude fungovať tak potom sa dá ísť ďalej, lebo bude isté že hw je v poriadku. Vždy treba začať najjednoduchšou vecou a overovať predpoklady. Nie urobiť program na dve strany a potom rozmýšlať prečo nefunguje.
0
Ukáž múdremu chybu a on sa ti poďakuje. Ukáž chybu hlupákovi a on sa urazí.

kuboo
Okoloidúci
Okoloidúci
Príspevky: 6
Dátum registrácie: 26 Jún 2013, 19:46

Re: ATtiny13 a rotacny enkoder

Príspevok od používateľa kuboo » 07 Júl 2013, 23:09

Signaly som meral len voltmetrom ci su v pripustnom rozsahu napati. Dnes som konecne nastudoval prerusenie. Podarilo sa najprv kopirovat vstup na vystup a potom urcenie smeru otacania enkodera bola fakt brnkacka :-).

Velka vdaka za navedenie na to prerusenie, sam by som sa este dlho babral s tym povodnym kodom :-).
0

Napísať odpoveď