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.
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).
http://www.mikrocontroller.net/articles/Erweiterte_LCD-Ansteuerung http://www.mikrocontroller.net/wikifiles/b/b7/LCD_Tutorial.zip
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
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.
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
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
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.
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?
LCD,,,,, schrieb: > Wie habt ihr das mit den Leerzeichen gelöst? lcd_data (' '); Oder wie meinst du die Frage?
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.
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
dann gib halt immer 18 Zeichen aus, von links beginnend die vollen, dann das geteilte und den Rest Leerzeichen. Sascha
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?
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
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
@ 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
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
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?
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
Zum Aufbau eines neuen Balkens solltest du nur einmal DisplayText aufrufen.
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
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);
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
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.
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
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
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?
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
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. ;)
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
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 Hello. Die Funktion nimmt halt einen ANSIString und so kommt dann ein Hello ;
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
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
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
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
Ab Delphi 2009 ist ein 'String' per Definition ein Unicodestring. Wenn du es nicht glauben willst, dann wirf mal google oder so mal an.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.