mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATMega8: INT0 und INT1 funktionieren sehr komisch


Autor: Luca Bertoncello (lucabert)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, Leute!

Ich habe ein sehr komisches Problem...
An meinem ATMega8 hängt eine kleine Schaltung mit einem LM339. Dieser 
schickt mit ein Signal nach dem Pegel zwei optischen Encoders.
Die Theorie ist, daß ich diese Signale nutzen kann, um die 
Geschwindigkeit zwei Motoren richtig zu halten.

Nun habe ich die zwei Ausgänge der LM339 an INT0 und INT1 meines ATMega8 
angehängt.

Ich habe die Interrupts aktiviert:
  MCUCR &= ~(1<<ISC00);
  MCUCR |= (1<<ISC01);
  MCUCR &= ~(1<<ISC10);
  MCUCR |= (1<<ISC11);

  GICR |= (1<<INT0);
  GICR |= (1<<INT1);
  GIMSK |= (1<<INT0);
  GIMSK |= (1<<INT1);

Und dann habe ich die zwei Funktionen für die Interrupts:
ISR(INT0_vect)
{
  nStepLeft++;
  if(nStepLeft > 200)
    dontUseMotorLeft();
}

ISR(INT1_vect)
{
  nStepRight++;
  if(nStepLeft > 200)
    dontUseMotorRight();
}

Die Funktionen "dontUseMotorLeft" und "dontUseMotorRight" 
selbstverständlich halten den entsprechenden Motor.

Nun was passiert: wenn ich die Motoren langsam laufen lasse, sind die 
200 Interrupts nach ~1/4 Umdrehung erreicht.
Lasse ich die Motoren schneller bewegen, dann sind die 200 Interrupts 
nach eine Umdrehung...
Komisch, oder?

Aber das lustiger muss noch kommen!

Ich habe probiert die zwei Interrupts zu deaktivieren und das gleiche 
mit Polling zu machen.
ES GEHT!! 200 Schritte sind genau eine Umdrehung, wie es sein soll nach 
Doku der Encoders, egal wie schnell die Motoren sich bewegen.

Kann jemand mir erklären, warum mit den Interrupts diese Zähler anderes 
arbeiten als mit Polling?

Danke
Luca Bertoncello

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es kann sein, dass mehrere Impulse pro gewünschter Flanke kommen, die 
dann bei höheren Geschwindigkeiten nicht mehr verarbeitet werden. Das 
könnte die Problematik bei langsamen Geschwindigkeiten erklären.

Eventuell wäre die Schaltung noch interessant :-)

Autor: Luca Bertoncello (lucabert)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Floh schrieb:
> Es kann sein, dass mehrere Impulse pro gewünschter Flanke kommen, die
> dann bei höheren Geschwindigkeiten nicht mehr verarbeitet werden. Das
> könnte die Problematik bei langsamen Geschwindigkeiten erklären.

Aber diese Impulse soll ich auch mit Polling lesen, oder?

> Eventuell wäre die Schaltung noch interessant :-)

Schaltung? Hier ist es!

Grüße
Luca

Autor: Spezi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

> An meinem ATMega8 hängt eine kleine Schaltung mit einem LM339.

Der LM339 hat OpenCollector-Ausgänge; du brauchst also noch PullUp-
Widerstände am Eingang des AVR für vernünftigen High-Pegel (zur Not die 
internen Pullups, aber die sind ziemlich hochohmig). Hast du da welche? 
(Ich würde 4k7 verwenden.)

Und Komparatoren sollten eine Hysterese haben; in deiner Schaltung sehe 
ich aber keine Mitkopplung zwischen Ausgang und Eingang.

Autor: Luca Bertoncello (lucabert)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Spezi schrieb:
> Hallo,
>
>> An meinem ATMega8 hängt eine kleine Schaltung mit einem LM339.
>
> Der LM339 hat OpenCollector-Ausgänge; du brauchst also noch PullUp-
> Widerstände am Eingang des AVR für vernünftigen High-Pegel (zur Not die
> internen Pullups, aber die sind ziemlich hochohmig). Hast du da welche?
> (Ich würde 4k7 verwenden.)

