AVR GCC uint16_t letzte Ziffer runden ?

Gast #3082489
Lesenswert?

Hallo zusammen,

ich habe mir eine Routine geschrieben, mit der ich das Summensignal 
eines RC-Empfängers in ein Array (uint16) lesen kann. Die Werte werden 
in µs erfasst und so auch in das Array geschrieben.

Da die Servos so eine Genauigkeit nicht abbilden können, würde ich gerne 
die letzte Stelle des Messwertes (uint16) runden, also nur 0 oder 5 am 
Ende. Da ich mit der Arithmethik völlig auf Kriegsfuß stehe, würde ich 
mich über Vorschläge zur Umsetzung freuen.

Vielen Dank schon einmal im voraus.
Marco
Gast #3082503
Lesenswert?

z.B.

rundet allerdings immer ab.
1
uint16_t zahl = zahl - (zahl%5);
1
uint16_t zahl;
2
uint8_t diff = zahl%5;
3

4
diff > 2 ? zahl = zahl - diff : zahl = zahl + (5-diff);

Das lässt sich natürlich wesentlich schöner und lesbarer schreiben. Das 
sollte nur als Beispiel dienen.
Getestet ist es auch nicht, kann also noch Fehler haben ;-).


Grüsse,
R.
#3082504
Lesenswert?

Mit uint16_t kannst du Zahlen zwischen 0 und 65535 darstellen. Die 
letzten Stellen haben dabei die Wertigkeit 1 - 2 - 4 - 8. Da ist es 
ungeschickt, auf 0 oder 5 runden zu wollen. Am nächsten dran wäre die 4.

Also addierst du 2 und streichst dann die letzten beiden Stellen weg 
(setzt sie auf 0).
Gast #3082509
Lesenswert?

Addiere 0,5 und teile die Zahl dann durch 10.

Divisionen und Fließkomma-Berechnungen sind für Mikrocontroller 
allerdings Schwerstarbeit.

Viel schneller ist es, einfach die unteren drei Bit abzuschneiden:

neu=alt/8  oder neu=alt>>3   (erzeugt beiden den gleichen 
Maschinen-Code).

Das entspricht einer Division durch 8 und es wird immer abgerundet. 
Prüfe nach, ob diese einfachere Variante für Deine Anwendung genügt.
Gast #3082541
Lesenswert?

Hallo und Danke für die schnellen Antworten.

Leider verstehe ich diesen Part nicht ganz :
1
uint16_t zahl = zahl - (zahl%5);

Was bedeutet das %5 ? Auf der Suche nach einer Übersichtsseite mit den 
ganzen Operatoren bin ich leider noch nicht fündig geworden.

Viele Grüße aus dem verschneiten Norden.

Marco
Gast #3082719
Lesenswert?

Georg G. schrieb:
> ist es
> ungeschickt, auf 0 oder 5 runden zu wollen.

Der einzige wahre Satz bisher.
Denn die wirkliche Frage lautet: WARUM?

Was genau versprichst du dir davon, die Werte auf- oder abzurunden? Den 
Servos ist das herzlich egal, dem Prozessor auch. Solange du bei 
16-Bit-Werten bleibst, verbrauchst du auch nicht weniger Speicher. Du 
verbrauchst nur Rechenzeit für die Umrechnung.

Also: Entweder reduzierst du die Auflösung um 2 oder ein vielfaches 
davon, dann aber richtig per Rechtsschift, oder du lässt die Werte, wie 
sie sind.

Nur so als Hinweis: Aktuelle "hochwertige" RC-Anlagen arbeiten mit 11 
bit, andere mit 10, und ein preiswertes Servo löst vielleicht mit viel 
Glück auf 7 bit auf...

Oliver
Moderator #3084085
Lesenswert?

Oliver schrieb:
> Georg G. schrieb:
>> ist es
>> ungeschickt, auf 0 oder 5 runden zu wollen.
>
> Der einzige wahre Satz bisher.
> Denn die wirkliche Frage lautet: WARUM?

Diese Frage ist genau die richtige Antwort auf die Anfrage.

Klar wird ein Servo das Steuersignal nicht auf die µs genau auswerten.
Wird der Wert aber vorher gerundet, kommt zum Fehler des Servos noch der
Rundungsfehler hinzu. Man verschwendet also Rechenaufwand und Flash-
Speicher dafür, das Gesamtsystem ungenauer zu machen.

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