PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Balkendarstellung auf LCD



meldano
14.07.2007, 03:41
Hi,

ich möchte gerne einen Messwert als Balken auf einem LCD anzeigen.
Bei einem 16 stelligen LCD habe ich ja 16 Zeichen. Jetzt habe ich mir ein Sonderzeichen erstellt, welches ein Zeichenfeld komplett ausfüllt.
Dazu folgender Code:



For Z=1 to Messwert
Locate 1,Z
LCD Chr (0)
Next


So wird der Balken auch sauber ausgegeben =D>

Doch würde ich die Auflösung gerne Verdoppeln. D.h. zwei Sonderzeichen bilden. Eins den linken und den rechten Teil schwarz. Und ein Sonderzeichen nur den rechten Teil schwarz.
Ich habe eine absolute Denksperre wie ich die Anforderung in einen sinnvollen Code umsetze.

Hat jemand einen Tip?

Danke
Daniel

darwin.nuernberg
14.07.2007, 08:38
Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Portc.7 , Rs = Portc.6
Config Lcd = 16 * 2

Deflcdchar 0 , 31 , 31 , 31 , 31 , 31 , 31 , 31 , 31 ' Volles Segment definieren als chr(0)
Deflcdchar 1 , 24 , 24 , 24 , 24 , 28 , 28 , 28 , 28 ' halbes Segment definieren als chr(1)

Initlcd

'Hauptprogramm

Dim X As Byte

Cls
Locate 1 , 1 ' Pos. in 1. Zeile an 1. Stelle
Lcd "Bargraph" ' Text auf das LCD Schreiben

For X = 1 To 16 ' von 1 bis 16 zählen
Locate 2 , X ' Pos. Cursor in Zeile 2 an Spalte X
Lcd Chr(1) ' Schreibe halbe Segment
Waitms 200 ' ein bisschen warten
Locate 2 , X ' Pos. Cursor in Zeile 2 an Spalte X
Lcd Chr(0) ' Schreibe ganzes Segment (über das halbe)
Waitms 200 ' ein bisschen warten
Next X ' Weiter


End 'end program

darwin.nuernberg
14.07.2007, 11:14
Ich hab nochmal ein anderes Beispiel geschrieben, diesmal auch mit halben Segment:


Ich gehe mal davon aus dass Du die ADC-Werte ausgeben möchtest, also eine 10-Bit Auflösung, ansonsten musst Du eben anpassen.


Die Zeichen müssen allerdings anders definiert werden als im vorherigen Beispiel:
Zeichen 7 = volles Segment
Zeichen 6 = halbes Segment
da der String-Befehl mit dem Zeichen 0 nichts macht.

Meine Funktion Bargraph wird aufgerufen, welche einen String erzeugt (eben mit den chr(7) und/oder dem chr(6))
1. Parameter ist der Messwert (ohne Prüfung des Maximalwertes)
2. Parameter 0 oder 1 gibt als Print zusätzliche infos iber RS232 aus oder eben nicht (debugging).


Sicherlich könnte man das ganze noch optimierter schreiben,
aber es erfüllt seinen Zweck.

Hier das Teil:




'-----------------------------------------------------------------------------------------
'name : LCD-Interface Messwert Darstellung.bas
'purpose : TEST: LCD 16 Chars, 2 Lines Bargraph Output
'micro : Mega32
'suited for demo : yes
'commercial addon needed : no
'programmer : darwin.nuernberg (www.roboternetz.de)
'-----------------------------------------------------------------------------------------

$regfile = "m32def.dat" ' specify the used micro
$crystal = 8000000 ' used crystal frequency
$baud = 9600 ' use baud rate
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space




' Die folgende Zeile entfernen wenn das Programm NICHT im Simulator laufen soll
$sim ' entfernen wenn keine BASCOM Simulation
' ================================================== ============================




Definitionen:
Declare Function Bargraph(byval Messwert As Word , Byval Verbose As Byte) As String ' Messwert = eine ADC-Variable


' LCD einrichten
Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Portc.7 , Rs = Portc.6 ' $sim is used for faster simulation
Deflcdchar 7 , 31 , 31 , 31 , 31 , 31 , 31 , 31 , 31 ' Volles Segment
Deflcdchar 6 , 24 , 24 , 24 , 24 , 28 , 28 , 28 , 28 ' halbes Segment
Config Lcd = 16 * 2
Initlcd

' ================================================== ============================


Hauptprogramm:

Dim Mw As Word ' Messert (0-255)
Dim X As Word