Nein, eigentlich nicht...
Ich habe die interne Pullups aktiviert:
  DDRD &= ~(1<<2);
  DDRD &= ~(1<<3);
  PORTD |= (1<<2);
  PORTD |= (1<<3);

Aber ein paar 4k7-Widerstände hätte ich auch zur Verfügung, und konnte 
sie verwenden, wenn sie besser als die interne Pullups sind...

> Und Komparatoren sollten eine Hysterese haben; in deiner Schaltung sehe
> ich aber keine Mitkopplung zwischen Ausgang und Eingang.

Ugh! Jetzt ist wieder zu schwer...
Ich bitte dich um Geduld weil ich erst seit ein paar Monate (nach mehr 
als 25 Jahre!) mich wieder mit Elektronik beschäftige...
Kannst du mir erklären, was du meinst, und (noch wichtiger!) wie ich es 
implementieren kann?

Danke!
Luca Bertoncello

Autor: Spezi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hysterese ist ein Unterschied in der Spannung, bei der ein Komparator 
ein- und wieder ausschaltet.
Bei dir schaltet der Komparator den Ausgang auf High (mit Pullup), wenn 
der pos. Eingang grösser als ca. 0,45V (bei 5V Versorgung) ist. Aber nur 
wenige Millivolt weniger schaltet er wieder zurück. Bei einer Spannung 
im Umschaltbereich kann das zu Schwingungen des Komparators führen. Dies 
verhindert die Hysterese: Der Komparator-Ausgang schaltet z.B. bei 0,5V 
auf High und bei unter 0,3V erst wieder auf Low.

Realisiert wird sie durch einen höherohmigen Widerstand zwischen Ausgang 
und Plus-Eingang des Komparators.

Was ist das für ein Geber am Eingang des Komparators? Optisch, 
mechanisch? Das kann auch Einfluss auf die Interrupts haben.

P.S.: Die kleineren Pullup-Widerstände sind wichtig bei höheren 
Impulszahlen des Gebers. Aber zum Testen einfach mal anklemmen und 
schauen, ob sich etwas ändert am Problem ...

Autor: Luca Bertoncello (lucabert)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Spezi schrieb:
> Hysterese ist ein Unterschied in der Spannung, bei der ein Komparator
> ein- und wieder ausschaltet.
> Bei dir schaltet der Komparator den Ausgang auf High (mit Pullup), wenn
> der pos. Eingang grösser als ca. 0,45V (bei 5V Versorgung) ist. Aber nur
> wenige Millivolt weniger schaltet er wieder zurück. Bei einer Spannung

Eigentlich nicht: ich habe ein Pegel von 1.5V berechnet...
Aber ich sehe gerade, daß ich eine alte Version der Schaltung 
veröffentlicht habe! Tut mir Leid!
Als Anhang die aktuelle!

> im Umschaltbereich kann das zu Schwingungen des Komparators führen. Dies
> verhindert die Hysterese: Der Komparator-Ausgang schaltet z.B. bei 0,5V
> auf High und bei unter 0,3V erst wieder auf Low.
>
> Realisiert wird sie durch einen höherohmigen Widerstand zwischen Ausgang
> und Plus-Eingang des Komparators.

Ugh! Meinst du, ich muß einfach einen Widerstand zwischen den Ausgang 
(PIN1, bzw. PIN2) und Plus (PIN7, bzw. PIN5)? Ist es was du meinst?
Wie hoch soll dieser Widerstand sein?

> Was ist das für ein Geber am Eingang des Komparators? Optisch,
> mechanisch? Das kann auch Einfluss auf die Interrupts haben.

Es sind zwei optische Encoder: COPAL RE10-100-200. Sie schicken mir eine 
quasi-sinusoidale Welle bei jeden Schritt. Eine volle Umdrehung sollte 
200 Schritte sein.

> P.S.: Die kleineren Pullup-Widerstände sind wichtig bei höheren
> Impulszahlen des Gebers. Aber zum Testen einfach mal anklemmen und
> schauen, ob sich etwas ändert am Problem ...

Wie gesagt, wenn du meinst, die sind besser als die interne Pullups von 
ATMega8, habe ich kein Problem zwei 4k7 Widerstände zwischen PIN1, bzw. 
PIN2 und +5V.

Kannst du mir aber erklären, warum sie besser als die interne 
Widerstände sind?

