How to index STRING's

TCTC Posts: 1,019
edited 2010-12-14 - 08:58:02 in Microcontrollers
I am having trouble understanding how to index a string in data. This is a learning program. I am trying to find a way for it to display the day just by changing one value. Please give me some ideas.

Also I dont know how to post code on this new forum. the old one had a button.

DIG VAR Word
CHAR VAR Word
BRIGHT VAR Byte
SEGMENT VAR Byte
SEG_TEMP VAR Byte
DIGIT VAR Byte
DIG_TEMP VAR Byte
STRING_TEMP VAR Byte
idx1 var Word
DAY VAR Byte

' =========================================================================
PROGRAM Start
' =========================================================================


'
' Subroutine Declarations
'
Boost_Control SUB
Display_Load SUB
Get_Char SUB
Get_Dig SUB
String SUB

'
' Program Code
'

Start:
BLANKING = 0
BRIGHT = 200
Main:
for day = 0 to 6
for idx1 = 0 to 50
for digit = 0 to 7
Boost_Control
String
Display_Load
next
next
next
GOTO Main


'
' Subroutine Code
'
SUB Boost_Control
PWM Boost, BRIGHT, 1
return

SUB String
STRING_TEMP = DIGIT + DAY
READ DAY_MAP + STRING_TEMP, SEGMENT
return


SUB Display_Load
Get_Char
Get_Dig
SHIFTOUT SDATA, CLOCK, MSBFIRST, DIG\16
SHIFTOUT SDATA, CLOCK, MSBFIRST, CHAR\16
PULSOUT STROBE, 1
return

SUB Get_Char
SEG_TEMP = SEGMENT - $20
SEG_TEMP = SEG_TEMP * 2
READ FONT_MAP + SEG_TEMP, CHAR
return

SUB Get_Dig
DIG_TEMP = DIGIT * 2
READ DIG_MAP + DIG_TEMP, DIG
return

' =========================================================================
' User Data
' =========================================================================
DAY_MAP:
DATA "SUNDAY",0
DATA "MONDAY",0
DATA "TUESDAY",0
DATA "WEDNESDAY",0
DATA "THURSDAY",0
DATA "FRIDAY",0
DATA "SATURDAY",0

DIG_MAP:
WDATA %00000000_10000000
WDATA %00000000_01000000
WDATA %00000000_00100000
WDATA %00000000_00010000
WDATA %00000000_00001000
WDATA %00000000_00000100
WDATA %00000000_00000010
WDATA %00000000_00000001



FONT_MAP:
WDATA %00000000_00000000 'SPACE
WDATA %01100000_00000000 '!
WDATA %00000100_01000000 '"
WDATA %11111111_11111100 '#
WDATA %10110111_01001000 '$
WDATA %00100111_10110100 '%
WDATA %10110000_10110100 '&
WDATA %00000000_00100000 ''
WDATA %00000000_00110000 '(
"CONFIDENCE"
The Feeling you get before you truely understand the situation.

