int nach 'Bar graphic' konvertieren

OP #5742174
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:
1
    if (iTurbo10e > 0)
2
        {
3
            for (int i = 0; i < iTurbo10e; i++)
4
                {
5
                strTmp = strTmp + "*";
6
                }
7
            for (int i = iTurbo10e; i <= 16; i++)
8
            {
9
              strTmp = strTmp + "-";
10
            }
11
            strTmpLCDLine2 = strTmp;
12
        }
13
      else
14
        {
15
          strTmpLCDLine2 = "----------------";
16
        }
17
  break;

Kommt jemandem etwas performanteres hin?
Gast
1
// Mit der Annahme, dass strTmpLCDLine2 ein Array ist mit mindestens 17 bytes
2

3
int i = 0;
4
for(; i < iTurbo10e; i++) {
5
  strTmpLCDLine2[i] = '*';
6
}
7
for(; i < 16; i++) {
8
  strTmpLCDLine2[i] = '-';
9
}
10
strTmpLCDLine2[i] = 0;
OP
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?
OP
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.
Moderator
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.
Angehängte Dateien:
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.
(Firma: matzetronics)
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.
OP
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.
(Firma: matzetronics)
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.
Gast
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.
OP
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.
OP
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
void loop()
2
{
3
    int iCursor = 0;
4
  int iBarC = 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 (int i = 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?
Gast
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 7 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.