Encoder (spôsob čítania) WinAVR

C,C++,C#

Moderátori: psichac, Moderátori

sarisHD
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1238
Dátum registrácie: 03 Mar 2009, 00:00

Encoder (spôsob čítania) WinAVR

Príspevok od používateľa sarisHD » 18 Feb 2011, 20:11

Ahojte!
Zase ja :roll:
Ale pozeral som po nete bud niake vzorové príklady alebo knižnice a nič tak sa vás chem spýtať ako mate vy spravenú tuto čast programu .. Ďakuejem :)
0

Používateľov profilový obrázok
daqq
Power user
Power user
Príspevky: 2528
Dátum registrácie: 10 Jún 2008, 00:00
Bydlisko: Bratislava
Vek: 36
Kontaktovať používateľa:

Príspevok od používateľa daqq » 18 Feb 2011, 20:18

Typ enkodera?
0
Outsource your thinking: Get religious!
Zistenie: Ked robite sucasne v C, C++, C#, Matlabe, trocha pokukujete po VHDL, sialenstvo nemoze byt daleko...este stastie, ze som lietadlo a nemam tieto problemy.

sarisHD
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1238
Dátum registrácie: 03 Mar 2009, 00:00

Príspevok od používateľa sarisHD » 18 Feb 2011, 20:20

http://www.sos.sk/?str=371&artnum=57561

Neviem ci to je presne on ale vyzeraju rovnako aj farebne aj to ze maju tlacitko ..
0

Používateľov profilový obrázok
vama
Ultimate člen
Ultimate člen
Príspevky: 1545
Dátum registrácie: 26 Aug 2008, 00:00
Bydlisko: BA
Vek: 31

Príspevok od používateľa vama » 18 Feb 2011, 20:32

Ved to nie je problem nieco taketo urobit. Ja som tiez programoval pre tento encoder program http://sk.farnell.com/alps/ec12e2424407 ... 12E2424407; (tusim je to ten isty :) ) , ibaze v ASM a pre PIC, ale princip je ten isty.

Staci ked budes jeden kanal sledovat a ked sa na nom objavy log. 0, tak vykonas oneskorenie (kvoli zakmitu kontaktov), toto oneskorenie je najlepsie pomocou logickeho analyzeru nastavit, ja som nastavil cca 2ms. Potom je este dobre (ale netreba) raz osledovat ci stale je kanal v log0 ak je nasledne zosnimas stav druheho kanalu a podla toho ci je v log1 alebo log0 urcis smer otacania, podla toho smeru inkrementujes alebo dekrementujes premennu a je to..
Vysledok je priam dokonaly na tu jednoduchost 8)
0
"Digitálna technika pozostáva len z 0 a 1, ktoré sú v správny čas na správnom mieste." M. Valášek

sarisHD
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1238
Dátum registrácie: 03 Mar 2009, 00:00

Príspevok od používateľa sarisHD » 18 Feb 2011, 20:46

nemozes trosku viac napisať :) lebo skušam to a dost mi to blbne :)
0

Používateľov profilový obrázok
vama
Ultimate člen
Ultimate člen
Príspevky: 1545
Dátum registrácie: 26 Aug 2008, 00:00
Bydlisko: BA
Vek: 31

Príspevok od používateľa vama » 19 Feb 2011, 11:16

Tak najprv povedz co by mal ten enkoder obsluhovat ? Ci sluzi ako digitalny potenciometer (inc/ dec premennu) alebo nieco ine?
0
"Digitálna technika pozostáva len z 0 a 1, ktoré sú v správny čas na správnom mieste." M. Valášek

sarisHD
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1238
Dátum registrácie: 03 Mar 2009, 00:00

Príspevok od používateľa sarisHD » 19 Feb 2011, 13:08

inc/dec premennú ..

ďiky moc ;)
0

Používateľov profilový obrázok
Kado
Power user
Power user
Príspevky: 1625
Dátum registrácie: 02 Sep 2007, 00:00
Bydlisko: PB
Vek: 40

Príspevok od používateľa Kado » 19 Feb 2011, 13:28

ja ti poradim, daj si jeden vystup enkodera na extern prerusenie INT0 alebo INT1, dalej pripoj na tento vstup kondik 15-22n, dalsi vystup pripoj na obycajny v/v pin, po resete nastav obidva piny ako vstupne so zapnutymi int. pullup-mi, dalej nastav extern prerusenie na zostupnu hranu, v obsluhe prerusenia testuj stav toho druheho pinu a na zaklade toho zvysuj znizuj danu premennu....a navyse pro vstupe do prerusenia zakaz dane prerusenie a pred opustenim ho znova povol...
0
Návrh zapojení s jednočipovými mikropočítačmi, tvorba programového vybavenia pre mikropočítače
http://www.jk-elektronika.info/index.html

