Ich stehe gerade auf dem Schlauch und bitte um einen Vorschlag.
Vermutlich ist es trivial.
Ein AVR wertet zwei Pins aus und soll sie nach vier Zustandsänderungen
auf zwei Möglichkeiten überprüfen:
Möglichkeit 1:
PIN 1 PIN 2
1 1
1 0
0 1
1 1
Möglichkeit 1:
PIN 1 PIN 2
1 1
0 1
1 0
1 1
Wie kann ich das prüfen?
Jasper schrieb:> Wie kann ich das prüfen?
Bist du sicher, dass deine Zustände sich wie in deinen Tabellen
angegeben ändern?
Irgendwie sollte bei 2 Bits und 4 Zuständen auch der Zustand 0 0
auftreten. Außerdem sollte die Zustandsfolge einem Gray-Code
entsprechen. Sonst hast du störende Zwischenzustände.
Algorithmen zur Encoderauswertung mit AB-Signalen gäbe es dann genug.
Jasper schrieb:> Ich stehe gerade auf dem Schlauch und bitte um einen Vorschlag.> Vermutlich ist es trivial.>> Ein AVR wertet zwei Pins aus und soll sie nach vier Zustandsänderungen> auf zwei Möglichkeiten überprüfen:>> Möglichkeit 1:> PIN 1 PIN 2>> 1 1> 1 0> 0 1> 1 1>>>> Möglichkeit 1:> PIN 1 PIN 2>> 1 1> 0 1> 1 0> 1 1>> Wie kann ich das prüfen?
Schiebe die 2 Bits einfach nacheinander in ein 8-Bit Register und
vergleiche dann den Wert als Unsigned Int.
1: 11 10 01 11 = 0xE7 = 231
2: 11 01 10 11 = 0xDB = 219
Miramare schrieb:> Schiebe die 2 Bits einfach nacheinander in ein 8-Bit Register und> vergleiche dann den Wert als Unsigned Int.>> 1: 11 10 01 11 = 0xE7 = 231> 2: 11 01 10 11 = 0xDB = 219
damit weiss er vllt 30% dessen was er wissen muss solltest ihm vllt noch
den Rest offenbaren
Jasper schrieb:> soll sie nach vier Zustandsänderungen> auf zwei Möglichkeiten überprüfen:
Das bis 4 Zählen hat schwerwiegende Nachteile. Der Drehgeber darf nicht
prellen und der Benutzer muß immer schön brav von Rastpunkt zu Rastpunkt
drehen.
Übliche Drehgeberroutinen werten daher nicht die Anzahl der Änderungen,
sondern die Zustände selber aus. Ein Prellen wird damit sofort wieder
abgezogen bzw. ein Richtungswechsel ist an beliebigen Positionen
erlaubt.
Jasper schrieb:> Ich stehe gerade auf dem Schlauch und bitte um einen Vorschlag.> Vermutlich ist es trivial.>> Ein AVR wertet zwei Pins aus und soll sie nach vier Zustandsänderungen> auf zwei Möglichkeiten überprüfen:>> Möglichkeit 1:> PIN 1 PIN 2>> 1 1> 1 0> 0 1> 1 1>> Möglichkeit 1:> PIN 1 PIN 2>> 1 1> 0 1> 1 0> 1 1>> Wie kann ich das prüfen?
Nimm 2 Positionsvariablen die bei 0 starten
wenn die aktuelle Kombination mit der für die beiden Möglichkeiten
übereinstimmt dann inkrementiere die Positionsvariable
hat sie den Wert 4 erreicht dann hast du einen Treffer gefunden
wenn die aktuelle Kombination nicht übereinstimmt dann setze die
Positionsvariable zurück auf 0.
Peter D. schrieb:> Das bis 4 Zählen hat schwerwiegende Nachteile. Der Drehgeber darf nicht> prellen und der Benutzer muß immer schön brav von Rastpunkt zu Rastpunkt> drehen.> Übliche Drehgeberroutinen werten daher nicht die Anzahl der Änderungen,> sondern die Zustände selber aus. Ein Prellen wird damit sofort wieder> abgezogen bzw. ein Richtungswechsel ist an beliebigen Positionen> erlaubt.
Prellen musst du natürlich vorher schon entsprechend vermeiden!
Jasper schrieb:> Ein AVR wertet zwei Pins aus und soll sie nach vier Zustandsänderungen> auf zwei Möglichkeiten überprüfen
Warum musst du da auf 4 Zustandsänderungen warten (wobei sowieso nur 3
Änderungen zwischen diesen 4 Zuständen sind...)
Jasper schrieb:> Wie kann ich das prüfen?
Was soll passieren, wenn ein anderes Bitmuster hereinkommt? Oder wenn
der Wechsel von 01 oder 10 über 00 bzw 11 geht (das tut er für ein paar
ns sicher, denn diese beiden Signale kommen garantiert nicht
gleichzeitig an den AVR-Pins an).
Also müssen dei Eingangssignale erst mal konditioniert (aka entprellt)
werden. Danach kommt die Erkennung, ob sich was geändert hat, dann kommt
die FSM, die abhängig von der Änderung weiterschaltet.
BTW: musst du da unbedingt alle 3 Zustandswechsel abwarten? Wenn nicht,
dann wäre das Programm recht einfach. Kommend von 11 müsstest du nur
jeweils abfragen, ob eines der beiden Bits auf 0 geht, und dann wieder
warten, bis beide (entprellten) Eingänge 11 sind.
Wie schnell wechseln da eigentlich die Zustände?
Hallo Jasper,
hier mal ein Beispiel wie das mit Arduino IDE aussehen könnte. Gibt
natürlich noch 100 andere Möglichkeiten.
---------------------------------------------------------------
// statt bin 6,7 kann auch jeder andere Pin (D3-D13) gewählt werden.
#define PIN1 6
#define PIN2 7
int entprell_zeit = 100;
long millis_alt = 0;
void setup() {
pinMode(PIN1, INPUT);
pinMode(PIN2, INPUT);
}
void loop() {
// Checkt alle 100ms die Eingänge und schaltet entsprechend
if(millis() - millis_alt >= entprell_zeit){
millis_alt += entprell_zeit;
int status_pin1 = digitalRead(PIN1);
int status_pin2 = digitalRead(PIN2);
if(status_pin1 == 0 && status_pin2 == 0){
// was auch immer er machen soll
}
else if(status_pin1 == 1 && status_pin2 == 0){
// was auch immer er machen soll
}
else if(status_pin1 == 0 && status_pin2 == 1){
// was auch imemr er machen soll
}
else if(status_pin1 == 1 && status_pin2 == 1){
// was auch immer er machen soll
}
}
// Hier kann noch anderer Code stehen
}
----------------------------------------------
p.s Ja ich weiß die Leute hier sollen selber denken, aber das hat gerade
mal eine Minute gedauert es runter zu schreiben ;)
Gruß
Ich hatte da was von Entprellen geschrieben. Das war ernst gemeint. Denn
wenn die Eingänge nicht absolut zeitgleich wechseln (und das tun sie
nicht!), dann geht das simple direkte Abfragen früher oder später
schief. Nach Murphy wird das Problem laufend auftreten...
Und nochmal schrieb im Beitrag #5908221:
> Wo war von einem Drehgeber die Rede?
Keine Ahnung. Ich habe nichts derartiges ins Gespräch gebracht.
> Wo war von Prellen die Rede?
Es ist die Rede von asynchronen Eingängen eines uC , die gemeinsam
abgefragt werden sollen, als ob sie gleichzeitig den Pegel zum jeweils
anderen Potential wechseln würden. Das tun sie nicht. Ein Übergang von
01 nach 10 geht zwangsläufig für ein paar ns über 00 oder 11. Immer. Und
wenn gerade dann die Eingänge eingelesen werden, dann... ja, was dann?
Und mit "Entprellen" ist hier gemeint, dass mindestens 2 Abfragen
hintereinander an beiden Pins zusammen das selbe Bitmuster anliegen
muss. Damit wird das oben beschriebene Problem behoben.
Den Rest des Posts lasse ich besser mal unkommentiert...
Lothar M. schrieb:> Ein Übergang von> 01 nach 10 geht zwangsläufig für ein paar ns über 00 oder 11. Immer.
Nicht wenn ich (oder besser, Jasper, der TO ;-)) die beide Pins nur jede
10ms pollt. Aber auch dann kann es natürlich passieren, dass der Weg
von 01 zu 10 nicht über Los geht.
Eric B. schrieb:> Nicht wenn ich (oder besser, Jasper, der TO ;-)) die beide Pins nur jede> 10ms pollt
Wahrscheinlich... ?
Wenn alle 10ms gepollt wird und die undefinierte Transision 10ns dauert,
dann geht rechnerisch 1 von 1 Million Abfragen schief. Wenn Murphy
mitmacht, dann passiert das immer Donnerstags nach der Frühstückspause.
Aber garantiert nicht dann, wenn man gerade den Fehler sucht.
Deshalb verhindert man so einen Fehler einfach, indem man die
Wahrscheinlichkeit aus dem Spiel nimmt.
Lothar M. schrieb:> Deshalb verhindert man so einen Fehler einfach, indem man die> Wahrscheinlichkeit aus dem Spiel nimmt.
Spitzen Idee
Das würde viele Probleme lösen
Sry
wobei hier exemplarisch PORTB und Pins PB3 und PB7 gewählt wurden. Es
lässt sich beliebig verkomplizieren oder auch etwas leichter machen,
wenn man die Variable input_folge als global deklariert - dann müsste
man nicht mit Pointern rumwerfen und das Programm wäre noch
übersichtlicher.
Viktor B. schrieb:> Ich würde es folgendermaßen machen
Das funktioniert aber bestenfalls mur genau dann, wenn die Eingänge den
Pegel immer zuverlässig mitten in dem 10ms Raster wechseln.
Mal angenommen, der zeitliche Abstand zwischen 2 Zustandsänderungen
schwankt beliebig zwischen 5 und 50ms. Oder zwischen 2 und 200ms. Oder
zwischen 9 und 11ms. Was dann?
Oder schlimmer noch: die Eingänge ändern sich mit exakt 10,1ms Abstand.
Dann geht es 100 mal gut, aber dann rasselt es...
Fazit: der Automat, der hier benötigt wird, hat prinzipiell keine
zeitliche Abhängigkeit, sondern seine Reaktion hängt nur von Änderungen
seiner Eingänge ab.
Entschuldigung für die später Rückmeldung.
Ich versuche mal etwas Licht ins Dunkel zu bringen.
Ich habe quasi einen optischen Drehgeber aus einer gelöcherten
Holzscheibe gebaut (8 Löcher).
Hier erfassen zwei Fototransistoren die Zustände. Eingentlich wollte ich
diese per INT0 und INT1 am AVR auswerten. Dabei ist es dann zum
angesprochenen Prellen gekommen. Ich hatte mir beholfen, indem ich die
Fototransistoren einfach per ADC auswerte.
Wert > 900: Highpegel,
Wert < 900: Lowpegel
Das funktioniet bisher ohne Probleme.
Hier ein Auszug aus meinem Code:
Lothar M. schrieb:> seine Reaktion hängt nur von Änderungen> seiner Eingänge ab.
Dann würde man das mit Pin change Interrupts machen und hätte das
Problem, dass die Pins zwichen dem Zustand 1,0 und 0,1 kurz durch 1,1
oder 0,0 gehen.
Vielleicht würde es besser gehen, wenn man jede 1 ms sampelt und dann
unterscheidet, ob sich die Eingänge geändert haben oder nicht. Ist aber
ziemlich viel Overhead.
Upd.: Wie ich sehe, hat der TO schon ein funktionierendes Programm. Dann
lohnt es sich ja nicht wirklich, mein Beispiel zu aktualisieren
Naja, mein Programm ist aus meiner Unwissenheit entstanden. Bisher läuft
es aber ich lasse mir gerne erklären wie man es besser macht.
Hatte nur gelesen das Fototransistoren relativ träge sind. Von daher
dachte ich das somit vielleicht ein mögliches Prellen gar nicht erfasst
wird weil die Dinger zu langsam reagieren und ich dann mit ADC-Werten >
900 im sicheren Bereich lande.
Jasper schrieb:> Von daher dachte ich
Ich würde das mit.einem Oszilloskop messen. Soooo arg teuer sind die
Dinger gar nicht... ?
Denn eigentlich kannst du nur etwas das du kennst, wirklich
zuverlässig auswerten.
Jasper schrieb:> Das funktioniet bisher ohne Probleme.
Ist ja auch kein Wunder. Das ist ja ganz im Gegensatz zu der "war nur
exemplarisch gemeint"en Frage aus dem Eröffnungspost ein Gray-Code, bei
dem "aus Gründe" eben niemals 2 Bits gleichzeitig wechseln. Und
deshalb die ganzen Probleme mit dem Übergang von 01 nach 10 (oder 10
nach 01) niemals auftreten können.