Comments

  • eagletalontimeagletalontim Posts: 1,384
    edited 2010-12-12 - 17:56:44
    Not 100% sure, but it seems that some of your SUBs should actually need to be FUNC. You can return a variable though the FUNC, SUBs are not made for that.

    For Example, Here is a SUB which I made to display a string or a character on a 2x16 display based on what line and character to start at.
    print       	SUB    3, 4
    
    print:
      text = __WPARAM12                            ' get string offset
      temp3 = __PARAM3
      temp4 = __PARAM4
    
      LCD_OUT LcdLine1
      IF temp3 = 1 THEN
        LCD_OUT LcdLine1
      ELSEIF temp3 = 2 THEN
        LCD_OUT LcdLine2
      ENDIF
      FOR temp5 = 1 TO temp4
        LCD_OUT LcdRt
      NEXT
      LCD_OUT LcdBkSpc
      
      DO
        READ text, temp5                     ' read a character
        IF temp5 = 0 THEN EXIT                      ' if 0, string complete
        SEROUT LcdTx, LcdBaud, temp5
        INC text                                   ' point to next character
      LOOP
      RETURN
    
      ' USAGE : print "Text To Display ", 2, 1
      ' This will display Text To Display on line 2 starting at character 1
    

    And for a FUNC example :
    FUNC Div
      temp1 = __PARAM1
      temp2 = __PARAM2
      temp1 = temp1 / temp2
      temp2 = __REMAINDER
      RETURN temp1, temp2
      ENDFUNC
    
      ' USAGE : myvar = Div 6, 3
      ' myvar will equal 2 since 6 / 3 = 2
    

    To post code, you can use [ CODE ]Your Code Here[ / Code] (without the spaces) Hope this helps!
  • TCTC Posts: 1,019
    edited 2010-12-12 - 18:23:40
    Not 100% sure, but it seems that some of your SUBs should actually need to be FUNC. You can return a variable though the FUNC, SUBs are not made for that.

    To post code, you can use [ CODE ]Your Code Here[ / Code] (without the spaces) Hope this helps!


    The code you gave looks interesting, but I have no idea what is going on. I only know PBASIC and I am trying to learn SX/B, that is why I have chosen this program. I want to start with baby steps and learn on the way. I am still trying to understand returning a variable (using FUNC). To me I can’t understand the benefits of not declaring a variable, why should I return a variable.
    "CONFIDENCE"
    The Feeling you get before you truely understand the situation.
  • eagletalontimeagletalontim Posts: 1,384
    edited 2010-12-12 - 18:45:14
    I noticed that not all your code is there so it would be hard for me to update the code and post it. To hopefully explain it a little better, a FUNC (function) is a way to eliminate the need for having to write the same code over and over for variables that need to be populated. For example, your String SUB would actually need to be a FUNC.

    The String SUB converted to a FUNC :
    FUNC String
       DIG_TEMP = __PARAM1   ' This would be the first parameter passed to the String Function : myvar = String param 1,  param 2
       DAY_TEMP = __PARAM2  ' This would be the second
       STRING_TEMP = DIGIT + DAY
       READ DAY_MAP + STRING_TEMP, SEGMENT  'Not sure what you have here.  This would only return 1 character.  You would need a FOR loop or a DO loop to retrieve all the characters.
       RETURN SEGMENT  'This will return the value of the variable SEGMENT.  The variable is not passed unless told to do so by the RETURN statement. 
       ENDFUNC
    

    In this example, I used myvar = String 1, 3
    The function will see that DIG_TEMP = 1 and DAY_TEMP = 3
    The variable SEGMENT is set by the READ function based on the passed variables you give it. Since the variable SEGMENT is not automatically passed back to the rest of your code, you need to have another variable in your main code (myvar) to hold the information returned by the function.

    Your SUB Boost_Control is good since there is no information needed to be sent back to your main code / loop.

    You should also take a look at the READ function in the SX/B Help in your SX-Key program. It will explain how to retrieve the full data string instead of 1 character.
  • TCTC Posts: 1,019
    edited 2010-12-12 - 18:49:34
    ' -------------------------------------------------------------------------
    ' Variables
    ' -------------------------------------------------------------------------
    DIG		VAR	Word
    CHAR		VAR	Word
    BRIGHT		VAR	Byte
    SEGMENT	VAR	Byte
    SEG_TEMP	VAR         Byte
    DIGIT		VAR	Byte
    DIG_TEMP	VAR         Byte
    STRING_TEMP	VAR	Byte
    idx1		VAR	Word
    DAY		VAR	Byte
    
    
    
    ' -------------------------------------------------------------------------
     'INTERRUPT
    ' -------------------------------------------------------------------------
    
    ISR_Start:
    
    
    ISR_Exit:
     
    
    
    ' =========================================================================
     PROGRAM Start
    ' =========================================================================
    
    
    ' -------------------------------------------------------------------------
    ' Subroutine Declarations
    ' -------------------------------------------------------------------------
    Boost_Control	SUB
    Display_Load	SUB
    Get_Char		SUB
    Get_Dig		SUB
    String		SUB
    
    ' -------------------------------------------------------------------------
    ' Program Code
    ' -------------------------------------------------------------------------
    
    Start:
    	BLANKING = 0
    	BRIGHT = 200
    Main:
    	FOR day = 0 to 6
    	        FOR idx1 = 0 to 50
                                    FOR digit = 0 to 7
    		        Boost_Control
    		        String
    		        Display_Load
    		next
    	        next
                     next
      GOTO Main
    
    
    ' -------------------------------------------------------------------------
    ' Subroutine Code
    ' -------------------------------------------------------------------------
    SUB Boost_Control
    	PWM Boost, BRIGHT, 1
    	return
    
    SUB String
    	STRING_TEMP = DIGIT + DAY
    	READ DAY_MAP + STRING_TEMP, SEGMENT
    	return
    		 
    
    SUB Display_Load
    	Get_Char
    	Get_Dig
    	SHIFTOUT SDATA, CLOCK, MSBFIRST, DIG\16
    	SHIFTOUT SDATA, CLOCK, MSBFIRST, CHAR\16
    	PULSOUT STROBE, 1
    	return
    
    SUB Get_Char
    	SEG_TEMP = SEGMENT - $20
    	SEG_TEMP = SEG_TEMP * 2
    	READ FONT_MAP + SEG_TEMP, CHAR
    	return
    
    SUB Get_Dig
    	DIG_TEMP = DIGIT * 2
    	READ DIG_MAP + DIG_TEMP, DIG
    	return
    
    ' =========================================================================
    ' User Data
    ' =========================================================================
    DAY_MAP:
    	DATA		"SUNDAY",0
    	DATA		"MONDAY",0
    	DATA		"TUESDAY",0
    	DATA		"WEDNESDAY",0
    	DATA		"THURSDAY",0
    	DATA		"FRIDAY",0
    	DATA		"SATURDAY",0
    
    DIG_MAP:
    	WDATA		%00000000_10000000
    	WDATA		%00000000_01000000
    	WDATA		%00000000_00100000
    	WDATA		%00000000_00010000
    	WDATA		%00000000_00001000
    	WDATA		%00000000_00000100
    	WDATA		%00000000_00000010
    	WDATA		%00000000_00000001
    	
    
    
    FONT_MAP:
    	WDATA		%00000000_00000000	'SPACE
    	WDATA		%01100000_00000000	'!
    	WDATA		%00000100_01000000	'"
    	WDATA		%11111111_11111100	'#
    	WDATA		%10110111_01001000	'$
    	WDATA		%00100111_10110100	'%
    	WDATA		%10110000_10110100	'&
    	WDATA		%00000000_00100000	''
    	WDATA		%00000000_00110000	'(
    	WDATA		%00000000_10000100	')
    	WDATA		%00000011_11111100	'*
    	WDATA		%00000011_01001000	'+
    	WDATA		%00000000_00000100	',
    	WDATA		%00000011_00000000	'-
    	WDATA		%00011010_00001000	'.
    	WDATA		%00000000_00100100	'/
    
    
    
    
    "CONFIDENCE"
    The Feeling you get before you truely understand the situation.
  • TCTC Posts: 1,019
    edited 2010-12-12 - 18:54:44
    Full learning code
    "CONFIDENCE"
    The Feeling you get before you truely understand the situation.
  • TCTC Posts: 1,019
    edited 2010-12-12 - 19:08:12
    The program will display "sunday" if I put "0" in DAY, but if I put "1" in DAY i get "unday". what I am trying to do is if i put "1" in DAY i get "monday", if "2" is in DAY then "it would display "tuesday",ect. hope that helps to understand where i am getting stuck?
    "CONFIDENCE"
    The Feeling you get before you truely understand the situation.
  • TCTC Posts: 1,019
    edited 2010-12-13 - 16:09:46
    Still have not figured it out. Dose anyone have any ideas?
    "CONFIDENCE"
    The Feeling you get before you truely understand the situation.
  • RobotWorkshopRobotWorkshop Posts: 2,300
    edited 2010-12-13 - 19:54:24
    It isn't clear to me yet exactly how you want to use the strings. However, I have some suggestions on some ways that I've dealt with them in the past.

    First, you should have a subroutine that can accept the address of the string you want and then do something with that. In many cases the strings will be terminated by a 0 or be a fixed length. Your routine will then start reading each byte and deal with it (Send it to a display, serial port, etc) then increment the variable used as the pointer and repeat. If it reads a 0 (or fixed length if your using that method) then exit the routine.

    From your listing it seems that some of the issue may be finding the start of each string. You have an address for the first one but they aren't all the same length. To find the start of the string you want there are a few methods. Since they aren't the same size you can walk through them each time. You use the address of the first one. If the offset is 0 then return. If not then read bytes until you hit the termination character (0 in this case) and subtract 1 from your count. When it gets to 0 then you're pointing at the string you want. Alternately, you can just make another table that has the addresses of the beginning of each string.

    If you make all the strings the same length then you can calculate the start of each string by adding the index of the string you want times the length of each entry (including termination character). That will give you the address of the beginning of the string you want.
  • eagletalontimeagletalontim Posts: 1,384
    edited 2010-12-13 - 20:32:10
    Try changing your DAY_MAP to this :
    DAY_MAP:
    DATA "SUNDAY    ",0
    DATA "MONDAY    ",0
    DATA "TUESDAY   ",0
    DATA "WEDNESDAY ",0
    DATA "THURSDAY  ",0
    DATA "FRIDAY    ",0
    DATA "SATURDAY  ",0
    

    And change your String sub to :
    SUB String
    STRING_TEMP = DAY * 10
    READ DAY_MAP + STRING_TEMP, SEGMENT
    return
    

    Since the Read function starts with the character number you specify, you should set all your DATA fields to have the same amount of characters. Yours would be set to 10 characters since Wednesday is the longest spelled word. When you call the String function, the READ function will start reading from the character at the calculated starting point.... example : DAY = 0 : STRING_TEMP = 0 * 10 which = 0. If you insert 2 for day, STRING_TEMP will equal 20 since 2 * 10 = 20 and will cause the READ function to start reading from character 20 which is the beginning of the third line. Check out the RFID example in the SX/B help section of the SX program for a better example. Hope this helps :)
  • TCTC Posts: 1,019
    edited 2010-12-14 - 08:58:02
    It isn't clear to me yet exactly how you want to use the strings. However, I have some suggestions on some ways that I've dealt with them in the past.

    First, you should have a subroutine that can accept the address of the string you want and then do something with that. In many cases the strings will be terminated by a 0 or be a fixed length. Your routine will then start reading each byte and deal with it (Send it to a display, serial port, etc) then increment the variable used as the pointer and repeat. If it reads a 0 (or fixed length if your using that method) then exit the routine.

    From your listing it seems that some of the issue may be finding the start of each string. You have an address for the first one but they aren't all the same length. To find the start of the string you want there are a few methods. Since they aren't the same size you can walk through them each time. You use the address of the first one. If the offset is 0 then return. If not then read bytes until you hit the termination character (0 in this case) and subtract 1 from your count. When it gets to 0 then you're pointing at the string you want. Alternately, you can just make another table that has the addresses of the beginning of each string.

    If you make all the strings the same length then you can calculate the start of each string by adding the index of the string you want times the length of each entry (including termination character). That will give you the address of the beginning of the string you want.

    This program is just to help me to learn. I was in a coma for 9 months and it is a little hard to learn, but i will not give up. Thank you for the ideas. I like it best when somone dose not give me the answer but give me the idea how.
    Check out the RFID example in the SX/B help section of the SX program for a better example. Hope this helps :)

    That will help me out alot thanks.
    SXlee wrote: »

    Thanks now you got my gears turning.
    "CONFIDENCE"
    The Feeling you get before you truely understand the situation.
Sign In or Register to comment.