predaj !!
http://svetelektro.com/modules.php?name ... 54#p549154

Používateľov profilový obrázok
vama
Ultimate člen
Ultimate člen
Príspevky: 1545
Dátum registrácie: 26 Aug 2008, 00:00
Bydlisko: BA
Vek: 31

Príspevok od používateľa vama » 19 Feb 2011, 13:30

Tak tu je moj program v ASM:

Kód: Vybrať všetko

;***************  enkoder (rucny) *****************************
ENKODER
	BCF		FLAG1		; nuluje flag
	CALL	CAK20m			; oneskorenie
	BTFSS	ENK_A		; caka na prechod 
	GOTO	$-1				; kanalu A enkodera do H
	CALL	CAK1.7m			; oneskorenie, kvoli zakmitu
	BTFSC	ENK_TL		; testuje ci je stlacene TL 
	GOTO	$+3
	BSF		FLAG1		; nastavi flag, ze TL. stlacene
   RETURN				; navrat	
	
   BTFSC	ENK_A		; caka na prechod 
	GOTO	$-5				; kanalu A enkodera do L
	CALL	CAK1.7m			; oneskorenie, kvoli zakmitu
	BTFSS	ENK_B		; zisti smer otocenia enkodera
	GOTO	ENK_DEC	

ENK_INC			; inkrementacny mod enkodera
	MOVF	ENK,0		; zisti ci je posledna polozka
	SUBWF	ENK_P,0
	BTFSS	STATUS,Z
	GOTO	$+3				
	CLRF	ENK				; ak je posledna polozka,
	RETURN					; ENK = 0 
	INCF	ENK,1			; ak nie je posledna polozka, 
	RETURN					; ENK + 1 

ENK_DEC			; dekrementacny mod enkodera
	MOVF	ENK,0		; zisti ci je prva polozka
	BTFSS	STATUS,Z
	GOTO	$+4	
	MOVF	ENK_P,0		; ak je prva polozka,
	MOVWF	ENK			        ; ENK = posledna polozka 
	RETURN			
	DECF	ENK,1			; ak nie je posledna polozka, 
							; ENK - 1 
cely ho nebudem opisovat, pretoze je urobeny tak, aby si mohol menit velkost premennej ktoru inc/ dec a taktiez aj test tlacidla nespominam, pretoze ja to mam cez flag.

Najskor sa vykona oneskotenie 20ms (kvoli zakmitu a rychlosti ovladania), potom caka na kanali A, kym dojde do kludoveho stavu log 1, dalsie oneskorenie 1.7 ms (zakmit). Caka na prechod kanalu A do log0, oneskorenie 1.7 ms (zakmit), otestuje kanal B a podla jeho stavu bud DEC/ INC premennu a to je vsetko.
Mne program funguje bezproblemov v oboch smeroch. 8)
0
"Digitálna technika pozostáva len z 0 a 1, ktoré sú v správny čas na správnom mieste." M. Valášek

sarisHD
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1238
Dátum registrácie: 03 Mar 2009, 00:00

Príspevok od používateľa sarisHD » 20 Feb 2011, 19:28

Ďakujem Idem to vyskúšať ;) dám vedieť ako som skončil :idea:

//Automatické spojenie príspevkov. Pridané po 2 hodinách 32 minútach:

skúšam niečo takéto a nič ..

Kód: Vybrať všetko

if (ENC_A == 1)
{
     _delay_ms(2);
     if (ENC_A == 1)
	 {
       _delay_ms(2);
       if (ENC_B == 0)
       {
         _delay_ms(2);
         if (ENC_B == 0)
         {
           jas++;
         }
        }
        else
        {
         jas--;
        }
	  }
} 


//Automatické spojenie príspevkov. Pridané po 1 hodine 20 minútach:

a niečo na tento spôsob čo som našiel na internete ?

Kód: Vybrať všetko

/*------------------------------------------------------------------------ 
 * 
 * ENCODER - Checks rotary encoder and returns the following:
 * 
 *               0:  no movement 
 *              -1:  ccw rotation 
 *               1:  cw rotation 
 * 
 *------------------------------------------------------------------------*/ 

