PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Menü Creator



guenter1604
20.07.2008, 21:35
Hallo NG,

bei der Suche nach einer Lösung für eine Menüstruktur bin ich hierauf gestossen:

https://www.roboternetz.de/wissen/index.php/Bascom_State_Machine_Menu

Jetzt wäre es doch optimal, wenn man einen Codegenerator hätte, der einem die gewaltige Tipparbeit abnehmen würde. Also die Titel eintippen, Struktur festlegen und dann fertiges Codegerüst erhalten.

Was findet ihr, sollte man das weiterverfolgen ?

Vitis
20.07.2008, 22:36
viel zu kompliziert das Ding ... lohnt nicht wenn Du mich fragst.
Da gibts effizientere Varianten.
Ich hab es so gelöst, dass ich meine Menüstruktur erstmal
angeschaut hab, was ich denn so brauche.

1. Verzweigungsmenü um von Menüpunkt möglichst
einfach zu Untermenü springen zu können.
2. Auswahlmenü für den zu ändernden Parameter
3. Optionsauswahl um Parameter auf vorgegebene Werte
einzustellen.
4. Werteingabe um Variable Werte in vorgegebenem Rahmen
min - max einzugeben über up- down-Tasten

Dann hab ich mir n data-Feld überlegt, das möglichst viele
der Möglichkeiten abdeckt und je nach bedarf an die
Erfordernisse angepasst wird. Dann dazu noch 2-3 Array
für die Werte zu speichern und fertig.
Der Ablauf ist dann so:

Mainloop -> Menüaufruf -> Menüauswahl -> Flag setzen für Submenüaufruf
und Submenütitel als Zahlenwert speichern -> exit in Mainloop
Mainloop Flag erkannt -> Loopuptabel für Submenü -> Submenüaufruf -> Selekt der Option -> Exit zu Mainloop usw. usw.

Liest sich komplex, ist aber ziemlich easy zu proggen und
wesentlich flexibler als die Soße in dem Tut

-tomas-
23.07.2008, 08:05
Hallo Vitis,