Cls ' LCD Löschen

For X = 0 To 1024
Locate 1 , 1
Lcd "Testwert = " ; X
Locate 2 , 1
Lcd Bargraph(x , 0)
Next X
Waitms 500

Do

Input "Messwert = " , Mw ' Zum Testen Eingabe erfordelich
Cls ' LCD Löschen
Locate 1 , 1 ' Pos. in 1. Zeile an 1. Stelle
Lcd "BARGRAPH" ' Text auf das LCD Schreiben

Locate 2 , 1
Lcd Bargraph(mw , 0) ' 2. Parameter = 0 keine Printausgaben

Loop
End 'end program

' ================================================== ============================

Function Bargraph(byval Messwert As Word , Byval Verbose As Byte) As String ' Messwert = eine 10-Bit-Variable

Local W_zeichenlaenge As Word
Local W_maxmesswert As Word
Local W_valueganzessegment As Word
Local W_valuehalbessegment As Word
Local W_anzahlzeichen As Word
Local W_anzahlhalbzeichen As Word
Local W_habzeichenvorhanden As Word

Bargraph = ""

If Messwert >= 1 Then
W_zeichenlaenge = 16 ' Zeichenlänge des Bargraph
W_maxmesswert = 1024 ' Maximaler Wert (10 Bit)
W_valueganzessegment = W_maxmesswert / W_zeichenlaenge
W_valuehalbessegment = W_valueganzessegment / 2

W_anzahlhalbzeichen = Messwert / W_valuehalbessegment
W_anzahlzeichen = W_anzahlhalbzeichen / 2
W_habzeichenvorhanden = W_anzahlhalbzeichen Mod W_anzahlzeichen

If Verbose > 0 Then ' Nur Ausgabe wenn > 0
Print "Zeichen für Bargraph = " ; W_zeichenlaenge
Print "Maximaler Wert = " ; W_maxmesswert
Print "Angezeigter Messwert = " ; Messwert
Print "Wert pro Segment = " ; W_valueganzessegment
Print "Wert pro halb Segment = " ; W_valuehalbessegment
Print "Anzahl Bargraph = " ; W_anzahlzeichen
Print "Halbes Zeichen = " ; W_habzeichenvorhanden
End If


If W_anzahlzeichen > 0 Then ' Nur wenn ganze Zeichen ausgegeben werden sollen
Bargraph = String(w_anzahlzeichen , 7)
Else
Bargraph = ""
End If

If W_habzeichenvorhanden > 0 Then
Bargraph = Bargraph + Chr(6)
End If

End If

End Function
End

darwin.nuernberg
14.07.2007, 13:24
Hier ein Beispiel mit noch feinerer Auflösung:

Es werden 5 Benutzerdefinierte Zeichen benötigt,

Die Auflösung von einer Pixelspalte ist nun möglich (Zeichen = 5 Pixel Breit)

Bei Wert = 0 wird kein Balken angezeigt,
ab Wert = 1 wird bereits ein Balken angezeigt.



'-----------------------------------------------------------------------------------------
'name : LCD-Interface Messwert Darstellung.bas
'purpose : TEST: LCD 16 Chars, 2 Lines / Bargraph Output
'micro : Mega32
'suited for demo : yes
'commercial addon needed : no
'programmer : darwin.nuernberg (www.roboternetz.de)
'-----------------------------------------------------------------------------------------

$regfile = "m32def.dat" ' specify the used micro
$crystal = 8000000 ' used crystal frequency
$baud = 9600 ' use baud rate
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space




' Die folgende Zeile entfernen wenn das Programm NICHT im Simulator laufen soll
$sim ' entfernen wenn keine BASCOM Simulation
' ================================================== ============================




Definitionen:
Declare Function Finebargraph(byval Messwert As Word , Byval Verbose As Byte) As String ' Messwert = eine 10-Bit-Variable


' LCD einrichten
Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Portc.7 , Rs = Portc.6 ' $sim is used for faster simulation
Deflcdchar 7 , 31 , 31 , 31 , 31 , 31 , 31 , 31 , 31 ' Volles Segment
Deflcdchar 6 , 30 , 30 , 30 , 30 , 30 , 30 , 30 , 30 ' 4 Spalten
Deflcdchar 5 , 28 , 28 , 28 , 28 , 28 , 28 , 28 , 28 ' 3 Spalten
Deflcdchar 4 , 24 , 24 , 24 , 24 , 24 , 24 , 24 , 24 ' 2 Spalten
Deflcdchar 3 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16 ' 1 Spalte