signed char 
encoder(void) 
{ 
   static unsigned char a, b; 
   if (!a & !b) { 
      if (ENC_A) { 
         a = ENC_A; 
         return (-1); 
      } 
      if (ENC_B) { 
         b = ENC_B; 
         return (1); 
      } 
   } 
   if (a & !b) { 
      if (!ENC_A) { 
         a = ENC_A; 
         return (1); 
      } 
      if (ENC_B) { 
         b = ENC_B; 
         return (-1); 
      } 
   } 
   if (a & b) { 
      if (!ENC_A) { 
         a = ENC_A; 
         return (-1); 
      } 
      if (!ENC_B) { 
         b = ENC_B; 
         return (1); 
      } 
   } 
   if (!a & b) { 
      if (ENC_A) { 
         a = ENC_A; 
         return (1); 
      } 
      if (!ENC_B) { 
         b = ENC_B; 
         return (-1); 
      } 
   } 
   return (0); 
}


//Automatické spojenie príspevkov. Pridané po 1 hodine 29 minútach:

Kód: Vybrať všetko

       if((a != ENC_A) | (b != ENC_B)){ 
          dir = a^ENC_B; 
          a = ENC_A; 
          b = ENC_B; 
        
           }
		   else
		   { 
            dir=2;
		   }
  if (dir == 1)
  {
  jas--;
  } 

  if (dir == 0)
  {
  jas++;
  }
Toto mi funguje do ++ strany . ..
0

Používateľov profilový obrázok
Radus
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1497
Dátum registrácie: 27 Okt 2009, 00:00
Bydlisko: Prešov
Vek: 42

Príspevok od používateľa Radus » 20 Feb 2011, 19:47

nevyskúšaš to s tým prerušením?

// External Interrupt(s) initialization (v main)

GICR|=0x80;
MCUCR=0x08;
GIFR=0x80;


interrupt [EXT_INT1] void enkoder (void)
{
if(smer) konstanta ++
else konstanta -+
}

toto som ti len tak narýchlo vysekal z programu, možno bude treba ošetriť proti zákmitom
Prílohy
Simulacia enkodera, kedže model v knižnici nemam, nevadi....
Simulacia enkodera, kedže model v knižnici nemam, nevadi....
0

sarisHD
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1238
Dátum registrácie: 03 Mar 2009, 00:00

Príspevok od používateľa sarisHD » 20 Feb 2011, 19:56

Len ze na portoch pre prerušenie mam LCD tak som to chcel takto riešit..
0

Používateľov profilový obrázok
Radus
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1497
Dátum registrácie: 27 Okt 2009, 00:00
Bydlisko: Prešov
Vek: 42

Príspevok od používateľa Radus » 20 Feb 2011, 20:05

... jasne, neprijemne :(
0

sarisHD
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1238
Dátum registrácie: 03 Mar 2009, 00:00

Príspevok od používateľa sarisHD » 20 Feb 2011, 20:11

ale ved prehodim LCD na iny port presnejsie robim na mege16 tak dam to na C tam je ADC ten zatial nepouivam ..
a mohol by som ta poprosit o icq ? ;) do ss ak mas alebo skype
0

Používateľov profilový obrázok
Kado
Power user
Power user
Príspevky: 1625
Dátum registrácie: 02 Sep 2007, 00:00
Bydlisko: PB
Vek: 40

Príspevok od používateľa Kado » 20 Feb 2011, 20:15

sarisHD napísal:Len ze na portoch pre prerušenie mam LCD tak som to chcel takto riešit..
najpresnejsie (a najjednoduchsie) to mas pomocou prerusenia, uz som to tu pisal, nie vymyslat oneskorovacie cakacie slucky a ine blbosti 8O
0
Návrh zapojení s jednočipovými mikropočítačmi, tvorba programového vybavenia pre mikropočítače
http://www.jk-elektronika.info/index.html

predaj !!
http://svetelektro.com/modules.php?name ... 54#p549154

sarisHD
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1238
Dátum registrácie: 03 Mar 2009, 00:00

Príspevok od používateľa sarisHD » 20 Feb 2011, 20:17

prepáč nie som taký skúsený a neviem co je pre mna lepšie tak skusim to cez prerušenia..
zatial ďakujem
0

Používateľov profilový obrázok
Radus
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1497
Dátum registrácie: 27 Okt 2009, 00:00
Bydlisko: Prešov
Vek: 42

Príspevok od používateľa Radus » 20 Feb 2011, 20:20

skúsil som ešte niečo na papieri:
... poznamenávam že len s AVR začínam....
možno to pôjde, možno ešte niečo proti zákmitom, treba nasimulovať..

bit A=0; // vyvod enkodera 1
bit B=0; // vyvod enkodera 2

bit C=1; //pomocná premenná

unsigned int konstanta = 0;

.
.
.

if (A&B&C)
{
konstanta++;
C=0;
}

if (A&!B&C)
{
konstanta-+;
C=0;
}

if (!A) C=1;

.
.
.

