Forum: Mikrocontroller und Digitale Elektronik drehgeber mit atmega8


von gast (Gast)


Lesenswert?

Hallo,


ich möchte einen Inkremental drehgeber RI38 welle 38 mm von Firma rs mit 
atmega8 auswerten.
meine Beiden Pin A und pin B habe ich jeweils an pin 1 und 3 an port c .

Das Programm von peter habe ich für atmega8 angepasst. (s. unten)
1
#ifndef F_CPU
2
#define F_CPU 4000000L                  // Systemtakt in Hz - define as  long>> Without errors in the computation 
3
#endif
4
 
5
#define PHASE_A    (PINC & 0x01)
6
#define PHASE_B    (PINC & 0x04)
7
 
8
#define LEDS_DDR  DDRB
9
#define  LEDS    PORTB      // LEDs against VCC
10
 
11
volatile int8_t enc_delta;      // -128 ... 127
12
static int8_t last;
13
 
14
 
15
void encode_init( void )
16
{
17
  int8_t new;
18
 
19
  new = 0;
20
  if( PHASE_A )
21
    new = 3;
22
  if( PHASE_B )
23
    new ^= 1;            // convert gray to binary
24
  last = new;            // power on state
25
  enc_delta = 0;
26
  //interrupt
27
  TCNT0 = 5;              //Set Timer/counter
28
  TIMSK |= (1<<TOIE0);        //Enable Timer/counter0 overflow interrupt
29
  TCCR0 |= (1<<CS01);
30
  TCCR0 |= (1<<CS00);        //Select the clock source to be used by the timer/counter --> CPU Takt  --> 4MHz/64 
31
  TIFR |= (1<<TOV0);        //interrupt starts with each overflow  
32
}
33
   
34
 
35
ISR( TIMER2_COMP_vect )        //1ms for manual movement
36
{
37
  int8_t new, diff;
38
 
39
  new = 0;
40
  if( PHASE_A )
41
    new = 3;
42
  if( PHASE_B )
43
    new ^= 1;            //convert gray to binary
44
  diff = last - new;        //difference last - new
45
  if( diff & 1 ){          //bit 0 = value (1)
46
    last = new;            //store new as next last
47
    enc_delta += (diff & 2) - 1;  //bit 1 = direction (+/-)
48
  }
49
}
50
 
51
 
52
int8_t encode_read1( void )      //read single step encoders
53
{
54
  int8_t val;
55
 
56
  cli();
57
  val = enc_delta;
58
  enc_delta = 0;
59
  sei();
60
  return val;            //counts since last call
61
}
62
 
63
int main(void)
64
{
65
66
  int32_t val = 0;
67
68
  DDRC = 0x00;    // PORTB auf Eingang
69
  PORTC = 0xFF;      // pull ups for key inputs  PortC1 and portC3
70
 
71
  LEDS_DDR = 0xFF;          // outputs for LEDs
72
  encode_init();
73
  sei();
74
 
75
  for(;;)
76
  {
77
    val += encode_read1();      // read a single step encoder
78
    LEDS = val;
79
  } 
80
    
81
}

von peter:

>"Die Auswertung eines Drehgebers macht man am besten in einem Timer
>Interrupt, der mit einer festen Frequenz ausgeführt wird. Die
>Abtastfrequenz >muss so hoch sein, dass bei maximaler Drehzahl zwischen
>zwei Codewechseln >mindestens 1 Abtastung erfolgt, besser jedoch mehr. "

Frage:
1.verstehe ich nicht ganz gut wie ich meine Frequenz einstellen muss.
drehgeber hat:

1000 Impulse pro umdrehung
drehzahl max. 10000 1/s
max Impulsfrequenz 200 khz

2. messe ich dann mein Signal am ozi und kriege sinus kurven und weiss 
nicht wie ich den interpretieren muss um meine Drehrichtung zu 
bestimmen.

Ich möchte eigentlich mit meinem Drehgeber Entfernungsrechnen, bei recht 
drehung immer die länge addieren und bei links drehung dekrementieren.



Anfängerin in Mikrokontrollerwelt, kann mir jemand dazu ein paar tipp 
geben.

danke
gruß

von Route_66 (Gast)


Lesenswert?

Hallo verstehst Du was Peter mit

//1ms for manual movement

meinte???

