Forum: Mikrocontroller und Digitale Elektronik LCD Display Bargraph


von LCD,,,,, (Gast)


Lesenswert?

Hallo,

ich hab hier ein 20x2 Zeichen LCD Display per USB an den PC 
angeschlossen. Die Hardware ist eigentlich unwichtig. Ich möchte nun 
folgendes Programmieren.
Zuerst will ich sagen, dass ich programmieren kann und das Display auch 
ansprechen kann mir geht es hier nur um die Vorgehensweise um ein 
Bargraph zu erzeugen, da meine doch noch sehr langsam ist.

Also erstmal die Kommandos. Mein Bargraph soll in der zweiten Zeile 
sein. An Position 1 und 20 die Klammern [ und ] um den Bargraph 
abzuschließen. Dazwischen mein Bargraph. Eine Ziffer bzw. ein Feld ist 
ja 5 Pixel breit. Nun hab ich verschiedene Blöcke mit einer Länge von 
1-5 Pixel in meinem CGRAM.

Nun möchte ich auf der Länge möglichst schnell meinen Bargraph mit einer 
variablen Länge von 0-100% zeichnen.

Was wäre die schnellste Variante um dies zu tun?

Bin um jede Antwort dankbar.

von Jürgen (Gast)


Lesenswert?

LCD,,,,, schrieb:
> Eine Ziffer bzw. ein Feld ist
> ja 5 Pixel breit. Nun hab ich verschiedene Blöcke mit einer Länge von
> 1-5 Pixel in meinem CGRAM.

Da du 18 Zeichen für den Bargraphen hast, sind das 90 Pixel.

LCD,,,,, schrieb:
> Nun möchte ich auf der Länge möglichst schnell meinen Bargraph mit einer
> variablen Länge von 0-100% zeichnen.

Prozentzahl * 0,9.
Ergebnis testen  ob >5
Wenn ja: Einen ausgefüllten Block ausgeben (ASC255 glaub) und vom 
Ergebniss 5 abziehen. Erneut testen.
Wenn nein: Sonderzeichen (1..5) ausgeben. (Pixelbreite = Nr. des 
Sonderzeichen).

von Falk B. (falk)


Lesenswert?


von spess53 (Gast)


Lesenswert?

Hi

Wo klemmt es denn nun genau? Deinen Wert auf einen Bereich von 0..90 
skalieren. Dieser Wert /5 ergibt die Anzahl der vollen Kästchen. Mod 5 
ergibt den Rest. Aus dem ergibt sich dein eigenes Zeichen.

Programmiersprache?

MfG Spess

von LCD,,,,, (Gast)


Lesenswert?

Ich hab denke ich den Fehler gefunden, warum mein Code so langsam ist. 
Es geht um das löschen der restlichen Balken. Ich hab danach immer noch 
3 Leerzeichen geschrieben und das hat zu lange gedauert.

Doch was ist nun die effektivste Methode um meinen vorherigen Balken zu 
löschen? Wenn ich davor eine Leerzeile schreibe dann flackert das so 
fürchterlich.

von Achim M. (minifloat)


Lesenswert?

LCD,,,,, schrieb:
> Doch was ist nun die effektivste Methode um meinen vorherigen Balken zu
> löschen? Wenn ich davor eine Leerzeile schreibe dann flackert das so
> fürchterlich.

Speichere ein Abbild des alten Balkens und überschreibe per 
Cursor-Setzen nur die Bereiche die beim "neuen" Balken fehlen bzw. 
dazugekommen sind.
Wenn der Unterschied Größer als ein bestimmtes Verhältnis ist, dann 
kannst du deine Leerzeilen-Methode nehmen.
Der Rechner prüft das alles in wenig Zeit, Flaschenhals ist die 
Übertragung.
mfg mf

von Jürgen (Gast)


Lesenswert?

Jürgen schrieb:

