Ich möchte ein VU Meter mit einem LCD Display erstellen. Da gibt es sehr viele Vorlagen und Anleitungen im Netz. Ich möchte aber nicht, das die Anzeige Links beginnt und dann im Takt nach rechts aufbaut. Ich hätte gern das sie in der Mitte beginnt und dann symmetrisch nach links und rechts aufbaut. Ich hoffe ich konnte mich verständlich ausdrücken.
Gibt es da schon etwas was ich nutzen könnte? Meine Kenntnisse reichen definitiv nicht aus um das selbst zu machen.
Peter
setzt einen I2C Display voraus.
// LCD
#include <LiquidCrystal_I2C.h>
const byte lcdSpalten = 16;
const byte lcdZeilen = 2;
LiquidCrystal_I2C lcd(0x27, lcdSpalten, lcdZeilen);
void setup()
{
Serial.begin(115200);
Serial.println(F("Start..."));
lcd.begin();
lcd.backlight();
randomSeed(A0);
}
void loop()
{
byte myDb = random(0, lcdSpalten - 1 / 2 );
if (millis() % 200 == 0)
{
vu(0, myDb);
}
}
void vu(const byte line, byte db)
{
if (db > lcdSpalten)
{ db = lcdSpalten; }
byte startPosition = (lcdSpalten / 2) - (lcdSpalten - db) / 2;
byte endPosition = lcdSpalten - startPosition;
lcd.setCursor(line, 0);
for (byte b = 0; b < lcdSpalten; b++)
{
if ((b > startPosition) && (b < endPosition))
{
lcd.print('*');
}
else
{
lcd.print(' ');
}
}
}
Super. Vielen Dank.
Werde ich nachher gleich testen. Würde ich alleine nie hinbekommen.
Muss jetzt erst einmal sehen inwieweit ich den Code verstehen.
Das ist nicht schwer.
Als erstes weisst Du wie breit das Dispplay ist. - lcdSpalten ist mit 16 gefüllt.
Im loop() erzeuge ich Zufallszahlen und übergebe diese an die Funktion vu, die in Zeile 0 den Wert grafisch anzeigen soll.
Dort wird erstmal auf die Spalten begrenzt.
Die Startposition errechnet sich wie folgt:
Gesamtzahl der Spalten: 16; davon die Hälfte: /2 = 8 für eine Seite;
Von der wird jetzt abgezogen: Gesamtzahl der Spalten: 16; minus übergebener Wert, der auch halbiert wird 6/2 = 3 - macht 8-3 = 5.
Die Endposition bräuchte man nicht errechnen, sondern einfach von der Startposition aus weiterrechnen.
Ich habs aber wegen der Logik gemacht, damit man was zum sehen hat...
Ausgabe auf dem SerMon:
14:41:25.305 -> *******
14:41:25.470 -> *
14:41:25.703 -> *************
14:41:25.901 -> *********
14:41:26.100 -> *****************
14:41:26.299 -> *
14:41:26.498 -> ***************
14:41:26.697 -> *******************
14:41:26.896 -> *
14:41:27.096 -> *****************
14:41:27.295 -> *************
14:41:27.494 -> *********
14:41:27.693 -> ***************
14:41:27.891 -> ***********
14:41:28.090 -> *****************
14:41:28.289 -> *
14:41:28.488 -> *************
14:41:28.687 -> *****************
14:41:28.886 -> ***********
14:41:29.085 -> ***************
14:41:29.284 -> ***************
14:41:29.483 -> *********
14:41:29.681 -> *****
14:41:29.880 -> ***************
14:41:30.079 -> *****************
14:41:30.278 -> *********
14:41:30.476 -> *************
14:41:30.675 -> ***********
14:41:30.874 -> ***
14:41:31.106 -> *****
Hallo,
mit eigenem Zeichensatz ist viel möglich. Üblicherweise haben Displays Platz für 8 selbst definierte Zeichen. Das reicht für eine Pixelfein aufgelöste Balkendarstellung. Ein Charakterfeld hat 8x5 Pixel. Leeres und volles Feld ist im Standardsatz enthalten. Also braucht man nur noch 2x 4 eigene Zeichensätze was in Summe 8 sind. geht wunderbar auf. Dafür muss man nicht einmal Zeichensätze umladen. 4 nach links füllende Felder und 4 nach rechte füllende Felder, auf die Spalte betrachtet. Da wird ein einfaches Display fast Grafikfähig.
Noch'n Nachtrag.
Du kannst natürlich auch die volle Breite übergeben und darus errechnen.
Hier mal in Kurz ohne endPunktVariable.
Das Ergebnis ist das gleiche, aber vielleicht übersichtlicher.
// LCD
#include <LiquidCrystal_I2C.h>
const byte lcdSpalten = 16;
const byte lcdZeilen = 2;
LiquidCrystal_I2C lcd(0x27, lcdSpalten, lcdZeilen);
void setup()
{
Serial.begin(115200);
Serial.println(F("Start..."));
lcd.begin();
lcd.backlight();
randomSeed(A0);
}
void loop()
{
byte myDb = random(0, lcdSpalten);
if (millis() % 100 == 0)
{
vu(0, myDb);
}
}
void vu(const byte line, byte db)
{
if (db > lcdSpalten)
{ db = lcdSpalten; }
byte startPosition = lcdSpalten / 2 - db / 2;
lcd.setCursor(line, 0);
for (byte b = 0; b < lcdSpalten; b++)
{
if ((b > startPosition) && (b < startPosition+db ))
{
lcd.print('*');
}
else
{
lcd.print(' ');
}
}
}
[pingelig]
"Liquid Crystal Display Display" ist doppeltgemoppelt (Pleonasmus)
[/pingelig]
Bei einem VU-Meter denke ich an eine Zahl, die hinsichtlich des Kommas an einer festen Stelle angezeigt wird. Das entspricht linksbündig mit einer festen Anzahl Leerzeichen aufgefüllt. Dazu verwende ich gerne snprintf. Ja, da ist eine Einarbeitung notwendig, aber wenn man mit den Beispielen etwas spielt, entwickelt sich ein Gefühl für die Möglichkeiten.
Beim UNO funktioniert %f
standardmäßig nicht, aber Meßwerte würde ich, wenn möglich, sowieso lieber als Ganzzahl verarbeiten. Als Anregung abgeleitet aus #3 und getestet mit einem UNO:
// LCD
#include <LiquidCrystal_I2C.h>
const byte lcdSpalten = 16;
const byte lcdZeilen = 2;
LiquidCrystal_I2C lcd(0x27, lcdSpalten, lcdZeilen);
void setup()
{
Serial.begin(115200);
Serial.println(F("Start..."));
lcd.begin();
lcd.backlight();
randomSeed(A0);
}
void loop()
{
if (millis() % 1000 == 0)
{
uint16_t messWert = random(0, 20000 );
vu(0, messWert);
}
}
void vu(const byte line, uint16_t wert)
{
char buf[17] = {"\0"};
snprintf( buf, sizeof(buf), "%8d.%02d", wert/100, wert%100);
lcd.setCursor(0, line);
lcd.print(buf);
}
Ich schreibe aber gerne LCD Display.
Vieleicht manchmal LCD Modul.
Grüße Uwe
LCD Modul ist nicht doppelt gemoppelt, LCDD schon
,
Das wird eine Darstellung wie ein magisches Auge auf Basis einer EM84. Wenn sowas in Zahlen dargesetellt werden soll, dann nur mit Nixie.
Im Wikipedia.
Die wurden meist waagerecht eingebaut. (Ich trauer einem alten Weimar noch nach)
Es ging um LCD Display.
Gruß Tommy
Ist doch LCDDisplay
Habe ich noch nie gesehen, wieder was gelernt.
Mein Radio gibt noch Töne von sich, allerdings ist es etwas verstaubt, was man am Kratzen auch hören kann.
Hallo,
Leute, wisst ihr nicht was ein VU-Meter ist?
VU Meter sind Aussteuerungsanzeigen.
Kann man wunderbar als Balkengrafik auf einem Display darstellen.
Googelt einmal danach.
Andere bauen dafür RGB Led Würfel mit den tollsten Effekten.
Magisches Auge ist was anderes für einen ganz anderen Zweck.
Da war ich ja auf dem vollkommen falschen Gleis
Hallo,
deswegen sah ich mich gezwungen korrigierend einzugreifen. Zurück auf dem Hauptgleis ist immer gut.
Doch.
Aufgabenstellung:
Damit ist der Verweis auf das MA doch wohl ausreichend begründet.
Achso, man kann natürlich das VU auch in Stereo als solche Balkenanzeige bauen
// LCD
#include <LiquidCrystal_I2C.h>
const byte lcdSpalten = 16;
const byte lcdZeilen = 2;
LiquidCrystal_I2C lcd(0x27, lcdSpalten, lcdZeilen);
void setup()
{
Serial.begin(115200);
Serial.println(F("Start..."));
lcd.begin();
lcd.backlight();
randomSeed(A0);
}
void loop()
{
byte myDbL = random(0, lcdSpalten/2);
byte myDbR = random(0, lcdSpalten/2);
if (millis() % 100 == 0)
{
vu(0, myDbL, myDbR);
}
}
void vu(const byte line, byte dbL, byte dbR)
{
if (dbL > lcdSpalten/2)
{ dbL = lcdSpalten/2; }
if (dbR > lcdSpalten/2)
{ dbR = lcdSpalten/2; }
byte startPosition = lcdSpalten / 2 - dbL;
lcd.setCursor(line, 0);
for (byte b = 0; b < lcdSpalten; b++)
{
if ((b > startPosition) && (b < startPosition+dbL+dbR ))
{
lcd.print('*');
}
else
{
lcd.print(' ');
}
}
}
Korrekt. Statt zwei Balken nebeneinander zwei die von der Mitte aus nach außen "pegeln".