Config Lcd = 16 * 2
Initlcd

' ================================================== ============================


Hauptprogramm:

Dim Mw As Word ' Messwert
Dim X As Word

Cls ' LCD löschen

For X = 0 To 1024 Step 12
Locate 1 , 1
Lcd " WERT " ; X
Locate 2 , 1
Lcd Finebargraph(x , 0)
Lcd "<"

Next X
Waitms 500

Do

Input " Messwert eingeben : " , Mw ' Eingabe zum Testen
Cls ' LCD löschen
Locate 1 , 1 ' Pos. in 1. Zeile an 1. Stelle
Lcd "BARGRAPH" ' Text auf das LCD Schreiben

Locate 2 , 1
Lcd Finebargraph(mw , 1) ' 2. Parameter = 0 keine Printausgaben
Lcd "<"

Loop
End 'end program

' ================================================== ============================

Function Finebargraph(byval Messwert As Word , Byval Verbose As Byte) As String * 17 ' Messwert = eine 10-Bit-Variable

Const Rows_in_bargraphline = 16 ' Zeichenlänge des Ausgabe - Strings (Chars)
Const Rows_per_bargraphchar = 5 ' Pixelspalten pro Zeichen (Sonderzeichen)
Const Bargraphmaxvalue = 1024 ' Maximaler Wert

Local Finebargraphresolution As Word ' feinste Auflösung
Local Roughbargraphresolution As Word ' Auflösung 1 Volles Zeichen
Local Countbargraphfullchar As Word ' Anzahl Vollzeichen
Local Bargraphrest As Word ' Rest welcher nicht als Vollzeichen dargestellt wird
Local Bargraphfinechar As String * 1 ' Char - für feinauflösung
Finebargraphresolution = Rows_in_bargraphline * Rows_per_bargraphchar
Finebargraphresolution = Bargraphmaxvalue / Finebargraphresolution

Roughbargraphresolution = Bargraphmaxvalue / Rows_in_bargraphline


Countbargraphfullchar = Messwert / Roughbargraphresolution ' Anzahl ganzer Segmente
Bargraphrest = Messwert Mod Roughbargraphresolution ' Restwert



Select Case Bargraphrest
Case 0 : Bargraphfinechar = Chr(32) ' Zur Darstellung des Restwertes
Case Is <= 12 : Bargraphfinechar = Chr(3)
Case Is <= 24 : Bargraphfinechar = Chr(4)
Case Is <= 36 : Bargraphfinechar = Chr(5)
Case Is <= 48 : Bargraphfinechar = Chr(6)
Case Is <= 60 : Bargraphfinechar = Chr(7)
Case Else : Bargraphfinechar = "" ' nichts weiter
End Select


If Verbose > 0 Then
Print " Maximalwert = " ; Bargraphmaxvalue ' Maximal darstellbarer Wert
Print " grobe Aufloesung = " ; Roughbargraphresolution ' grobe Auflösung (1-Zeichen)
Print " feinste Aufloesung = " ; Finebargraphresolution ' feine Auflösung (1 Pixelspalte)
Print " Anzahl ganzer Seg. = " ; Countbargraphfullchar ' Anzahl der "Vollzeichen"
Print " Rest des Wertes = " ; Bargraphrest ' verbleibender Wert für Feindarstellung
Print
End If


If Countbargraphfullchar > 0 Then
Finebargraph = String(countbargraphfullchar , 7) + Bargraphfinechar
Else
Finebargraph = Bargraphfinechar
End If
Finebargraph = Trim(finebargraph)

End Function

End 'end program

meldano
14.07.2007, 16:21
Hi,

danke für die Infos!

Muss mich mal reinlesen.

Daniel

darwin.nuernberg
14.07.2007, 21:54
Nimm aus dem letzten Beispiel die beiden Zeilen

Lcd "<"
raus, dann funktioniert (in der Simulation) die Darstellung besser.

PS: Die Funktion kann auch einfach an breitere/schmälere Displays angepasst werden, nur 2 Paramter sind zu ändern:


Function Finebargraph(byval Messwert As Word , Byval Verbose As Byte) As String * 17 ' Messwert = eine 10-Bit-Variable
Const Rows_in_bargraphline = 16

darwin.nuernberg
19.07.2007, 17:44
Hallo meldano,
was ist jetzt mit dem Proggi für den LCD-Bargraph????

