Shop OBEX P1 Docs P2 Docs Learn Events
Code for a Menu — Parallax Forums

Code for a Menu

tdeyletdeyle Posts: 85
edited 2008-10-31 18:50 in Propeller 1
Okay. I have a project that I have been working on for the past few months.

I have the backend working, but I need a Menu system. I have already coded a menu system that works fine, but is messy and large.

I am trying to streamline the code and make it a little more elegant. I am using the Parallax 4x20 character display as well as the
Serial Terminal Debugger on the PC to see where the program is.

I have broken down the menu into separate 5 types:
- Splash Screens (all text, either timed display or press down to continue)
- Menus (Contains all text, but displays an arrow indicating the current selection)
- Choice Menus (Contains choices that when selected, will adjust one value that is displayed)
- Status Screens (Contains values that are displayed from other cogs)
- Tables (Contains a Table of Values that can be adjusted)

The system is controlled with a 4 position button arranged for Up, Down, Left, Right; two buttons for Select and Back; and two more buttons for
Incrementing and Decrementing values.

Basically, I have a method that detects what Menu is being requested which sends it to another method to display the data according to a configuration
table. There are variables to track where the selection is, a method to keep track when an input is made which assigns a value to a variable, to which
the displaying method uses to perform a function (Move Selection Up, Select, Go back one Menu, etc.). I know, when I read it back, it sounds a little confusing,
but I drew a picture - MethodFlowChart.jpg

I am having trouble early on.

The trouble I am having is with the "Menu" MenuType. It seems that when I select one of the options, I move to the next menu. When I go back,
I get the previous menu. But, after doing this two-three times, the program crashes. I have added PST debugging strings that would give me a clue as
to what is happening.

For some reason, the log shows that just before it becomes unresponsive, the program proceeds to go to MenuNumber #12, but ends up displaying #196.

Why would the MenuNumber be a different value to what was assigned to it in the previous line? The code is attached as well as the log file.

Any help is appreciated. If you have any questions on items that I have left out, let me know.

case InputFlag
  7:
    simple.str(string(">"))
    simple.str(string("Current MenuNumber: "))
    simple.str(numb.dec(MenuNumber))
    simple.tx(13)

    MenuNumber := byte[noparse][[/noparse]ConfigAddress]
    YPos := byte[noparse][[/noparse]ConfigAddress]

    simple.str(string(">"))
    simple.str(string("Going BACK to Menu Number: "))
    simple.str(numb.dec(MenuNumber))

    simple.str(string(", with YPos: "))
    simple.str(numb.dec(YPos))
    simple.tx(13)
    
    GetBaseAddresses(MenuNumber)
    
  8:
    simple.str(string(">"))
    simple.str(string("Current MenuNumber: "))
    simple.str(numb.dec(MenuNumber))
    simple.tx(13)
    
    MenuNumber := byte[noparse][[/noparse]@@MenuNumberTable[noparse][[/noparse]MenuNumber+35]][noparse][[/noparse]4+YPos]
    YPos := 1      

    simple.str(string(">"))
    simple.str(string("Going AHEAD to Menu Number: "))
    simple.str(numb.dec(MenuNumber))

    simple.str(string(", with YPos: "))
    simple.str(numb.dec(YPos))
    simple.tx(13)

    GetBaseAddresses(MenuNumber)

Comments

  • tdeyletdeyle Posts: 85
    edited 2008-10-30 19:15
    Okay, so I added a few more debugging comments, this time in the GetBaseAddresses method.

    PST doesn't show any of the comments! So the DisplayMethod is not calling the GBA method.

    Problem is, I can't see why. Is it too obvious?
  • tdeyletdeyle Posts: 85
    edited 2008-10-30 19:41
    This is too funny!

    When I saved the SPIN file to upload to here, I saved in on my network drive.

    Forgetting that I had to save it in my project folder after, I started making the changes that I mentioned below. Each time I tried to write it to the Prop, it was obviously using the one in the project folder, not the one that I was editing.

    It now shows the DisplayMenu method calling the GBA method, and displaying the debug comments in it.

    I also moved the GetBaseAddresses call from inside the CASE loop, to the last entry of the DisplayMenu method:

    case InputFlag
      7:
        simple.str(string(">"))
        simple.str(string("Current MenuNumber: "))
        simple.str(numb.dec(MenuNumber))
        simple.tx(13)
    
        MenuNumber := byte[noparse][[/noparse]ConfigAddress]
        YPos := byte[noparse][[/noparse]ConfigAddress]
    
        simple.str(string(">"))
        simple.str(string("Going BACK to Menu Number: "))
        simple.str(numb.dec(MenuNumber))
    
        simple.str(string(", with YPos: "))
        simple.str(numb.dec(YPos))
        simple.tx(13)
        
      8:
        simple.str(string(">"))
        simple.str(string("Current MenuNumber: "))
        simple.str(numb.dec(MenuNumber))
        simple.tx(13)
        
        MenuNumber := byte[noparse][[/noparse]ConfigAddress][noparse][[/noparse]4+YPos]
        YPos := 1      
    
        simple.str(string(">"))
        simple.str(string("Going AHEAD to Menu Number: "))
        simple.str(numb.dec(MenuNumber))
    
        simple.str(string(", with YPos: "))
        simple.str(numb.dec(YPos))
        simple.tx(13)
        
    GetBaseAddresses
    
    



    This seems to have worked, extending the amount of times I can Select and go Back in a menu. However, I still get a crash with the MenuNumber value = 196. Now, I counted the number of times that I can press Select -> Back -> Select -> Back, etc., and noticed that it was 21 times, consistently.
  • tdeyletdeyle Posts: 85
    edited 2008-10-30 20:00
    Well, it looks as though during the WaitForInput method, the ConfigAddress is changed, for some reason.
  • tdeyletdeyle Posts: 85
    edited 2008-10-30 20:05
    I shortened the stack down from 200 to 100, only got 8 Select -> Back presses out of it before it crashed.

    Looks like I have to loop this differently.
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-10-31 14:26
    Hello tdeyle,

    I'm willing to help but i don't understand your menusystem and what the problem is.

    I guess it has taken you some HOURS or even days to develop this menustructure.

    I don't like analysing your menu-picture for hours until I understand it
    from the code given it takes a lot of time to analyse what is going on just from READING the code

    As I don't have an LCD laying around could you create a version that get's along with one serial connection
    to show everything ? Or maybe a version that can use PropTerminal ?
    Then all that is needed is a prop and a serial connection
    Then everyone can test your program without needing your special hardware

    The zipfile you posted seems to be just the display-object but the mainfile that calls the start-method of
    the display-object is not included

    best regards

    Stefan
  • tdeyletdeyle Posts: 85
    edited 2008-10-31 14:37
    Understood, I figured it wouldn't be a simple "look at the code" and something would jump out.

    Let me take a few and try to rewrite the code for the PropTerminal.
  • Paul BakerPaul Baker Posts: 6,351
    edited 2008-10-31 17:07
    Have you taken a look at the menu system developed by Jon Williams? http://www.parallax.com/dl/docs/cols/nv/vol2/col/nv62.pdf
    It is written for the Stamp, but I have always found it relatively easy to port BS2 code to the Propeller. It could definitely provide some insight to program flow.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • tdeyletdeyle Posts: 85
    edited 2008-10-31 17:22
    Thanks Paul! I will check it out.
  • Sleazy - GSleazy - G Posts: 79
    edited 2008-10-31 18:05
    The more strings you can reference from DAT blocks by address, the better.· That way youre not using·bytes on "string" each time when calling the serial object. If you reference DAT block strings by address, it also allows you to reuse that address in other subroutines, instead of having to type out and store the literal string each time. Just a tip.
  • Sleazy - GSleazy - G Posts: 79
    edited 2008-10-31 18:12
    I also find it easier to use lookup tables with aforementioned DAT addresses instead of using a CASE structure. That way , you can write one block of code , and lookup addresses of the strings needed for a desired operation. If you use the CASE structure youve shown, youre going to run out of space quickly. Especially trying to make NTSC menus.

    Try to write a universal method for each serial operation, as a subroutine with an input variable acquired from a lookup table. The index of the lookup table would be analogous to the current menu status.
  • tdeyletdeyle Posts: 85
    edited 2008-10-31 18:40
    Bear with me, memory usage is not a strong suit for me.

    So after reading your post, Sleazy-G, I ran the program piggybacked on the Stack Length code. I found out that every time I press the SELECT or BACK button, I use 10 longs.

    Why is that? How do I regain that memory back? I don't understand why it is happening.
  • tdeyletdeyle Posts: 85
    edited 2008-10-31 18:42
    Okay, after a little reading, I notice that the reason is because the methods aren't returning to the calling method. This returns the space that was taken to run that method.
  • tdeyletdeyle Posts: 85
    edited 2008-10-31 18:50
    Aha! So I put the GetBaseAddresses in a REPEAT loop, so that every Display method that is called by it returns, replenishing the stack!

    Checked with the StackLength code and it seems to not go up over 41. I know that is not a firm number, I will still keep it @ 100, I was only using it to see if I ran out of space.
Sign In or Register to comment.