Leerzeichen = 18
> Prozentzahl * 0,9.
> Ergebnis testen  ob >5
> Wenn ja: Einen ausgefüllten Block ausgeben (ASC255 glaub) und vom
> Ergebniss 5 abziehen.
Leerzeichen-1. Erneut testen.
> Wenn nein: Sonderzeichen (1..5) ausgeben. (Pixelbreite = Nr. des
> Sonderzeichen).
Leerzeichen-1

Restliche Leerzeichen ausgeben

von Jürgen (Gast)


Lesenswert?

Den alten Graphen nicht löschen, sondern einfach überschreiben.

von Matthias H. (Gast)


Lesenswert?

Jürgen schrieb:
> Den alten Graphen nicht löschen, sondern einfach überschreiben.

Am besten von Rechts, falls der neue Balken kürzer ist und von Links, 
falls der neue länger wird.

von LCD,,,,, (Gast)


Lesenswert?

Hat den jmd. von euch schonmal ein Bargraph für zum Beispiel ein 
VU-Meter gemacht? Wie habt ihr das mit den Leerzeichen gelöst?

von LCD..... (Gast)


Lesenswert?

hat das noch keiner gemacht?

von Matthias H. (Gast)


Lesenswert?

LCD,,,,, schrieb:
> Wie habt ihr das mit den Leerzeichen gelöst?

lcd_data (' ');

Oder wie meinst du die Frage?

von LCD..... (Gast)


Lesenswert?

den balken wieder zu löschen....

von Falk B. (falk)


Lesenswert?


von LCD..... (Gast)


Lesenswert?

Ich hab ja auch mein Bargraph, der läuft auch soweit doch mein Problem 
ist es, wie ich ihn am besten lösche, damit mein neuer Wert gezeichnet 
werden kann.
Wenn ich die Zeile davor lösche, dann flackert alles so fürchterlich.

von Jürgen (Gast)


Lesenswert?

Du brauchst den Graphen nicht zu löschen. Überschreib ihn einfach. Bilde 
einen kompletten String mit 20 Zeichen der die komplette Zeile 
überschreibt.
Dann setze den Cursor in die 2. Zeile. Dann die komplette Zeichenkette 
zu LCD schicken. Fertig

von Sascha W. (sascha-w)


Lesenswert?

dann gib halt immer 18 Zeichen aus, von links beginnend die vollen, dann 
das geteilte und den Rest Leerzeichen.

Sascha

von LCD..... (Gast)


Lesenswert?

wenn ich immer volle 18 Zeichen ausgibt, also dann Rest mit Leerzeichen 
auffülle, dann wird alles fürchterlich langsam. Gibts da keine andere 
Möglichkeit?

von Klaus (Gast)


Lesenswert?

LCD..... schrieb:
> wenn ich immer volle 18 Zeichen ausgibt, also dann Rest mit Leerzeichen
> auffülle, dann wird alles fürchterlich langsam

Dann machst du beim Ausgeben eines Zeichens was falsch. Die Ausgabe 
eines Zeichens sollte nicht viel mehr als 1 bis 2µs dauern, da siehst du 
auch 20 Zeichen nicht flackern.

MfG Klaus

von spess53 (Gast)


Lesenswert?

Hi

>wenn ich immer volle 18 Zeichen ausgibt, also dann Rest mit Leerzeichen
>auffülle, dann wird alles fürchterlich langsam. Gibts da keine andere
>Möglichkeit?

Dann kläre uns mal über deine Hardware und Software auf.

Ein HD44780 braucht 41µs um ein Zeichen auszugeben und den Adresszähler 
zu incrementieren. Das macht bei 20 Zeichen 820µs. Also sind über 1000 
Zeilen/s möglich.

MfG Spess

von Falk B. (falk)


Lesenswert?

@  Klaus (Gast)

>> wenn ich immer volle 18 Zeichen ausgibt, also dann Rest mit Leerzeichen
>> auffülle, dann wird alles fürchterlich langsam

>Dann machst du beim Ausgeben eines Zeichens was falsch.

Wohl wahr.

