www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik drehgeber mit atmega8


Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)
#ifndef F_CPU
#define F_CPU 4000000L                  // Systemtakt in Hz - define as  long>> Without errors in the computation 
#endif
 
#define PHASE_A    (PINC & 0x01)
#define PHASE_B    (PINC & 0x04)
 
#define LEDS_DDR  DDRB
#define  LEDS    PORTB      // LEDs against VCC
 
volatile int8_t enc_delta;      // -128 ... 127
static int8_t last;
 
 
void encode_init( void )
{
  int8_t new;
 
  new = 0;
  if( PHASE_A )
    new = 3;
  if( PHASE_B )
    new ^= 1;            // convert gray to binary
  last = new;            // power on state
  enc_delta = 0;
  //interrupt
  TCNT0 = 5;              //Set Timer/counter
  TIMSK |= (1<<TOIE0);        //Enable Timer/counter0 overflow interrupt
  TCCR0 |= (1<<CS01);
  TCCR0 |= (1<<CS00);        //Select the clock source to be used by the timer/counter --> CPU Takt  --> 4MHz/64 
  TIFR |= (1<<TOV0);        //interrupt starts with each overflow  
}
   
 
ISR( TIMER2_COMP_vect )        //1ms for manual movement
{
  int8_t new, diff;
 
  new = 0;
  if( PHASE_A )
    new = 3;
  if( PHASE_B )
    new ^= 1;            //convert gray to binary
  diff = last - new;        //difference last - new
  if( diff & 1 ){          //bit 0 = value (1)
    last = new;            //store new as next last
    enc_delta += (diff & 2) - 1;  //bit 1 = direction (+/-)
  }
}
 
 
int8_t encode_read1( void )      //read single step encoders
{
  int8_t val;
 
  cli();
  val = enc_delta;
  enc_delta = 0;
  sei();
  return val;            //counts since last call
}
 
int main(void)
{

  int32_t val = 0;

  DDRC = 0x00;    // PORTB auf Eingang
  PORTC = 0xFF;      // pull ups for key inputs  PortC1 and portC3
 
  LEDS_DDR = 0xFF;          // outputs for LEDs
  encode_init();
  sei();
 
  for(;;)
  {
    val += encode_read1();      // read a single step encoder
    LEDS = val;
  } 
    
}

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ß

Autor: Route_66 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo verstehst Du was Peter mit

//1ms for manual movement

meinte???

Autor: Tueftler86 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Da I (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Da I (Gast)
Datum:

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

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht 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?

...

Autor: Schluck (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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? :-)

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christian H. (netzwanze) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Schluck (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.