Funktioniert es so wie Du es Dir vorgestellt hast,
ist etwas brauchbares für Dich dabei gewesen,
oder hast Du keinen gefallen mehr an Deiner Idee?

Poste doch mal was...
Wnn ich mir schon die mühe gemacht habe, will ich auch wissen ob sie sich gelohnt hat.
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=298727#298727

meldano
19.07.2007, 20:14
Hi,

die Idee wird schon noch umgesetzt. Da aber die letzten Tage zu kurz waren um mich anständig damit auseinander zu setzen, ist leider noch nicht viel geschehen.

Mein Messwert ist ein 7-Bit breites Signal an einem Pin Register. D.h. 0...127.
Der Controller ist ein Tiny2313. Die ganze Sache muss mit möglichst wenig Code auskommen da der Tiny nur 2k Flash hat.

Da ich noch Anfänger bin, kann ich im Moment aber noch nichts mit deinen Beispielen anfangen.
Z.B.

Function Finebargraph(byval Messwert As Word , Byval Verbose As Byte) As String * 17


und


Local Bargraphfinechar As String * 1

sagt mir noch gar nichts da ich noch nicht mit diesen Funktionen gearbeitet habe.

Ein Ergebnis poste ich auf jeden Fall, da ich ja selber immer die Suche nutze um evt. auftretetene Probleme zu lösen.

Guß
Daniel

P.S. Vielleicht erklärst du mir ja mal die "Funktionsgeschichte".

darwin.nuernberg
19.07.2007, 20:30
Sind ja auch keine fertigen sondern eben selbst programmiert.

Eine Funktion ist ein Unterprogramm oder auch Sub genannt, welches ein Ergebniss zurückliefert. In meinem Falle eben einen String (Zeichenfolge)

Der Funktion wird ein Wert übermittelt und gibt einen String zurück.
In diesem Fall eben die Sonderzeichen, welche im LCD definiert wurden.

String = Funktion(Variable1,Variable2)
wobei Variable1Dein Messwert ist und Variable2 einfach eine Zusatzinfoausgabe anregt oder nicht.

Und Local ist genau sowas wie ein DIM allerdings nur in Unterprogrammen oder Functions zu verwenden und auch nur dort gültig (vom Rest nicht sichtbare Variablen)

In diesem Fall ein String mit der Länge von 1 Zeichen


Aber ich merk schon, Du bist noch nicht so Fit mit Basic, macht aber nix, ich denke das ist genau die richige Herausforderung zum lernen.

Viel spass noch

whynot
08.07.2008, 10:17
Hallo,
hat mich auch interesiert, trotz null Erfahrung (2 Tage) habe ich da mal was gebastelt.
Im Simulator geht es ziemlich gut, muss mein LCD noch umbauen. Hängt an PortC alle ADCs wech.

Vieleicht hilft das ja.


' Nur im Simulator getestet,ADC Port 5.
' Die Ungleichmäsige Balkenverteilung sollte am Simulator liegen.
' Wenn die Variabelen nicht perfekt Dimensioniert sind,
' mögen man mir vergeben. Mein erster Atmel läuft seit 2 Tagen.
' Für 20 Zeichen Display gemacht sollte mit anpassung auch für andere gehen.
' Werte halt anpassen
' Vereinfachung und verbesserung werden immer gern angenommen.

' whynot '


$regfile = "M8def.dat"
$crystal = 8000000
$baud = 9200
$hwstack = 32
$swstack = 10
$framesize = 40

$sim '!!! vor dem Programmieren rausnehmen !!!

Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5

Config Lcd = 20 * 4
Deflcdchar 1 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 16
Deflcdchar 2 , 20 , 20 , 20 , 20 , 20 , 20 , 20 , 20
Deflcdchar 3 , 21 , 21 , 21 , 21 , 21 , 21 , 21 , 21

Dim C As Integer
Dim B As Integer
Dim A As Integer
Dim W As Integer
Dim B1 As Integer
Dim H As Integer

Cls

Do
A = Getadc(5) / 17 ' dieser wert soll 1/3 von dem darunter sein.
W = Getadc(5) / 52 ' der wert mus aufgerundet werden von der rechnung max messwert/zeichenzahl
B = 3 * W
C = A - B
H = 19 - W ' der Wert = zeichenzahl-1
If W > 0 Then Lcd String(w , 3) ;
Lcd String(1 , C ) ;
If W < 19 Then Lcd String(h , 32) ' der Wert = zeichenzahl-1
Home Upperline
Loop

End

Gruss Achim