mikrocontroller.net

Forum: Projekte & Code Drehimpulsgeber mit Rasterstellung bei 00/11 auswerten


Autor: Christian K. (christiank)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier mal ein neuer Ansatz zum Auswerten von Drehimpulsgebern....

In der Praxis hat man häufig Drehimpulsgeber (rotary switches) die
Raststellungen bei 00 und 11 haben. Die Zwischenstellungen 01 der 10
treten nur dynamisch während der Drehung auf. Solche Geber sind z.B.
als Eingabeinstrument üblich.

Der sehr gute Code aus diesem Thread
http://www.mikrocontroller.net/forum/read-4-37992.html#new
hat passt für diesen Typ nicht so gut denn:

a) Bei den oben beschriebenen Drehimpulsgebern zählt er doppelt weil er
bei jedem Wechsel inc- oder decrementiert. D.h. wird um eine
Raststellung weitergedreht, zählt der Zähler +/-2.

b) Wärend des Kontaktprellens ist der Ausgangswert nicht konstant
sondern kann +/-1 wechseln. Das kann ein Problem sein, wenn das
Anwenderprogram ungünstig ausliest.

c) Er ist nicht unbedingt einfach zu verstehen.

Hier nun mein Code für AVR:

  static uint8_t last_state = 0;
  static uint8_t last_cnt = 0;
  uint8_t new_state;

  new_state=PINE & (_BV(PINE4) | _BV(PINE3));
  if ((new_state^last_cnt)==(_BV(PINE4) | _BV(PINE3)) )
  {
    if ((new_state ^ last_state)==_BV(PINE4))
      enc_delta+=1;
    else
      enc_delta-=1;
    last_cnt=new_state;
  }
  last_state=new_state;

Er funktioniert folgendermassen:
- Am Anfang werden die zwei Input-Ports eingelesen.
- Dann wird geprüft, ob sich beide Bit's unterscheiden
- Wenn nein wars das schon
- Wenn ja, schauen wir woher wir kommen
  kommen wir von rechts (je nach Beschaltung) zählen wir hoch, sonst
runter
- Dann speichern wir uns noch den State bei dem wir gezählt haben
- Am Ende merken wir uns den ausgewerteten State damit wir nächstes mal
wissen woher wir kommen

Dabei wird natürlich automatisch entprellt.

Have Fun.

Autor: Techniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Christian!

Bin in C noch nicht so bewandert.
Kannst du mit erklären, was "_BV" bedeutet?

Danke!

