Hallo Forum, die Schul- und Studienzeit ist schon lange her und ehrlicherweise weiß ich auch nicht, ob das Thema jemals behandelt wurde. Folgendes Problem: Ich habe einen Wertebereich von 0 - 1023 (=10Bit) und möchte eine LED-Zeile mit 7 LED für eine logarithmische Anzeige des aktuellen Werts verwenden. LED0 stellt den niedrigste Wert dar, LED6 den höchsten. Alle Werte <= 512 lassen LED6 leuchten. Werte von 0 - 511 sollen logarithmisch dargestellt werden. Nur zur Erklärung, das was ich schreibe ist falsch (BSP: Verdoppelung von LED zu LED). LED0 = 2hoch0 => LED1 = 2hoch1 .. LEDN = 2hochN Herauskommen soll so ein (Pseude)Code: void setLED(int value) { //0 <= value <= 1023 if (value > X0) LED0_AN; .. if (value > X5) LED5_AN; if (value > 511) LED6_AN; } Ich möchte gerne wissen, wie ich X0 - X5 berechne. (also logarihmisch auf 0 - 511 abbilde) Danke und Grüße Harry
Du vergleichst einfach die esten 6 Bits und fragst auf >64, 32, 16, 8, 4, 2, 1
Mannfred T. schrieb: > Du vergleichst einfach die esten 6 Bits und fragst auf >64, 32, 16, 8, > 4, 2, > 1 Nee, das war zu einfach, oder ? :-)
Harry R. schrieb: > Mannfred T. schrieb: >> Du vergleichst einfach die esten 6 Bits und fragst auf >64, 32, 16, 8, >> 4, 2, >> 1 > > Nee, das war zu einfach, oder ? > :-) Er hat zwar nicht natürlicher oder dekadischer Logarithmus gesagt, aber nicht Logarithmus zur Basis 2 gemeint. Es geht doch vermutlich um VU-Meter oder S-Meter.
Michael B. schrieb: > Er hat zwar nicht natürlicher oder dekadischer Logarithmus gesagt, aber > nicht Logarithmus zur Basis 2 gemeint. Ab 128 wird dann LED 5.5 eingeschaltet - oder wie stellst du dir das vor? Harry R. schrieb: > Alle Werte <= 512 lassen LED6 leuchten. > > Werte von 0 - 511 sollen logarithmisch dargestellt werden. Kurz: LED6 soll nicht leuchten, wenn der Wert größer als 512 ist? > Ich möchte gerne wissen, wie ich X0 - X5 berechne. > (also logarihmisch auf 0 - 511 abbilde) Wenn du es nicht rechnen kannst, nimm ein Blatt Karopapier, zeichne dir auf der X-Achse in gleichem Abstand die Umschaltpunkte für deine LEDs ein. Auf der Y-Achse stellst du ln(Wert) dar. Verbinde die Umschaltpunkt von erster und letzter LED durch eine Gerade und lies für die dazwischenliegenden den ln(Wert_i) ab. Die Umkehrfunktion zu ln() ist exp(). Statt auf Karopapier kannst du natürlich auch eine einfache Geradengleichung bemühen.
:
Bearbeitet durch User
Bei 512 soll die siebte LED leuchten, siebte Wurzel aus 512: B = 512**(1/7) => ~ 2,43802731 Für die sieben LEDs: B ** 1 => 2 (immer gerundet) B ** 2 => 6 … B ** 6 => 210 B ** 7 => 512 Es ergeben sich: >= 2, 6, 14, 35, 86, 210, 512
Harry R. schrieb: > Alle Werte <= 512 lassen LED6 leuchten. > ... > if (value > 511) LED6_AN; Das widerspricht sich. Ich nehme an, dass in der oberen Zeile ein >= stehen sollte. Die Schwellenwerte sollen eine geometrische Folge bilden. LED6 soll für value >= 512 leuchten. Wann soll LED0 leuchten? Für value >= 1 (den Wert kannst du beliebig vorgeben)? Falls ja, dann leuchtet LED<i>, wenn value >= 1 * (512 / 1)**(i/6) = sqrt(8)**i. Für andere Schwellenwerte für LED0 und LED6 geht die Berechnung entsprechend.
:
Bearbeitet durch Moderator
Michael B. schrieb: > Er hat zwar nicht natürlicher oder dekadischer Logarithmus gesagt, aber > nicht Logarithmus zur Basis 2 gemeint. Es war nicht definiert, welchen Bereich er abdecken will. Nach unten ist das immer offen. Die Aufteilung in 7 gleichmäßige Bereiche mündet aber automatisch in eine Zusammenfassung der unteren Bits. 1024 sind ja bekanntlich 10. Folglich ist die Aufteilung natürlich. Und: > VU-Meter ... sie entspricht auch der üblichen Darstellung von 1 LED = 6dB.
Mannfred T. schrieb: > Du vergleichst einfach die esten 6 Bits und fragst auf >64, 32, 16, 8, > 4, 2, > 1 Klingt irgendwie naheliegend, doch bei acht LEDs wäre die Antwort wohl '>128, 64, 32, 16, 8, 4, 2, 1 gewesen. Unabhängig ob der Maximalwert nun 1023, 4095 oder nur 255 gewesen wäre; ein sicheres Zeichen, dass hier was faul ist. Stattdessen, kleine Rechnung mit den Unbekannten a und b: 1 = a*10^(0*b) --> 1. LED an 7 = a*10^(1023*b) --> 7. LED an Hieraus lassen sich a und b bestimmen; und sein nun bekannt. Nun sind diejenigen Werte gesucht, für die eine ganze(!) LED angeht. Sei n also eine ganze Zahl, z.B. 1, 2, 3, 4, ... 7 und u der zugehörige (ADC-) Eingangswert, dann mit obiger Gleichung n = a * 10^(b*u) Den Kram nun nach u auflösen und die verschiedenen Werte für n einsetzen. Fertig. Michael B. schrieb: > Er hat zwar nicht natürlicher oder dekadischer Logarithmus gesagt, aber > nicht Logarithmus zur Basis 2 gemeint. Ich denke aus obiger Rechnung lässt sich erahnen, dass die verwendete Basis des Logarithmus am Ende schnuppe ist. P.S.: Ja, ist ein bisschen dämlich, dass bei 0 schon die erste LED leuchtet (also immer) und erst bei 1023 die letzte (also beinahe nie). Dem TO sei es überlassen das anzupassen. Edit: Äh, kann sein, dass statt 10^ oben immer log-zur-welcher-Basis-auch-immer stehen sollte/müsste. ;-)
:
Bearbeitet durch User
Sebastian S. schrieb: > Äh, kann sein, dass statt 10^ oben immer > log-zur-welcher-Basis-auch-immer stehen sollte/müsste. So isses. Siebte Wurzel aus 512. ;-)
Norbert schrieb: > Siebte Wurzel aus 512. ;-) Hm, was an der Wurzelfunktion logarithmisch sein soll bleibt, fürchte ich, dein Geheimnis. Wie der Umstand, dass der TO glaubt, dass bei einer logarithmischen Teilung 512 ein Schwellwert sein muss ...
Harry R. schrieb: > Ich möchte gerne wissen, wie ich X0 - X5 berechne. > (also logarithmisch auf 0 - 511 abbilde)
Sebastian S. schrieb: > Hm, was an der Wurzelfunktion logarithmisch sein soll bleibt, fürchte > ich, dein Geheimnis. Wie der Umstand, dass der TO glaubt, dass bei einer > logarithmischen Teilung 512 ein Schwellwert sein muss ... gnuplot: B = 512 ** (1.0 / 7.0) plot [0:7] B**x Vielleicht hilft's ja…
Sebastian S. schrieb: > Ich denke aus obiger Rechnung lässt sich erahnen, dass die verwendete > Basis des Logarithmus am Ende schnuppe ist. Das braucht man nicht ahnen, das sagt einem die Mathematik:
Da
eine Konstante ist heißt das nichts anderes, als dass man von einem (logM) zum anderen Logarithmus (logN) durch einfache Division mit einer Konstanten (oder Multiplikation mit dem Kehrwert der Konstanten) gelangt.
:
Bearbeitet durch User
Hannes J. schrieb: > als dass man von einem > (logM) zum anderen Logarithmus (logN) durch einfache Division mit einer > Konstanten (oder Multiplikation mit dem Kehrwert der Konstanten) > gelangt. Ja, hatte ich im Sinn. Und dass am Ende eben jene Konstante sich beim Hin- und Herrechnen eben wieder rauskürzt. Ich war nur etwas zu faul, dass zu zeigen bzw. das wollte ich dem TO überlassen es herauszubekommen ;-)
10 Bit .. das wird bestimmt von einem einfachen AD-Wandler kommen. Ignorier einfach die letzten 3 Bits, denn da ist oft nur noch ein Rauschen drin. Und schon hast du 7 Bits, die du eins zu eins mit den LEDs verknüpfen kannst. Das reicht für ein Geblinker an einen Benutzer vollkaumen aus. ADValue >>= 3; if(ADValue & (1<<0)) SetLED(0) ... if(ADValue & (1<<7) ) SetLED(7)
Peter schrieb: > Und schon hast du 7 Bits, die du eins zu eins mit den LEDs verknüpfen > kannst. Der TE will keine binäre Anzeige des ADC-Werts, sondern eine Balkenanzeige.
Rainer W. schrieb: > Michael B. schrieb: > > Kurz: LED6 soll nicht leuchten, wenn der Wert größer als 512 ist? Tippfehler, es soll heißen: Alle Werte >= 512 lassen LED6 leuchten.
Georg M. schrieb: > Harry R. schrieb: >> Ich möchte gerne wissen, wie ich X0 - X5 berechne. >> (also logarithmisch auf 0 - 511 abbilde) Spalte A & B sind klar, aber wie kommst du auf die Werte in C ? VG
Harry R. schrieb: > Spalte A & B sind klar, aber wie kommst du auf die Werte in C ? Runden und eins abziehen. if(value > 0) LED0 on; if(value > 2) LED1 on; if(value > 8) LED2 on; if(value > 24) LED3 on; . . . . Übrigens, die Tabellenwerte kann man anpassen. Praktisch muss es sein und nicht unbedingt streng mathematisch.
Sebastian S. schrieb: > Klingt irgendwie naheliegend, doch bei acht LEDs wäre die Antwort wohl Der TO spricht von 7 LEDs.
Norbert schrieb: > Vielleicht hilft's ja… Nö. Aber eher dein Original-Post (nochmal gelesen) Wenn ich das richtig verstanden habe verwendest du den Logarithmus zu Basis siebte Wurzel 512, richtig? Wobei (wäre ich der TO) ich dann eher B = 1023^(1/9) verwenden würde und dann die Werte für 2 bis 8, aber egal ...
:
Bearbeitet durch User
Sebastian S. schrieb: > Wenn ich das richtig verstanden habe verwendest du den Logarithmus zu > Basis siebte Wurzel 512, richtig? Korrekt. > Wobei (wäre ich der TO) ich dann eher B = 1023^(1/9) verwenden würde und > dann die Werte für 2 bis 8, aber egal ... Das würde jedoch die Bedingung >=512 für die letzte LED nicht erfüllen. Wir lägen da bei den Stufen …,102,219,474,1023
Norbert schrieb: > Das würde jedoch die Bedingung >=512 für die letzte LED nicht erfüllen. Ich weiß. Aber die erscheint mir etwas seltsam bzw. Motivation ist mir nicht klar (warum nicht 557 oder 702 oder ...?). Daher meine Alternativ-Überlegung, aber die ist nicht so wichtig hier. Der TO will 512 (warum auch immer) und die erste LED soll immer an sein (wozu auch immer); sei es wie es sei.
Ich habe nicht viel hier gelesen, aber es wurde hier Beitrag "VU-Meter mit Attiny13a statt LM3916" mal ein VU-Meter mit einem Tiny umgesetzt. Vielleicht sind ein paar Anregungen drin.
Logarithmisch heißt: Ein konstantes Verhältnis (der Werte zueinander) führt zu einem konstantem linearen Abstand zueinander. Das heißt, 1/2, 1/2*2, 1/2*2*2, 1/2*2*2*2, ... entspricht 1, 2, 3, 4, ... Aber auch 1/3, 1/3*3, 1/3*3*3, 1/3*3*3*3, ... entspricht 1, 2, 3, 4, ... Du musst eigentlich nur wissen, was du darstellen willst. - Und bist damit wohl überfordert...
> Der TE will keine binäre Anzeige des ADC-Werts, sondern eine > Balkenanzeige. Ich hab das Problem geloest indem ich erstmal ein bisschen analoge Vorarbeit geleistet habe (Diodenkennlinie) und dann den Rest mit einer Tabelle im Rom. Das ist garantiert nicht Mathematisch korrekt, aber fuer ein VU-Meter mit cooler Anzeige reicht es. Das Problem wenn man es komplett im Controller machen will besteht IMHO darin das der AD-Wandler nicht genug Aufloesung haben wird. Vanye
Vanye R. schrieb: > Ich hab das Problem geloest indem ich erstmal ein bisschen analoge > Vorarbeit geleistet habe (Diodenkennlinie) und dann den Rest mit einer > Tabelle im Rom. Das ist garantiert nicht Mathematisch korrekt, aber fuer > ein VU-Meter mit cooler Anzeige reicht es. > Das Problem wenn man es komplett im Controller machen will besteht IMHO > darin das der AD-Wandler nicht genug Aufloesung haben wird. VU-Meter, selbst im Profibereich, besitzen selten einen Anzeigeumfang von größer 30dB. Der TO sprach von einem 10-bit-Wandler - entsprechend einer Auflösung von 60dB. Mit 30db Reserve kann ich keine Notwendigkeit erkennen für eine Signal-Vor-Verbiegung an irgendwelchen komischen Dioden-Kennlinien. just my 2ct
> VU-Meter, selbst im Profibereich, besitzen selten einen Anzeigeumfang > von größer 30dB. Ich hab Anzeigen mit 64Segmenten verwendet. Da sollte halt bei Rauschen das unterste Segment leicht flackern und bei maximaler Laustaerke mit Finger im Ohr und erbosten Nachbarn das Peakhold vom obersten Segment ab und an zuschlagen. Ich fand halt das sowas schoener aussieht als die 5-8Leds des 90er Jahre Tapedeck. .-) Sowas erlaubt dann einen schoenen vergleich zwischen Musik von frueher und aktuell. Und ja du hast recht 30dB reichen heute aus. Eigentlich sogar schon 10dB. Vanye
Vanye R. schrieb: > Sowas erlaubt dann einen schoenen vergleich zwischen Musik von frueher > und aktuell. Du beziehst dich auf den loudness war? 64 finde ich etwas viel. Ausgehend von 0dB rückwärts gerechnet, sind 32 sicher ausreichend. -30dB ist praktisch nicht mehr zu hören, es sei denn man dreht die 100% (0dB) so weit auf, dass einem die Ohren wegfliegen.
Harry R. schrieb: > LED0 stellt den niedrigste Wert dar Wofür wird das gebraucht? Mindestens Null sollten doch hoffentlich immer da sein?
Percy N. schrieb: > Harry R. schrieb: >> LED0 stellt den niedrigste Wert dar > > Wofür wird das gebraucht? Mindestens Null sollten doch hoffentlich immer > da sein? LED0 stellt nicht den Wert ›Null‹ dar, sondern den niedrigsten Wert der bei gegebenen Parametern dort sein würde. Das wäre, bei Einhaltung der anderen Vorgaben, gerundet die ›Zwei‹
Vanye R. schrieb: > Ich hab Anzeigen mit 64Segmenten verwendet. Bei so einer Anzeige wirst du mit einem linearen 10 Bit Wandler mangels Dynamik im Unteren Bereich keine logarithmische Kennlinie, die die Segmente einzeln nacheinander aktiviert, realisieren können.
Norbert schrieb: > LED0 stellt nicht den Wert ›Null‹ dar, sondern den niedrigsten Wert der > bei gegebenen Parametern dort sein würde. Das wäre, bei Einhaltung der > anderen Vorgaben, gerundet die ›Zwei‹ Eine logarithmische Skala kann man niemals nach unten schließen, somit muss immer die unterste LED alle Werte darunter mit einschließen. Mit 7 LEDs lassen sich maximal 8 Bereiche indizieren, wenn man sie als Trennwert definiert. Ausgehend vom idealen Maximum von 1024 sind das also log (1024,2) / log (8/2) = 3,33 Die Aufteilung wäre demnach: 1024, 307, 92 ... 2,1,0 läuft also in Rundungsfehler hinein. Besser ist die Mitteldefinition mit nur 7 Werten unter Weglassen des ersten und letzten: -> 3,15 -> 1024,324,103, ... 3,3 1 0 Die sich ergebenden Grenzwerte sind: 577, 183, 58, 18, 6, 2, 1 Am Schlauesten ist es, den unteren wegzulassen und noch einen Bereich mehr zu nehmen: 591, 197, 66, 22, 7, 2, 1
Auch dir ist es offensichtlich nicht möglich den ERSTEN (Eröffnungs)Beitrag zu lesen. Zumindest nicht in einer Art, welche dich erkennen lässt das EXPLIZIT die Bedingung ›größte LED bei >=512‹ gegeben wurde.
Norbert schrieb: > Zumindest nicht in einer Art, welche dich > erkennen lässt das EXPLIZIT Tja und du bist nicht in der Lage, den zweiten Beitrag zu lesen, in dem ich direkt geantwortet habe, die die Lösung des TO enthält und seine Vorgabe berücksichtigt. Das tut sie nämlich. Ich erkläre es aber gern: Durch Weglassen der hinteren Bits vereinfacht sich die Abfrage, bzw die Faktoren werden durch 4 dividiert und sinnvoll fortgesetzt. 512/4 sind die 128, alle weiteren durch Faktor 2, der durch die Eingangsbedingung implizit definiert. Manni T. schrieb: > Du vergleichst einfach die esten 6 Bits und fragst auf >64, 32, 16, 8, > 4, 2, > 1
Wie so oft im Leben wird eine unsinnige und falsche Rechnung durch Wiederholung weder besser noch wahrer.
Norbert schrieb: > Wie so oft im Leben wird eine unsinnige und falsche Rechnung durch > Wiederholung weder besser noch wahrer. Erstmal lesen und zitieren lernen: Der TE schreibt nicht von ">=" sondern "<=", hat also schon einmal einen Schreibfehler drin, den man uminterpretieren muss. Der weiteren "rechnen lernen": Ein Logarithmus ist ein Maß für Dynamik. Ohne eine untere Grenze kann man nicht ausrechnen, wie die Potenzen zu setzen und zu verteilen sind. Deine Annahme 7-wurzel unterstellt, dass alle anderen Potenzen unterhalb der untersten zusammengefast werden sollen. Warum sollte das so sein? Eine sinnvolle Anzeige wird immer kontinuierlich sein. Als Folge muss die nächste LED auch in Relation das anzeigen, was die erste anzeigt und das ist nun einmal die Hälfte. Damit ergeben sich 512,256,128 .... etc. Es macht einfach keinen Sinn einen Teil der Anzeige anders arbeiten zu lassen, als den anderen. Meine Vereinfachung lässt einfach nur die unteren Bits weg.
Manni T. schrieb: > Der weiteren "rechnen lernen": > Ein Logarithmus ist ein Maß für Dynamik. Ohne eine untere Grenze kann > man nicht ausrechnen, wie die Potenzen zu setzen und zu verteilen sind. Ein unterste Grenze für die sinnvoll untere Grenze ist durch das Auflösungsvermögen des ADC gegeben, da der ADC keine reellen Zahlen liefert.
Rainer W. schrieb: > Ein unterste Grenze für die sinnvoll untere Grenze ist durch das > Auflösungsvermögen des ADC gegeben, da der ADC keine reellen Zahlen > liefert. Das ist der typische Denkfehler der Neoelektroniker der letzten Generation: Aus physikalischer Sicht ist die Grenze durch die Qualität des analogen Signals definiert, konkret durch das S/N. Die Auflösung des ADC wird (hoffentlich) sehr viel höher sein, weil ansonsten falsch dimensioniert. Angenommen man baut die Schaltung richtig und sinnvoll, dann müsste der ADC wenigstens eine um 10, besser 100-fach höhere Auflösung haben, als der geringste Pegel, damit sein Fehler nicht größer wird, als das darin inkludierte Rauschen. Messtechnik, erstes Semester. Man kann daher den geringsten noch sinnvoll darstellbaren Pegel, der die unterste LED rechtfertigt mit mindestens einem Faktor 8 ansetzen. Auch das rechtfertigt das Weglassen der unteren Bits bei der Betrachtung der Komparatorwerte, denn der geringste Werte wäre dann mit 8 immerhin noch auf 12% genau. Der Fehler von 6% dürfte deutlich geringer sein, als der Fehler, der in einem ADC-Wert von 8 steckt und der würde auch gerade maximal 1% Genauigkeit haben, bei einem 10-Bit ADC. Werte um 1,2 oder ähnlich abzuprüfen, macht somit aus 2 Gründen keinen Sinn.
Manni T. schrieb: > ne Menge Ich plotte deinen Vorschlag in rot und die korrekte Lösung in grün. X-Achse ADC-Eingangswert. Schauen wir auf OUTPUT1 Bei sehr flüchtiger Betrachtung könnte man auf die Idee kommen, passt schon irgendwie. Aber schon der simple Plot mit reellen anstelle von natürlichen Zahlen offenbar so einiges Problematisches. OUTPUT2 Der fundamentale Fehler besteht darin, einen Wertebereich von 0…1023 bei der Basis 2 in sieben Stufen quetschen zu wollen. Da das selbstverständlich niemals funktionieren kann, dividierst du den Eingangswert ÷ 8. (was nebenbei das Gleiche ist, als wenn man vom Ergebnis(Y)
subtrahiert.) Spätestens hier sollte jedem klar sein das dies niemals Zielführend sein kann. Warum? Alle Y-Werte unterhalb 0 werden einfach weggeworfen und, schlimmer noch, ein Offset eingebracht OUTPUT3 und eine Kurvenform welche nicht den Anforderungen entspricht erzeugt. Prüfen wir mal die ersten ADC-Werte > 0: 1: 1>>3 == 0 Hier sollte wie gewünscht die erste LED leuchten 2: 2>>3 == 0 3: 3>>3 == 0 4: 4>>3 == 0 …verdammt… 6: 6>>3 == 0 7: 7>>3 == 0 8: 8>>3 == 1 Zumindest der LED ist nun endlich ein Licht aufgegangen (bei gerade einmal 800% des gewünschten ADC-Eingangswertes) Nun zu den grünen Kurven OUTPUT4 und OUTPUT5 Um diese zu erreichen muß selbstverständlich die passende Zahlenbasis zu den Vorgaben gesucht werden. Vorgaben: > 7 LEDs. Eine logarithmische Anzeige des aktuellen Werts. > LED0 stellt den niedrigste Wert dar, LED6 den höchsten. Der niedrigste Wert kann nur bei einem ADC-Eingangswert von 1 entstehen (Log(0) ist noch nicht erfunden worden) > Alle Werte <= 512 lassen LED6 leuchten. Offensichtlich ein Tippfehler, soll vermutl. heißen: Alle Werte >= 512 lassen LED6 leuchten. Wir haben also sieben Punkte (LEDs), wir haben sechs Intervalle dazwischen. Die korrekte Zahlenbasis errechnet sich zu:
Kurz mal prüfen:
Ja, passt. Ein Übereinander legen sowohl deines Vorschlags als auch der richtigen Lösung zeigt die Probleme OUTPUT6 Jetzt wäre es an der Zeit zu sagen: Ja, stimmt, die Rechnung zur Zahlenbasis zwei kann so nicht funktionieren. Aber du hast einen viel besseren Weg gefunden, du verbiegst nun die Fakten, erklärst das der TE gar nicht weiß was er will (du jedoch schon) und erfindest auch noch neue Fakten (dein Weltbild zu ADCs) hinzu. Interessanterweise passen diese von dir weichgekneteten »Fakten« nun wunderbar zu deinem im Anfang gezeigten Vorschlag (ja genau, dem Roten) Leider scheint das ja heutzutage der Trend zu sein, passt das Weltbild nicht zur eigenen Vorstellung, dann wird halt das Weltbild passend gemacht.
Moin, Mach mal einen Spaziergang, ess mal einen Apfel. scnr, WK
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.