Drehgeber auswerten - Zählproblem

#3974514
Lesenswert?

Hallo zusammen,

ich hab folgenden Code geschrieben, mit Hilfe der bekannten Threats von 
dem Thema.
Er funktioniert auch weitestgehenst....

Problem:
Beim Hochzählen pendelt er immer zwischen zwei Werten.
(Runterzählen funktioniert problemlos)

Falls mir jemand den Fehler sagen kann (oder sagen das kein Fehler 
drinnen ist und dieser woanders liegen muss) wäre ich sehr dankbar.


Randinformationen:
Atmega2560
KEY_PIN is PINL
Increment_A = 5
Increment_B = 3
F_CPU = 14745600
1
main-schleife
2

3
wert += enc_get()
4

5
wert an Uart senden
6

7

8
/***********************************************************************************/
9

10
// -128 .. +127
11
volatile  uint8_t  enc_last_state;  // "letzter Zustand"
12
volatile  uint8_t  enc_last_count;  // "Bitcombination beim letzten zählen"
13
volatile  uint8_t  enc_new_state;
14
volatile  int8_t  enc_delta;
15

16

17
void init_incremental_encoder()
18
{
19
  //Initializing 8-Bit Timer2 - incremental encoder
20

21
  TCCR2A = 0x00;    // normal mode
22
  TCCR2B = 0x04;  //prescaler 64 = 0x04
23
  TIMSK2 = 0x01;    // enable timer overflow Interrupt
24
  //TCNT2 = 0x00;    // count-parameter
25

26
enc_delta = 0;
27
enc_last_count = KEY_PIN & ((1<<Increment_A ) | (1<<Increment_B ));
28

29
return;
30
}
31

32

33

34

35

36
ISR( TIMER2_OVF_vect )
37
{
38

39
enc_new_state = KEY_PIN & ((1<<Increment_A ) | (1<<Increment_B ))  ;  // save state
40

41
// Change in State on both important positions?
42
if (  (enc_new_state ^ enc_last_count) == ((1<<Increment_A )|(1<<Increment_B))    ) 
43
  {
44
    // right or left turn?
45
    if(  (enc_new_state ^ enc_last_state) == (1<<Increment_B ) )
46
      {enc_delta += 1;}
47
    else
48
      {enc_delta -= 1;}
49

50
    enc_last_count = enc_new_state;    // save Bitcombination of last count
51
  }
52
enc_last_state = enc_new_state;        // save last state
53

54
}
55

56

57

58

59

60
int8_t enc_get()
61
{
62
  int8_t val;
63
  cli();
64
  val = enc_delta;
65
  enc_delta = 0;
66
  sei();
67
  return val;
68
}
Gast #3975025
Lesenswert?

Wuhu W. schrieb:
> (enc_new_state ^ enc_last_count) == ((1<<Increment_A )|(1<<Increment_B))

Eher

(enc_new_state ^ enc_last_count) & ((1<<Increment_A ) | (1<<Increment_B 
))

ist dann ungleich 0

Ganz allgemein würde ich
enc_new_state ^ enc_last_count)
weil es 2 mal benutzt wird in eine Variable tum

enc_change_state = (enc_new_state ^ enc_last_count)

denn es könnte sich (volatile) mittendrin ändern.
Moderator (Firma: Titel) Persönliche Seite #3977378
Lesenswert?

Wuhu W. schrieb:
> Threats
=Bedrohungen...
Thread=Faden

Walter schrieb:
>> Teo Derix schrieb:
>> Pin am Encoder vertauscht!
> dann kommt nach 11 immer noch 00
Dann zeig doch mal ein paar Fotos von deinem Aufbau. Wenn der Encoder so 
zählt  wie du dad geschrieben hast, kommt mit der geposteten Routine 
nichts sinnvolles raus. Die erwartet nämlich richtigen Graycode:
00-01-11-10-00-...
#3986808
Lesenswert?

Sorry das es so lang gedauert hat, hier meine funktinierende Lösung:

Wenn es um 2 stellen springt, also 00->11 oder 11->00, dann ergibt sich 
aus meiner links/rechts abfrage für beides eine 1, ich gehe zum else. 
Dort wird die letzte Absolute Position überprüft.

(Wenn er dann nur zwischen 2 zahlen pendelt, muss ich pins tauschen/ bzw 
+- in dieser else routine vertauschen)

Ich hoffe ihr versteht was ich mein

@Lothar Miller,  danke ;)

1
  
2
  // Change in State on both important positions?
3
  if (  (enc_1.buffer_new_state ^ enc_1.last_count) == ((1<<Increment_1_A )|(1<<Increment_1_B))    )
4
    {
5
      enc_1.time2 ++;    // for fast counting
6

7
      // right or left turn?
8
      if    (  (enc_1.buffer_new_state ^ enc_1.last_state) == (1<<Increment_1_B ) )
9
        {enc_1.delta += enc_1.add;}
10

11
      else if  (  (enc_1.buffer_new_state ^ enc_1.last_state) == (1<<Increment_1_A ) )
12
        {enc_1.delta -= enc_1.add;}
13
      else
14
      /**/
15
      //  This Part is normaly not required.But the rotary encoder in use has this Graycode: 00-10-11-00-10-11-00
16
      //  Therefore it evaluetes the last position to determine the turn-direction
17
      //  In case of failure, change + and - in the following
18
      /**/
19
        {
20
          if(enc_1.last_state != 0)
21
          enc_1.delta += enc_1.add;
22
          else
23
          enc_1.delta -= enc_1.add;  
24
        }
25

26
      enc_1.last_count = enc_1.buffer_new_state;    // save Bitcombination of last count
27
    }//if
28

29
  enc_1.last_state = enc_1.buffer_new_state;        // save last state
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren