LCD Menü

foley

Neues Mitglied
06. März 2008
51
0
0
Sprachen
Hallo,

wollte mir gerade ein kleines Menü erstellen und schon scheitert es wieder. :eek:

erstmal der code:


Code:
'Definition für Mega 8
$regfile "m8def.dat"

'Angabe der Taktfrequenz (1Mhz)
$crystal = 1000000

'======================================================
'Konfigurationen
'======================================================
Config Portc.0 = Input
Config Portc.1 = Input

'======================================================
'Deklarationen
'======================================================
'
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Cursor Off
Cls
'======================================================
'Initialisierungen
'======================================================
Portc.0 = 1
Portc.1 = 1
'======================================================
'Hauptprogramm-Schleife
'======================================================
Cursor Off
Cls

Do

If Pinc.0 = 0 Then


      Locate 1 , 1
      Lcd "Start"
      Lowerline
      Lcd "An nach"
      End If

If Pinc.1 = 0 Then


      Locate 1 , 1
      Lcd "Ende"
      Lowerline
      Lcd "Aus nach"
      End If

Loop


End

folgende Probleme:

Beim Umschalten bleibt leider ein Buchstabe stehen, (An nachh).

Und ich möchte jeweils noch eine Variable hinter den Punkten haben. z.B.

Start 20
An nach 50

leider bekomme ich die Variable nicht vernünftig untergebracht.

Wäre super wenn jemand ne idee hätte.

Danke schonmal im Vorraus.

Gruss Alex
 
Hallo Alex,

Problem 1: "An nachh"
Ist doch ganz einfach. Bau mal ein CLS ein und lösche das LCD-Display bevor Du was neues ausgiebst und Du wirst sehen, dann ist auch das doppelte h weg.
Was passiert: Du gibst Zeilenweise Strings auf dem Display aus. Gut, kann man machen, aber woher soll das Dipslay wissen wann "überflüssige" Zeichen gelööscht werden sollen.
Du hast zwei String:

Lcd "An nach"
Lcd "Aus nach"

und

Lcd "Start"
Lcd "Ende"

In beiden Fällen ist der eine String um ein Zeichengrößer als der andere String. Du schribst die Strings immer an der gleichen Stelle aufs Display und dann bleibt eben der Rest stehen. Verstanden?

Was kannst Du machen:
- Also entweder mit CLS vor jeder neuen Ausgabe das LCD löschen oder ein Leerzeichen in den kürzeren String anhängen.


Problem 2: Variablen auf dem Display.
Das ist auch kein Problem. Hier verwendest Du den LCD Befehl genau so wie den Print Befehl. Strings die ausgegebenw erden sollen stehen in Anführungszeichen. Mehrere Elemente trennt man durch Semikolon und Variablen kann man direkt hinzufügen.

Beispiel:

Code:
Dim A as Byte
A = 20
LCD "Testtext : " ; A

Du kannst auch andere Zahlenformate direkt mit angeben.
Beispiel:

Code:
Dim A as Byte
A = 20
LCD "Testtext : " ; BIN(A)  ' Ausgabe in Binärschreibweise
LCD "Testtext : " ; HEX(A)  ' Ausgabe in Hexschreibweise


Die BASCOM Hilfe sagt dazu folgendes:

More variables can be displayed separated by the ; -sign
LCD a ; b1 ; "constant"
The LCD statement behaves just like the PRINT statement. So SPC() can be used too.

The only difference with PRINT is that no CR+LF is added when you send data to the LCD.


Grüße,
Markus
 
Hey Thomas, ätsch, ich war schneller :) :D :p ;) :rolleyes:

Grüße,
Markus
 
Danke erstmal,

leider funktioniert meine Bacom Hilfe nicht wirklich, vielleicht liegt es daran das es eine Demo ist, na ja egal.

Irgendwie funktioniert das hier auch ein wenig anders als mein letztes Steckenpferd (step7). :eek:

Egal.

noch eine frage: wieso zählt er mir die Variable Zaehler nicht hoch::confused:
Code:
Definition für Mega 8
$regfile "m8def.dat"

'Angabe der Taktfrequenz (1Mhz)
$crystal = 1000000


Config Portc.0 = Input
Config Portc.1 = Input
Config Portc.2 = Input

Dim Zaehler As Word
Zaehler = 0

'Portc.0 = 1
'Portc.1 = 1
'Portc.2 = 1

Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Cursor Off
Cls


Do

If Portc.0 = 1 Then
   Zaehler = Zaehler + 1
   Wait 1
End If




If Zaehler = 0 Then
   Locate 1 , 1
   Lcd "schleife 1"
End If

If Zaehler = 1 Then
   Locate 1 , 1
   Lcd "schleife 2"
End If

If Zaehler = 2 Then
   Locate 1 , 1
   Lcd "schleife 3"
End If

If Zaehler = 3 Then
   Zaehler = 0
End If


Loop

End

Entweder habe ich heute ein Brett vorm Kopf oder es nicht nicht mein Tag.

Danke schonmal

Gruss Alex
 
Guten Abend Alex,

so aus dem Bauch heraus würde ich sagen, dass Du auf das falsche Register zugreifst.

Probiers mal mit

Code:
Config Pinc.0 = Input
Config Pinc.1 = Input
Config Pinc.2 = Input

anstelle von

Code:
Config Portc.0 = Input
Config Portc.1 = Input
Config Portc.2 = Input

Verwende auch bei der Abfrage nicht Port sondern Pin, also

Code:
If Pinc.0 = 1
....

Noch ein anderen Hinweis:

Wenn Du Anstelle von den ganzen If blablabla EndIf einen schönen Select aufbaus dann wird das ganze übersichtlicher und die Lösung ist eleganter:

Code:
Select Case Zaehler
     Case 0:
         bla bla bla
         bla bla bla
     Case 1:
         bla bla bla
         bla bla bla
     Case 2:
         bla bla bla
         bla bla bla
End Select

Solch ein Select Case Konstrukt lässt sich übrigens auch auf PIN's von Eingängen anwenden. Dazu solltest Du Dir aber die Hilfe von BASCOM ansehen.

Wenn in Deinem Fall die BASCOM-Hilfe nicht funktioniert so rate ich Dir das über 700 Seiten große Tutorial auf dem MCS-Hompage zu laden. Das ist ein PDF und in diesem Dokument ist wirklich alles zu jedem Befehl eingehend mit Beispielcodes beschrieben. Ist sinnvoll und garantiert keien verlorene Zeit!

Das Ding ist 16MByte groß und wirklich gut. Hier der Link:

http://www.mcselec.com/index.php?option=com_docman&task=doc_download&gid=140&Itemid=54

Grüße,
Markus
 
juppi,

Danke für den letzten Beitrag.

das hat doch mal richtig geholfen,
nebenbei hab ich dann auch mal bemerkt das Eingänge gegen GND geschaltet werden. :eek:

Langsam fängt es an interessant zu werden.

Jetzt muss ich mir nur mal durch den kopf gehen lassen wie ich 230V Verbraucher damit schalten kann. :D

Aber eins nach dem anderen.

Erstmal vielen Dank an der Stelle.

Gruss Alex
 
Hallo Alex,

freut mich, wenn Dir weiter geholfen werden konnte :p

Wenn Du 230V-Dampf schalten möchtest so würde ich dies erstmal mit Relais lösen. Wenn Dir zum Basteln auch gleichzeitig 12V zur Verfügung stehen so kannst Du Dir mal meine Lösung unter:

http://www.avr-praxis.de/forum/showthread.php?t=53

ansehen. Dort verwende ich auch normale Relais mit denen auch wirklich Leistung geschaltet werden kann. Ich habe die Lösung mit 12V und einer Transistor-Stufe umgesetzt.
Es gibt wohl auch kleinere Relais die mit einer Spulenspannung von 5V arbeiten. Ich selbst habe aber noch keine gefunden. Meist eignen die sich nämlich aufgrund Ihrer Baugröße nicht für 230V.

Schau Dir auch mal die Read-Relais-Technik an. Ist auch nicht schlecht. Da klapper nix und Leistung bekommst Du auch drüber.

Wenn Du eine Lösung gefunden hast, dann behalte das Wissen bitte nicht für Dich. Würde auch gerne erfahren wie es weiter gegangen ist.

Spannend ist es in der Tat und interessant ist die Bastelei und Tüftlerei auch. Oft braucht man nur ein bissle Gedult zum Ausprobieren. Habe heute den ganzen Tag versenkt weil ich ein Problem mit Latches in einem 16-Bit-LED-Array hatte. War nur ein kleiner Adressierungsfehler den ich vor ein paar Minuten gefunden habe aber der Tag und teilweise auch meine Nerven war futsch wie nix:)

In diesem Sinne guten Abend und gute Nacht,

Markus
 
Hi Markus,

kannst du das Bild mit dem Plan für die Relais, besser aufgelöst mal zur Verfügung stellen?

Irgendwie erkenne ich leider nicht wirklich was darauf.

P.S. Kann auch an der Uhrzeit liegen. :D

Gruss Alex
 
Grüß euch.
ich wollte mich als Anfänger von BASCOM auch mal an so eine LCD-Menü rann wagen und habe mir aus diesem Betreig folgenden Code zusammengestellt das mittels Drehimpulsgeber vor und zurück geschalten werden soll:

Code:
$regfile = "m8def.dat"
$crystal = 3686400

Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 ,
Config Lcdpin = Pin , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Cursor Off

Dim Menu As Byte
Config Portd = Output

Ddrb = &B00000111
Portb = &B00000101

Menu = 1

Do
   If Pinb.0 = 0 Then
      Incr Menu
      Wait 10
   End If

   If Pinb.2 = 0 Then
      Decr Menu
      Wait 10
   End If

   Select Case Menu
      Case 1:
         Locate 1 , 1
         Lcd "1. 1541 ID"
      Case 2:
         Locate 1 , 1
         Lcd "2. SD2IEC ID"
      Case 3:
         Locate 1 , 1
         Lcd "3. TEST"
   End Select

   If Menu > 3 Then Menu = 1

Loop
End

Leider funktioniert das ganze nicht so wie ich möchte.
Es wird nur der erste Menüpunkt angezeigt. Beim drehen des Impulsgeber tut sich gar nichts.
Was mach ich da falsch?
 
Hallo Schatten!

Willkommen im AVR-Praxis-Forum! :ciao:


Ich habe deinen Code eben mal nur überflogen, aber....
Arbeitest du mit einem "echten" Drehencoder, oder was meinst du mit Drehimpulsgeber? :hmmmm:

BASCOM hat für einen Drehencoder extra einen Befehl zur Erfassung (über zwei Subroutinen, rechts und links)

Schau dir doch mal die Hilfe zum Befehl "ENCODER" an. ;)


Gruß,
Cassio
 
Auch ein schönes :hello: !

Du hast schon recht, der Befehl Encoder war mir bekannt, nur erfüllt der soweit ich erkennen konnte die gleiche Funktion als würde ich einen Schalter betätigen. Nichts desto Trotz habe ich das ganze mal etwas umgestrickt.

Der eigentlich Fehler war jedoch die Zeile "Wait 10" Es muß natürlich heißen "waitms 10"

Das ganze sieht jetzt so aus:

Code:
$regfile = "m8def.dat"
$crystal = 3686400

Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 ,
Config Lcdpin = Pin , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 16 * 2
Cursor Off

Dim Menu As Byte
Dim B As Byte
Config Portd = Output

Ddrb = &B00000111
Portb = &B00000101

Menu = 1

Do
   B = Encoder(pinb.0 , Pinb.2 , Links , Rechts , 1)
   Print B
   Waitms 10

   Select Case Menu
      Case 1:
         Locate 1 , 1
         Lcd "1. 1541 ID"
      Case 2:
         Locate 1 , 1
         Lcd "2. SD2IEC ID"
      Case 3:
         Locate 1 , 1
         Lcd "3. TEST"
      Case Else
         Menu = 1
   End Select

Loop

Links:
   Cls
   Menu = Menu + 1
   Waitms 10
   Return

Rechts:
   Cls
   Menu = Menu - 1
   Waitms 10
   Return

End

Das verhalten ist mir jedoch Schleierhaft.
Es wird zuerst Menü 2 angezeigt (Lcd "2. SD2IEC ID")
Sobald ich in eine Richtung drehe (oder den Taster drücke) erscheint das nächste oder vorrige Menü, jedoch nur sollange der Taster gedrückt ist. Läßt man los springt er wieder ins Menü 2 zurück???

Idee?
 
Hallo!

@Der Schatten

Überleg mal was Du hier geschrieben hast.

Ddrb = &B00000111
Portb = &B00000101


MfG
caargoo
 
nur erfüllt der soweit ich erkennen konnte die gleiche Funktion als würde ich einen Schalter betätigen.

Hallo !

Nun ja, nicht so ganz.....

Wenn du das mit Tastern simulieren möchtest, must du aber ein gutes Timing in den Fingern haben und die beiden Taster entsprechend betätigen. ;)

Darum nur noch mal für mich zum Verständnis...... hast du nun einen echten Drehencoder im Einsatz, oder doch nur Taster? :hmmmm:

Deiner Fehlerbeschreibung nach:
jedoch nur sollange der Taster gedrückt ist
würde ich mal auf ganz normale Taster tippen.

So ganz komme ich nun damit nicht klar.


Gruß,
Cassio
 
Also momentan benutze ich 2 Taster mit denen ich durchs Menü navigiere.
Ich habe aber auch einen echten Drehencoder den ich dann verwenden möchte. Für die Funktion momenan denke ich irrelevant, da ich festgestellt habe das beide den selben Fehler/Funktion herbeiführen.

Die beiden Zeilen:
Ddrb = &B00000111
Portb = &B00000101

muß ich gestehen habe ich aus einem fertigen Script übernommen.
Damit wird ja einfach auf nicht verwendete Ports ein Widerstand gelegt damit sie nicht offen sind soweit ich das ganze verstanden habe.

