CPU: ATMEGA328
LCD: 16x2 Zeichen
Der numerische Wert 'iTurbo10e' kann 0 bis maximal 16 haben. Dieser soll
in einer Art 'Zeichenstrahl' auf dem LCD ausgegeben werden.
Beispiele:
bei 0:
----------------
bei 1:
*---------------
bei 5:
*****-----------
bei 16:
****************
Hierfür der Code:
Philipp G. schrieb:> Kommt jemandem etwas performanteres hin?
zuerst
strTmpLCDLine2 = "----------------";
und dann die '*', wenn welche gezeichnet werden müssen.
... schrieb:> strTmpLCDLine2 = "----------------";> for (int i = 0; i < iTurbo10e; i++)> {> strTmpLCDLine2[i] = "*";> }
Hach, dabei ist es doch so einfach. Danke jungs.
hilfesteller schrieb:> // Mit der Annahme, dass strTmpLCDLine2 ein Array ist mit mindestens 17> bytes>> int i = 0;> for(; i < iTurbo10e; i++) {> strTmpLCDLine2[i] = '*';> }> for(; i < 16; i++) {> strTmpLCDLine2[i] = '-';> }> strTmpLCDLine2[i] = 0;
Dabei sind es aber zwei Loops, Begründung warum das performanter ist als
die beiden Vorredner?
Wenn dir 16 Zeichen als Auflösung reichen, bist du fertig. Ich habe mir
mal Blöcke mit einem bis 6 vertikalen Linien als Sonderzeichen
definiert, um dann innerhalb eines Zeichens noch 5 Unterabstufungen zu
machen.
Matthias S. schrieb:> Wenn dir 16 Zeichen als Auflösung reichen, bist du fertig. Ich habe mir> mal Blöcke mit einem bis 6 vertikalen Linien als Sonderzeichen> definiert, um dann innerhalb eines Zeichens noch 5 Unterabstufungen zu> machen.
Ist eigentlich eine gute Idee von Dir. Denn das Display lässt 8
Sonderzeichen programmieren.
Ich möchte also 4 Blöcke programmieren.
1) 1/4 Block
2) 1/2 Block
3) 3/4 Block
4) Full Block
Damit komme ich auf eine Auflösung von 64.
Nur weiss ich jetzt nicht, ob ich mit Arduino Mitteln das hinbekomme.
Anbei das DB:
https://cdn-reichelt.de/documents/datenblatt/A500/DS_DIP162.pdf
Jemand eine Idee hierzu? -> CG RAM Address Set
Philipp G. schrieb:> Dabei sind es aber zwei Loops, Begründung warum das performanter ist als> die beiden Vorredner?
Zwei Loops kosten ja erstmal nicht mehr. Außerdem wird i im zweiten Loop
auch nicht nochmal initialisiert.
Das Array wird nicht unnötig mit - beschrieben und dann mit *
überschrieben.
Wenn man die Performance wirklich bewerten will, dann sollte man die
verschiedenen Arten nach der optimierten Übersetzung im Assembler
anschauen.
Philipp G. schrieb:> Matthias S. schrieb:>> Wenn dir 16 Zeichen als Auflösung reichen, bist du fertig. Ich habe mir>> mal Blöcke mit einem bis 6 vertikalen Linien als Sonderzeichen>> definiert, um dann innerhalb eines Zeichens noch 5 Unterabstufungen zu>> machen.>> Ist eigentlich eine gute Idee von Dir. Denn das Display lässt 8> Sonderzeichen programmieren.>> Ich möchte also 4 Blöcke programmieren.>> 1) 1/4 Block> 2) 1/2 Block> 3) 3/4 Block> 4) Full Block
Hier sind zwei Vorschläge für die gleichzeitige Darstellung von 2 bzw. 4
Balkendiagrammen mit einem Wertebereich von 0–64 bzw. 0–32 in einer
Form, die die Abstände zwischen den einzelnen Zeichen des Textdisplays
und damit dessen 16×2-Natur etwas kaschiert.
Unter den Beispielen sind die jeweils benötigten Zeichenmuster gezeigt.
Das jeweils erste braucht natürlich nicht neudefiniert zu werden, da es
als Leerzeichen schon existiert.
M.K. B. schrieb:> Philipp G. schrieb:>> Dabei sind es aber zwei Loops, Begründung warum das performanter ist als>> die beiden Vorredner?>> Zwei Loops kosten ja erstmal nicht mehr. Außerdem wird i im zweiten Loop> auch nicht nochmal initialisiert.
Und in der anderen Variante gibt's auch eine zweite Schleife, nämlich
die, die das Array mit den Minussen ausfüllt. Und da muss diese
Schleife immer alle Elemente beschreiben und nicht nur die, in denen
tatsächlich am Ende ein Minus stehen soll.
Philipp G. schrieb:> Nur weiss ich jetzt nicht, ob ich mit Arduino Mitteln das hinbekomme.
Ich habe das damals in ASM51 gemacht, aber das Prinzip war einfach.
Ausgabewert durch 6 teilen, weil mein Display ein 6*8 Pixel/Letter war.
Das Ganzzahlergebnis als Anzahl der Vollblöcke aufs Display schicken und
der Rest der Division war die Nummer des Sonderzeichens. Also 0 für
keinen vertikalen Strich, 1 für einen Strich usw. Die Sonderbehandlung
des Leerzeichens habe ich mir m.E. damals gespart.
Die Sonderzeichen sahen genauso aus, wie Yalu im seinem Beitrag im
linken Bild illustriert.
Matthias S. schrieb:> Ich habe das damals in ASM51 gemacht, aber das Prinzip war einfach.> Ausgabewert durch 6 teilen, weil mein Display ein 6*8 Pixel/Letter war.> Das Ganzzahlergebnis als Anzahl der Vollblöcke aufs Display schicken und
Ja, das ist schon klar, aber ich muss meinem Display ja erst die
Sonderzeichen beibringen. Frage ist halt ob ich das mit Arduino Mitteln
hinbekomme.
Philipp G. schrieb:> Frage ist halt ob ich das mit Arduino Mitteln> hinbekomme.
Mit Arduino Libraries kenne ich mich nicht aus, aber in purem AVR-GCC
ist das einfach - wobei ich schon lange keine LCD Routinen mehr selber
mache, sondern Peter Fleury den Job überlassen habe. Seine LCD
Funktionen sind einfach, anpassbar und idotensicher.
http://homepage.hispeed.ch/peterfleury/avr-software.html
Hier ist es dann die Funktion 'lcd_data()', mit der man den CG RAM
befüllt.
Philipp G. schrieb:> Ja, das ist schon klar, aber ich muss meinem Display ja erst die> Sonderzeichen beibringen. Frage ist halt ob ich das mit Arduino Mitteln> hinbekomme.
Ich könnte die 100m in 8 Sekunden laufen aber ich weiß nicht ob ich das
mit meinen Turnschuhen hinbekomme.
Will sagen:
Wenn man nicht Schwimmen kann ist seltenst die Badehose schuld.
Also schieb deine Unfähigkeit nicht auf deine falsche Entschiedung
Arduino zu verwenden, sondern arbeite daran.
Hallo Philiph,
nur als Denkanstoß: ich habe die Bargraph Funktion nur mit einem
Sonderzeichen realisiert. Man positioniert den Sonderzeichen und füllt
den Inhalt zur Laufzeit dem Wert entsprechend: 0x10 für einen vertikalen
Balken, 0x18 für 2, 0x1C für drei, 0x1E für 4 (natürlich das alles 8 mal
damit das Symbol die volle Höhe erreicht) und für 5 Balken (Zeichen
voll) nehme ich den Zeichencode 0xFF. Vorteil: du kannst die anderen
Sonderzeichen für andere Zwecke nutzen. Der Bargrahp selbst hat Lücken
zwischen einzelnen Zeichen (zwischen 5 und 6 , 10 und 11, usw.) aber
das ist Display bedingt.
Ozvald K. schrieb:> nur als Denkanstoß: ich habe die Bargraph Funktion nur mit einem> Sonderzeichen realisiert. Man positioniert den Sonderzeichen und füllt> den Inhalt zur Laufzeit dem Wert entsprechend: 0x10 für einen vertikalen> Balken, 0x18 für 2, 0x1C für drei, 0x1E für 4 (natürlich das alles 8 mal> damit das Symbol die volle Höhe erreicht) und für 5 Balken (Zeichen
Gute Idee, ich habe eben bemerkt, ich kann sogar jedes einzelne Pixel
frei definieren, könnte sogar eine Graphik hinterlegen.
Danke für den Tipp, so mach ichs.
Ok, das funktioniert. Ich habe 5 Zeichen definiert, Zeichen 0 entspricht
einem Balken, 1 entspricht 2 Balken, etc.
Ab jetzt wird es ein bisschen tricky.
-> (Max vertikale Balken = 5 * 16 = 80)
Wenn ich die 40 schreibe, ist der Balken in der Mitte. Schreibe ich dann
eine 21, löscht mein Code die gesamte Zeile und schreibt den Balken
entsprechend der 21.
Jetzt wäre natürlich viel schöner, er würde die 20 stehen lassen, den
Rest löschen und nur einen Balken mehr schreiben.
Beispiel:
Wert = 40
Bar = 5 Balken * 8 Digits sind ausgefüllt, Rest leer.
Neuer Wert = 21
Bar = 1 Balken, 2 Digits sind ausgefüllt, Rest leer
Hierzu muss er also 6 Digits löschen, und dann nur ein Balken schreiben.
Anbei bei Code:
1
voidloop()
2
{
3
intiCursor=0;
4
intiBarC=0;
5
iRandom=random(0,80);// generate a random number
6
// byte(0) = |
7
// byte(1) = ||
8
// byte(2) = |||
9
// byte(2) = ||||
10
// byte(4) = |||||
11
12
for(inti=0;i<=iRandom;i++)
13
{
14
if(i>=(iCursor+1)*5)
15
{
16
iCursor=iCursor+1;
17
iBarC=0;
18
}
19
LCD.setCursor(iCursor,0);
20
LCD.write(byte(iBarC));
21
iBarC=iBarC+1;
22
}
23
24
delay(300);
25
LCD.clear();
26
}
Das muss dann natürlich in beide Richtungen funktionieren. Oder meint
ihr, das ist unnötig?
Philipp G. schrieb:> Neuer Wert = 21> Bar = 1 Balken, 2 Digits sind ausgefüllt, Rest leer
4 Digits sind ausgefüllt und 1 Balken
Philipp G. schrieb:> Jetzt wäre natürlich viel schöner,
Geschmacksache. Dazu müsstest du den letzten Wert merken und den
Unterschied zu neuem Wert ausrechnen. Ich habe es folgendermaßen
realisiert: Wert = 21 ->
21/5= 4 volle Zeichen, 1 Rest ist Anzahl der Balken im Sonderzeichen.
Leerzeichen = 16 - volle Digits - Sonderzeichen wenn gebraucht wird (bei
0 Rest nicht) Die Routine geht immer komplett durch und füllt alle 16
Stellen. Es mag jetzt nicht so high sophisticated erscheinen, aber wenn
der µC nicht ausgelastet ist, dann ist es egal, du merkst den
Unterschied nicht was die Geschwindigkeit angeht.
Umso mehr Logik, desto mehr Speicher wird benötigt. Bei ATMEGA328 gibt
es eh genug davon, aber bei mir läuft es auf TINY13 und musste ich mit
Flash sparsam umgehen. Die viele "wenn, dann..."-s brauchen mehr
Speicher und am Ende sieht nicht besser aus.
Ozvald K. schrieb:>> Bar = 1 Balken, 2 Digits sind ausgefüllt, Rest leer>> 4 Digits sind ausgefüllt und 1 Balken
Ja. Stimmt.
Ozvald K. schrieb:> Ich habe es folgendermaßen> realisiert: Wert = 21 ->
Hättest Du Lust, diesen zu teilen?
Philipp G. schrieb:> Das muss dann natürlich in beide Richtungen funktionieren. Oder meint> ihr, das ist unnötig?
ob das nötig ist hängt davon ab was der Controller sonst noch mach. Der
entstehende Geschwindigkeitsgewinn bringt dir fürs Display nichts da das
eh nicht so schnell in der Darstellung ist.
Sascha
Philipp G. schrieb:> Hättest Du Lust, diesen zu teilen?
Ich habe es in Assembler realisiert, ob du damit Freude haben willst?
:-)
Deswegen "nur" die Beschreibung aber kein Code hier
Ozvald K. schrieb:> Philipp G. schrieb:> Hättest Du Lust, diesen zu teilen?>> Ich habe es in Assembler realisiert, ob du damit Freude haben willst?> :-)> Deswegen "nur" die Beschreibung aber kein Code hier
Nein, bitte nicht, davon bekomme ich Kopfschmerzen.
Aber cool dass du sowas in ASM hinbekommst.