> Die Ausgabe
>eines Zeichens sollte nicht viel mehr als 1 bis 2µs dauern,

Dir reine Ausgabe schon, das "Verdauen" im LCD aber 40us. Macht aber 
auch hier gerade mal 800us für 20 Zeichen.

MfG
Falk

von Klaus (Gast)


Lesenswert?

Falk Brunner schrieb:
> Dir reine Ausgabe schon, das "Verdauen" im LCD aber 40us. Macht aber
> auch hier gerade mal 800us für 20 Zeichen.

Hast recht, hab nur auf die cycle-time geschaut.

MfG Klaus

von LCD..... (Gast)


Lesenswert?

Hardware:
http://www.modding-faq.de/index.php?artid=615

Software in Delphi

von Oliver J. (skriptkiddy)


Lesenswert?

Zeig mal die Delphi Sourcen.

von Ralli (Gast)


Lesenswert?

Tja - und dann dauert es noch ganz schön lange, bis die
Kristalle im LCD zu ihren neuen Positionen "geschwommen"
sind...

10 Wechsel pro Sekunde sind bei Standard-LCD-Displays
eher zu viel. (Reicht aber für die visuelle Erfassung!)

Man muss schon SEHR unsachgemäßen Code anwenden, damit
man dieser Anzeigeträgheit nicht hinterherkommt!

Könnte es sein, dass die benutze delphi-Routine das
Display für jedes einzelne neue Zeichen komplett neu
beschreibt?

von Zick (Gast)


Lesenswert?

Gigantische Delays eingebaut?

von LCD..... (Gast)


Lesenswert?

Also das ganze wird in einem Timer aufgerufen:
1
procedure TForm1.Screen1();
2
  var data:ansistring; prozDreh,i:integer;
3
begin
4
  DisplayText(2,2,'                  '); //damit flackerts
5
  prozDreh := //von 0-100 wird berechnet und skaliert
6
  for I := 2 to 19 do
7
  begin
8
    prozDreh := prozDreh - 5;
9
    case prozDreh of
10
      1: begin ShowSonderzeichen(2,i,1);end;// DisplayText(2,i+1,'   '); end;
11
      2: begin ShowSonderzeichen(2,i,2);end;// DisplayText(2,i+1,'   '); end;
12
      3: begin ShowSonderzeichen(2,i,3);end;// DisplayText(2,i+1,'   '); end;
13
      4: begin ShowSonderzeichen(2,i,4);end;// DisplayText(2,i+1,'   '); end;
14
    end;
15
    if prozDreh<=0 then break
16
    else if prozDreh>=5 then ShowSonderzeichen(2,i,5);
17
  end;
18
  DisplayText(2,1,'[');
19
  DisplayText(2,20,']');
20
end;
Dazu noch die Routinen:
1
function showSonderzeichen(Zeile,Spalte:Integer;Sonderzeichen:Integer):Boolean;
2
  var temp:Integer; temp2:Char;
3
begin
4
  temp := 128+(Spalte-1)+(Zeile-1)*64;
5
  USB_LCD_Command(temp, 0);
6
  temp2 := Chr(Sonderzeichen-1);
7
  USB_LCD_Data(@temp2, 1, 0);
8
  result := true;
9
end;
und
1
function DisplayText(zeile,spalte:Integer;text:ansistring):Boolean;
2
  var temp:integer;
3
begin
4
  temp := 128+(Spalte-1)+(Zeile-1)*64;
5
  USB_LCD_Command(temp,0);      //1. Zeile 1.Zeichen
6
  USB_LCD_Data(PCHAR(text),length(text),0);
7
  result := true;
8
end;
Display wurde davor initialisiert. Es ist ein 20x2 Zeichendisplay. 
Hardware steht oben

von Tip (Gast)


Lesenswert?

Zum Aufbau eines neuen Balkens solltest du nur einmal DisplayText 
aufrufen.

von LCD..... (Gast)


Lesenswert?

Tip schrieb:
> Zum Aufbau eines neuen Balkens solltest du nur einmal DisplayText
> aufrufen.

wie meinen? zu beachten dass // kommentare einleitet für nicht delphi 
kenner

von Tip (Gast)


Lesenswert?

Bau doch die ganze Zeile in der Variablen "text" zusammen (incl. "[","]" 
und Sonderzeichen) und schicke das mit einem einzigen Kommando
zum Display.

USB_LCD_Data(PCHAR(text),length(text),0);

von spess53 (Gast)


Lesenswert?

Hi

>Zum Aufbau eines neuen Balkens solltest du nur einmal DisplayText
>aufrufen.

Richtig. Delphi hat wunderbare Stringfunktionen.

Könnte in etwa so aussehen (nicht getestet):

procedure TForm1.Screen1();
  var
    data:      string;
    prozDreh,i,j:integer;
begin
  prozDreh := 70;   //Testwert

  data := StringOfChar(' ',20);
  data[1]:='[';
  data[20]:='[';
  i:=prozDreh div 5;
  data := StuffString(data,1,i,StringOfChar(#5,i));
  j:= prozDreh mod 5;
  if j>0 then data[i+1]:=Char(j);
  DisplayText(2,1,data);
end;

Du musst aber StrUtils in die uses aufnehmen.

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

data[20]:='[';   ->data[20]:=']';

MfG Spess

von LCD..... (Gast)


Lesenswert?

Hallo,

danke die Lösung funktioniert um einiges schneller als meine. ;)
Ich hab aber noch ein Problem. Dieses Problem nennt sich #5. Mein 
Display kann dies nicht darstellen. Nun würde ich gerne wieder mein 
Sonderzeichen nutzen, damit es einheitlich wird. Kann ich dies anstellen 
oder welche Zeichen sind zu empfehlen?
Danke nochmal.

von spess53 (Gast)


Lesenswert?

Hi

>Dieses Problem nennt sich #5.
> Mein Display kann dies nicht darstellen.

Ich war der Meinung, das dein Sonderzeichen 5 bei dir das volle 
'Kästchen' ist. Wenn ja, dann ersetze es mal durch Char(5). Alternativ 
sollte auch Char($FF) gehen. Bei einem 44780 kompatiblen Controller ist 
das auch ein █.

MfG Spess

von Vlad T. (vlad_tepesch)


Lesenswert?

Ralli schrieb:
> 10 Wechsel pro Sekunde sind bei Standard-LCD-Displays
> eher zu viel. (Reicht aber für die visuelle Erfassung!)

aha, ich habe vor einiger Zeit eine Demo gesehen (ich glaub von der 
Breakpoint, aber ich finds nicht) wo einer auf nem Standard 16x2 Display 
irre Grafik gezeigt hat. ich glaub plasma oder so was in der Art

von LCD..... (Gast)


Lesenswert?

spess53 schrieb:
> Hi
>
>>Dieses Problem nennt sich #5.
>> Mein Display kann dies nicht darstellen.
>
> Ich war der Meinung, das dein Sonderzeichen 5 bei dir das volle
> 'Kästchen' ist. Wenn ja, dann ersetze es mal durch Char(5). Alternativ
> sollte auch Char($FF) gehen. Bei einem 44780 kompatiblen Controller ist
> das auch ein █.
>
> MfG Spess

Mein Sonderzeichen 5 sieht folgendermaßen aus:
1
00000
2
00000
3
11111
4
11111
5
11111
6
00000
7
00000
Mit Char($FF) bekomme ich ein volles Kästchen aber meiner Meinung nach 
ist dies zu groß, deswegen hab ich meine Sonderzeichen so gestaltet, 
dass ich 3 Zeilen in der Mitte hab. Dies sieht meiner Meinung nach am 
schönsten aus. Dein Code zeigt auch am Ende meine Sonderzeichen 1-4 an, 
jedoch nicht 5. Wie muss ich dies gestalten?

von LCD..... (Gast)


Lesenswert?

Hat sich erledigt. Mit ansiChar(5) hab ich mein Sonderzeichen bekommen. 
;)

