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.
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
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.
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.
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.
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. ;-)
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 ...
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 ...
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:
$$\log_{N}x = \frac{\log _{M}x}{\log_{M}N}$$
Da
$$\log_{M}N$$
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.
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.
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 ...
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.
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.
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.
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.
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.
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‹
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.
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.
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.
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.
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.
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.
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)
$$\log_2(8)$$
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:
$$basis = \sqrt[6]{512}$$
Kurz mal prüfen:
$$\color{Blue} (\sqrt[6]~{512}) ^ {6} = 512$$
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.