Hallo,
wie muss ich das Array aus dem Artikel
http://www.mikrocontroller.net/articles/Drehgeber anpassen, wenn bei mir
die Dekodertabelle für die halbe Auflösung immer noch doppelt zu schnell
geht?
Also bei mir zeigt es bei jedem Schritt einen Sprung von 2 an.
// Dekodertabelle für wackeligen Rastpunkt
// halbe Auflösung
int8_t table[16] PROGMEM = {0,0,-1,0,0,0,0,1,1,0,0,0,0,-1,0,0};
D.h. ich bräuchte obiges Array für viertelte Auflösung.
Danke!
Was meinst du mit "jedem Schritt"?
Einen Rastpunkt eines Drehknopfs?
Das was du vermutlich willlst, geht nicht mehr mit einer Änderung der
Tabelle (zumindest nicht ohne deutliche Verlängerung der Tabelle und
Änderung des Codes).
Warum halbierst du nicht einfach die tatsächlich zum Weiterrechnen
benutzte Position?
Du bräuchtest also zwei Positionen: die bisherige genauere, aus der mit
obiger Tabelle jeweils ein neuer Wert gebildet wird, und eine weitere,
die dann immer als die genaue/2 berechnet wird. Mit letzterer arbeitest
du im Programm, sie hat die halbe Auflösung.
jørg schrieb:> Teil einfach enc_delta durch 2
Gefährlich. Was passiert, wenn encode_read so oft aufgerufen wird, dass
enc_delta bei jeder Abfrage 0 oder 1 ist?
Edit:
Da die Tabelle nur noch zwei von 0 verschiedene Werte enthält, bringt
sie keine Geschwindigkeitsvorteile mehr, im Gegenteil. Folgender Code
ist schneller und spart einschließlich der nun nicht mehr benötigten
Tabelle 30 Bytes an Flash-Speicher ein.
@jørg (Gast)
>Teil einfach enc_delta durch 2
Nein, das geht schief. Er muss den aus enc_delta abgeleiteten Wert
normal speichern und daraus den Wert / 2 teilen.
Hä? In der von dir verlinkten Seite sind doch extra Funktionen dafür
angelegt worden:
int8_t encode_read2( void )
int8_t encode_read4( void )
usw.
Da ists vorgemacht, wie man das am besten (=ohne extra Variable) löst.
Yalu X. schrieb:> Z.B. so:> int8_t table[16] PROGMEM = {0,0,0,0,0,0,0,1,0,0,0,0,0,-1,0,0};
Ich habe eine Anfrage erhalten, wie man denn auf diese Tabelle käme.
Hier ist eine kurze Erklärung:
Die Signale A und B können zusammen vier Zustände annehmen: 00, 01, 10
und 11. Bei jedem Timer-Interrupt geht der Zustand (A,B) in einen Zu-
stand (A',B') über. Dafür gibt es 4·4=16 Möglichkeiten. In folgender
Tabelle sind auf der linken Seite alle 16 möglichen Zustandsübergänge
und auf der rechten Seite der Wert für die Inkrementierung des Zählers
(-1, 0 oder +1) aufgelistet. man betrachte sich dazu die Signaldiagramme
am Anfang des Artikels [Drehgeber].
Ist die Interruptfrequenz hoch genug, d.h. zwischen zwei Zustandsüber-
gänge fällt mindestens ein Interrupt, ändert sich bei jedem Interrupt
der Pegel von höchstens einem der Signale A und B. Ändern sich beide
Signale zusammen, wurde der Knopf zu schnell gedreht, so dass mindestens
ein Zustandsübergang nicht registriert wurde. Diese Fälle sind in der
Tabelle mit einem 'F' gekennzeichnet.
Ja nachdem, welche Signalflanken bzw. Zustandsübergänge man für die In-
krementierung des Zählers nutzt, erhält man unterschiedliche Auflösun-
gen:
I4 (volle Auflösung): Alle Flanken (4 pro Periode)
I2 (halbe Auslösung): Nur Flanken von A (2 pro Periode)
I1 (Viertelsauflösung): Nur Flanken von A, während B=1 (1 pro Periode)
1
-----------+--------------
2
Zustands-| Inkrement
3
übergang | (F=Fehler)
4
-----+-----+----+----+----
5
A B | A'B'| I4 | I2 | I1
6
-----+-----+----+----+----
7
0 0 | 0 0 | 0 | 0 | 0
8
0 0 | 0 1 | +1 | 0 | 0
9
0 0 | 1 0 | -1 | -1 | 0
10
0 0 | 1 1 | F | F | F
11
0 1 | 0 0 | -1 | 0 | 0
12
0 1 | 0 1 | 0 | 0 | 0
13
0 1 | 1 0 | F | F | F
14
0 1 | 1 1 | +1 | +1 | +1
15
1 0 | 0 0 | +1 | +1 | 0
16
1 0 | 0 1 | F | F | F
17
1 0 | 1 0 | 0 | 0 | 0
18
1 0 | 1 1 | -1 | 0 | 0
19
1 1 | 0 0 | F | F | F
20
1 1 | 0 1 | -1 | -1 | -1
21
1 1 | 1 0 | +1 | 0 | 0
22
1 1 | 1 1 | 0 | 0 | 0
23
-----+-----+----+----+----
Der Beispielcode in
http://www.mikrocontroller.net/articles/Drehgeber#Dekoder_f.C3.BCr_Drehgeber_mit_wackeligen_Rastpunkten
fasst nun die vier Bits A, B, A' und B' eines Zustandsübergangs zu einer
Integerzahl last (0..15) zusammen und nutzt diese als Index für die
Tabelle der Inkremente. Der Tabellenwert wird dann zur Zählervariablen
enc_delta hinzuaddiert.
In dem von mir geposteten Codefragment für die Viertelsauflösung wird
genau das Gleiche getan, nur ohne Tabelle. Da die Tabelle nur zwei von 0
verschiedene Werte enthält, werden die entsprechenden Indizes (7 und
13) stattdessen mittels zweier if-Abfragen direkt ausgewertet.