Menu system in Spin with 3 buttons and minimum / maximum range.
eagletalontim
Posts: 1,399
And now on to another part of my coding.... I have a simple menu system setup I wrote using arrays to pre-define the menu item and another array that stores the value for each menu item.
Example of what I have now (Not all Code is here) :
What I have works just fine, but I don't like the navigation of the menu system since I am only using 3 buttons (Up, Down, Menu/Enter). I want to convert the entire menu to be much more accessible without having to go through each menu item till I get to the one I need to change.
Currently, I am working with the Parallax 2x16 Serial display so my space is limited on what I can put on the screen. The first initial screen is the "working" screen which shows updated variables as the program runs and reads sensors. This screen must be cleared and the cog stopped to prevent other writing on the screen while in the menu system. Once the cog is stopped, another is started for the Menu system to take over. If there is a better way to do this, please let me know.
My idea is to stay with the 3 buttons but have the menu button instantly access the menu instead of holding it down for 2 or 3 seconds. Then once the menu is loaded, each menu item will be listed on the screen 2 items at a time. When I press the down button, the menu items will shift up so I can "scroll" through the menu. The selected line will be show with an ">" and will stay on the first line of the screen. Once the menu item I want to edit is in the selected line, I can then press the Menu/Enter button to edit its value. I can more than likely get to this point with the changes but here is where I am not sure what to do to make this easier in programming terms. I am only a little knowledgeable in Spin and cannot grasp PASM at all.
Each menu item's value (the Stored[] variable) will be a numerical value stored in the EEPROM which is updated by adjusting the value in the menu. Each menu item's value will need to have a pre-defined range (Minimum and Maximum value). Some values will be 1, 2, or 3, some will be 15 through 100. This means that when a specific menu item is being changed, the value must not go higher or lower than that specific menu item's pre-defined range. What would be the best way to accomplish this in SPIN? Using Arrays seems to be easiest for me currently since I can use the Array pointer as the multiplier for where to save the value in the EEPROM.
Example of what I have now (Not all Code is here) :
VAR LONG Menu[255] BYTE Stored[255] PUB Main Menu[0] := string("Menu Item 1") Menu[1] := string("Menu Item 2") Menu[2] := string("Menu Item 3") Menu[3] := string("Menu Item 4") StartLCD PUB StartLCD StopLCD cogon := (cog := cognew(LCDupdate, @LCDstack)) > 0 PUB StopLCD if cogon~ cogstop(cog) PUB StartMenu StopLCD cogon := (cog := cognew(EnterMenu, @LCDstack)) > 0 PUB EnterMenu | btnpresstime, startid, userExit startid := 0 userExit := 0 lcd.init(24, 9600, 2) lcd.displayOn lcd.backLight(TRUE) waitcnt(1_000_000 + cnt) lcd.gotoxy(0,0) lcd.str(string("Programming Menu")) lcd.gotoxy(0,1) lcd.str(string("Loading.... ")) waitcnt(100_000_000 + cnt) repeat DisplayMenu(startid) UpdateMenuValue(startid, 0) userExit := 0 repeat until userExit == 1 btnpresstime := 0 repeat while ina[downbutton] == 1 or ina[upbutton] == 1 or ina[menubutton] == 1 if(ina[downbutton] == 1) if(btnpresstime == 0) UpdateMenuValue(startid, -1) if(ina[upbutton] == 1) if(btnpresstime == 0) UpdateMenuValue(startid, 1) if ina[menubutton] == 1 if btnpresstime == 0 saveval(Stored[startid], startid) userExit := 1 btnpresstime++ waitcnt(20_000_000 + cnt) if(btnpresstime == 10) restartMain := 1 startid++ if(startid > menuItems) startid := 0 PUB DisplayMenu(id) lcd.gotoxy(0,0) lcd.str(Menu[id]) lcd.gotoxy(0, 1) lcd.str(String("Value : ")) PUB UpdateMenuValue(id, amount) lcd.gotoxy(8, 1) Stored[id] := Stored[id] + amount lcd.str(string(" ")) lcd.gotoxy(8, 1) lcd.str(num.dec(Stored[id]))
What I have works just fine, but I don't like the navigation of the menu system since I am only using 3 buttons (Up, Down, Menu/Enter). I want to convert the entire menu to be much more accessible without having to go through each menu item till I get to the one I need to change.
Currently, I am working with the Parallax 2x16 Serial display so my space is limited on what I can put on the screen. The first initial screen is the "working" screen which shows updated variables as the program runs and reads sensors. This screen must be cleared and the cog stopped to prevent other writing on the screen while in the menu system. Once the cog is stopped, another is started for the Menu system to take over. If there is a better way to do this, please let me know.
My idea is to stay with the 3 buttons but have the menu button instantly access the menu instead of holding it down for 2 or 3 seconds. Then once the menu is loaded, each menu item will be listed on the screen 2 items at a time. When I press the down button, the menu items will shift up so I can "scroll" through the menu. The selected line will be show with an ">" and will stay on the first line of the screen. Once the menu item I want to edit is in the selected line, I can then press the Menu/Enter button to edit its value. I can more than likely get to this point with the changes but here is where I am not sure what to do to make this easier in programming terms. I am only a little knowledgeable in Spin and cannot grasp PASM at all.
Each menu item's value (the Stored[] variable) will be a numerical value stored in the EEPROM which is updated by adjusting the value in the menu. Each menu item's value will need to have a pre-defined range (Minimum and Maximum value). Some values will be 1, 2, or 3, some will be 15 through 100. This means that when a specific menu item is being changed, the value must not go higher or lower than that specific menu item's pre-defined range. What would be the best way to accomplish this in SPIN? Using Arrays seems to be easiest for me currently since I can use the Array pointer as the multiplier for where to save the value in the EEPROM.
Comments
http://forums.parallax.com/showthread.php?141846-Menus-on-the-Parallax-4X20-Serial-LCD-Screen.&p=1118421&viewfull=1#post1118421
I am sure I can do the scrolling menu which is the easier part of my question My biggest issue is the minimum and maximum values for each individual menu item.
BTW, this is not good design due to scope.
http://obex.parallax.com/objects/696/
I have an (unpublished) 3-button version I can post if it would help...though extending the 1-button method to 3 is pretty straightforward.
You already have an array for storing the values I guess. So, what you need is simply add 2 more arrays one named maxval and one called minval.
This does not look like an array, but you can use it in the same way. In the code where you increment or decrement the value you's simply write:
' increment
value[ actual_selection ] := ++value[ actual_selection ] <# maxval[ actual_selection ]
' decrement
value[ actual_selection ] := --value[ actual_selection ] #> minval[ actual_selection ]
I have no idea what scope means and can't figure out how it is different from this :
It would be as easy as
check_buttons, update_screen1 and update_screen2 being functions.
check_buttons reads the buttons and according to the mode it is doing different things:
if mode == MODE_SCREEN1 it switches into the other mode if the right button is pushed (switch to menu).
if mode == MODE_SCREEN2 it switches into the other mode if the right button is pushed (going back to main screen).
and it updates values if increase decrease buttons are pushed
and it updates print_from variable if buttons for scrolling in the menu are pushed.
update_screen1 simply print values that are updated by other code running in n other COGs
update_screen2 prints the actual part of the menu (print_from variable) and the editable values