von Tueftler86 (Gast)


Lesenswert?

1000 Impulse/Umdrehung mal 10000 Umdrehungen pro sekunde (wenn ich das 
richtig interpretiert habe) macht schon 10MHz.
Da braucht man einen ganz flinken AVR mit ich würde sagen wenigstens 
100Mhz, und dann nicht im Timerinterrupt auslesen sondern in 
INT0+INT1-Betrieb.

von Da I (Gast)


Lesenswert?

Öh... seit wann liest man Drehgeber mit Timer-Interrupt aus?
Einen Pin davon an nen INT0, INT1 oder was grad frei ist und in der ISR 
dann schauen, was der zweite Pin für nen Pegel hat => Drehrichtung.

von Matthias L. (Gast)


Lesenswert?

>Öh... seit wann liest man Drehgeber mit Timer-Interrupt aus?
>Einen Pin davon an nen INT0, INT1 oder was grad frei ist und in der ISR
>dann schauen, was der zweite Pin für nen Pegel hat => Drehrichtung.

MÖÖÖÖP.

Drehgeber

von Da I (Gast)


Lesenswert?

Hoi... so kann ma sich täuschen.
Nur hatt ich mit der anderen Methode bisher nie Probleme.

von Hannes L. (hannes)


Lesenswert?

Sollte man nicht fairerweise zwischen
- manuell betätigten Drehgebern (Eingabegerät, weit unter 100 Schritte
  pro Umdrehung, Verwendung als Benutzerinterface)
und
- maschinell betätigten Drehgebern (optische Encoder mit weit über
  100 Schritten pro Umdrehung, Verwendung zur Drehzahlmessung und
  Lagebestimmung von Maschinen)
unterscheiden?

...

von Schluck (Gast)


Lesenswert?

Es sind wohl 1000 Impulse/Umdrehung bei max. 10000 U/min. Maximal also 
ca. 160kHz.
Dazu mußt Du den Mega8 auf jeden Fall mit 16MHz takten und die Signale 
an INT0 und INT1 anlegen und auswerten.
Du schreibst etwas von Sinussignalen? Dann müßten diese noch nach 
Rechteck umgeformt werden, wobei die Hysterese nicht zu klein sein 
sollte. Damit keine kürzeren Impulse als 5µs (f<200kHz) an die 
INTx-Eingänge gelangen, ist ist sinnvoll, die Rechtecksignale mit 
D-Flipflops zu synchronisieren. Der Takt dazu sollte ca. 200kHz betragen 
und kann mit einem Timer erzeugt werden.
Alles verstanden? :-)

von Benedikt K. (benedikt)


Lesenswert?

Es geht auch mit dem Timerinterrupt, so wie hier:
http://elm-chan.org/works/smc/report_e.html

von Falk B. (falk)


Lesenswert?

@  Hannes Lux (hannes)

>Sollte man nicht fairerweise zwischen

IMO nein. Das führt nur zu der Denkweise, "naja, bei Drehknöpfen kann 
schon mal ein Schritt verloren gehen, dafür ist meine Bastellösung 
sparsamer".

Von dem Abschnitt im Artikel halte ich nichts. Ich würde ihn 
rausschmeissen. Aber ich glaub auch noch ein wenig an die Demokratie :-0

MFG
Falk

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Da I schrieb:
> Hoi... so kann ma sich täuschen.
> Nur hatt ich mit der anderen Methode bisher nie Probleme.

Die Sparvariante kann man tatsächlich in einigen Fällen anwenden.
Jedoch benötigt man hierzu einen optischen (prellfreien) Drehgeber für 
Handbedienung mit Rasten.

Für alles andere ist ein Algorithmus mit Timer vorzuziehen (bzw die 
einzig Sinnvolle Anfrage). Siehe Link in Matthias Lipinskys Antwort.

von Schluck (Gast)


Lesenswert?

>Für alles andere ist ein Algorithmus mit Timer vorzuziehen

Ein Mega48 mit 20MHz Takt kann per INT0 bei geschickter 
ASM-Programmierung 500kHz mit einem 32bit Zähler verarbeiten. Das obige 
Beispiel (elm-chan) arbeitet mit 52kHz, wenn ich nicht irre. Sofern die 
Impulse prellfrei anliegen, muß auch nicht synchronisiert werden.

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.