Need help with the following code
JMLStamp2p
Posts: 259
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
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
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
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
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)
At lest you will overwrite the last received bytes when doing
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...
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
I do not know the device you are using!
The display seems to work o.k.
But what is this "keypad"???
JMLStamp2p
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
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 ?
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" ?
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
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.
VAR
Byte datain '3 element Byte Array
Byte Delimiter
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)
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