Forum: Mikrocontroller und Digitale Elektronik Encoder Kanal B


von Alina K. (alinakoch)


Angehängte Dateien:

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

von Robert D. (d0rni)


Lesenswert?

hast du das richtige gemeinsame Beinchen gefunden? Und hast du das auch 
auf Masse gelegt?

von Alina K. (alinakoch)


Lesenswert?

Robert Dorn schrieb:
> hast du das richtige gemeinsame Beinchen gefunden? Und hast du das auch
> auf Masse gelegt?

Ja, ich habe den Encoder richtig angeschlossen

von Yalu X. (yalu) (Moderator)


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

: Bearbeitet durch Moderator
von Alina K. (alinakoch)


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

von Yalu X. (yalu) (Moderator)


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
}

: Bearbeitet durch Moderator
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.