www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ADC Messwert, Betrag ermitteln


Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
if (X_messwert<0x1FF) X_messwert = 0x1FF - X_messwert;
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

Autor: Bernd N (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> 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.

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?
int16_t voltage = readADC();
voltage -= ADC_OFFSET;
int16_t messwert = ABS(voltage);

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
if(voltage<0) voltage = -voltage;
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 :-)

Autor: Maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.