Shop OBEX P1 Docs P2 Docs Learn Events
Need help with the following code — Parallax Forums

Need help with the following code

JMLStamp2pJMLStamp2p Posts: 259
edited 2008-02-19 16:43 in Propeller 1
Concerning the code below:
I am inputting 3 numbers via a matrix Keypad to a Serial LCD by Matrix Orbital.
On the 3rd press I get 2 characters when I should be getting 3 and instead of getting the numbers on the LCD I am getting characters. I have made comments to the extent that I undestand the code and need some help where I am going wrong.
PS: Thank You Gorin for getting me this far jumpin.gif

CON
·_CLKMODE = XTAL1 + PLL16X···
·_XINFREQ = 5_000_000

VAR
· Byte datain[noparse][[/noparse]4]··············'3 element Byte Array
· Byte Delimiter
·
OBJ
· data : "FullDuplexSerial"
· num : "Numbers"
·
PUB Main | Timer_1_Value, Value············ 'local varibles to Main
·
·data.Stop····················· 'Stop outside call to FullDuplexSerial
·data.start(3,2,0,19200)····'Setup Serial for the LCD
·data.tx(254)·················· 'Initiate LCD screen control······················
·data.tx(88)··················· 'Clear LCD screen
·data.tx(254)···
·data.tx(72)··················· 'LCD to home position


·repeat
·· rxStr(@datain)··· 'Call rxStr Method and pass address of datain Array
························· ·'This Method accepts 3 characters from the Keypad
························ · 'before returning them to the LCD.
··
·· data.str(@datain)····· 'Send String from the starting address of datain
······························ · 'to LCD

·· 'data.tx(Num.ToStr(@datain,10))···

· '
{{
·· Below: Fill 3 Bytes of a memory array with the first 3 characters
·· I enter from my Keypad, Reset the pointer and copy those 3 Bytes
·· from the array to the location of the String pointer.

}}

PUB RxStr (stringptr) : Value | ptr

·· ptr:=0······················· · 'Set pointer = to "0"
·· bytefill(@dataIn,0,3)······ 'Fill 3 Bytes of Memory with "0"
·· dataIn[noparse][[/noparse]ptr] := data.rx····· 'Fill Array with 1st byte recieved
·· ptr++························· · 'Increment pointer to next location
··································· · 'in the array.
········
·· repeat while ((DataIn[noparse][[/noparse]ptr-1] <> 13) and (DataIn[noparse][[/noparse]ptr-1] <> Delimiter)) and (ptr < 3)·······
······ dataIn[noparse][[/noparse]ptr] :=· data.rx····
······ ptr++
······
·· 'Above code means to repeat until pointer = 3
·· 'or the datain Byte array has 3 bytes filled.


·· dataIn[noparse][[/noparse]ptr-1]:=0·················· · 'Reset Pointer··········
·· byteMove(stringptr,@datain,3)·· 'Copy 3 bytes of memory from @datain
············································ · 'to the location of the stringptr

