Encoder Kanal B

OP #3563498
Lesenswert?
• ▲
▼
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
Lesenswert?
• ▲
▼
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
Lesenswert?
• ▲
▼
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
Lesenswert?
• ▲
▼
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

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.

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.