Forum: Compiler & IDEs Drehcoder ALPS Stec12E08 will nicht


von Mücke (Gast)


Angehängte Dateien:

Lesenswert?

Hallo und einen schön Abend,

ich habe hier einen Drehencoder von Reichelt und zwar ist es der ALPS 
STEC12E08, das Datenblatt habe ich angehangen. Ich versuche ihn den 
ganzen Tag schon zum laufen zubringen doch er möchte leider nicht so 
ganz.

Das Tutorial hier http://www.mikrocontroller.net/articles/Drehgeber, 
habe ich auch schon durchgelesen und das angepasste Programm auf mein µc 
geladen doch leider ohne Erfolg. Dort wird der Drehencoder ja ohne 
Interrupt ausgelesen, allerdings passiert nicht mal ansatzweise etwas 
wenn ich den Encoder drehe.

So wie ich das in sämtlichen Beiträgen raus gelesen habe, ist es ein 
Encoder mit wackeligen Rastpunkt, sieht man auch ganz gut im Datenblatt, 
ferner in den Zustandsdiagrammen. Somit sollte ja wenn auf Phase A, eine 
steigende auf INT0 Flanke reinkommt ein Interrupt ausgelöst werden und 
in dem kann ich dann die Phase B auswerten, und eine Variable entweder 
inkrementieren oder dekrementieren. Soweit so gut, ein bisschen 
funktioniert mein Programm auch, allerdings nur ein bisschen :( Wenn ich 
den Encoder drehe wird meine Variable ständig inkrementiert, allerdings 
völlig willkürlich, entweder um 2 oder 3 oder 4, wobei ich denke das es 
vom prellen des Encoders kommt.

Hier mal mein Programm dazu. Hoffe ihr könnt mir etwas helfen da ich 
echt nicht weiter komme. Noch ein paar Infos dazu: Takt 8Mhz, 
Rn-Control, Display angeschlossen 1x16 Char. Den Encoder habe ich wie im 
Datenblatt angeschlossen mit den beiden Pull-ups.
1
 
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <stdlib.h>
5
#include "lcd.h"
6
#include <avr/pgmspace.h>
7
#include <util/delay.h>
8
9
volatile uint8_t val = 50;     //globale Variable für Drehencoder
10
11
12
13
ISR (INT0_vect) {              //Interruptroutine
14
  if (!(PORTD & (1 << PIND3))) //Phase B auswerten, wenn von Phase A eine 
15
    val++;                     //steigende Flanke ausgeht, wird Phase B ausgewertet,
16
  else                //ist dann Phase B negativ ist die Drehrichtung C.W.
17
    val--;                //und umgekehrt, sprich Phase B postiv, Drehrichtung C.C.W.
18
  PIND &= ~ (1 << PIND3);
19
}
20
21
22
void timer_init (void) {                 //Timer0 auf Int0 initialisieren
23
  MCUCR |= (1 << ISC01) | (1 << ISC00);  //steigende Flanke
24
  GICR |= (1 << INT0);
25
  sei();                                 //Globale Interrupts ein
26
  }
27
28
29
int main (void) {
30
  DDRD &=~ (1 << PIND2)| (1 << PIND3);   //Eingäne definieren
31
32
  DDRB  |= (1 << PB6);                   //Displaybeleuchtung ein 
33
  PORTB |= (1 << PB6);
34
35
  uint8_t help;              
36
  char value [10];
37
38
  help = val;
39
40
41
  timer_init ();                         //Timerinitialisierung
42
43
  lcd_init(LCD_DISP_ON);                 //LCD Initialisierung 
44
  lcd_clrscr ();
45
46
  lcd_puts ("Drehencoder");              //Displayanzeige
47
  _delay_ms (300);
48
  lcd_clrscr ();
49
50
  itoa (val, value, 10);              //Typenumwandlung von Integer in char
51
  lcd_puts (value);
52
53
54
55
56
  while (1) {
57
58
59
    if (help != val) {          //Variable vom Drehencoder auf dem Display darstellen
60
      lcd_clrscr ();            //welche nur bei Bedarf aktuallisiert wird
61
      itoa (val, value, 10);
62
      lcd_puts (value);
63
      help = val;
64
65
    }
66
67
  }
68
69
}

Vielen Dank schonmal im Vorraus :)

von Falk B. (falk)


Lesenswert?

@Mücke (Gast)

>Das Tutorial hier http://www.mikrocontroller.net/articles/Drehgeber,
>habe ich auch schon durchgelesen

Aber scheinbar nicht verstanden. :-(

>und das angepasste Programm auf mein µc
>geladen doch leider ohne Erfolg. Dort wird der Drehencoder ja ohne
>Interrupt ausgelesen, allerdings passiert nicht mal ansatzweise etwas
>wenn ich den Encoder drehe.

Tj, du bist auch mal wieder oberschlau. Mach es wie im Tutorial mit 
einem Timer-Interrupt und gut. Deine External Interrupt Sache ist Müll!

>ferner in den Zustandsdiagrammen. Somit sollte ja wenn auf Phase A, eine
>steigende auf INT0 Flanke reinkommt ein Interrupt ausgelöst werden und

NEIN! LIES DEN VERDAMMTEN ARTIKEL!

von Mücke (Gast)


Lesenswert?

kann sein das ich es nicht verstanden habe, deswegen wohl auch der 
Beitrag. Aber trotzdem danke für deine Mühe und Hilfe, ich werds nochmal 
lesen : )

von Mücke (Gast)


Lesenswert?

Hallo nochmal,

und zwar habe ich mir das Tutorial noch einmal zu gemühte geführt und 
siehe da es funktioniert und zwar tadellos :-) Jetzt habe ich auch den 
Code verstanden^^

Allerdings hat sich, so denke ich, in dem Tutorial ein kleiner aber 
entscheidender Fehler eingeschlichen. Und zwar bei der Initialisierung 
in dem Program mit dem wackeligen Rastpunkt.
1
int main( void )
2
{
3
  int32_t val = 0;
4
 
5
  LEDS_DDR = 0xFF;      <<<--Hier fehlt die Funktion encode_init ()
6
  sei();
7
 
8
  while(1){
9
    val += encode_read();      
10
    LEDS = val;
11
  }
12
}

Ohne die Init klappt es bei mir jedenfalls nicht.

Einen schönen Abend noch :-)

von Falk B. (falk)


Lesenswert?

@  Mücke (Gast)

>und zwar habe ich mir das Tutorial noch einmal zu gemühte geführt und
>siehe da es funktioniert und zwar tadellos :-)

Surprise, Surprise . . .

>Jetzt habe ich auch den Code verstanden^^

Na immerhin.

>Allerdings hat sich, so denke ich, in dem Tutorial ein kleiner aber
>entscheidender Fehler eingeschlichen. Und zwar bei der Initialisierung
>in dem Program mit dem wackeligen Rastpunkt.

Ja, ist ein Fehler. Danke für die Mitteilung. Hab ich korrigiert.

MFG
Falk

von Frank B. (foobar)


Lesenswert?

Du kannst es übrigens auch interruptbasiert programmieren, aber wichtig 
dabei ist, nicht auf einen flankenwechsel den Interrupt auszulösen, 
sondern per Timerinterrupt, wie ich es hier implementiert habe:

http://www.frank-buss.de/attiny/index.html

Prellen ist egal bei Quadraturencodern, solange der Interrupt schneller 
ist, als der Abstand zwischen zwei Rasterpositionen bei schnellster 
Drehung.

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.