Bitte korrigiert mich wenn da etwas falsch ist.

Habs jetzt dahin geändert:

Ddrb = &B11111010
Pinb.0 = 0
pinb.2 = 0

Ergebnis: Die Anzeige hüpft sporadisch durch die Menüs. Taster habe keine Funktion.
 
Hallo Schatten,

aus PINx kann man den logischen Zustand des entsprechenden Portpins lesen, PINx ist nicht beschreibbar.

DDRx sind Register für die Datenrichtung (DataDirectionRegister). Eine "1" an der entsprechenden Bitadresse bedeutet, dass der Pin als Ausgang geschaltet ist, bei einer "0" ist er als Eingang geschaltet.

PORTx ist das Portregister. Hier gibt es folgende Besonderheiten:
  1. Ist ein Pin als Ausgang geschaltet, ist der logische Zustand eines Pins high, wenn im Portregister das zugehörige Bit "1" ist und low, wenn das Bit "0" ist.
  2. Ist der Pin als Eingang geschaltet, dann ist der interne Pullup-Widerstand aktiviert, wenn im Portregister das zugehörige Bit "1" ist. Ist das Bit im Portregister "0", dann ist der Pullup-Widerstand deaktiviert, die Eingangsimpedanz des Pins ist also hochohmig.
Vielleicht hilft dir das ja ein bisschen weiter.

Grüße,
Dirk

Achso ja, und willkommen im AVR-PRAXiS-Forum :ciao:
 
Hi, danke erstmal für deineausfürliche Info!

Folgendes habe ich festgestellt:
Es ist nicht erforderlich die Ports auf Ausgang zu setzen wenn ich etwas auf ein LCD ausgeben möchte. Warum?

Und wenn ich es richtig verstanden habe muß ich folgendes tun:
Wenn ich jetzt mit einem Taster etwas schalten möchte muß ich zuerst die entsprechenden Pins mit DDRx auf Eingang setzen und dann mittels PORTx den Pullup auf nicht benutzte Pins setzen.

Aber irgenwie komme ich nicht auf einen grünen Zweig.

Der Atmega8 hat auf PortB 6 Aus/Eingange und genau die möchte ich gerne für meine Taster/Drehencoder verwenden. Pin 0 und Pin 2.

Das ganze sieht jetzt nach deiner Anleitung hin so aus:

Ddrb = &B11111010
Portb = &B11111111

Nur damit habe ich genau wieder das gleiche Verhalten das ich nur bei gedrückter Taste zum nächsten Menüpunkt spinge. Beim Loslassen wieder eins zurück.

*verzweifel*

Könnte mir jemand ein Beispiel geben, damit ich mir ein besseres Bild machen kann.
 
Hallo!

Deine Register für die Pins und Ports sehen doch nun OK aus.

Ddrb = &B1111_1010
Ein Ausgang hat immer eine 1 als Anweisung, ein Eingang die 0 !

Für jeden Eingang solltest du (normalerweise) immer den internen Pullup-Widerstand aktivieren.
Portb = &B0000_0101

Damit hast du nur Bit0 und Bit2 als Eingang definiert und die Pullups aktiviert.

Die Einstellung ist nun also in Ordnung!


Ich möchte nur noch mal darauf hinweisen, dass du einen Drehencoder nicht einfach mit zwei getrennte Taster gleichsetzen kannst!

Schau dir doch noch mal die Funktionsweise eines Drehencoders in der BASCOM-Hilfe an.

Obendrein gibt es verschiedene Modelle eines Drehencoders.... nicht alle müssen so funktionieren wie beschrieben.

Unabhängig davon kannst du es natürlich erst mal mit normalen Tastern probieren.

Nur mal so als Beispiel.....

Code:
Dim Menu As Byte 

Ddrb = &B00000111 
Portb = &B00000101 


Menu = 1 

Do

If PINB.0 = 0 Then
If Menu < 3 Then
Incr Menu
Else
End If
Elseif PINB.2 = 0 Then
If Menu > 1 Then
Decr Menu
Else
End If
Else
End If

Locate 1, 1
Select Case Menu 
Case 1: Lcd "1. 1541 ID      " 
Case 2: Lcd "2. SD2IEC ID    " 
Case 3: Lcd "3. TEST         " 
Case Else : Lcd "F E H L E R     "
End Select 

Waitms 25
Loop


Kannst es ja mal ausprobieren......
Sollte eigentlich funktionieren!

Ach so....
Ich habe zwar diese Schreibweise beim "Config LCD" noch nicht gesehen,
Code:
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , 
Config Lcdpin = Pin , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
aber wenn es denn funktioniert.....

Kenne es nur, dass alles in einer Zeile stehen muss.
Code:
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2


Gruß,
Cassio
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)