von spess53 (Gast)


Lesenswert?

Hi

>Hat sich erledigt. Mit ansiChar(5) hab ich mein Sonderzeichen bekommen.
>;)

Warum nimmst du eigentlich ANSI-Strings? Für Strings <=255 Zeichen 
reichen auch Pascal-Strings. Deswegen hatte ich hier

Beitrag "Re: LCD Display Bargraph"

auch  '   data:      string;' geschrieben. Dann passt auch 'Char(5)'.

MfG Spess

von LCD..... (Gast)


Lesenswert?

ich muss das ganze data als ansistring deklarieren, da sonst das display 
den text nicht richtig ausgiebt. Ich hab delphi 2009 und da gibts dieses 
blöde unicode problem. ;)

von spess53 (Gast)


Lesenswert?

Hi

>Ich hab delphi 2009 und da gibts dieses blöde unicode problem. ;)

ANSI-String hat doch nichts mit UNI-Code zu tun. Das wäre WideString.

MfG Spess

von LCD..... (Gast)


Lesenswert?

spess53 schrieb:
> Hi
>
>>Ich hab delphi 2009 und da gibts dieses blöde unicode problem. ;)
>
> ANSI-String hat doch nichts mit UNI-Code zu tun. Das wäre WideString.
>
> MfG Spess

Ein normaler String wird hier aber zum Verhängnis, da ein Hello dann zu 
Hello. Die Funktion nimmt halt einen ANSIString und so kommt dann 
ein Hello ;

von spess53 (Gast)


Lesenswert?

Hi

Das liegt möglicherweise an deiner Komponente für die serielle 
Schnittstelle. Welches Zeichen wird denn da zwischen den Zeichen 
eingefügt?

MfG Spess

von LCD..... (Gast)


Lesenswert?

Das LCD ist ja mit dieser Hardware an USB angeschlossen:
http://www.modding-faq.de/index.php?artid=615

Da war eine USB_LCD.dll. Mit dieser kann man das LCD ansprechen und die 
Funktionen möchten halt ein ANSI-String

von Oliver J. (skriptkiddy)


Lesenswert?

LCD..... schrieb:
> Da war eine USB_LCD.dll. Mit dieser kann man das LCD ansprechen und die
> Funktionen möchten halt ein ANSI-String

So sieht es aus. Die DLL ist in C gehackt und die meisten C-Routinen 
möchten halt einen Ansi-C-String. Mit den (mal vorsichtig ausgedrückt) 
"Multi-byte-Zeichen" können auf C-String ausgelegte Funtionen nichts 
anfangen. Da bin ich auch schon mal drüber gestolpert.

Gruß Skriptkiddy

von spess53 (Gast)


Lesenswert?

Hi

> Mit den (mal vorsichtig ausgedrückt) "Multi-byte-Zeichen" können auf
>C-String ausgelegte Funtionen nichts anfangen.

Der von mir benutzte Typ 'String' ist ein Pascal-String und stammt aus 
einer Zeit, in der Multibyte-Zeichensätze noch unbekannt waren.

MfG Spess

von Oliver J. (skriptkiddy)


Lesenswert?

Ab Delphi 2009 ist ein 'String' per Definition ein Unicodestring. Wenn 
du es nicht glauben willst, dann wirf mal google oder so mal an.

von spess53 (Gast)


Lesenswert?

Hi

>Ab Delphi 2009 ist ein 'String' per Definition ein Unicodestring. Wenn
>du es nicht glauben willst, dann wirf mal google oder so mal an.

Warum soll ich das nicht glauben. Zumindest bis Turbo-Delphi trifft 
meine Aussage zu.

MfG Spess

von Matthias (Gast)


Lesenswert?

Was ist mit ShortString?

von spess53 (Gast)


Lesenswert?

Hi

>Was ist mit ShortString?

Das scheint die neue Bezeichnung für Pascal-Strings zu sein.

MfG Spess

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.