>Da gibts effizientere Varianten
Sicherlich muss man sich in eine State Machine hineindenken, aber bevor Du von irgendeiner Soße laberst, solltest Du erst einmal an einem lauffähigem Bascom-Codebeispiel zeigen, wie Du es effizienter gelöst hast [-X

Vitis
23.07.2008, 18:32
hier eine Menüstruktur von mir:



$nocompile


Sub Menueaufruf_restore(parameterindex)
Select Case Parameterindex ' Verzweigen nach jeweiligem Menü
Case 1:
Restore Menue_1
Case 2:
Restore Menue_2
Case 3:
Restore Menue_3
Case 4:
Restore Menue_4
Case 5:
Restore Menue_5
Case 6:
Restore Menue_6
Case 7:
Restore Menue_7
Case 8:
Restore Menue_8
Case 9:
Restore Menue_9
'Case 15:
'Restore Menue_15
Case 10:
Restore Menue_10
Case 11:
Restore Menue_11
Case 12:
Restore Menue_12
Case 13:
Restore Menue_13
Case 14:
Restore Menue_14
Case 15:
Restore Menue_15
Case 16:
Restore Menue_16
Case 17:
Restore Menue_17
Case 18:
Restore Menue_18
Case 19:
Restore Menue_19
Case 20:
Restore Menue_20
Case 21:
Restore Menue_21
Case 22:
Restore Menue_22
Case 60:
Restore Menue_60
Case 61:
Restore Menue_61
Case 63:
Restore Menue_63
Case 70:
Restore Menue_70
Case 71:
Restore Menue_71
Case 72:
Restore Menue_72
Case 73:
Restore Menue_73
Case 74:
Restore Menue_74
Case 75:
Restore Menue_75
Case 76:
Restore Menue_76
Case 77:
Restore Menue_77
Case 80:
Restore Menue_80
Case 81:
Restore Menue_81
Case 82:
Restore Menue_82
Case 83:
Restore Menue_83
Case Else: ' Defaultwert ist Hauptmenü
Restore Menue_1
'Menue_auswahl = 0
End Select
End Sub


' Menüstruktur

Menue_1:
Data 1 ' Menüart 1 = Verzweigungsmenü
Data "Hauptmenü{013}" ' Menütitel
' Aufbau ist Auswahl, Zieladresse
Data " {013}" , 1
Data " Tankkonfiguration {013}" , 70
Data " Anlagenkonfig {013}" , 5
Data " Uhrzeit {013}" , 3
Data " Datum {013}" , 2
'Data 10

Menue_2:
Data 1
Data " Datum {013}"
Data " Datum Jahr {013}" , 16
Data " Datum Monat {013}" , 17
Data " Datum Tag {013}" , 18
Data " {013}" , 20
Data " Uhrzeit " , 3


Menue_3:
Data 1
Data " Uhrzeit{013}"
Data " Stunde {013}" , 60
Data " Minute {013}" , 61
Data " Datum {013}" , 2
Data " Regel-Intervall {013}" , 20
Data " Reset Zentrale " , 4


Menue_4:
Data 1
Data " Reset {013}"
Data " {013}" , 4
Data " {013}" , 4
Data " {013}" , 4
Data " {013}" , 4
Data " Reset Zentrale " , 19


Menue_5:
Data 1
Data " Anlage {013}"
Data " Log zurücksetzen {013}" , 21
Data " Regel-Intervall {013}" , 20
Data " Log-Intervall {013}" , 63
Data " Tastensound {013}" , 13
Data " Menü 2" , 8
'

Menue_6:
Data 1
Data " Tankmenü {013}"
Data " Solltemp {013}" , 73
Data " Mostoechsle {013}" , 74
Data " Mostmenge {013}" , 75
Data " Soll RZ {013}" , 76
Data " Tankmenü 2 " , 7

Menue_7:
Data 1
Data "Tankmenü 2{013}"
Data " Oechsleabnahme {013}" , 77
Data " Sensoradresse {013}" , 82
Data " {013}" , 7
Data " CO2-Menü {013}" , 10
Data " Tankmenü 1 " , 6

Menue_8:
Data 1
Data " Anlage 2{013}"
Data " Baudrate PC {013}" , 14
Data " Manuell / PC {013}" , 15
Data " Messboxen {013}" , 71
Data " Reset Zentrale {013}" , 19
Data " Menü 3 " , 9


Menue_9:
Data 1
Data " Anlage 3{013}"
Data " Teilertara {013}" , 72
Data " Terminal {013}" , 22
Data " {013}" , 9
Data " {013}" , 9
Data " Menü 2 " , 8

Menue_10:
Data 1
Data " CO2-Menü {013}"
Data " {013}" , 10
Data " CO2 prewarmup {013}" , 80
Data " CO2 delta {013}" , 81
Data " CO2 Regelzyklus{013}" , 83
Data " Tankmenü " , 7

Menue_11:
Data 2
Data "Abschaltdr.{013}" ' Menütitel
Data " bar" ' Einheit
Data &H03 , &HFF ' Stufen
Data 0 , 10 ' Maximalwert
Data 1 ' ERAM-Parameter Index
Data 5 ' zählersteps
Data 2 ' Kommastellen
Data 1 ' Aussprungmenü

Menue_12:
Data 2 ' 2= Werteingabe
Data "Minimaldr.{013}"
Data " bar"
Data &H03 , &HFF ' Stufen
Data 0 , 10 ' Maximalwert
Data 2 ' ERAM-Parameter Index
Data 5 ' zählersteps
Data 2 ' Kommastellen
Data 1 ' Aussprungmenü

Menue_13:
Data 5 ' 5= Wertauswahl
Data "Sound{013}"
Data 8 ' ERAM-Parameter Index
Data " on {013}" , 1
Data " off {013}" , 0 ' Stufen
Data "" , 0 ' Maximalwert
Data "" , 0
Data "" , 0 ' zählersteps

Menue_14:
Data 5
Data "BaudratePC{013}"
Data 7 ' ERAM-Parameter Index
Data " 9600 {013}" , 0
Data " 19200 {013}" , 1 ' Stufen
Data " 57600 {013}" , 3 ' Maximalwert
Data " 115200 {013}" , 4
Data " 128000 {013}" , 5 ' zählersteps

Menue_15:
Data 5
Data "Manuell/PC{013}"
Data 9 ' ERAM-Parameter Index
Data " Manuell {013}" , 0
Data " PC {013}" , 1 ' Stufen
Data " {013}" , 4 ' Maximalwert
Data " {013}" , 4
Data " {013}" , 4 ' zählersteps

' zählersteps


Menue_16:
Data 2
Data "Datum Jahr"
Data " "
Data &H00 , &H63 ' Stufen
Data 0 , 99 ' Maximalwert
Data 1 ' ERAM-Parameter Index
Data 1 ' zählersteps
Data 0 ' Kommastellen
Data 5 ' Aussprungmenü

Menue_17:
Data 2
Data "Datum Monat"
Data " "
Data &H00 , &H0C ' Stufen
Data 0 , 12 ' Maximalwert
Data 2 ' ERAM-Parameter Index
Data 1 ' zählersteps
Data 0 ' Kommastellen
Data 2 ' Aussprungmenü

Menue_18:
Data 2
Data "Datum Tag"
Data " "
Data &H00 , &H1F ' Stufen
Data 0 , 31 ' Maximalwert
Data 3 ' ERAM-Parameter Index
Data 1 ' zählersteps
Data 0 ' Kommastellen
Data 2 ' Aussprungmenü

Menue_19:
Data 99
Data "Reset{013}"
Data " "
Data &H00 , &H0A ' Stufen
Data 0 , 1 ' Maximalwert
Data 1 ' ERAM-Parameter Index
Data 1 ' zählersteps
Data 2 ' Kommastellen
Data 0 ' Aussprungmenü

Menue_20:
Data 2
Data "Intervall"
Data "Sec "
Data &H04 , &HB0 ' Stufen
Data &H04 , &HB0 ' Maximalwert
Data 4 ' ERAM-Parameter Index
Data 10 ' zählersteps
Data 0 ' Kommastellen
Data 5 ' Aussprungmenü

Menue_21:
Data 5
Data "Log Reset{013}"
Data 10 ' ERAM-Parameter Index
Data " nein {013}" , 0
Data " Reset {013}" , 1 ' Stufen
Data " {013}" , 3 ' Maximalwert
Data " {013}" , 4
Data " {013}" , 5 ' zählersteps

Menue_22:
Data 5
Data "Terminal{013}"
Data 12 ' ERAM-Parameter Index
Data " aus {013}" , 0
Data " ein {013}" , 1 ' Stufen
Data " {013}" , 4 ' Maximalwert
Data " {013}" , 4
Data " {013}" , 4

' > 60 SRAM Parameter
Menue_60:
Data 3
Data "Stunde"
Data "Uhr "
Data &H00 , &H17 ' Stufen
Data 0 , 23 ' Maximalwert
Data 1 ' SRAM-Parameter Index
Data 1 ' zählersteps
Data 0 ' Kommastellen
Data 3 ' Aussprungmenü

Menue_61:
Data 3
Data "Minute"
Data "Min "
Data &H00 , &H3B ' Stufen
Data 0 , 59 ' Maximalwert
Data 2 ' SRAM-Parameter Index
Data 1 ' zählersteps
Data 0 ' Kommastellen
Data 3 ' Aussprungmenü

Menue_63:
Data 2
Data "Log_Interv."
Data " "
Data &H00 , &H0A ' Stufen
Data 0 , 10 ' Maximalwert
Data 11 ' ERAM-Parameter Index
Data 1 ' zählersteps
Data 0 ' Kommastellen
Data 5 ' Aussprungmenü ' Aussprungmenü


Menue_70:
Data 3
Data "Tankauswahl"
Data " "
Data &H00 , &HFF ' Stufen
Data 0 , 255 ' Maximalwert
Data 3 ' SRAM-Parameter Index
Data 1 ' zählersteps
Data 0 ' Kommastellen
Data 6 ' Aussprungmenü

Menue_71:
Data 2
Data "Messboxen"
Data " "
Data &H00 , &H0A ' Stufen
Data 0 , 10 ' Maximalwert
Data 5 ' ERAM-Parameter Index
Data 1 ' zählersteps
Data 0 ' Kommastellen
Data 5 ' Aussprungmenü

Menue_72:
Data 2
Data "Tarateiler"
Data " "
Data &H00 , &H64 ' Stufen
Data 0 , 100 ' Maximalwert
Data 6 ' ERAM-Parameter Index
Data 1 ' zählersteps
Data 0 ' Kommastellen
Data 5 ' Aussprungmenü

Menue_73:
Data 4
Data "Solltemp"
Data "°C "
Data &H0A , &H78 ' Stufen
Data 0 , 40 ' Maximalwert
Data 1 ' SRAM-Parameter Index
Data 5 ' zählersteps
Data 2 ' Kommastellen
Data 6 ' Aussprungmenü

Menue_74:
Data 4
Data "Most Oe"
Data "Oe "
Data &H01 , &H2C ' Stufen
Data &H01 , &H2C ' Maximalwert
Data 2 ' SRAM-Parameter Index
Data 1 ' zählersteps
Data 1 ' Kommastellen
Data 6

Menue_75:
Data 4
Data " Mostmenge "
Data "L "
Data &H4E , &H20 ' Stufen
Data &H4E , &H20 ' Maximalwert
Data 3 ' SRAM-Parameter Index
Data 25 ' zählersteps
Data 0 ' Kommastellen
Data 6

Menue_76:
Data 4
Data "Soll RZ"
Data "g/l "
Data &H02 , &H58 ' Stufen
Data &H01 , &H2C ' Maximalwert
Data 5 ' SRAM-Parameter Index
Data 1 ' zählersteps
Data 1 ' Kommastellen
Data 6

Menue_77:
Data 4
Data "Delta Oe"
Data "Oe "
Data &H02 , &H58 ' Stufen
Data &H01 , &H2C ' Maximalwert
Data 4 ' SRAM-Parameter Index
Data 1 ' zählersteps
Data 1 ' Kommastellen
Data 6

Menue_80:
Data 4
Data "CO2 prew. "
Data "sec "
Data &H00 , &H3C ' Stufen
Data &H00 , &H3C ' Maximalwert
Data 10 ' SRAM-Parameter Index
Data 1 ' zählersteps
Data 0 ' Kommastellen
Data 10 ' Rücksprungadresse

Menue_81:
Data 4
Data "CO2 delta"
Data "dig "
Data &H00 , &H3C ' Stufen
Data &H00 , &H3C ' Maximalwert
Data 11 ' SRAM-Parameter Index
Data 1 ' zählersteps
Data 0 ' Kommastellen
Data 10 ' Rücksprungadresse

Menue_82:
Data 4
Data "Sensor Ad."
Data " "
Data &H00 , &HFF ' Stufen
Data &H00 , &HFF ' Maximalwert
Data 12 ' SRAM-Parameter Index
Data 1 ' zählersteps
Data 0 ' Kommastellen
Data 7 ' Rücksprungadresse

Menue_83:
Data 4
Data "CO2 Messz."
Data " "
Data &H00 , 40 ' Stufen
Data &H00 , 40 ' Maximalwert
Data 13 ' SRAM-Parameter Index
Data 1 ' zählersteps
Data 0 ' Kommastellen
Data 7 ' Rücksprungadresse

Die Werte werden dann in einem eram bzw. einem sram-array abgelegt.
Was nun daranstatemachine ist wird sich nun jeder fragen.
Die Augabe des Menüs.
Die Ausgabe ist so angelegt, dass sie nicht in der Abfrage der tasten stehenbleibt,
sondern die Mainloop einfach nach der Anzeige weiterläuft
und die Funktion des Systems im Hintergrund einfach
weitergeht, bis wieder ein Ereignisflag kommt.
z.B. Taste UP, dann entweder je nach Menüart den Auswahlbalken im
Menü nach oben und Anzeige aktualisieren oder
den ausgewählten wert erhöhen und anzeige aktualisieren und weiter
gehts im normalen programmablauf.

was da nun besser ist als an den anderen beispiel?

ganz einfach. ich kann durch die verwendung von arrays das Menü
frei skalieren. Kleines Menü, array kleiner machen, großes Menü
einfach vergrößern.
Da die Sprungadressen im Menü selbst integriert sind kann ich
im Menü beliebige Verzweigungen setzen und an jede beliebige
Stelle springen

ach so, was die ausgabe angeht bin ich auch variabel, da die
anzeigeroutinen von den menüroutinen getrennt sind.
hab gerade n menü für ne 16-segment-anzeige adaptiert, das
für n glcd ursprünglich erstellt wurde.
nur die anzeigeroutinen ändern und schon get das ganze
menü auf der anderen plattform

... so, jetzt kannst Du mal zeigen was Du kannst ;)