Tut mir Leid, wenn die Frage etwas blöd sind, aber, wie gesagt, es ist 
eine kurze Zeit seit der ich mich wieder mit Elektronik beschäftige...

Danke!
Luca Bertoncello

Autor: Spezi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mir mal das Datenblatt des Gebers angesehen. (3 Seiten)
Aif Seite 3 sind mehrere Schaltungen zur Auswertung der optischen 
Ausgänge gezeigt, die mit einem Komparator arbeiten. Dort findest du 
auch die erwähnten Mitkopplungs-Widerstände für die Hysterese des 
Komparators.

Versuche mal, deine Schaltung so anzupassen.

Zur Frage nach den Pullups: Die internen Pullup-Widerstände haben ca. 
50kOhm. Dein AVR hat eine Eingangs-Kapazität an jedem Pin 
(prinzipbedingt). Wenn der LM339 seinen Transistor abschaltet, muss der 
Pullup-Widerstand den Eingangs-Kondensator aufladen, damit der Pin ein 
"High" erkennt.
Je höher die Frequenz am Eingang des Pins ist, um so kleiner muss der 
Pullup sein, damit der Kondensator noch schnell genug aufgeladen werden 
kann. Da könnten die internen Pullups zu gross sein, und dann werden 
Impulse "verschluckt". Dann verkleinert man die Widerstände 
entsprechend.
(Ausserdem werden sie hier auch für die Hysterese gebraucht ...)

Autor: Luca Bertoncello (lucabert)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Spezi schrieb:
> Ich habe mir mal das Datenblatt des Gebers angesehen. (3 Seiten)
> Aif Seite 3 sind mehrere Schaltungen zur Auswertung der optischen
> Ausgänge gezeigt, die mit einem Komparator arbeiten. Dort findest du
> auch die erwähnten Mitkopplungs-Widerstände für die Hysterese des
> Komparators.
>
> Versuche mal, deine Schaltung so anzupassen.

OK, ich sehe die erste Schaltung, also mit einem Operationalverstärker.
Es gibt einen Widerstand zwischen Output und +, aber einfach als R 
bezeichnet... ich finde kein Wert...
Kannst du mir sagen, wo du dieses Wert siehst?

> Zur Frage nach den Pullups: Die internen Pullup-Widerstände haben ca.
> 50kOhm. Dein AVR hat eine Eingangs-Kapazität an jedem Pin
> (prinzipbedingt). Wenn der LM339 seinen Transistor abschaltet, muss der
> Pullup-Widerstand den Eingangs-Kondensator aufladen, damit der Pin ein
> "High" erkennt.
> Je höher die Frequenz am Eingang des Pins ist, um so kleiner muss der
> Pullup sein, damit der Kondensator noch schnell genug aufgeladen werden
> kann. Da könnten die internen Pullups zu gross sein, und dann werden
> Impulse "verschluckt". Dann verkleinert man die Widerstände
> entsprechend.
> (Ausserdem werden sie hier auch für die Hysterese gebraucht ...)

Aha! Also, das konnte erklären, warum bei höheren Geschwindigkeit die 
Signalen verloren werden...

Ich werde heute Abend versuchen 2 4k7-Pullup-Widerstände einzubauen, und 
dann sehen, ob es besser geht.

Ich würde mich aber freuen, wenn du mir noch helfen würdest, mit der 
Hysterese...

Besten Dank!
Luca Bertoncello

Autor: dr.Schmock (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn die Software mit Polling funktioniert, dann würde ich mich erstmal 
mit den Interrupts befassen - und die Hardware erstmal beiseite lassen.

Der Fehler könnte durch Prellen ausgelöst werden. Bei langsamen 
Motorbewegungen entstehen ja auch langsame Flanken.
Versuche mal, die Interrupt-Routinen so abzuändern, dass du das 
Interrupt-Flag am Ende der Routine löschst.

Das müsste dann so aussehen:
ISR(INT0_vect)
{
  nStepLeft++;
  if(nStepLeft > 200)
    dontUseMotorLeft();
  GIFR |= (1<<INTF0);
}
ISR(INT1_vect)
{
  nStepRight++;
  if(nStepLeft > 200)
    dontUseMotorRight();
  GIFR |= (1<<INTF1);
}

Grüße

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.