Encoder Kanal B

OP #3563498
Hallo!

Ich versuche gerade, mit dem ATMega328 den Encoder STEC11B einzulesen, 
leider wird die Position pos immer nur hinaufgezählt. Das Programm kommt 
nie in die if-Bedingung der else-Schleife.
Anbei ist noch ein Diagramm, wie die Eingänge der beiden Kanäle des 
Encoders aussehen.
1
uint8_t pos = 10;
2
char EncoderBLast = 0;
3
char EncoderALast = 0;
4

5
void setup()
6
{
7

8

9
  DDRD &= ~ 0x04; //Pin B, 2, Eingang
10
  DDRD &= ~ 0x08; //Pin A, 3, Eingang
11
  DDRD |= 0x10;
12

13
  #define EncoderA (PIND & 0x04)//0x04 PINC & (1<<PC3);
14
  #define EncoderB (PIND & 0x08)
15
  if (EncoderA) EncoderA == 0;
16
  if (EncoderB) EncoderB == 0;
17

18

19
  Serial.begin(9600);
20

21
  TCCR0A = (1 << COM0A1);
22
  TCCR0A = (1 << COM0B1);
23
  OCR0A = 100; //1ms
24
  TIMSK0 = (1 << OCIE0A);
25
  sei();
26
}
27

28
ISR(TIMER0_COMPA_vect)
29
{
30
  if (EncoderA != 0 && (EncoderALast == 0)) //pos Flanke
31
  {
32
    if (EncoderB == 0)
33
    {
34
      pos = pos + 1;
35
      delay(10);
36
      Serial.println(pos);
37
    }
38
    else
39
    {    
40
      if (EncoderB == 1)
41
      {
42
        pos = pos - 1;
43
        delay(10);        
44
      }
45
    }
46
  }
47

48
  EncoderALast == EncoderA;
49
}
50

51
void loop()
52
{
53
  ;
54
}

Kann mir jemand sagen, wo das Problem liegt?

Liebe Grüße
Angehängte Dateien:
Moderator #3563621
Wie soll jemals EncoderB == 1 werden?

Lass die Abfrage einfach weg, sie ist schon durch das vorangehende
"else" abgedeckt.

Ansonsten ist es nicht sehr geschickt, die Eingänge innerhalb der
Interruptroutine mehrfach abzufragen. Sie könnten sich zwischendurch
ändern, was dan u.U. zu verschluckten Schritten führt. Besser ist es,
die Eingänge am Anfang in Variablen zu lesen und dann nur noch auf diese
Variablen zuzugreifen.

Und was machen eigentlich diese beiden Zeilen:
1
  if (EncoderA) EncoderA == 0;
2
  if (EncoderB) EncoderB == 0;

Schmeiß sie raus.

Hast du dieses hier schon durchgelesen: Drehgeber
OP #3563645
Yalu X. schrieb:
> Wie soll jemals EncoderB == 1 werden?
>
> Lass die Abfrage einfach weg, sie ist schon durch das vorangehende
> "else" abgedeckt.
>
> Ansonsten ist es nicht sehr geschickt, die Eingänge innerhalb der
> Interruptroutine mehrfach abzufragen. Sie könnten sich zwischendurch
> ändern, was dan u.U. zu verschluckten Schritten führt. Besser ist es,
> die Eingänge am Anfang in Variablen zu lesen und dann nur noch auf diese
> Variablen zuzugreifen.
>
> Und was machen eigentlich diese beiden Zeilen:
>
>
1
>   if (EncoderA) EncoderA == 0;
2
>   if (EncoderB) EncoderB == 0;
3
>
>
> Schmeiß sie raus.
>
> Hast du dieses hier schon durchgelesen: Drehgeber

Danke für deine schnelle Antwort.
Wenn ich die if-Bedingung in der else-Schleife weglasse, springt es 
ständig in diese Schleife hinein, obwohl ich den Encoder im 
Uhrzeigersinn drehe..

Und wie meinst du das, die Eingänge am Anfang der ISR in Variablen 
lesen? Kannst du mir ein Beispiel nennen?

Liebe Grüße
Moderator #3563690
Alina Koch schrieb:
> Wenn ich die if-Bedingung in der else-Schleife weglasse, springt es
> ständig in diese Schleife hinein, obwohl ich den Encoder im
> Uhrzeigersinn drehe..

Stimmt, da ist nämlich noch ein Fehler:
1
  EncoderALast == EncoderA;

"==" ist in C der Vergleichsoperator, der Zuweisungsoperator heißt "=".
Du willst hier abere etwas zuweisen.

> Und wie meinst du das, die Eingänge am Anfang der ISR in Variablen
> lesen? Kannst du mir ein Beispiel nennen?

So (die anderen Fehler sind auch beseitigt):
1
ISR(TIMER0_COMPA_vect)
2
{
3
  uint8_t EncoderACurrent, EncoderBCurrent;
4

5
  EncoderACurrent = EncoderA;
6
  EncoderBCurrent = EncoderB;
7

8
  if (EncoderACurrent != 0 && (EncoderALast == 0)) //pos Flanke
9
  {
10
    if (EncoderBCurrent == 0)
11
      pos = pos + 1;
12
    else
13
      pos = pos - 1;
14
    Serial.println(pos);
15
  }
16

17
  EncoderALast = EncoderACurrent;
18
}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 12 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.