-tomas-
24.07.2008, 01:33
Hallo Vitis,

danke, dass Du reagiert hast. Das Forum lebt von Code-Schnipseln. Das letzte Data-Feld "Aussprungmenü" macht Deinen Code zur State Machine.
Sieht wirklich übersichtlich aus, da Du Menütexte und Verzweigungen zusammengebracht hast.

Ich komme erst in ein paar Tagen dazu, tiefer in die Sache einzusteigen und melde mich dann wieder. Ich würde dann das Menü der State Machine im Tut mit Deiner Lösung nachbauen und ins Tutorial reinstellen. Dann werden wir auch die Code-Länge vergleichen können.

Kannst Du noch ein Stück aus der Main-Loop (Read etc) nachliefern, da mich insbes. Dein Ansatz für die Navigation in den Ebenen und UP/DOWN-Funktion für die Werteingabe interessiert?
(siehe erstes Feldes mit 1=Verzweigungsmenü/2=Werteingabe/5= Wertauswahl etc)

Tomas

Vitis
24.07.2008, 11:43
aber bevor Du von irgendeiner Soße laberst

... danke, aber das ist nicht mein Forumstil ...
die Anzeigesequenz kannste Dir ja erdenken.
Ich hab nen Weg gezeigt, wie man's effizient machen
kann, fertigen Code liefere ich nicht auf
Zuruf. [-(

guenter1604
24.07.2008, 13:51
Hallo Vitis,

sieht viel übersichtlicher aus!
Welche zusätzliche Hardware benötige ich noch, um deine Schnapsbrennerei nachzubauen ?



=D>

Günter

-tomas-
24.07.2008, 16:38
Hallo Vitis,


das ist nicht mein Forumstil
So verrückt ist das manchmal. Eigentlich fühlte ich mich von Deinem Spruch "die Soße in dem Tut" ernsthaft angegriffen, da ich mir die Mühe gemacht hatte, den Artikel zur State Machine in RN-Wissen zu schreiben.


fertigen Code liefere ich nicht auf Zuruf
Wieder ein Missverständnis. Ich werde den Artikel in RN-Wissen erweitern. Du kannst Dich daran zu beteiligen - die anderen Leser werden es Dir danken.

Tomas

Vitis
24.07.2008, 22:20
Hardware ? ... hmmm mal überlegen.
110000 Liter Fassraum in Edelstahl auf 30 Gebinden mit Pillowplates,
dann 60 Magnetventile, 120 Temperatursensoren,
nochmal 10 Gasdurchflusssensoren, etwa 2 km
Schlauch 1/2-Zoll, 80m PVC-Rohr, ne Kühlanlage > 10kw
Kühlleistung und diverse Kleinteile. Das wars auch schon.

ach so, ganz vergessen, 8 Platinen mit Atmel Produkten
verschiedener Bauart, die im Verbund über Bus laufen

-tomas-
25.07.2008, 13:46
Hallo Günter,

ich habe mal die Idee von Vitis aufgegriffen und Soße von State Machine in RN-Wissen mit Select Case und Pointern realisiert.
https://www.roboternetz.de/wissen/index.php/Bascom_State_Machine_Menu

Vitis hat noch 3 getrennte Tabellen geführt für:- Select Case...Restore
- Datensätze (DATA...)
- die Tabelle Unterprogrammaufrufe (hat Vitis leider nicht veröffentlicht)
Im Gegensatz dazu habe ich jetzt alles in die Statement Blocks von Select Case hineingequetscht, so dass nicht mehr getrennte Tabellen geführt und abgestimmt werden müssen.
Codeschnipsel

Do '********** MAIN-Loop *******
'Menüeintrag und Tastencodes finden und ggf. State wechseln
If Key <> Key_null Then 'save power
State_renew = 0
Gosub State_detect 'hier nur Tastendruck auswerten
For I = 1 To 4
'Read J
LPM R24,Z+
sts {J},R24
If Key = Keycode(i) Then
If J > 0 Then
State_renew = 1
Key = Key_null 'reset key status
State = J
End If
End If
Next I
End If

'Unterprogramm des aktuellen State auslesen und ggf. anspringen
Gosub State_detect
If Gosub_adr > 0 Then
Gosub_adr = Gosub_adr / 2 'see Bascom-Doc Mixing ASM and BASIC
LDS R31, {Gosub_Adr+1} 'High
LDS R30, {Gosub_Adr} 'Low
'Call zum Sub
ICALL
End If

* * *

Loop
End


State_detect:
Gosub_adr = 0
Select Case State
* * *
Case 44:
Lcd_textbuffer = "44 Battery"
!Call Restore_label
Data 43 , 0 , 40 , 48
Case 45:
Gosub_adr = Loadlabel(temperaturefunc)
!Call Restore_label
Data 0 , 0 , 41 , 0

* * *
End Select
Return


Restore_label:
Pop ZH 'R31
POP ZL 'R30
LSL ZL 'Multipliziere Adr mit 2
ROL ZH
'this is a return from Sub State_detect to main loop
Return
Den Pointer auf die Datensätze setze ich in ASM dynamisch, alternativ kann man auch wie Vitis Labels setzen und mit RESTORE adressieren.
Mit dem Befehl ICALL werden die zugehörigen Unterprogramme über die Labeladressen angesprungen.
Die Datensätze können nach Bedarf aufgebohrt werden, so wie es Vitis mit Incr/Decr. etc. vorgeschlagen hat.

Der Preis der Übersichtlichkeit ist ein etwas aufgeblähter Code (s. Artikel in RN-Wissen).
Letztendlich eine Geschmacksfrage...

Anbei der vollständige lauffähiger Code für den Bascom-Simulator (getestet 1.11.9.1)

'Beispiel für ein State Machine Menü
'Das Beispiel ist für den BASCOM-Simulator angepasst worden
' getestet mit BASCOM 1.11.9.1
' Codelänge 3288 Byte

$regfile = "m32def.dat"
$framesize = 32 'Stack
$swstack = 32
$hwstack = 64

'
'Hinweis: Im Simulator müssen die Eingaben in dem blauen "Terminal Emulator Window" erfolgen!
'Auf der Tastatur ergeben sich für die VIER Joystick-Positionen folgende Umsetzungen
'
' [Key_plus ]
' [Key_prev] [ ] [Key_next]
' [Key_minus]
'
'
' [ Taste_8 ]
' [Taste_4 ] [ ] [Taste_6 ]
' [ Taste_2 ]
'
'bzw. im ASCII-Code:

Dim Keycode_string As String * 4
'Key_plus|Key_minus|Key_prev|Key_next
Keycode_string = "{056}{050}{052}{054}"
Dim Keycode(4) As Byte At Keycode_string Overlay
Const Key_null = 0 'keine Taste gedrückt

'Pins des LCD-Modules setzen ggf. an eigene Anschlüsse anpassen
Config Lcd = 16 * 1
Initlcd
Cls

'******** Joystick/Key Settings ***********************************************
Dim Key As Byte 'key in Mainloop

'******** LCD ************************************************** ***************
Dim Lcd_textbuffer As String * 25

'******** allg Variablen ************************************************** ****
Dim I As Byte , J As Byte

'********* State Variables ************************************************** **
Dim State As Byte , State_renew As Byte
Dim Gosub_adr As Word

'Initial state variables
State_renew = 1
State = 10 'Startbildschirm
Key = Key_null

'********** MAIN-Loop ************************************************** *******
Do

'Menüeintrag und Tastencodes finden und ggf. State wechseln
If Key <> Key_null Then 'save power
State_renew = 0
Gosub State_detect 'hier nur Tastendruck auswerten
For I = 1 To 4
'Read J
LPM R24,Z+
sts {J},R24
If Key = Keycode(i) Then
If J > 0 Then
State_renew = 1
Key = Key_null 'reset key status after get a new state of state machine (prevent influence on GOSUBs)
State = J
End If
End If
Next I
End If

'Unterprogramm des aktuellen State auslesen und ggf. anspringen
Gosub State_detect
If Gosub_adr > 0 Then
Gosub_adr = Gosub_adr / 2 'see Bascom-Doc Mixing ASM and BASIC
LDS R31, {Gosub_Adr+1} 'High
LDS R30, {Gosub_Adr} 'Low
'Call zum Sub
ICALL
End If

'---------------------------------------------------------------
'place for your own code in main loop
'---------------------------------------------------------------

'LCD refresh wenn Menü verändert
If State_renew = 1 Then
State_renew = 0
Gosub Lcd_print
End If

'Tastaturabfrage mit Halt nur für Simulator, ansonsten Sleep+Timer_ISR verwenden!!
Key = Waitkey()

Loop
End

'********* State routines ************************************************** *
'---------------------------------------------------------------
'Subroutine: State_detect
'Call from: main loop
'Purpose: Status der State Machine feststellen
'Result: Pointer auf "DATA KeyCodes" und zugehörige Gosub
'---------------------------------------------------------------
State_detect:
Gosub_adr = 0
Select Case State
Case 10:
Lcd_textbuffer = "1 Butterfly Bascom"
!Call Restore_label
Data 0 , 20 , 0 , 11 'Key_plus|Key_minus|Key_prev|Key_next
Case 11:
Lcd_textbuffer = "11 Rev 2"
!Call Restore_label
Data 0 , 0 , 10 , 0 'Key_plus|Key_minus|Key_prev|Key_next
Case 20:
Lcd_textbuffer = "2 Time"
!Call Restore_label
Data 10 , 30 , 0 , 21
Case 21:
Lcd_textbuffer = "21 Clock"
!Call Restore_label
Data 0 , 22 , 20 , 23
Case 22:
Lcd_textbuffer = "22 Date"
!Call Restore_label
Data 21 , 0 , 20 , 24
Case 23: 'Show HH:MM:SS
Gosub_adr = Loadlabel(showclock)
!Call Restore_label
Data 0 , 24 , 21 , 25
Case 24: 'Show DD:MM:YY
Gosub_adr = Loadlabel(showdate)
!Call Restore_label
Data 23 , 0 , 22 , 26
Case 25:
Lcd_textbuffer = "211 Adjust Clock"
!Call Restore_label
Data 27 , 0 , 23 , 65
Case 26:
Lcd_textbuffer = "221 Adjust Date"
!Call Restore_label
Data 0 , 28 , 24 , 66
Case 27:
Lcd_textbuffer = "212 Clock Format"
!Call Restore_label
Data 0 , 25 , 23 , 67
Case 28:
Lcd_textbuffer = "222 Date Format"
!Call Restore_label
Data 26 , 0 , 23 , 68
Case 30:
Lcd_textbuffer = "3 DataLogger"
!Call Restore_label
Data 20 , 40 , 0 , 31
Case 31:
Lcd_textbuffer = "31 Log Cycle"
!Call Restore_label
Data 0 , 32 , 30 , 35
Case 32:
Lcd_textbuffer = "32 Delete Flash"
!Call Restore_label
Data 31 , 33 , 30 , 36
Case 33:
Lcd_textbuffer = "33 Show LogCount"
!Call Restore_label
Data 32 , 34 , 30 , 37
Case 34:
Lcd_textbuffer = "34 Print to RS232"
!Call Restore_label
Data 33 , 0 , 30 , 38
Case 35: 'HH:MM
Gosub_adr = Loadlabel(datalogger_setloginterval)
!Call Restore_label
Data 0 , 0 , 31 , 0
Case 36:
Lcd_textbuffer = "321 RIGHT Delete DF"
!Call Restore_label
Data 0 , 0 , 32 , 76
Case 37: '1234
Gosub_adr = Loadlabel(datalogger_logcount)
!Call Restore_label
Data 0 , 0 , 33 , 0
Case 38:
Lcd_textbuffer = "341 RIGHT Print9600B"
!Call Restore_label
Data 0 , 0 , 34 , 78
Case 40:
Lcd_textbuffer = "4 ADC"
!Call Restore_label
Data 30 , 50 , 0 , 41
Case 41:
Lcd_textbuffer = "41 Temperature"
!Call Restore_label
Data 0 , 42 , 40 , 45
Case 42:
Lcd_textbuffer = "42 Voltage"
!Call Restore_label
Data 41 , 43 , 40 , 46
Case 43:
Lcd_textbuffer = "43 ADC Port RAW"
!Call Restore_label
Data 42 , 44 , 40 , 47
Case 44:
Lcd_textbuffer = "44 Battery"
!Call Restore_label
Data 43 , 0 , 40 , 48
Case 45: '+24°C
Gosub_adr = Loadlabel(temperaturefunc)
!Call Restore_label
Data 0 , 0 , 41 , 0
Case 46: '0 mV
Gosub_adr = Loadlabel(voltagefunc)
!Call Restore_label
Data 0 , 0 , 42 , 0
Case 47: 'CH:RAW
Gosub_adr = Loadlabel(adc_raw_func)
!Call Restore_label
Data 0 , 0 , 43 , 0
Case 48: '2900mV
Gosub_adr = Loadlabel(adc_batt_func)
!Call Restore_label
Data 0 , 0 , 44 , 0
Case 50:
Lcd_textbuffer = "5 Options"
!Call Restore_label
Data 40 , 0 , 0 , 51
Case 51:
Lcd_textbuffer = "51 LCD contrast"
!Call Restore_label
Data 0 , 52 , 50 , 56
Case 52:
Lcd_textbuffer = "52 Bootloader"
!Call Restore_label
Data 51 , 53 , 50 , 57
Case 53:
Lcd_textbuffer = "53 LCD OFF"
!Call Restore_label
Data 52 , 54 , 50 , 83
Case 54:
Lcd_textbuffer = "54 LCD Auto Power"
!Call Restore_label
Data 53 , 55 , 50 , 58
Case 55:
Lcd_textbuffer = "55 Key Click"
!Call Restore_label
Data 54 , 0 , 50 , 59
Case 56: '0...15
Gosub_adr = Loadlabel(setcontrast)
!Call Restore_label
Data 0 , 0 , 51 , 0
Case 57:
Lcd_textbuffer = "521 RIGHT bootloader"
!Call Restore_label
Data 0 , 0 , 52 , 87
Case 58: 'OFF/5..90min
Gosub_adr = Loadlabel(autopower)
!Call Restore_label
Data 0 , 0 , 54 , 0
Case 59: 'ON/OFF
Gosub_adr = Loadlabel(keyclick_set)
!Call Restore_label
Data 0 , 0 , 55 , 0
'Untermenüs zu State 25 bis 28
Case 65: 'sub for "211 Adjust Clock"
Gosub_adr = Loadlabel(setclock)
!Call Restore_label
Data 67 , 0 , 23 , 0
Case 66: 'sub for "221 Adjust Date"
Gosub_adr = Loadlabel(setdate)
!Call Restore_label
Data 0 , 68 , 24 , 0
Case 67: 'sub for "212 Clock Format"
Gosub_adr = Loadlabel(setclockformat)
!Call Restore_label
Data 0 , 65 , 23 , 0
Case 68: 'sub for "222 Date Format"
Gosub_adr = Loadlabel(setdateformat)
!Call Restore_label
Data 66 , 0 , 24 , 0
'Untermenüs zu State 36 und 38
Case 76: 'sub for "321 RIGHT Delete DF"
Gosub_adr = Loadlabel(datalogger_erase)
!Call Restore_label
Data 0 , 0 , 36 , 0
Case 78: 'sub for "341 RIGHT Print9600B"
Gosub_adr = Loadlabel(datalogger_rs232)
!Call Restore_label
Data 0 , 0 , 38 , 0
'Untermenü zu State 53 und 57

Case 83: 'sub for "53 LCD OFF"
Gosub_adr = Loadlabel(power_off_func)
!Call Restore_label
Data 0 , 0 , 53 , 0
Case 87: 'sub for "521 RIGHT bootloader"
Gosub_adr = Loadlabel(bootfunc)
!Call Restore_label
Data 0 , 0 , 57 , 0
'Error Handling
Case Else
State = 10
!Call Restore_label
Data 0 , 0 , 0 , 0

End Select
Return

'---------------------------------------------------------------
'Subroutine: Restore_label
'Call from: State_detect
'Purpose: Ersatz für RESTORE Label, erspart das Setzen der Labels für DATA
'Result: Pointer ZH:ZL steht auf der Rücksprungadresse => DATA aa,bb,cc,dd
'---------------------------------------------------------------
Restore_label:
Pop ZH 'R31
POP ZL 'R30
LSL ZL 'Multipliziere Adr mit 2
ROL ZH
'this is a return from Sub State_detect to main loop
Return

'********* LCD SUB routines ************************************************** *
'---------------------------------------------------------------
'Subroutine: Lcd_print
'Call from: anywhere
'Purpose: gibt Lcd_textbuffer auf dem LCD-Display aus
'Result: LCD
'---------------------------------------------------------------
Lcd_print: 'Print lcd_textbuffer
Cls
Lcd Lcd_textbuffer
State_renew = 0
Return

'********* SUB Clock routines****************************************** ********
Showclock:
'Show the clock on the LCD
Lcd_textbuffer = "HH:MM:SS"
Gosub Lcd_print
Return

Setclock:
'Adjusts the Clock
Lcd_textbuffer = "HH=11"
Gosub Lcd_print
Return

Setclockformat:
'Adjusts the Clockformat (12H or 24H)
Lcd_textbuffer = "12H / 24H"
Gosub Lcd_print
Return

'********* SUB date routines **************************************************
Showdate:
'Show the date on the LCD
Lcd_textbuffer = "DD.MM.YY"
Gosub Lcd_print
Return

Setdate:
'Adjusts the Date
Lcd_textbuffer = "Month=12"
Gosub Lcd_print
Return

'---------------------------------------------------------------
Setdateformat:
'Adjusts the Dateformat "DDMMYY" , "MMDDYY" , "YYMMDD"
Lcd_textbuffer = "DDMMYY/YYMMDD"
Gosub Lcd_print
Return

'********* Datalogger routines ************************************************
Datalogger_setloginterval:
'set the datalog intervall HOUR:MINUTES
Lcd_textbuffer = "HH:MM"
Gosub Lcd_print
Return

Datalogger_erase:
'erase the dataflash
State = 32 'St_datalogger_erase
State_renew = 1
Return

Datalogger_logcount:
'Show DF_LogCount
Lcd_textbuffer = "1234"
Gosub Lcd_print
Return

Datalogger_rs232:
'Print all DataLogs to RS232
State = 34 'St_datalogger_rs232 as next status of state machine
State_renew = 1
Return

Temperaturefunc:
'temperature measurement in °C
Lcd_textbuffer = "+24C"
Gosub Lcd_print
Return

Voltagefunc:
'voltage measurement mV
Lcd_textbuffer = "0mV"
Gosub Lcd_print
Return

Adc_raw_func:
'ADC Temperature/Voltage/Light result as RAW
Lcd_textbuffer = "CH:RAW"
Gosub Lcd_print
Return

Adc_batt_func:
'battery voltage measurement
Lcd_textbuffer = "2900mV"
Gosub Lcd_print
Return

'********* Sub MENU / OPTIONS ********************************
Setcontrast:
'Adjust the LCD contrast
Lcd_textbuffer = "0...15"
Gosub Lcd_print
Return

Bootfunc:
State = 10 'St_avrbf as next status of state machine
State_renew = 1
Return

Power_off_func:
'LCD OFF
State = 53 'Return State is St_options_power_off
Return

Autopower:
'Enable/Disable auto power save
Lcd_textbuffer = "ON/OFF"
Gosub Lcd_print
Return

Keyclick_set:
'Enable/Disable keyclick
Lcd_textbuffer = "ON/OFF"
Gosub Lcd_print
Return

Vitis
26.07.2008, 01:48
siehste, war doch garnicht so schwer ;)

die ASM-Geschichten machen den Code zwar nicht besonders
übersichtlich aber "never change a running system" [-X

mal nebenbei, auch mein system hat seine schwächen
aber läuft :)

-tomas-
26.07.2008, 11:33
es gibt noch gute Nachrichten:
nachdem wir vor 2 Jahren das Thema diskutiert hatten:
"State Machine: LOADLABEL in DATA einsetzen"https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=191075&highlight=#191075
wurde in BASCOM in der Version 1.11.8.9 den Befehl ADR und ADR2 ergänzt

Das gibt uns ganz neue Möglichkeiten die Datensätze anzulegen \:D/ und den Resourcenfresser "Select Case" zu beerdigen
Codeschnipsel
S10:
ADR2 Null : ADR2 S20 : ADR2 Null : ADR2 S11 'Key_plus|Key_minus|Key_prev|Key_next
ADR2 Null 'Subroutine for current State
Data "1 Butterfly Bascom" 'Menue Display TextAnbei eine geänderte Fassung des Beispiel-Menüs. Die Codelänge schrumpfte von 3300Byte auf sagenhafte 2200 Byte und liegt damit mit der alten unübersichtlichen Fassung aus dem AVR Butterfly Evaluation Kit gleichauf

Anbei wieder vollständig lauffähiger Code für den Bascom-Simulator (getestet 1.11.9.1)

'Beispiel für ein State Machine Menü
'Das Beispiel ist für den BASCOM-Simulator angepasst worden
' getestet mit BASCOM 1.11.9.1
' Codelänge 2242 Byte

$regfile = "m32def.dat"
$framesize = 32 'Stack
$swstack = 32
$hwstack = 64

'
'Hinweis: Im Simulator müssen die Eingaben in dem blauen "Terminal Emulator Window" erfolgen!
'Auf der Tastatur ergeben sich für die VIER Joystick-Positionen folgende Umsetzungen
'
' [Key_plus ]
' [Key_prev] [ ] [Key_next]
' [Key_minus]
'
'
' [ Taste_8 ]
' [Taste_4 ] [ ] [Taste_6 ]
' [ Taste_2 ]
'
'bzw. im ASCII-Code:

Dim Keycode_string As String * 4
'Key_plus|Key_minus|Key_prev|Key_next
Keycode_string = "{056}{050}{052}{054}"
Dim Keycode(4) As Byte At Keycode_string Overlay
Const Key_null = 0 'keine Taste gedrückt

'Pins des LCD-Modules setzen ggf. an eigene Anschlüsse anpassen
Config Lcd = 16 * 1
Initlcd
Cls

'******** Joystick/Key Settings ***********************************************
Dim Key As Byte 'key in Mainloop

'******** LCD ************************************************** ***************
Dim Lcd_textbuffer As String * 25

'******** allg Variablen ************************************************** ****
Dim I As Byte , J As Byte
Dim W As Word

'********* State Variables ************************************************** **
Dim State As Word 'aktueller State
Dim State_renew As Byte 'Flag
Dim State_gosub As Word 'aktuelles Unterprogramm

'Initial state variables
State_renew = 1
State = Loadlabel(s10) 'Startbildschirm
Key = Key_null 'keine Taste gedrückt


'********** MAIN-Loop ************************************************** *******
Do
'Menüeintrag und Tastencodes finden und ggf. State wechseln
'hier nur Tastendruck auswerten
Gosub Change_state
'Pointer nach Statuswechsel neu setzen
If State_renew = 1 Then Gosub Change_state
'Unterprogramm des aktuellen State anspringen
LDS R31, {State_gosub+1} 'High see Bascom-Doc Mixing ASM and BASIC
LDS R30, {State_gosub} 'Low
LSR R31 'Division durch 2 (Alternativ ADR verwenden)
ROR R30
'Call zum Sub
ICALL

'Displaytext auslesen
Read Lcd_textbuffer

'---------------------------------------------------------------
'place for your own code in main loop
'---------------------------------------------------------------

'LCD refresh wenn Menü verändert
If State_renew = 1 Then
State_renew = 0
Gosub Lcd_print
End If

'Tastaturabfrage mit Halt nur für Simulator, ansonsten Sleep+Timer_ISR verwenden!!
Key = Waitkey()

Loop
End

'********* State routines ************************************************** *
'---------------------------------------------------------------
'Subroutine: Change_state
'Call from: main loop
'Purpose: Status der State Machine feststellen und ggf. Wechseln
'Result: Pointer auf State / Variable State_renew
'---------------------------------------------------------------
Change_state:
lds R8, {State}
lds R9, {State + 1}
For I = 1 To 4
Read W
If Key = Keycode(i) Then
If W <> Loadlabel(null) Then
State_renew = 1
Key = Key_null 'reset key status after get a new state of state machine (prevent influence on GOSUBs)
State = W
End If
End If
Next I
Read State_gosub 'Adesse des akt. Unterprogramms einlesen
Return

'---------------------------------------------------------------
'DATA: State Machine
'Result: Pointers auf States , Unterprogramme
' Menütexte
'---------------------------------------------------------------

Null:
'Null is a dummy flag for State and Gosub -> do nothing
Return

S10:
ADR2 Null : ADR2 S20 : ADR2 Null : ADR2 S11 'Key_plus|Key_minus|Key_prev|Key_next
ADR2 Null 'Subroutine for current State
Data "1 Butterfly Bascom" 'Menue Display Text
S11:
ADR2 Null : ADR2 Null : ADR2 S10 : ADR2 Null 'Key_plus|Key_minus|Key_prev|Key_next
ADR2 Null
Data "11 Rev 2"
S20:
ADR2 S10 : ADR2 S30 : ADR2 Null : ADR2 S21
ADR2 Null
Data "2 Time"
S21:
ADR2 Null : ADR2 S22 : ADR2 S20 : ADR2 S23
ADR2 Null
Data "21 Clock"
S22:
ADR2 S21 : ADR2 Null : ADR2 S20 : ADR2 S24
ADR2 Null
Data "22 Date"
S23: 'Show HH:MM:SS
ADR2 Null : ADR2 S24 : ADR2 S21 : ADR2 S25
ADR2 Showclock
Data ""
S24: 'Show DD:MM:YY
ADR2 S23 : ADR2 Null : ADR2 S22 : ADR2 S26
ADR2 Showdate
Data ""
S25:
ADR2 S27 : ADR2 Null : ADR2 S23 : ADR2 S65
ADR2 Null
Data "211 Adjust Clock"
S26:
ADR2 Null : ADR2 S28 : ADR2 S24 : ADR2 S66
ADR2 Null
Data "221 Adjust Date"
S27:
ADR2 Null : ADR2 S25 : ADR2 S23 : ADR2 S67
ADR2 Null
Data "212 Clock Format"
S28:
ADR2 S26 : ADR2 Null : ADR2 S23 : ADR2 S68
ADR2 Null
Data "222 Date Format"
S30:
ADR2 S20 : ADR2 S40 : ADR2 Null : ADR2 S31
ADR2 Null
Data "3 DataLogger"
S31:
ADR2 Null : ADR2 S32 : ADR2 S30 : ADR2 S35
ADR2 Null
Data "31 Log Cycle"
S32:
ADR2 S31 : ADR2 S33 : ADR2 S30 : ADR2 S36
ADR2 Null
Data "32 Delete Flash"
S33:
ADR2 S32 : ADR2 S34 : ADR2 S30 : ADR2 S37
ADR2 Null
Data "33 Show LogCount"
S34:
ADR2 S33 : ADR2 Null : ADR2 S30 : ADR2 S38
ADR2 Null
Data "34 Print to RS232"
S35: 'HH:MM
ADR2 Null : ADR2 Null : ADR2 S31 : ADR2 Null
ADR2 Datalogger_setloginterval
Data ""
S36:
ADR2 Null : ADR2 Null : ADR2 S32 : ADR2 S76
ADR2 Null
Data "321 RIGHT Delete DF"
S37: '1234
ADR2 Null : ADR2 Null : ADR2 S33 : ADR2 Null
ADR2 Datalogger_logcount
Data ""
S38:
ADR2 Null : ADR2 Null : ADR2 S34 : ADR2 S78
ADR2 Null
Data "341 RIGHT Print9600B"
S40:
ADR2 S30 : ADR2 S50 : ADR2 Null : ADR2 S41
ADR2 Null
Data "4 ADC"
S41:
ADR2 Null : ADR2 S42 : ADR2 S40 : ADR2 S45
ADR2 Null
Data "41 Temperature"
S42:
ADR2 S41 : ADR2 S43 : ADR2 S40 : ADR2 S46
ADR2 Null
Data "42 Voltage"
S43:
ADR2 S42 : ADR2 S44 : ADR2 S40 : ADR2 S47
ADR2 Null
Data "43 ADC Port RAW"
S44:
ADR2 S43 : ADR2 Null : ADR2 S40 : ADR2 S48
ADR2 Null
Data "44 Battery"
S45: '+24°C
ADR2 Null : ADR2 Null : ADR2 S41 : ADR2 Null
ADR2 Temperaturefunc
Data ""
S46: '0 mV
ADR2 Null : ADR2 Null : ADR2 S42 : ADR2 Null
ADR2 Voltagefunc
Data ""
S47: 'CH:RAW
ADR2 Null : ADR2 Null : ADR2 S43 : ADR2 Null
ADR2 Adc_raw_func
Data ""
S48: '2900mV
ADR2 Null : ADR2 Null : ADR2 S44 : ADR2 Null
ADR2 Adc_batt_func
Data ""
S50:
ADR2 S40 : ADR2 Null : ADR2 Null : ADR2 S51
ADR2 Null
Data "5 Options"

S51:
ADR2 Null : ADR2 S52 : ADR2 S50 : ADR2 S56
ADR2 Null
Data "51 LCD contrast"
S52:
ADR2 S51 : ADR2 S53 : ADR2 S50 : ADR2 S57
ADR2 Null
Data "52 Bootloader"

S53:
ADR2 S52 : ADR2 S54 : ADR2 S50 : ADR2 S83
ADR2 Null
Data "53 LCD OFF"

S54:
ADR2 S53 : ADR2 S55 : ADR2 S50 : ADR2 S58
ADR2 Null
Data "54 LCD Auto Power"

S55:
ADR2 S54 : ADR2 Null : ADR2 S50 : ADR2 S59
ADR2 Null
Data "55 Key Click"
S56: '0...15
ADR2 Null : ADR2 Null : ADR2 S51 : ADR2 Null
ADR2 Setcontrast
Data ""
S57:
ADR2 Null : ADR2 Null : ADR2 S52 : ADR2 S87
ADR2 Null
Data "521 RIGHT bootloader"

S58: 'OFF/5..90min
ADR2 Null : ADR2 Null : ADR2 S54 : ADR2 Null
ADR2 Autopower
Data ""
S59: 'ON/OFF
ADR2 Null : ADR2 Null : ADR2 S55 : ADR2 Null
ADR2 Keyclick_set
Data ""
'Untermenüs zu State 25 bis 28
S65: 'sub for "211 Adjust Clock"
ADR2 S67 : ADR2 Null : ADR2 S23 : ADR2 Null
ADR2 Setclock
Data ""
S66: 'sub for "221 Adjust Date"
ADR2 Null : ADR2 S68 : ADR2 S24 : ADR2 Null
ADR2 Setdate
Data ""
S67: 'sub for "212 Clock Format"
ADR2 Null : ADR2 S65 : ADR2 S23 : ADR2 Null
ADR2 Setclockformat
Data ""
S68: 'sub for "222 Date Format"
ADR2 S66 : ADR2 Null : ADR2 S24 : ADR2 Null
ADR2 Setdateformat
Data ""
'Untermenüs zu State 36 und 38
S76: 'sub for "321 RIGHT Delete DF"
ADR2 Null : ADR2 Null : ADR2 S36 : ADR2 Null
ADR2 Datalogger_erase
Data ""
S78: 'sub for "341 RIGHT Print9600B"
ADR2 Null : ADR2 Null : ADR2 S38 : ADR2 Null
ADR2 Datalogger_rs232
Data ""
'Untermenü zu State 53 und 57
S83: 'sub for "53 LCD OFF"
ADR2 Null : ADR2 Null : ADR2 S53 : ADR2 Null
ADR2 Power_off_func
Data ""
S87: 'sub for "521 RIGHT bootloader"
ADR2 Null : ADR2 Null : ADR2 S57 : ADR2 Null
ADR2 Bootfunc
Data ""


'********* LCD SUB routines ************************************************** *
'---------------------------------------------------------------
'Subroutine: Lcd_print
'Call from: anywhere
'Purpose: gibt Lcd_textbuffer auf dem LCD-Display aus
'Result: LCD
'---------------------------------------------------------------
Lcd_print: 'Print lcd_textbuffer
Cls
Lcd Lcd_textbuffer
State_renew = 0
Return

'********* SUB Clock routines****************************************** ********
Showclock:
'Show the clock on the LCD
Lcd_textbuffer = "HH:MM:SS"
Gosub Lcd_print
Return

Setclock:
'Adjusts the Clock
Lcd_textbuffer = "HH=11"
Gosub Lcd_print
Return

Setclockformat:
'Adjusts the Clockformat (12H or 24H)
Lcd_textbuffer = "12H / 24H"
Gosub Lcd_print
Return

'********* SUB date routines **************************************************
Showdate:
'Show the date on the LCD
Lcd_textbuffer = "DD.MM.YY"
Gosub Lcd_print
Return

Setdate:
'Adjusts the Date
Lcd_textbuffer = "Month=12"
Gosub Lcd_print
Return

'---------------------------------------------------------------
Setdateformat:
'Adjusts the Dateformat "DDMMYY" , "MMDDYY" , "YYMMDD"
Lcd_textbuffer = "DDMMYY/YYMMDD"
Gosub Lcd_print
Return

'********* Datalogger routines ************************************************
Datalogger_setloginterval:
'set the datalog intervall HOUR:MINUTES
Lcd_textbuffer = "HH:MM"
Gosub Lcd_print
Return

Datalogger_erase:
'erase the dataflash
State = Loadlabel(s32) 'St_datalogger_erase
State_renew = 1
Gosub Change_state
Return

Datalogger_logcount:
'Show DF_LogCount
Lcd_textbuffer = "1234"
Gosub Lcd_print
Return

Datalogger_rs232:
'Print all DataLogs to RS232
State = Loadlabel(s34) 'St_datalogger_rs232 as next status of state machine
State_renew = 1
Gosub Change_state
Return

Temperaturefunc:
'temperature measurement in °C
Lcd_textbuffer = "+24C"
Gosub Lcd_print
Return

Voltagefunc:
'voltage measurement mV
Lcd_textbuffer = "0mV"
Gosub Lcd_print
Return

Adc_raw_func:
'ADC Temperature/Voltage/Light result as RAW
Lcd_textbuffer = "CH:RAW"
Gosub Lcd_print
Return

Adc_batt_func:
'battery voltage measurement
Lcd_textbuffer = "2900mV"
Gosub Lcd_print
Return

'********* Sub MENU / OPTIONS ********************************
Setcontrast:
'Adjust the LCD contrast
Lcd_textbuffer = "0...15"
Gosub Lcd_print
Return

Bootfunc:
State = Loadlabel(s10) 'St_avrbf as next status of state machine
State_renew = 1
Gosub Change_state
Return

Power_off_func:
'LCD OFF
State = Loadlabel(s53) 'Return State is St_options_power_off
Return

Autopower:
'Enable/Disable auto power save
Lcd_textbuffer = "ON/OFF"
Gosub Lcd_print
Return

Keyclick_set:
'Enable/Disable keyclick
Lcd_textbuffer = "ON/OFF"
Gosub Lcd_print
Return
Zur Info die Struktur des Testmenü:
https://www.roboternetz.de/wissen/images/8/83/Butterflymenu.png

dl1akp
01.08.2008, 06:58
Hi Leute,

Kann mir als Dummy mal einer sagen:

Was zum Geier ist eine State Machine??? :-k

Danke, schönes Wochenende
dl1akp

Vitis
01.08.2008, 09:32
Im Prinzip ist es ganz einfach.
Programme werden ja immer komplett ausgeführt.
Sprich, es wird im Flussdiagramm oben angefangen und sich
nach unten durchgearbeitet.
Bei großen komplexen Programmen kann das aber ärger geben.
Z.B. Du hast eine Vorrichtung, die mit sagen wir mal CAN-Bus, Display,
Tastenpanel, RS232, und diverse Sensoren dann kann z.B.
Der Displayrefresh bei jedem Programmdurchlauf die ganze
Geschichte mächtig ausbremsen. Kommt dann noch dazu
Tastenabfrage kanns ganz finster werden.
Dein Bus wird durch die tausende von PRogrammschritten
fürs Userinterface arschlangsam.
Geht man nun hin und fragt nur alle x Programmdurchläufe
die Tasten ab gewinnt man schon Ausführungszeit.
Tut man nun das Display nur bei bestimmten Events, z.B.
Tastendruck aktualisieren gewinnt man nochmal ne Menge
Ausführungszeit.
Man speichert also die Zustände, die States, des Programmablaufs
in eine selbst definierte Struktur. Die einzelnen Programmteile
gehen dabei immer in die Hauptroutine zurück, wo dann
geprüft wird ob nun ein Zustand ansteht ... z.B. ein Telegramm
vom Bus. Von dort gehts dann in die entsprechende Subroutine
und wieder zurück in die Mainloop.

Stromi
01.08.2008, 10:04
Respekt !!!
Ich habe selten soviel gute Information auf einmal in einem Forum gelesen.
Ich habe wiedermal viel gelernt von euch.
Danke !! =D>

Vitis
02.08.2008, 09:12
Bei nem Menü fürs Display, also nem User Interface,
wird die Sache etwas verzwickter.
N Menü lässt sich eigentlich recht einfach
zusammenschustern. Per Select - Case
Menüpunkte auswählen und warten auf Tastenabfrage
ist einfach, aber ne Struktur, die ständig rein und raus
springt und dabei die Zustände festhält ist ne ganz
andere Geschichte.