Inkrement auslesen, Auflösung verringern

Gast #5239426
Lesenswert?

Guten Tag,

ich lese einen inkrementellen Drehgeber mit 16 Bit aus, wobei ich 
allerdings die Auflösung um zwei Bit verringern will. Das Ergebnis 
benötige ich als Inkrement. Wichtig ist mir, dass der Fehler durch die 
Auflösungsverringerung nicht anwächst.

Würde ich einfach die Differenz zweier aufeinander Dekoderstände durch 
den Dezimierungsfaktor teilen, wüchse der Fehler schnell an. Also mache 
ich eine Division mit Restglied:
1
/* Inkrement aus Hardware-Decoder gewinnen bei verrringerter Aufloesung */
2
int getIncrement(void)
3
{
4
    const int8_t decimation = 4; // Zweierpotenz
5

6
    static uint16_t enc_n = 0;
7
    static int16_t rest = 0;
8
    
9
    uint16_t enc = (uint16_t) TIM_GetCounter(TIM3);
10
    int16_t denc = (int16_t) (enc - enc_n); // Vorzeichenrichtige Differenz
11
    enc_n = enc;
12
    
13
    int16_t dx = (denc+rest)/decimation;
14
    rest = (denc+rest)%decimation;
15

16
    return dx;
17
}

Das funktioniert wie erwartet.

Allerdings: Ist der Aufwand wirklich nötig, oder bin ich einem 
Denkfehler aufgesessen und es geht viel einfacher?
Gast #5239448
Lesenswert?

Dezimator schrieb:

> Allerdings: Ist der Aufwand wirklich nötig, oder bin ich einem
> Denkfehler aufgesessen

Letzteres. Der Fehler wird sich immer im Bereich der weggeschnibbelten 
Bits bewegen, also im konkreten Fall eine Größe zwischen 0 und 3 
annehmen. Du muss dazu nur die zwei wegzuschnibbelnden Bits ÜBERALL 
ignorieren, das ist schon alles.

Am einfachsten machst du das, indem du einfach schon den Eingangswert 
durch den Dezimierungsfaktor teilst und in der Folge bloß noch mit den 
dezimierten Werten hantierst.
#5239454
Lesenswert?

@c-hater (Gast)

>Letzteres. Der Fehler wird sich immer im Bereich der weggeschnibbelten
>Bits bewegen, also im konkreten Fall eine Größe zwischen 0 und 3
>annehmen. Du muss dazu nur die zwei wegzuschnibbelnden Bits ÜBERALL
>ignorieren, das ist schon alles.

Tja, und eben weil das eher unpraktisch ist, packt man das in eine 
Funktion.

>Am einfachsten machst du das, indem du einfach schon den Eingangswert
>durch den Dezimierungsfaktor teilst und in der Folge bloß noch mit den
>dezimierten Werten hantierst.

Er muss aber intern mit dem Rest weiter zählen, sonst kommt Mist raus.
Gast #5239545
Lesenswert?

Falk B. schrieb:

> Tja, und eben weil das eher unpraktisch ist, packt man das in eine
> Funktion.

Na klar, das war doch auch garnicht die Frage. Natürlich würde man das 
in eine Funktion packen. Überall schließt natürlich diese Funktion 
ein.

>>Am einfachsten machst du das, indem du einfach schon den Eingangswert
>>durch den Dezimierungsfaktor teilst und in der Folge bloß noch mit den
>>dezimierten Werten hantierst.
>

> Er muss aber intern mit dem Rest weiter zählen, sonst kommt Mist raus.

OMG, ich glaub' es nicht: Derselbe Denkfehler wie beim TO. Und das mit 
der angeblich SOOO GROOSSEN Programiererfahrung..

Nein, wenn man wie beschrieben vorgeht, also gleich an der Quelle die 
Bits wegschnibbelt und in der Folge nur noch mit der reduzierten 
Darstellung arbeiten (inbesondere auch beim Halter des letzten 
Zustands), kann man den Rest in den weggeschnibbelten Bits tatsächlich 
komplett ignorieren, der Fehler wird trotzdem niemals über den genannten 
Bereich anwachsen, weil er automagisch korrigiert wird, sobald er einen 
Wert von 4 (bzw. Vielfache davon) erreicht, dann gibt es nämlich in der 
reduzierten Interpretation einfach eine um 1 größere Änderung als 
nominell anstehen würde.

Das gilt übrigens für sogar für jeden Reduktionsfaktor, nicht nur für 
Zweierpotenzen. Man kann dann bloß nicht mehr so einfach die ignorierten 
Bits bennennen. Das interessiert aber auch niemanden wirklich...
Gast #5239888
Lesenswert?

c-hater schrieb:
> Am einfachsten machst du das, indem du einfach schon den Eingangswert
> durch den Dezimierungsfaktor teilst und in der Folge bloß noch mit den
> dezimierten Werten hantierst.

Das wird nicht klappen. Dann stimmt der Überlauf der unsigned-Variablen 
nicht mehr.


Falks Lösung dürfte klappen, wenn man val static macht und statt & 3 
&(~3) macht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren