Shop OBEX P1 Docs P2 Docs Learn Events
Print Menu on 4x20 LCD? — Parallax Forums

Print Menu on 4x20 LCD?

computer guycomputer guy Posts: 1,113
edited 2010-01-24 01:17 in Propeller 1
Hi,


I need to store the following data in my code and call it later, does anyone know how I can?

Text              Function

Menu
├─Date/Time       goto "Date/Time" menu
│ ├─Set Date      goto "Set Date"  menu
│ │ ├─Day         goto "Set Day"   menu
│ │ ├─Month       goto "Set Month" menu
│ │ └─Year        goto "Set Year"  menu
│ └─Set Time      goto "Set Time"  menu
│   ├─Hour        goto "Set Hour"  menu
│   └─Minute      goto "Set Min"   menu
└─Timer           goto "Timer"     menu
  ├─Duration      goto "Set Duration" menu
  └─PreHeat       goto "Set PreHeat"  menu




A multidimensional array was my first idea, however this isn't supported in SPIN.

Any other ideas?


Thank you smile.gif

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"powered by Propeller" domed stickers $1.50 - Find them here
Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net

Post Edited (computer guy) : 1/15/2010 12:00:35 PM GMT
«1

Comments

  • Graham StablerGraham Stabler Posts: 2,510
    edited 2010-01-12 12:28
    You could create the same functionality as a matrix (2D array) with a 1D array:

    1 2
    3 4

    Where the numbers are the element in the 1D array.

    You then write a simple function getelement(row, column) which will convert the specified row and column into a 1D index of the 1D array. You can also do the same for 3D matrices.

    Graham
  • computer guycomputer guy Posts: 1,113
    edited 2010-01-12 12:31
    Hi Graham,

    Could you please explain this in more detail. I kind of see what you are saying but not entirely and to be honest I think I am just getting more confused every time I try and make sense of it.


    Thank you smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "powered by Propeller" domed stickers $1.50 - Find them here
    Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2010-01-12 13:39
    I drew a 2D array, an array with two columns and two rows. This can be how you think about your data however the actual data can still be stored in a single 1D array. Take this 3X3 array:

    r1c1 r1c2 r1c3 r2c1 r2c2 r2c3 r3c1 r3c2 r3c3

    So the first element is row 1 column 1, the second is row 1 column 2. It is a 1D array representing the following 3X3 array:

    r1c1 r1c2 r1c3
    r2c1 r2c2 r2c3
    r3c1 r3c2 r3c3

    Your function would be designed to get a particular element from the 1D array given the specified row and column. In this case which is not very accurate because the first element is 1 not 0 like in spin then you would have

    1D_index = (row*3) - 3 + (column - 1)


    (row*3)-3 gives you the address of the first element of a particular row to which you add the column to get the particular element

    How you use this for your particular application I am not sure but it was you that suggested multidimensional arrays [noparse]:)[/noparse]

    Graham
  • computer guycomputer guy Posts: 1,113
    edited 2010-01-12 13:50
    My idea was to have multiple arrays and then use the index as an ID field that links the arrays. Is this similar or am I missing the point?

    MenuName[noparse][[/noparse] 0] := "Date/Time"
    MenuName[noparse][[/noparse] 1] := "Set Time"
    MenuName[noparse][[/noparse] 2] := "Set Date"
    
    MenuFunc[noparse][[/noparse] 0] := DateTime
    MenuFunc[noparse][[/noparse] 1] := SetTime
    MenuFunc[noparse][[/noparse] 2] := SetDate
    
    MenuParent[noparse][[/noparse] 1] := 0
    MenuParent[noparse][[/noparse] 2] := 0
    
    



    Thank you smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "powered by Propeller" domed stickers $1.50 - Find them here
    Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2010-01-12 14:57
    I honestly don't know if you missed the point or not, I was just showing a fairly typical way of implementing a 2D array.

    Graham
  • mparkmpark Posts: 1,305
    edited 2010-01-12 16:40
    computer guy said...
    ...
    MenuFunc[noparse][[/noparse] 0] := DateTime
    MenuFunc[noparse][[/noparse] 1] := SetTime
    MenuFunc[noparse][[/noparse] 2] := SetDate
    
    



    If I understand correctly, you want to store pointers to three routines in the MenuFunc array so that later you can invoke one dynamically based on an index into the array. Unfortunately, Spin does not allow this.
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2010-01-12 18:48
    mpark said...
    computer guy said...
    ...
    MenuFunc[noparse][[/noparse] 0] := DateTime
    MenuFunc[noparse][[/noparse] 1] := SetTime
    MenuFunc[noparse][[/noparse] 2] := SetDate
    
    



    If I understand correctly, you want to store pointers to three routines in the MenuFunc array so that later you can invoke one dynamically based on an index into the array. Unfortunately, Spin does not allow this.

    But you could store a label that you fed into a case statement, each case being a different function.

    Graham
  • computer guycomputer guy Posts: 1,113
    edited 2010-01-12 22:05
    Graham,
    Graham Stabler said...

    But you could store a label that you fed into a case statement, each case being a different function.

    Thats what I was planning to do.

    Can you have an array of strings and if so, what datatype would I use?
    e.g.
    PUB main
      Array := [noparse][[/noparse]"Test", "Test2", "Test3"]
      debug.str(Array[noparse][[/noparse] 0])
    
    or
    
    DAT
      Array     Byte    "Test", "Test2", "Test3"
    
    PUB main
      debug.str(Array[noparse][[/noparse] 0])
    
    



    Thank you smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "powered by Propeller" domed stickers $1.50 - Find them here
    Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net

    Post Edited (computer guy) : 1/12/2010 10:13:20 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2010-01-12 23:34
    Nope. You can't have an array of strings. Strings are already arrays of bytes and you can't have arrays of arrays except with HomeSpun. What you can do is have an array of string addresses that points into an array of bytes. Look at FemtoBasic near the beginning where there's a table of keywords.
  • VIRANDVIRAND Posts: 656
    edited 2010-01-12 23:42
    I am not sure what language you are familiar with that gives you that structure,
    but lets say it is C which I can understand but not write.
    Don'y you have to define the structure yourself?

    I think the way people have been suggesting is to figure out what the structure looks like in memory and then
    make arithmetic that converts your indexes into a single index. That requires memory allocated for all possible
    array values fields.

    The alternative is to have variable length strings which can be null and require 1 or less bytes if they are empty,
    like a lot of classic (1980s) BASICs do. In SPIN you would have to manage all elements of all arrays within one
    string, and I guess each element would have pointers to other elements to create a tree structure, or whatever
    structure works well for you. This method may or may not require "garbage collection" (if the array gets full and
    elements are often changing size or being removed)... Perhaps there are newer ways of doing this. I still think like
    it's 1980 and need to conserve RAM, which is appropriate for Propeller. If you use an SD card for storage,
    different rules apply that I don't yet know well enough to explain, but may be better for your data structure,
    because they have gigabytes.

    Post Edited (VIRAND) : 1/13/2010 1:44:44 AM GMT
  • computer guycomputer guy Posts: 1,113
    edited 2010-01-13 00:13
    Wow. This is getting really complicated.
    Thank you all for your help though.

    I will explain what I am wanting to do.
    I have an lcd display (4x20) and 4 buttons (Up, Down, Ok, Back) and I want to build a menu structure and make it possible to go into sub menus.
    This entire concept is new to me.


    Thank you smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "powered by Propeller" domed stickers $1.50 - Find them here
    Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net

    Post Edited (computer guy) : 1/13/2010 12:18:06 AM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-01-13 07:45
    So, what you need is a structure in memory that describes a menu and stores the text to display and some functions for displaying parts of the menu.

    dat
    mainmenu word @mm_entry1, @mm_entry2, @mm_entry3, @mm_entry4, @mm_entry5, 0
     
    submenu1 word @s1_entry1, @s1_entry2, 0
    submenu2 word @s2_entry1, @s2_entry2, @s2_entry3, 0
     
    mm_entry1  byte "mm entry 1 text",0
    mm_entry2  byte "mm entry 2 text",0
    mm_entry3  byte "mm entry 3 text",0
    ....
    s2_entry3  byte "s2 entry 3 text",0
     
    

    This would be a data structure for your problem.
    Then you need a function that can print the menu on the LCD display, like

    printMenu( menu_address )
    and maybe
    scrollMenu( start_with_entry )

    Next is a input loop, which will react on the user input and a big case statement that is calling the right functions.

    pub main
      printMenu( @mainmenu )
      menu_entry_focus := 0
      menu_level_iterator := 1
      menu_level_mask := $f
     
      repeat
        key := keyboard.getKey
        if key==level_up_key
          menu_level_iterator >>= 4
          menu_entry_mask >>= 4
          menu_entry_focus &= menu_entry_mask        ' delete the part of the previous level
          key:=ok                                    ' this will then reprint the menu
        case key
          up:
            menu_entry_focus:=menu_entry_focus - menu_level_iterator
            ' check that it's not negative
            ' if focus is outside of the lines currently displayed, call scrollMenu
          down:
            menu_entry_focus:=menu_entry_focus + menu_level_iterator
            ' check that it's not bigger than the number of entries in the active menu
            ' if focus is outside of the lines currently displayed, call scrollMenu
          ok:
            case menu_entry_focus
              $0:
                printMenu( @submenu1 )
                menu_level_iterator <<= 4
                menu_entry_mask := menu_entry_mask << 4 | $f
              $1:
                printMenu( @submenu2 )
                menu_level_iterator <<= 4
                menu_entry_mask := menu_entry_mask << 4 | $f
              $2:
                ' this is not a submenu, so you simply call the function behind this entry
                callWhatever
              ....
              
    

    With the menu_level_iterator you keep track of the route you used to go to the actual submenu. The main-menu currently can have 16 entries (because I used <<= 4, 4 bits = value 0-15·). So, the first digit of the hexadecimal menu_entry_focus will tell you which entry in the main menu has been selected. The entry selected in the next menu-level will be shown in the second digit of the hexadecimal. For example
    $21 means that first submenu 2 has been selected in the main menu and then entry 3 has been selected.

    As we have longs in SPIN you can have a menu structure with 8 levels and each submenu can have 16 entries. Should be enough.

    So, in the case statement you would add a value for every possible menu and sub-menu entry. And on this level you can decide whether the selected entry directly calls functions or would lead to a deeper level submenu.

    Hope that helped more than it confused ;o)

    PS: This is not tested code, I just hacked it for this post. I bet there are some minor bugs, but it should show the principle. (For example $0 is a bug. $0 should rather print the main menu and the first submenu can be selected with $1 ;o) So, in fact you only have 15 entries per menu-level, as the $0 of each level is needed for redisplay the submenu·when going up and down in the menu levels.

    Post Edited (MagIO2) : 1/13/2010 7:54:02 AM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-01-14 19:52
    Got silent in this thread! Either it worked, or you still digest what I wrote!?
  • computer guycomputer guy Posts: 1,113
    edited 2010-01-14 22:19
    I am still digesting. lol
    Thank you smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "powered by Propeller" domed stickers $1.50 - Find them here
    Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net
  • computer guycomputer guy Posts: 1,113
    edited 2010-01-15 06:16
    Ok.... I'm stuck on how to "print menu".
    Tried a few things, with interesting results but not what it should output.


    Thank you smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "powered by Propeller" domed stickers $1.50 - Find them here
    Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net
  • computer guycomputer guy Posts: 1,113
    edited 2010-01-15 23:51
    Why doesn't
    LCD.str(mainmenu[noparse][[/noparse]0])
    
    


    output the string contained in mm_entry1?


    Thank you smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "powered by Propeller" domed stickers $1.50 - Find them here
    Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-01-16 00:06
    I worked with pointers in a dat for another thing yesterday and found out that somehow the pointers in a dat section have other values than in the SPIN code.

    For example:

    tv.dec( @table )
    tv.dec( table_adr )

    dat
    table_adr word @table
    table byte 0[noparse][[/noparse]10]

    shows tow different results. Maybe it even get's worse when you use several dat section and that one with the menu is somewhere at the end.

    For me it worked to add 16 to the value - possibly the 16 bytes that contain the clock-settings and some SPIN pointers.

    It also works to do a
    dat
    org 16

    PS: It's clear where the 16 comes from. It's the·propeller-tool 'internal' dat-section which is used to store the clock-settings and some SPIN pointers.

    Post Edited (MagIO2) : 1/16/2010 12:11:32 AM GMT
  • Paul Sr.Paul Sr. Posts: 435
    edited 2010-01-16 00:14
    ... so try LCD.str(@mainmenu[noparse][[/noparse]0])
  • mojorizingmojorizing Posts: 249
    edited 2010-01-16 00:18
    Computer Dude,
    here's my example of a menu driven 4 button 4X20 LCD code. It's for a hand held diagnostic tool for car. Disregard the PUB PROCESS_ECU , that's not finished in this version of my scantool, but gives an example how the LCD and push buttons work. This was actually ported from the SX forum from a post with me and JonnyMac talking about this same thing but with the SX.

    '' Scantool ver.1
    
    '' File: Scantool1.spin
    ''
    '' PUB MAIN could have repeat functions
    '' 
    ''
    CON
      _clkmode = xtal1 + pll16x        'Sets the clock speed to 80 MHz using a times 16 multiplier
      _xinfreq = 5_000_000             'Crystal speed: 5 MHz
    
      LCD_Pin                       = 10                        
      LCD_Baud                      = 19_200                   
      LCD_Lines                     = 4
      
       
      Btn_Up                        =11   'Left_Button 
      Btn_Down                      =12   'Middle_Button
      Btn_Select                    =13   'Right_Button
      Btn_Escape                    =14   'bottom button
    
      Enable_K_line                 =15
      K_Line_Rcv                    =16                
      K_Line_Xmtr                   =17
      L_Line                        =18
    
      Off                           = 0
      On                            = 1  
    
    VAR
                          
      LONG  Stack0[noparse][[/noparse]150]        'FOR UPDATES_LCD
      LONG  Stack1[noparse][[/noparse]150]        'FOR PROCESS_ECU
      LONG  Stack2[noparse][[/noparse]150]        'FOR BUTTON_PUSH
      '==========UPDATE LCD
      BYTE  MENU
      BYTE  SUBMENU
      BYTE  FUNCTION
      BYTE  CURRENTMENU
      BYTE  CURRENTPROMPT
      BYTE  txByte             ' transmit byte
      BYTE  rxByte             ' recv byte
      '==========PROCESS ECU
      BYTE  NumOfBytes
      BYTE  Counter
      BYTE  Command
      BYTE  Index
      BYTE  Text[noparse][[/noparse]20]
      '==========BUTTON PUSH
      BYTE  Button_Push_Flag   
      
    OBJ
    
      LCD           : "Serial_Lcd"
      HANDSHAKE     : "Simple_Serial"           ' intialize
      COMMS         : "Simple_Serial"           ' comunication
      
    PUB Start
    
      DIRA[noparse][[/noparse]15]~~
      OUTA[noparse][[/noparse]15]~~                     'Enable transciever high
      DIRA[noparse][[/noparse]18]~~
      OUTA[noparse][[/noparse]18]~                      'Enable L_line low
      
      HANDSHAKE.start(1, L_Line, 5)   'setup L_Line  parameters     
      'COMMS.init(K_Line_Rcv, K_Line_Xmtr, 9800)
       
      CogNew(UPDATES_LCD, @Stack0)                  
      CogNew(PROCESS_ECU, @Stack1)
      CogNew(BUTTON_PUSH, @Stack2) 
    
    
    PUB UPDATES_LCD  |  mnuStr, offset, TEMP
          
      If LCD.init(LCD_Pin, LCD_Baud, LCD_Lines)     'Initialize LCD
        LCD.Cursor(Off)                         
        LCD.Backlight(On)                       
        LCD.Cls
        PAUSE(100)      '100ms
    Repeat
      LCD.Line_1
      offset:= BYTE[noparse][[/noparse]@LineOffset + MENU]     'need to initialize menu
      LCD.str(@Prompt + offset)
    
      LCD.Line_2
      case MENU
        0: mnuStr := @Menu0
        1: mnuStr := @Menu1
      offset:= BYTE[noparse][[/noparse]@LineOffset + CURRENTPROMPT]
      LCD.str(mnuStr + offset)
      
      LCD.Line_3
      TEMP := lookupz( MENU : 6, 3, 3 )
      IF CURRENTPROMPT == TEMP
        offset := 0
      ELSE
        offset := offset + 21
      IF MENU == 0
          mnuStr := @Menu0
      IF MENU == 1
          mnuStr := @Menu1
      IF MENU == 2
          mnuStr := @Menu2
      
      LCD.str(mnuStr + offset)
     
      LCD.Line_4
      offset := offset + 21
      TEMP := lookupz( MENU : 6, 3, 3 )
      IF CURRENTPROMPT == TEMP
        offset := 21
      ELSE
        TEMP := lookupz( MENU : 5, 2, 2 )
        IF CURRENTPROMPT == TEMP
          offset := 0
      IF MENU == 0
          mnuStr := @Menu0
      IF MENU == 1
          mnuStr := @Menu1
      IF MENU == 2
          mnuStr := @Menu2
      LCD.str(mnuStr + offset)
      
    PUB PROCESS_ECU
    
     
        NumOfBytes := comms.rx                              'recv number of bytes          
        comms.tx(!NumOfBytes)                               'send complement
        Counter := comms.rx          'recv counter         
        comms.tx(!Counter)           'send complement    
        Command := comms.rx                                 'recv Command        
        comms.tx(!Command)           'send complement    use value of Command to direct flow
        IF Command == $F7            'ACK Block                         
          comms.tx($09)              'send ACK Block
        IF Command == $F6            'text to follow
          Text := 0
          Repeat Index from 0 to (NumOfBytes-3)             ' recv the correct number of bytes
              Text[noparse][[/noparse]Index] := rxByte
              comms.tx(!rxByte) 
        IF Command == $FB           'ADC read
    
    
        IF Command == $FC           'Error memory read
    
    
        IF Command == $F5           'actuator activate - response to a selection
    
    
    'master
     'start with Menu and Submenu
     'use CASE to branch to correct process  if menu ==1 and submenu ==2 then ......
    
        comms.tx($03)     
    PUB BUTTON_PUSH  | newstate, oldstate, xstate, TEMP
    '  Btn_Up                        =11   'Left_Button 
    '  Btn_Down                      =12   'Middle_Button
    '  Btn_Select                    =13   'Right_Button
    '  Btn_Escape                    =14   'bottom button
    ' have all the possible commands for selection, with a command flag.  PROCESS_ECU will then use this to make a case selection.
       oldstate := inA[noparse][[/noparse]14..11]   ' initial state of input pins
       REPEAT
         newstate := inA[noparse][[/noparse]14..11]   ' current state of input pins
         xstate := newstate ^ oldstate & newstate   ' detect change of 1 to 4 bits, 0->1
         oldstate := newstate   ' push state down
         
         IF xstate & |<0            'the bits 14..11 are shifted to 3..0 in xstate
           PAUSE(40)                 ' call method for Pin11 up
           REPEAT until inA[noparse][[/noparse]11]
           -- CURRENTPROMPT
           TEMP := lookupz( MENU : 6, 4, 3 )
           IF CURRENTPROMPT == $FF
            CURRENTPROMPT := TEMP
                       
         IF xstate & |<1
           PAUSE(40)                 ' call method for Pin12  down
           REPEAT until inA[noparse][[/noparse]12]
           ++CURRENTPROMPT
           TEMP := lookupz( MENU : 6, 4, 3 )
           IF CURRENTPROMPT > TEMP
            CURRENTPROMPT := 0
         
         IF xstate & |<2 AND  Button_Push_Flag := Off       'can't select if currently processing a command 
          PAUSE(40)                 ' call method for Pin13  select
           REPEAT until inA[noparse][[/noparse]13]
           ++ Menu
           SUBMENU := CURRENTPROMPT
           CURRENTPROMPT := 0
           Button_Push_Flag := On   'selection has been made, not processed
           
         IF xstate & |<3
           PAUSE(40)                ' call method for Pin14    escape
           REPEAT until inA[noparse][[/noparse]14]             
           -- MENU
           CURRENTPROMPT := 0
           
        PAUSE(40)
    
    PUB PAUSE(millisecs)                          'As set up here it is .25 millisceconds
      waitcnt(((((clkfreq)/1000))*millisecs) +cnt)   'Osc speed is 40 MHz
    
    PUB L_LINE_HANDSHAKE (ADDRESS)
        HANDSHAKE.tx (ADDRESS)    
      
    DAT
    Prompt
            BYTE  "Select System       ", 0 'MENU = 0
            BYTE  "Select Function     ", 0 'MENU = 1
    
    MENU0   ' use with "Select Device:" and "Up     Down   Select" 
            BYTE " Motronic           ", 0  'CURRENTPROMPT = 0
            BYTE " Climate Control    ", 0  'CURRENTPROMPT = 1
            BYTE " ABS                ", 0  'CURRENTPROMPT = 2
            BYTE " Airbag             ", 0  'CURRENTPROMPT = 3
            BYTE " Tiptronic          ", 0  'CURRENTPROMPT = 4
            BYTE " Alarm              ", 0  'CURRENTPROMPT = 5
            BYTE " PDAS               ", 0  'CURRENTPROMPT = 6
    
    MENU1
            BYTE " Error codes        ", 0
            BYTE " Clear codes        ", 0
            BYTE " Actual values      ", 0
            BYTE " Activate outputs   ", 0
    
    MENU2
            
    LineOffset
            BYTE  0, 21, 42, 63, 84, 105, 126, 148, 169   ' line width + 1 (for 0)
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Bad spellers of the world untie!
  • computer guycomputer guy Posts: 1,113
    edited 2010-01-16 00:19
    Adding 16 worked great. Thank you MagIO2 smile.gif

    Edit:
    I have this so far and it's printing the menu to the LCD (it only has two items at the moment)
    repeat i from 0 to strsize(mainmenu)
        LCD.str(mainmenu[noparse][[/noparse] i] + 16)
        LCD.putc($0D)
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "powered by Propeller" domed stickers $1.50 - Find them here
    Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net

    Post Edited (computer guy) : 1/16/2010 1:31:15 AM GMT
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-01-16 00:22
    sorry paul, but that's definitely wrong! We are not interested in the address of the variable mainmenu[noparse][[/noparse]0], we want to access the address stored in mainmenu[noparse][[/noparse]0].

    LCD.str( mainmenu[noparse][[/noparse]0] )

    is correct. mainmenu[noparse][[/noparse]0] only does not contain what we expected ... see my post above.
  • MagIO2MagIO2 Posts: 2,243
    edited 2010-01-16 00:25
    I'd prefere the ORG version, as then you can be sure it's done at compile-time.

    If you say

    LCD.str( mainmenu[noparse][[/noparse]0]+16 )

    the calculation is done at runtime, wasting speed and RAM for additional code.
  • computer guycomputer guy Posts: 1,113
    edited 2010-01-16 00:29
    mojorizing, Thank you for sharing your code however I find it really confusing. I think it may be a bit more complicated than I need.


    Thank you smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "powered by Propeller" domed stickers $1.50 - Find them here
    Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net
  • computer guycomputer guy Posts: 1,113
    edited 2010-01-16 00:36
    MagIO2 said...
    I'd prefere the ORG version, as then you can be sure it's done at compile-time.

    If you say

    LCD.str( mainmenu[noparse][[/noparse]0]+16 )

    the calculation is done at runtime, wasting speed and RAM for additional code.

    Could you please explain "ORG" to me. I tried putting "ORG 16" at the start of the DAT section and removing the + 16, however this didn't work.


    Thank you smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "powered by Propeller" domed stickers $1.50 - Find them here
    Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net
  • computer guycomputer guy Posts: 1,113
    edited 2010-01-16 01:38
    Perhaps someone is able to write a printmenu function for me that outputs.
    >Menu Item 1
     Menu Item 2
     Menu Item 3
    
    



    From the DAT structure that MagIO2 provided.
    Please...? smilewinkgrin.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "powered by Propeller" domed stickers $1.50 - Find them here
    Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net
  • mparkmpark Posts: 1,305
    edited 2010-01-16 01:43
    In general you can't add the offset at compile time (it isn't always 16). Look up the @@ operator in the manual.
  • computer guycomputer guy Posts: 1,113
    edited 2010-01-16 01:51
    Thank you mpark, however where would I use this? @@ is not valid in the DAT section.


    Thank you smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "powered by Propeller" domed stickers $1.50 - Find them here
    Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net
  • mparkmpark Posts: 1,305
    edited 2010-01-16 01:57
    Instead of
    LCD.str( mainmenu[noparse][[/noparse]0]+16 )
    try
    LCD.str( @@mainmenu[noparse][[/noparse]0] )
  • computer guycomputer guy Posts: 1,113
    edited 2010-01-16 02:06
    Thank you mpark smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "powered by Propeller" domed stickers $1.50 - Find them here
    Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net
  • computer guycomputer guy Posts: 1,113
    edited 2010-01-16 03:14
    I currently have:

    PRI printmenu(menuptr) | i
    
      LCD.cls
      LCD.backlight(true)
      i := 0
      repeat
        if i == 0
          LCD.str(string(">"))
        else
          LCD.str(string(" "))
        LCD.str(@@mainmenu[noparse][[/noparse] i++])
        LCD.putc($0D)
      while mainmenu[noparse][[/noparse] i] > 0
    
    



    and it's working great. smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "powered by Propeller" domed stickers $1.50 - Find them here
    Check out my Design and Technology project for my Higher School Certificate www.ecosureblog.net
Sign In or Register to comment.