Forum: Mikrocontroller und Digitale Elektronik Logarithmus aus Int berechnen


von Zangetsu (Gast)


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

von Martin G. (mager)


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)

von Rene B. (themason) Benutzerseite


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.

von Zangetsu (Gast)


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?

von Falk B. (falk)


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.
1
int a;
2
float b;
3
4
b=a;

MFG
Falk

von Stefanie B. (sbs)


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:
1
float f;
2
int i;
3
i=IrgendwasWildes();
4
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.
1
int Tabelleneintraege[]={1,3,9,16,25,36,100};
2
int zugehörigeWerte[]  ={1,2,3, 4, 5, 6, 10};
3
4
int getWert(int input){
5
  int ret;
6
  int i=0;
7
  while(Tabelleneintrag[i]<input)i++;
8
9
  //dein Wert liegt jetzt zwischen i und i+1
10
  // also musst du zwischen zugehörigeWerte[i] und zugehörigeWerte[i+1]
11
  // linear interpolieren.
12
  
13
  ret=Tabelleneintraege[i]+ \
14
   ( Tabelleneintraege[i+1]-Tabelleneintraege[i]) / \  
15
(zugehörigeWerte[i+1]-zugehörigeWerte[i])*input-Tabelleneinträge[i];
16
  return ret;
17
}

Zu guter Letzt:

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

Viele Grüße
Stefan

von Karl H. (kbuchegg)


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.
>
>
1
> int a;
2
> float b;
3
> 
4
> b=a;
5
> 
6
>

@Zangetsu

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

denn x / 1024  ergibt bei dir immer 0

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

von Yalu X. (yalu) (Moderator)


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#Berechnung_einzelner_Bin.C3.A4rziffern

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.