Comments

  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-15 20:23
    Added a couple of lines to the this section of code and I am now getting 3 characters displayed on my LCD but the 3rd is always "0"


    repeat
    rxStr(@datain) 'Call rxStr Method and pass address of datain Array
    'This Method accepts 3 characters from the Keypad
    'before returning them to the LCD. The rxStr Method
    'copys the data in the array to the location of the
    'String pointer before returning.


    data.str(@datain) 'Send String from the starting address of datain
    'to LCD
    Value := num.FromStr(@datain,10)
    data.dec(Value)
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-15 20:39
    Very confusing what you are doing...
    At lest you will overwrite the last received bytes when doing
    dataIn[noparse][[/noparse]ptr-1]:=0
    


    BYTEFILL is kind of redundant..
    What do you need DataIn for?

    Nevertheless - those are not your issues....
    Analyse what you receive by DATA.RX
    Can the bitrate be the same as for the display? I wonder...
  • Mike GreenMike Green Posts: 23,101
    edited 2008-02-15 20:52
    Here's another version of RxStr. This allows you to specify the number of characters wanted and returns the terminating character or -1 if the length is reached.
    PUB RxStr(cnt,strPtr) : char
    repeat
       if cnt-- == 0    ' Exit if we already have the characters
          byte[noparse][[/noparse]strPtr] := 0
          return
       char := data.rx  ' Get the next character
       if char == 13 or char == Delimiter
          byte[noparse][[/noparse]strPtr] := 0
          return
       byte[noparse][[/noparse]strPtr++] := char  ' Save the new character
    
    
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-15 20:55
    deSilva,

    I have changed the line dataIn[noparse][[/noparse]ptr-1]:=0 to dataIn[noparse][[/noparse]ptr]:=0
    and now I am getting all 3 characters to my LCD.
    I used bytefill just to make sure I was clearing the datain "byte array" before I continue to
    input my next 3 characters. I am new to the prop so please let me know if I am going about this wrong. From what I understand "Byte datain" is a byte aray to hold my 3 characters that I input via my Keypad, Is this not right ? The Baud rate for the display is 19200 and I assumed that what I am getting back is the ASCII characters when I want the actual 1-9, "A,B,C & D". Can you give me some more advise ?
    JMLStamp2p
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-16 01:16
    JML Stamp,
    I do not know the device you are using!
    The display seems to work o.k.
    But what is this "keypad"???
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-16 13:24
    The keypad is a (4 by 4) Matrix Keypad sold by Parallax.
    JMLStamp2p
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-16 14:26
    Mike, I have incorperated your rxStr Method below and it seemed to be easier for me to understand. For example, now when I input three "1's" from my Keypad I am getting three "X's" showing on my LCD. Or if I input three "2's" I get three "S's" howing up. I would like to have the actual numbers show up and have each one show up as I enter it on the Keypad.


    PUB Main | Value 'local varible to Main

    num.INIT 'Initiate the numbers method
    data.Stop 'Stop outside call to FullDuplexSerial
    data.start(3,2,0,19200) 'Setup Serial for the LCD

    data.tx(254) 'Initiate LCD screen control
    data.tx(88) 'Clear LCD screen
    data.tx(254)
    data.tx(72) 'LCD to home position
    '

    repeat
    rxStr(3,@datain) 'Call rxStr Method and pass count & address
    'This Method accepts "var" characters from the Keypad
    'before returning them to the LCD.

    Value := num.Fromstr(@datain,10) 'Parameters are Straddr & Format

    data.str(@datain) 'Send String from the starting address of datain to LCD


    PUB RxStr(Num_of_Chars,strPtr) : char
    repeat

    if Num_of_Chars-- == 0 ' Exit if we already have the characters
    byte[noparse][[/noparse]strPtr] := 0
    return
    char := data.rx ' Get the next character

    if char == 13 or char == Delimiter
    byte[noparse][[/noparse]strPtr] := 0
    return

    byte[noparse][[/noparse]strPtr++] := char ' Save the new character
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-16 14:59
    Mike & DeSilva,
    Am I understanding the following lines correctly ?

    Value := num.Fromstr(@datain,10) 'Parameters are Straddr & Format

    Value is := the coversion via "FromStr(StrAddr, Format)" in the numbers.spin object.
    Converts a z-String at the address of datain to a long signed number.
    Note: I don't understand the "format" parameter completely, need some help ...
    Can this Method give me the conversion I want ?

    data.str(@datain) 'Send String from the starting address of datain to LCD

    Note: I have tried changing this line to "data.dec(@datain)"
    When I did this I get the number "1456" on the Keypad no matter what button I press.
    Is this the starting address in memory of "datain"

    Do I still need to do some conversion below these lines to get a DEC numbers ?
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-16 15:02
    Typo:

    Note: I have tried changing this line to "data.dec(@datain)"
    When I did this I get the number "1456" on the LCD no matter what button I press on the Keypad. Is this the starting address in memory of "datain" ?
  • deSilvadeSilva Posts: 2,967
    edited 2008-02-16 15:04
    I should leave this to Mike....
    Nevertheless.. When I understand it right you are using a keypad matrix connected to something called MEMKey, both sold by Parallax and having quite astonishing price tags which make me think I am working in the wrong business... But I deviate..

    The datasheet says:
    (a) This device works with 2400 baud
    (b) the keys can be programmed
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-16 17:44
    Ok guys,
    I have added the ASCII conversion code to the rxStr Method and the Keypad is now sending the correct numbers and symbols to the LCD. I have changed the count in the
    call to "rxStr(1,@datain)" to (1) for now while i was working on getting the code to work properly up to this point.
    I now need to change this back to "rxStr(3,@datain)" and then add the code to save three bytes or a 3-digit number in a seperate varible. Any suggestions or sample code to help accomplish this would be appreciated.
    JMLStamp2p

    Complete working Code up to this point:


    CON
    _CLKMODE = XTAL1 + PLL16X
    _XINFREQ = 5_000_000

    VAR
    Byte datain '3 element Byte Array
    Byte Delimiter

    OBJ

    data : "FullDuplexSerial"
    num : "Numbers"


    PUB Main | Value 'local varibles

    num.INIT
    data.Stop 'Stop outside call to FullDuplexSerial
    data.start(3,2,0,19200) 'Setup Serial for the LCD

    data.tx(254) 'Initiate LCD screen control
    data.tx(88) 'Clear LCD screen
    data.tx(254)
    data.tx(72) 'LCD to home position
    '

    repeat
    rxStr(1,@datain)
    'Call rxStr Method and pass count, address of datain
    'This Method accepts 3 characters from the Keypad
    'before returning them to the LCD. The rxStr Method
    'copys the Keypad # we entered to the location of
    'the String pointer before returning.

    '
    'The lines below determine how the LCD Displays the data from the
    'Keypad.
    '


    Value := (@datain) 'Parameters are Straddr & Format

    '
    PUB RxStr(Num_of_Chars,strPtr) : char 'char is the varible that holds
    'the string of characters that
    'are to be returned to the
    'calling routine which is
    'Main. This String will then be
    'assigned to the varible "Value".

    repeat
    if Num_of_Chars-- == 0 'Exit if we already have 3 characters
    byte[noparse][[/noparse]strPtr] := 0 'Set the pointer = to "0".
    return 'Return to calling routine.

    char := data.rx 'char is = to the character that has
    'been recieved from the Keypad.
    'Get the next character
    'from the Input buffer

    '

    'ASCII conversion below:

    if char == (88)
    char := 1
    data.dec(char)

    if char == (83)
    char := 2
    data.dec(char)

    if char == (78)
    char := 3
    data.dec(char)

    if char == (73)
    char := "A"
    data.tx(char)

    if char == (87)
    char := 4
    data.dec(char)

    if char == (82)
    char := 5
    data.dec(char)

    if char == (77)
    char := 6
    data.dec(char)

    if char == (72)
    char := "B"
    data.tx(char)

    if char == (86)
    char := 7
    data.dec(char)

    if char == (81)
    char := 8
    data.dec(char)

    if char == (76)
    char := 9
    data.dec(char)

    if char == (71)
    char := "C"
    data.tx(char)

    if char == (85)
    char := "*"
    data.tx(char)

    if char == (80)
    char := 0
    data.dec(char)

    if char == (75)
    char := "#"
    data.tx(char)

    if char == (70)
    char := "D"
    data.tx(char)


    '


    if char == 13 or char == Delimiter 'If we get the Terminating
    'Character clear the pointer
    'and return.
    byte[noparse][[/noparse]strPtr] := 0
    return

    byte[noparse][[/noparse]strPtr++] := char 'Save the new character
    'and Increment the strPtr
    'to the next location in
    'memeory.
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-16 17:59
    Typo in the VAR block: corrected below, JMLStamp2p

    VAR
    Byte datain '3 element Byte Array
    Byte Delimiter
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-16 18:01
    Well for some rason when I post the code it is not accepting the open & close brackets for the byte array "datain", just know thay are there. :>)
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-02-16 21:16
    Put a space after the first bracket like this [noparse][[/noparse] 4]. The forum software eats them otherwise because it thinks that is some kind of instruction. I think that its got all of us at some stage.
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-16 21:38
    A Step further:

    With the following code I can enter a 3 digit number and then press "A" on the keypad which will jump to the (Transmit_1) Method and then return for the next 3 digit number and so on.

    The numbers are showing up on the LCD correctly one at a time, and the LCD screen
    can be cleared by pressing "D".

    On the ASCII conversion part of the code under "if char == (73)"
    I would like to read into a varible "Timer_1" the first 3 digit number I entered before pressing "A" and pass that number to the Timer_1 Method. This line is not written yet so If anyone could help it would be appreciated.

    JMLStamp2p

    '

    CON
    _CLKMODE = XTAL1 + PLL16X
    _XINFREQ = 5_000_000

    VAR
    Byte datain[noparse][[/noparse] 3]
    Byte Delimiter
    Long Timer_1,Timer_2,Timer_3

    OBJ

    data : "FullDuplexSerial"
    num : "Numbers"


    PUB Main | Value

    num.INIT
    data.Stop
    data.start(3,2,0,19200) 'Setup Serial for the LCD

    data.tx(254)
    data.tx(88)
    data.tx(72)
    '

    repeat
    rxStr(3,@datain)

    'Value := num.Fromstr(@datain,10)
    Value := (@datain)

    PUB RxStr(Num_of_Chars,strPtr) : char

    repeat
    if Num_of_Chars-- == 0
    byte[noparse][[/noparse]strPtr] := 0
    return

    char := data.rx

    if char == (88)
    char := 1
    data.dec(char)

    if char == (83)
    char := 2
    data.dec(char)

    if char == (78)
    char := 3
    data.dec(char)

    if char == (73)
    char := "A" 'If "A" is pressed drop to next line
    Transmit_Timer_1 'Jump to the Timer_1 Method
    data.tx(254)
    data.tx(71)
    data.tx(1) 'Collume-1
    data.tx(2) 'Row-2

    if char == (87)
    char := 4
    data.dec(char)

    if char == (82)
    char := 5
    data.dec(char)

    if char == (77)
    char := 6
    data.dec(char)

    if char == (72)
    char := "B"
    Transmit_Timer_2
    data.tx(254)
    data.tx(71)
    data.tx(1)
    data.tx(3)

    if char == (86)
    char := 7
    data.dec(char)

    if char == (81)
    char := 8
    data.dec(char)

    if char == (76)
    char := 9
    data.dec(char)

    if char == (71)
    char := "C"
    Transmit_Timer_3
    data.tx(254)
    data.tx(71)
    data.tx(1)
    data.tx(4)

    if char == (85)
    'Transmit

    if char == (80)
    char := 0
    data.dec(char)

    if char == (75)
    char := "#"
    data.tx(char)

    if char == (70)
    char := "D"
    data.tx(char)
    byte[noparse][[/noparse]strPtr] := 0 'Set the pointer = to "0".
    data.tx(254) 'Clear LCD screen
    data.tx(88)



    return 'Return to calling routine.

    byte[noparse][[/noparse]strPtr++] := char 'Save the new character

    PUB Transmit_Timer_1

    data.start(1,0,0,9600)
    data.tx(Timer_1)

    waitcnt (1_000_000 + cnt)
    data.start(3,2,0,19200)

    PUB Transmit_Timer_2

    data.start(1,0,0,9600)
    data.tx(Timer_2)

    waitcnt (1_000_000 + cnt)
    data.start(3,2,0,19200)

    PUB Transmit_Timer_3

    data.start(1,0,0,9600)
    data.tx(Timer_3)

    waitcnt (1_000_000 + cnt)
    data.start(3,2,0,19200)
  • JMLStamp2pJMLStamp2p Posts: 259
    edited 2008-02-19 16:43
    Good morning all,

    Can someone lead me to some examples or a good read on arrays. I need to be able to read the 3 bytes of data from " datain[noparse][[/noparse] 3] " , multiply the first byte * 100, the second * 10 and the 3rd *1. I then need to add these togather and save the result in a varible to pass to another method.

    Thanks for the help,
    JMLStamp2p
Sign In or Register to comment.