programujem v codevision, tak neviem... to ma len tak teraz napadlo, urcite je to aj zle :)
0

sarisHD
Zaslúžilý člen
Zaslúžilý člen
Príspevky: 1238
Dátum registrácie: 03 Mar 2009, 00:00

Príspevok od používateľa sarisHD » 20 Feb 2011, 23:29

Tak a už to ide...Ďakujem Radus

Kód: Vybrať všetko

/****************************************************************************
Title:    Ovladanie PWM,LCD,ENCODER
Author:   Martin Šarmír <sarmir.m@gmail.com> http://www.sarishdwz.cz
File:     ""LCD_PWM.c""
Software: AVR-GCC
Hardware: ATmega16 at 8 Mhz

Description: 

*****************************************************************************/
#include <avr/io.h>
#include <avr/iom16.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#include "lcd.h"
#include "ds18b20.h"


#ifndef F_CPU
#define F_CPU 8000000
#endif

unsigned char jas;
int tep;




#define ENC_B  (PIND & 0x40)
#define ENC_TL (PIND & 0x80)



void InitAll()
{
   TCCR0|=(1<<WGM00)|(1<<WGM01)|(1<<COM01)|(1<<CS00); 
   DDRD|=(0<<PD6)|(0<<PD2)|(0<<PD7);
   DDRB|=(1<<PB3);
  
   lcd_init(LCD_DISP_ON);

   GICR|=0x40;
   MCUCR=0x03;
   MCUCSR=0x00;
   GIFR=0x40;

}

void SetPWMOutput(uint8_t pwm)
{
   OCR0=pwm;
}

void VypisPercent(uint8_t i)
{
   unsigned char pom;
   char buffer[7];
   char buffer1[7];
   pom = (unsigned char)((unsigned int)i * 100 / 255);

   itoa (pom,buffer,10);
   itoa (i,buffer1,10);
   lcd_clrscr();
   lcd_puts(buffer);
   lcd_putc('%');
   lcd_gotoxy(5,0);
   lcd_puts("PWM Jas");
   lcd_gotoxy(0,1);
   lcd_puts(buffer1);
   
}

int Teplota()
{
  char buffer[16];
  therm_read_temperature(buffer);
  tep = buffer;
}


int VypisT(uint16_t buffer)
{
 lcd_clrscr();
 lcd_gotoxy(0,0);
 lcd_puts(buffer);
 lcd_gotoxy(4,0);
 lcd_puts(" C");   
}

ISR(INT0_vect)
{
 _delay_ms(2);
  if (ENC_B)
  {
  if (jas == 255)
  {
  }
  else
  jas++;
  }
  else
  if (jas == 0)
  {
  }
  else
  {
  jas--;
  }
} 

int main (void)
{
int pom;


  InitAll();
  sei();
  jas=255;
 
for(;;)
{
VypisPercent(jas);
SetPWMOutput(jas);
_delay_ms(20);
if (ENC_TL == 0)
{
Teplota();
VypisT(tep);
_delay_ms(1000);
}
 
}
  
}




0

Používateľov profilový obrázok
Kado
Power user
Power user
Príspevky: 1625
Dátum registrácie: 02 Sep 2007, 00:00
Bydlisko: PB
Vek: 40

Príspevok od používateľa Kado » 21 Feb 2011, 17:31

nádhera...v preruseni od extern udalosti cakas 2milisekundy??? no nadhera... rychlo to daj prec... radsej daj na extern. vstup prerusenia kondik voci zemi, tak 15-22n bude OK
0
Návrh zapojení s jednočipovými mikropočítačmi, tvorba programového vybavenia pre mikropočítače
http://www.jk-elektronika.info/index.html

predaj !!
http://svetelektro.com/modules.php?name ... 54#p549154

Používateľov profilový obrázok
vama
Ultimate člen
Ultimate člen
Príspevky: 1545
Dátum registrácie: 26 Aug 2008, 00:00
Bydlisko: BA
Vek: 31

Príspevok od používateľa vama » 21 Feb 2011, 18:01

to Kado:
Ten kondenzator sice asi pomoze, ale zas mu tam vznikne skresleny obdlznik, aby ten nesposobil nejake nepresnosti.
Preco si proty casovym slucka? ved ked maju kontakty zakmit tak aj u tlacidiel sa to riesi cas. sluckami (popripadne opakovanim vzorkovanim), alebo HW cesta - BKO.
0
Naposledy upravil/-a vama v 06 Mar 2011, 14:37, upravené celkom 1 krát.
"Digitálna technika pozostáva len z 0 a 1, ktoré sú v správny čas na správnom mieste." M. Valášek

Napísať odpoveď