Hallo Leute
Ich habe einem Signal das positive wie negative Werte annehmen kann (zb.
Sinus) einen Offset der halben ADC-Referenzspannung gegeben um die
Wandlung zu ermöglichen. Diesen Offset will ich nun so rausrechnen, dass
ich jeweils den Betrag des Signals erhalten.
Es liegt ein 10Bit ADC vor. Ich habe dies so gemacht:
1
if (X_messwert<0x1FF) X_messwert = 0x1FF - X_messwert;
2
else X_messwert = X_messwert - 0x1FF;
Mir erscheint dies jedoch recht unelegant. Ich dachte zuerst
fälschlicherweise man könnte mit dem 2er Komplement rechnen. Gibt es
eine andere Möglichkeit?
Gruß
Maddin
>> der halben ADC-Referenzspannung gegeben...
Welchen Wert suchst du ? positive Halbwelle und dessen Betrag ? /2 wenn
der Offset so ist, wie du ihn angegeben hast.
Wenn das Signal größer als 0V ist, also somit ein Spannungswert größer
der halben Referenzspannung gemessen wird, dann suche ich natürlich
diesen positiven Anteil.
Ist das Signal negativ, wird ein Spannungswert kleiner der halben
Referenzspannung gemessen. Gesucht wird in diesem Fall der Betrag des
negativen Spannungswert, also Offset - gemessener Spannungswert
Was soll da nun noch /2 gerechnet werden?
Was heißt elegant? Aus irgendwelchen Gründen 2 Takte einsparen und das
Programm (bei der Samplerate eines üblichen AVR-ADCs) um 0.1%
beschleunigen? Oder lieber lesbar?
Bei Deinem Beispiel brauche ich 10s, um zu verstehen, was passiert. Wie
schnell ist dieses Beispiel verständlich?
Tom schrieb:> Bei Deinem Beispiel brauche ich 10s, um zu verstehen, was passiert.
Deshalb frage ich.
Tom schrieb:> int16_t voltage = readADC();> voltage -= ADC_OFFSET;> int16_t messwert = ABS(voltage);
Hm ja, das ist nun auch nicht halbes und nichts ganzes. Ich will den
Betrag ermitteln und du versuchst mir zu helfen in dem du mir eine
Funktion ABS() anbietest...?
Nun geht es doch darum was ABS macht? Ist es eine C99 Funktion? Dann
möchte ich darauf verzichten. Mus ich ABS() selbst schreiben? Dann würde
da auch wieder sowas drinne stehen wie:
1
if(voltage<0) voltage = -voltage;
2
else...
Wenn es dir hier nicht um die Art und Weise der Betragsermittelung geht,
sondern um die Verwendung von Funktionen um die Übersichtlichket zu
erhöhen, dann gebe ich dir schon recht. Nur ging es mir in erster Linie
nicht darum.
Gruß
Maddin
Maddin schrieb:> Tom schrieb:>> Bei Deinem Beispiel brauche ich 10s, um zu verstehen, was passiert.>> Deshalb frage ich.>> Tom schrieb:>> int16_t voltage = readADC();>> voltage -= ADC_OFFSET;>> int16_t messwert = ABS(voltage);>> Hm ja, das ist nun auch nicht halbes und nichts ganzes. Ich will den> Betrag ermitteln und du versuchst mir zu helfen in dem du mir eine> Funktion ABS() anbietest...?
#define ABS(x) (x) < 0 ? -(x) : (x)
ausserdem gibt es auch noch abs Funktionen in math.h
wenn man sich die nicht selber machen will (was ja auch vernünftig ist)
> Nur ging es mir in erster Linie> nicht darum.
Sondern?
Pberleg dir einfach mal, was der Compiler wohl aus diesem Konstrukt
machen wird, bzw. probier es aus (aber Optimizer einschalten).
Das übersetzt sich zu
16 Bit Subtraktion
16-Bit Vergleich
Sprung wenn negativ ------
16 Bit Komplement |
<-----
In den meisten Fällen bringt es nichts bis extrem wenig, wenn man
versucht extrem schlau zu sein. Lesbarer Code optimiert meistens auch
ziemlich gut.
Karl heinz Buchegger schrieb:> #define ABS(x) (x) < 0 ? -(x) : (x)
Oh na an sowas hab ich noch garnicht gedacht. Dachtemit defines sollte
man nur Dinge die vor der Laufzeit feststehen definieren.
Karl heinz Buchegger schrieb:> ausserdem gibt es auch noch abs Funktionen in math.h
In Anbetracht der Tatsache, dass z.B. sqrt() bei mir 1,6kB frisst (die
ich nicht habe), lasse ich in Zukunft lieber möglichst Abstand von
Funktionen die ich nicht selbst geschrieben habe.
Danke euch und Gruß
Maddin
Maddin schrieb:> In Anbetracht der Tatsache, dass z.B. sqrt() bei mir 1,6kB frisst (die> ich nicht habe),
Nun ja. sqrt ist ja auch nicht so einfach zu berechnen, wie ein
Absolutwert.
> lasse ich in Zukunft lieber möglichst Abstand von> Funktionen die ich nicht selbst geschrieben habe.
Wie würdest du eine Funktion schreiben, die einen Absolutwert berechnet?
Du kannst davon ausgehen, dass diejenigen die deine Standardfunktionen
geschrieben haben auch keine Trottel waren und man in 30 Jahren gelernt
hat, wie man eine iabs schreibt
int iabs( int value )
{
return value > 0 ? value : -value;
}
Ist ja nicht gerade Raketentechnik :-)
Ausserdem muss ich mich korrigieren. Im math.h vom WinAvr ist ghar kein
iabs oder labs enthalten. Bin wohl schon zu sehr C++ verwöhnt :-)
Karl heinz Buchegger schrieb:> dass diejenigen die deine Standardfunktionen> geschrieben haben auch keine Trottel waren und man in 30 Jahren gelernt> hat, wie man eine iabs schreibt
Oho, habsch auch net behauptet. Die Verwendung von externen Funktionen
macht meiner Meinung nach nur Sinn, wenn man genau weiß was diese tun,
welche Datentypen man ihr übergeben muss, welche man zurück bekommt usw.
In meinen Fällen hat die Recherche dafür meist länger gedauert als das
Schreiben einer eigenen Funktion. Außerdem übt das.
Im Beispiel der iabs() is da natürlich nich viel dran. Mein Code war da
viel komplexer (und unnötig aufwendiger).
Maddin schrieb:> Oho, habsch auch net behauptet. Die Verwendung von externen Funktionen> macht meiner Meinung nach nur Sinn, wenn man genau weiß was diese tun,> welche Datentypen man ihr übergeben muss, welche man zurück bekommt usw.
Da hast du recht.
Ich finde, jeder sollte einmal das Repertoire der Standardfunktionen
programmiert haben (mit Ausnahme der Dinge, die über double gehen). Das
schult ungemein und die meisten Funktionen sind auch ziemlich primitiv,
in ähnlichem Komplexitätsgrad wie eben dieses iabs bzw. kaum komplexer
(ok, malloc/free sind schon aufwändiger)
> In meinen Fällen hat die Recherche dafür meist länger gedauert als das> Schreiben einer eigenen Funktion. Außerdem übt das.
Nun ja.
Ist halt ein zweischneidiges Schwert. Ich geb dir natürlich recht, dass
man da Übung bekommt. Auf der anderen Seite ist es für andere im Team
immer schwieriger wenn einer aus der Reihe tanzt und meint, er müsse
jeden Pfurz selber als Funktion implementieren. Mann muss dann immer
umdenken und mehr im Kopf behalten, wenn man Code liest.