Autor: MartinS (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Ich schreibe das hier mal auf basis von Port B Bit 0 und 1.
1. Zwischenspeichern von PB0 & PB1
2. PB0 XOR PB1 = 0 -> nix passiert nix tun
               = 1 -> es wurde gedreht
3. PB0 XOR Zwischenspeicher PB0 = 1 es wurde nach links gedreht
                                 = 0 es wurde nach rechts gedreht
4. (Entprellung)
   wenn bei 3. das Ergebnis 1 war dann nicht neu bei 1. anfangen bevor
  nicht auch PB1 den status gewechselt hat,
   wenn bei 3. das Ergebnis 0 war dann nicht neu bei 1. anfangen bevor
  nicht PB0 den status gewechselt hat.

Autor: Andre (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Techniker:

_BV ist letztlich nur ein Makro:(1 << (x)).

Schöner wäre es, wenn Du _BV nicht nimmst, sondern das Makro
ausschreibst. Dann ist es portabler (andere Compiler).
Mit _BV wird der Code allenfalls ein bißchen leserlicher.

Autor: Andreas Kassner (andi_k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann mir jemand den übersetzten C-Code von oben geben (AVR-ASM)?
Habe mit meinen Unkenntnissen in C versucht, das in ASM zu wandeln aber
ich komme auf keinen Nenner.
Kann leider nur ASM.

Danke im Voraus!

MfG
Andi

Autor: Christian K. (christiank)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier, nur kopiert, nicht näher angeschaut....

a) Optimization for size

70:         new_state=PINE & (_BV(PINE4) | _BV(PINE3));
+000003A4:   91800000    LDS     R24,0x0000       Load direct from data
space
+000003A6:   7188        ANDI    R24,0x18         Logical AND with
immediate
+000003A7:   8389        STD     Y+1,R24          Store indirect with
displacement
71:         if ((new_state^last_cnt)==(_BV(PINE4) | _BV(PINE3)) )  //
we are either in main state 00 or 11
+000003A8:   8199        LDD     R25,Y+1          Load indirect with
displacement
+000003A9:   9180014C    LDS     R24,0x014C       Load direct from data
space
+000003AB:   2789        EOR     R24,R25          Exclusive OR
+000003AC:   3188        CPI     R24,0x18         Compare with
immediate
+000003AD:   F4A1        BRNE    PC+0x15          Branch if not equal
73:           if ((new_state ^ last_state)==_BV(PINE4))
+000003AE:   8189        LDD     R24,Y+1          Load indirect with
displacement
+000003AF:   9190014B    LDS     R25,0x014B       Load direct from data
space
+000003B1:   2789        EOR     R24,R25          Exclusive OR
+000003B2:   3180        CPI     R24,0x10         Compare with
immediate
+000003B3:   F431        BRNE    PC+0x07          Branch if not equal
74:             enc_delta+=1;
+000003B4:   9180014A    LDS     R24,0x014A       Load direct from data
space
+000003B6:   5F8F        SUBI    R24,0xFF         Subtract immediate
+000003B7:   9380014A    STS     0x014A,R24       Store direct to data
space
+000003B9:   C005        RJMP    PC+0x0006        Relative jump
76:             enc_delta-=1;
+000003BA:   9180014A    LDS     R24,0x014A       Load direct from data
space
+000003BC:   5081        SUBI    R24,0x01         Subtract immediate
+000003BD:   9380014A    STS     0x014A,R24       Store direct to data
space
77:           last_cnt=new_state;
+000003BF:   8189        LDD     R24,Y+1          Load indirect with
displacement
+000003C0:   9380014C    STS     0x014C,R24       Store direct to data
space
79:         last_state=new_state;
+000003C2:   8189        LDD     R24,Y+1          Load indirect with
displacement
+000003C3:   9380014B    STS     0x014B,R24       Store direct to data
space
+000003C5:   9621        ADIW    R28,0x01         Add immediate to
word

b) Optimization for speed
70:         new_state=PINE & (_BV(PINE4) | _BV(PINE3));
+000003A4:   91800000    LDS     R24,0x0000       Load direct from data
space
+000003A6:   7188        ANDI    R24,0x18         Logical AND with
immediate
+000003A7:   8389        STD     Y+1,R24          Store indirect with
displacement
71:         if ((new_state^last_cnt)==(_BV(PINE4) | _BV(PINE3)) )  //
we are either in main state 00 or 11
+000003A8:   8199        LDD     R25,Y+1          Load indirect with
displacement
+000003A9:   9180014C    LDS     R24,0x014C       Load direct from data
space
+000003AB:   2789        EOR     R24,R25          Exclusive OR
+000003AC:   3188        CPI     R24,0x18         Compare with
immediate
+000003AD:   F4A1        BRNE    PC+0x15          Branch if not equal
73:           if ((new_state ^ last_state)==_BV(PINE4))
+000003AE:   8189        LDD     R24,Y+1          Load indirect with
displacement
+000003AF:   9190014B    LDS     R25,0x014B       Load direct from data
space
+000003B1:   2789        EOR     R24,R25          Exclusive OR
+000003B2:   3180        CPI     R24,0x10         Compare with
immediate
+000003B3:   F431        BRNE    PC+0x07          Branch if not equal
74:             enc_delta+=1;
+000003B4:   9180014A    LDS     R24,0x014A       Load direct from data
space
+000003B6:   5F8F        SUBI    R24,0xFF         Subtract immediate
+000003B7:   9380014A    STS     0x014A,R24       Store direct to data
space
+000003B9:   C005        RJMP    PC+0x0006        Relative jump
76:             enc_delta-=1;
+000003BA:   9180014A    LDS     R24,0x014A       Load direct from data
space
+000003BC:   5081        SUBI    R24,0x01         Subtract immediate
+000003BD:   9380014A    STS     0x014A,R24       Store direct to data
space
77:           last_cnt=new_state;
+000003BF:   8189        LDD     R24,Y+1          Load indirect with
displacement
+000003C0:   9380014C    STS     0x014C,R24       Store direct to data
space
79:         last_state=new_state;
+000003C2:   8189        LDD     R24,Y+1          Load indirect with
displacement
+000003C3:   9380014B    STS     0x014B,R24       Store direct to data
space

Autor: Andreas Kassner (andi_k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Christian!

Funktioniert jetzt.
Allerdings scheint es sich genau so wie mein bisheriger Algorythmus zu
verhalten (siehe Datenblatt des DDM427 von ALTRON unten rechts).
Erst ab 2KHz Abtastrate geht beim schnellen Drehen nichts verloren.

MfG
Andi

Autor: Christian K. (christiank)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Andi,

ich verwende 500Hz Abtastrate. Läuft allerdings nur als manuelles
Eingabegerät. Dass heisst, es stört eigentlich nicht, wenn beim
schnellen drehen per Hand Pulse verloren gehen. Der User kann beim
Kurbeln sowieso nicht mitzählen... Bei der langsamen Feineinstellung -
solange man mitzählen kann - reichen die 500Hz.

Grüße
  Christian

Autor: MartinS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder mach die ganze geschichte mit externen Interrupts, oder in
Hardware.

Autor: The Daz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Christian

Aeh, das kapier ich nicht :

 if ((new_state^last_cnt)==(_BV(PINE4) | _BV(PINE3)) )
 {
   if ((new_state ^ last_state)==_BV(PINE4))

Nur einer dieser beiden Ausdruecke kann wahr sein. Folglich kann die
Routine nur rueckwaerts zaehlen, oder ?

Autor: Christian K. (christiank)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso?

last_cnt und last_state sind verschieden, kann man leicht übersehen
:-)

last_cnt ist die Bitkombination bei der zuletzt gezählt wurde (00) oder
(11)

last_state ist der letzte Zustand (10)/(01) d.h. woher ich komme

Gruesse
  Christian

Autor: The Daz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Damn, du hast recht. Lesen hilft ungemein :)

Autor: Felix Jankowski (feejai)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weis net, wies euch da geht, aber ich krieg immer PINEx nicht
deklariert und damit bricht der gcc ab!

Autor: SuperUser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Felix,

ist das dein erstes Program für AVR?

Ein

#include <avr/io.h> (beim gcc)

Sollte natürlich nicht fehlen und dein µC im makefile definiert sein...

Autor: Felix Jankowski (feejai)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, mein oberes Posting is absolouter Mist, habs jetzt schon kapiert
was PINE sein soll. Brett vorm Kopf.

Autor: Tobi Tubbu (tubbu-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

habe den Code so erweitert, dass man auch mehrere Drehgeber einlesen
kann.
void evalRots(unsigned int rotData)
//Erkennt die Umdrehungen der Encoder
{
  static unsigned int last_state = 0;
  static unsigned int last_cnt = 0;
  
  for(unsigned char i=0; i< 12; i+=2)    //Encoder Anzahl: 6
  {
    if (((rotData^last_cnt) & (1 << i))  && ((rotData^last_cnt) & (1 <<
(i+1))))
    {
      if ((rotData ^ last_state) & (1 << i))
        enc_delta[(i>>1)]--;
      else
        enc_delta[(i>>1)]++;
      
      if((last_cnt^rotData) & (1 << i))      //bits verschieden?
        last_cnt^=(1 << i);            //togglen
      if((last_cnt^rotData) & (1 << (i+1)))    //bits verschieden?
        last_cnt^=(1 << (i+1));          //togglen

    }
    if((last_state^rotData) & (1 << i))        //bits verschieden?
      last_state^=(1 << i);            //togglen
    if((last_state^rotData) & (1 << (i+1)))      //bits verschieden?
      last_state^=(1 << (i+1));          //togglen
  }
}

Bei mir befinden sich die Graycode werte in einem Integer, da ich die
Encoder über zwei schieberegister einlese. rotData kann aber auch
einfach in Port des uc sein. Der Code macht im prinzip genau das
gleiche wie der Orginalcode des Threads, wahrscheinlich lässt sich da
noch einiges vereinfachen, laufen und funktionieren tut er aber.

Tubbu

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Christian,

kannst Du mal das hier ausprobieren ?

http://www.mikrocontroller.net/forum/read-4-37992....


Peter

Autor: Lurch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe einen Drehimpulsgeber von Alps (STEC12E06 von Conrad) der mit jeder
Rasterstellung den Zähler um 4 weiterzählt, was für meinen Fall nicht
gewünscht ist. Ich habe das Beispiel von Christian ausprobiert, leider
nicht mit dem gewünschten Erolg. Der Code aus dem dem Thread

http://www.mikrocontroller.net/forum/read-4-37992.html#

von Peter Dannegger lässt sich auch dann prima verwenden wenn zwischen
den Rasterstellungen 2 oder 4 Impulse kommen, aber nur einer gezählt
werden soll.

ISR(TIMER0_OVF_vect)
{
  static char enc_last = 0x01;
  char i = 0;

    if( PHASE_A )
      i = 1;

    if( PHASE_B )
      i ^= 3;        // convert gray to binary

    i -= enc_last;      // difference new - last
    if( i & 1 ){      // bit 0 = value (1)
      enc_last += i;      // store new as next last
    enc_delta += (i & 2) - 1;  // bit 1 = direction (+/-)
    if (!(enc_delta % 4)) {  // nur jeden 4. Schritt zählen
    if ((i & 2)) {    // prüfen ob auf oder ab
      count++;    // 0-255
    }
    else {
      count--;    // 255-0
    }
    }
    }
}

Läuft super.

Arne

Autor: Marco Beffa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe erfolglos versucht den Code hier zu verwenden.

Wäre jemand so freundlich mir das ganze nochmals klar und deutlich zu
erklären? Die Codeschnippsel oben sind eher verwirrend!!


last_cnt ist die Bitkombination bei der zuletzt gezählt wurde (00) oder
(11)

last_state ist der letzte Zustand (10)/(01) d.h. woher ich komme

wo wird bei 00 und 11 etwas gezählt? da soll ja gerade nichts
passieren...


Mit freundlichen Grüssen

Autor: Marco Beffa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dies ist mein Code:

void encoder(void)
{

struct
{
 unsigned int speicher_A :1;
 unsigned int speicher_B :1;
}encoder;

if(PF.PORT.BIT.B1 == PF.PORT.BIT.B2)
{
 encoder.speicher_A = PF.PORT.BIT.B1;
 encoder.speicher_B = PF.PORT.BIT.B2;
}

if(PF.PORT.BIT.B1 ^ PF.PORT.BIT.B2)  //Bits unterschiedlich?
 {
   if(encoder.speicher_B ^ PF.PORT.BIT.B2) // Hat Bit2 geändert?
    {
      while(PF.PORT.BIT.B1 == encoder.speicher_A); //warten
      LCD_clear(0);
      LCD_writeString("Links", 0, 0,0);

    }

   else
    {
      while(PF.PORT.BIT.B2 == encoder.speicher_B);
      LCD_clear(0);
      LCD_writeString("Rechts", 0, 60,0);
    }
 }
}


90 % der Fälle funtkioniert er, jedoch werden manchmal Drehungen nicht
erkannt (auch wenn sie sehr langsam gemacht wurden). Es muss also
irgendwo ein Fehler sein! Ausserdem finde ich das mit der while
schleife ebenfalls nicht gut, aber irgendwie muss ich ja die Änderung
des andern Bits abwarten, oder?

MFG

Autor: SuperUser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Irgendwie kann ich bei deinem Code keine grosse Ähnlichkeit mit dem
Original erkennen...

Vielleicht ist wichtig, dass _BV(PINE4) und _BV(PINE3) verschieden
sind. _BV(PINE4) bedeutet z.B. (1<<3) d.h. 8, und _BV(PINE3) = 1<<2 =
4. Ist bei deinem PF.PORT.BIT.B1 vermutlich nicht so?

Ausserdem kostet dein LCD_clear() und LCD_write() vmtl. soviel Zeit,
dass die Drehpulse verloren gehen. Der Code sollte schon mit einer
gewissen Poll-Frequenz laufen (bei mir 400Hz).

Hier nocheinmal der Original-Code damit man nicht scrollen muss...

void encoder(void)
{
  static uint8_t last_state = 0;
  static uint8_t last_cnt = 0;
  uint8_t new_state;

  new_state=PINE & (_BV(PINE4) | _BV(PINE3));
  if ((new_state^last_cnt)==(_BV(PINE4) | _BV(PINE3)) )
  {
    if ((new_state ^ last_state)==_BV(PINE4))
      enc_delta+=1;
    else
      enc_delta-=1;
    last_cnt=new_state;
  }
  last_state=new_state;
}

Autor: Dirk Frerichs (dirk-frerichs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo

ich versuche gerade das zum laufen zu bekommen
scheitere aber kläglich

hier mal ein paar schnipsel:



// belegung des Rotary Encoders
#define ROTARY_DDR      DDRD
#define ROTARY_PIN      PIND
#define ROTARY_PORT     PORTD
#define ROTARY_A        5
#define ROTARY_B        6
#define ROTARY_P        7

int enc_delta=0;

void encoder(void)
{
  static uint8_t last_state = 0;
  static uint8_t last_cnt = 0;
     uint8_t new_state;

  new_state=ROTARY_PIN & ((1<<ROTARY_A) | (1<<ROTARY_B));

  if ((new_state^last_cnt)== (1<<ROTARY_A) | (1<<ROTARY_B))
    {

  if ((new_state ^ last_state)==(1<<ROTARY_A))
    enc_delta+=1;
  else
    enc_delta-=1;

  last_cnt=new_state;
  }
  last_state=new_state;
}


int main (void)
{
     ROTARY_DDR &=~ (1<<ROTARY_A)|(1<<ROTARY_B)|(1<<ROTARY_P);
     ROTARY_PORT |= (1<<ROTARY_A)|(1<<ROTARY_B)|(1<<ROTARY_P);



  for(;;)
  {

        encoder();

        itoa(enc_delta,out,10);
  lcd_gotoxy(13,0);
  lcd_puts(out);

        }

}



es kommt aber leider nur ein extrem schnelles zählen auf das LCD
new_state und last_state sind immer auf 0
es passiert nix bei drehung

könnte mir bitte jemand sagen warum ?
hab schin gesucht , finde aber nix

Danke

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht enc_delta als volatile deklarieren, damit im Hauptprogramm 
Änderungen an der Variable erkannt werden...

Autor: Dirk Frerichs (dirk-frerichs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
leider keine besserrung

Autor: Erazer (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Im Anhang ein Code der bei mir bestens funktioklappt.

Autor: Erazer (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:
PullUpwiderstände sind bei mir am Drehgeber.
Daher im Code keine eingeschaltet.

Autor: Dirk Frerichs (dirk-frerichs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi

also ich habe es nun zum laufen bekommen
zwar mit anderem code

da dieser aber immer 2 schritte zählt  teile ich das ganze immer durch 2


#define ROTARY_DDR      DDRD
#define ROTARY_PIN      PIND
#define ROTARY_PORT     PORTD
#define ROTARY_A        5
#define ROTARY_B        6
#define ROTARY_P        7

volatile int enc_delta =0 ;


SIGNAL (SIG_OVERFLOW0)
{
  static char enc_last  = 0x01;
  char     i       = 0;
  if( (ROTARY_PIN & (1<<ROTARY_B) ))
    i = 1;
  if( (ROTARY_PIN & (1<<ROTARY_A) ))
    i ^= 3;
    i -= enc_last;
  if( i & 1 )
    {
    enc_last += i;
      enc_delta += (i & 2) - 1;
      }
}

Autor: Erazer (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier der entgültige Code

Autor: tomgr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

habe hier nen Drehimpulsgeber (noname), der immer in der Raststellung 00 
hat.
Dadurch kann ich mit dem hier vorhandenen Code keine Auswertung machen.

Das Ding zählt halt nur in eine Richtung.

Also, R ist die Raststellung :
links  (R)00 - 01 - 11 - 01 - (R)00
rechts (R)00 - 10 - 11 - 10 - (R)00

Ich bitte mal um ne kleine hilfe.

gruss tomgr

Autor: SuperUser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum sollte der Code mit deinem Drehgeber nicht funktionieren? Er wird 
halt nur doppelt zählen...

Autor: wilfried mühlenhoff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich verwende Encoder mit 30 oder 40iger Auflösung.
Da kriegt der AVR ganz schön was zu tun.
Sollte man den kleinsten Eingang über IRQ aufnehmen,
anstatt mit hoher Samplerate zu arbeiten?

Das Softwareentprellen ist auch nicht ganz ohne.
Habe ich das auch bei Drehgebern mit HALL-IC?

P.S.
Habe meine Drehgeberreste jetzt in EBay eingestellt.
Wer noch welche braucht...

Autor: Harry (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi folks,

I´m very sorry but when I see this : "_BV(PINE4) | _BV(PINE3" . I´m just 
wondering how it functions.

Because you cannot write in the register PINX.

Or I´m wrong ? or I´m messed up ? somebody has to explain me that...

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
That are defines for the port register and the register bits. _BV() is a 
macro that gives the bit vector for the given bit.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  wilfried mühlenhoff (Gast)

>Ich verwende Encoder mit 30 oder 40iger Auflösung.
>Da kriegt der AVR ganz schön was zu tun.

Nö.

>Sollte man den kleinsten Eingang über IRQ aufnehmen,
>anstatt mit hoher Samplerate zu arbeiten?

Nein, siehe Artikel Drehgeber.

>Habe ich das auch bei Drehgebern mit HALL-IC?

Ja. Siehe Artikel.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Harry (Gast)

>Because you cannot write in the register PINX.

Yes, you can! ;-)
In the new AVRs, writing a PINX bit will toggle the corresponding PORTX 
Bit!

Regards
Falk

Autor: Wuhu W. (wuhuuu2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe den Code verwendet, nur ergibt sich bei mir bei der Abfrage

new_state ^ last_state = 11

Also ein unerwünschte Ergebnis, da ja nur 10 oder 01 erwartet wird.

Kann mir jemand helfen?
ISR( TIMER2_OVF_vect )
{

new_state = PINL & ((1<<5) | (1<<3))  ;  // save state

// Change in State on both important positions?
if (  (new_state ^ last_count) == ((1<<5 )|(1<<3))    ) 
  {
    // right or left turn?
    if(  (new_state ^ last_state) == (1<<3 ) )
      {enc_delta += 1;}
    else                               // Falle für unerwünschten Zustand
      {enc_delta -= 1;}

    enc_last_count = enc_new_state;    // save Bitcombination of last count
  }
enc_last_state = enc_new_state;        // save last state

}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.