mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Logarithmus aus Int berechnen


Autor: Zangetsu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag

Ich möchte mit dem Atmega48 und den WinAVR einen Analogen Wert einlesen 
und diesen logarithmisch umwandeln. Die A/D Wandlung verläuft wie im 
AVR-GCC-Tutorial. Der Wert lässt sich gut einlesen und wird bisher in 
einen Integer gespeichert.

Für den Logarithmus habe ich die Formel:

x=20*log10(x/1024);

Diese eignet sich aber nicht für Integer und bei Float steig der 
Programmspeicherbedarf um etwa 100% an wenn ich das ADCH Register in den 
Float hineinschreiben will.

Wie kann ich nun das Register sauber in einen Float verrechnen? oder 
kennt jemand eine Alternative zu meiner Lösung?

Freundliche Grüsse

Zangetsu

Autor: Martin Gerken (mager)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arbeite mit einer Tabelle (der ACD liefert 10bit = 0-1023; wenn Du für 
jeden 10. Wert einen Tabelleneintrag als 16bit-int hast sollte das 
gehen)

Autor: Rene B. (themason) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@zangetsu

So wie ich das sehe willst du dB ausrechnen (20*log10(x)).

Eine Möglichkeit dazu ist Zählen wieviele Nullen (von links aus gesehen) 
bis zur ersten 1 kommen. Jede 0 sind -6dB. Dann die Restlichen 
(beispielsweise 4 Bit) über eine kleine Tabelle ausrechnen um die 
Zwischenschritte von 1-5dB zu erhalten.

Bsp :
0000 1000 0000

4 Nullen -> -24dB
"000" nach der 1 -> +0dB als zus. Addition

0010 1000 0000 -> -12dB
"010" nach der 1 -> ca +2dB -> -10dB

Das ganze ist nur exemplarisch und müsste mal genauer ausgerechnet 
werden.
Aber das wäre neben der Tabelle ein Lösungsweg.

Autor: Zangetsu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok muss ich wohl zur Tabelle greifen. Aber nur um sicher zu gehen: gibt 
es wirklich keine "normale" Möglichkeit einen Integer in einen Float zu 
schreiben?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Zangetsu (Gast)

>Ok muss ich wohl zur Tabelle greifen. Aber nur um sicher zu gehen: gibt
>es wirklich keine "normale" Möglichkeit einen Integer in einen Float zu
>schreiben?

Sicher.
int a;
float b;

b=a;


MFG
Falk

Autor: Stefanie B. (sbs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ok muss ich wohl zur Tabelle greifen. Aber nur um sicher zu gehen: gibt
>es wirklich keine "normale" Möglichkeit einen Integer in einen Float zu
>schreiben?

Entweder durch das Casten:
float f;
int i;
i=IrgendwasWildes();
f=(float)i;
Dann ist in f statt z.B. 243 die 243,00 gespeichert.

Oder du bastelst die dein Float selbst, indem du das Vorzeichen, den 
Exponent, sowie die Mantisse zurechtfrickelst.
( http://de.wikipedia.org/wiki/Gleitkommazahl )


Zurück zum Logarithmieren:
1) Nimm ne Tabelle in der die Funktionswerte in äquidistanten Abständen 
gespeichert sind und interpoliere dazwischen linear.

2) Mit Kenntnis über den Logarithmus (bzw den betrachteten Bereich), 
kannst du die Tabelle anpassen und dort wo sich die Werte stärker ändern 
mehrere Einträge machen.
int Tabelleneintraege[]={1,3,9,16,25,36,100};
int zugehörigeWerte[]  ={1,2,3, 4, 5, 6, 10};

int getWert(int input){
  int ret;
  int i=0;
  while(Tabelleneintrag[i]<input)i++;

  //dein Wert liegt jetzt zwischen i und i+1
  // also musst du zwischen zugehörigeWerte[i] und zugehörigeWerte[i+1]
  // linear interpolieren.
  
  ret=Tabelleneintraege[i]+ \
   ( Tabelleneintraege[i+1]-Tabelleneintraege[i]) / \  
(zugehörigeWerte[i+1]-zugehörigeWerte[i])*input-Tabelleneinträge[i];
  return ret;
}

Zu guter Letzt:

Du kennst Festkomma-Arithmetik?
( http://de.wikipedia.org/wiki/Festkommazahl )
( http://www.mikrocontroller.net/articles/Festkommaarithmetik )

Viele Grüße
Stefan

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

Bewertung
0 lesenswert
nicht lesenswert
Falk Brunner schrieb:
> @  Zangetsu (Gast)
>
>>Ok muss ich wohl zur Tabelle greifen. Aber nur um sicher zu gehen: gibt
>>es wirklich keine "normale" Möglichkeit einen Integer in einen Float zu
>>schreiben?
>
> Sicher.
>
>
> int a;
> float b;
> 
> b=a;
> 
> 

@Zangetsu

Aber sicher nicht so
x=20*log10(x/1024);

denn x / 1024  ergibt bei dir immer 0

http://www.mikrocontroller.net/articles/FAQ#Datent...

Autor: Yalu X. (yalu) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vor kurzem gab es hier einen anderen Thread zum Thema Logarithmus und
Exponentialfunktion (finde ihn gerade nicht). Für den Logarithmus wurde
folgendes Verfahren vorgeschlagen, das mit Integermultiplikationen und
-additionen auskommt:

  http://de.wikipedia.org/wiki/Logarithmus#Berechnun...

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.