Variable Question
Joms
Posts: 279
I have been messing around with this problem for over two hours and can't seem to figure it out.· What I am trying to do is I have a variable that I store a hex number in.· I am then trying to use the serial out to send it as two seperate hex numbers.
checksum·· VAR·· Byte
checksum = $33·· <
there is actually an expression here, but I have tested it and it outputs $33
SEROUT 15, 16572, [noparse][[/noparse]HEX checksum.LOWNIB, HEX checksum.HIGHNIB]
What I want to come out of the serial port is "33 33" in hex.· Please let me know if you see where I am going wrong.· I have tried multiple variables, I have tried playing with different word/byte/nib/bit combinations.· I have also been trying to go through the Variable section of the help file because I think the answer is there, I just dont see it.· Please let me know if you have any ideas.· Thanks in advance...
checksum·· VAR·· Byte
checksum = $33·· <
there is actually an expression here, but I have tested it and it outputs $33
SEROUT 15, 16572, [noparse][[/noparse]HEX checksum.LOWNIB, HEX checksum.HIGHNIB]
What I want to come out of the serial port is "33 33" in hex.· Please let me know if you see where I am going wrong.· I have tried multiple variables, I have tried playing with different word/byte/nib/bit combinations.· I have also been trying to go through the Variable section of the help file because I think the answer is there, I just dont see it.· Please let me know if you have any ideas.· Thanks in advance...
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- Stephen
Character 3 is hex 33
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- Stephen
Just examples would be...
D3 = 44 33
0C = 30 43
One second question:
I am trying to get the two variables 'dest' and 'src' to be a hex. When I put a HEX in front of the variables I get an error that says Unexpected Constant. I have tried putting them in () and it still gives me an error. Does anyone know how to actually get them to calculate as a HEX? They are inputed to the program earlier as a decimal.
CheckSum = $FF + (-($4E + $30 + $54 + $49 + $9 + $30 + $30 + Dest + $9 + $30 + $30 + Src)//$100) + 1
The two variables 'dest' and 'src' is actually the only two things that will be changing in the program. The program comes up with a decimal number and stores it, but when I output it it will output as a HEX. The number can be anywhere from a single digit number to a four digit number. When calculating the checksum the program needs to add all four of the digits together even if they are zero's because a zero charactor is actually a hex 30.
When I calculate it out on paper it seems to work and if I get rid of the variables and put '$30 + $30 + $30 + $31' in place of a '1' stored in the variable it will work. So basically I just need to find a way to make the program always see four places and use hex instead of the actually charactor.
Thanks for all your help so far too!, I really appreciate it!
I suspect that your block format doesn't really need the "HEX2". Commonly the checksum information is sent as an 8 bit character value. For example, a block might be: SEROUT 15,...,[noparse][[/noparse]$01, $65, $75, $66, $76] with the first byte being the SOH. The check sum would be calculated as "checksum = $65 + $75 + $66 + $76". You'd send the checksum as: SEROUT 15,...,[noparse][[/noparse]-checksum]. I don't know how the receiving end knows the block size. I assume it's either fixed and known or included in the data somehow.
Post Edited (Mike Green) : 6/27/2008 4:42:40 AM GMT
SEROUT 15, 16572, [noparse][[/noparse]6,1,78,48,84,73,9,48,48,49,56,9,48,48,52,67,51,51,4]
Basically this is what it all means:
6 - Acknowledge from last command
1 - Start of Heading
78,48 - Protocol ID
84,73 - Command
9 - Horizontal Tab
48,48,49,56 - Dest Variable
9 - Horizontal Tab
48,48,52,67 - Src Variable
51,51 - Checksum
4 - End of Transmission
Basically the only two things that change are the Dest variable and the Src variable in which I need to calculate the checksum and send the command. The checksum is calculated by doing the arithmatic that I talked about earlier. What I am having problems with is that '0' as a charactor is actually '$30' as a hex or '48' as a decimal. When I input the number into the variable I need it to output after it calculates using all four digits in the variable, even if it has leading zero's....
or
"SEROUT 15, ..., [noparse][[/noparse]DEC4 OutValue, ...]
The "HEX4" or "DEC4" modifiers say to the BS2 to "convert" the value in memory into a STRING version of itself, and send that. HEX4 means as a 4 character string with leading zeros -- which SOUNDS like what you're trying to do.
I don't know whether you want to send the most significant bits first or last, so they're just in "Bytes" with the least significant 4 bits in Bytes[noparse][[/noparse] 0 ] and the most significant 4 bits in Bytes[noparse][[/noparse] 3 ]. temp and i are just temporary byte variables that you have to declare.
'{$STAMP BS2}
'{$PBASIC 2.5}
Dest VAR Byte
Src VAR Byte
CheckSum VAR Byte
i VAR Nib
temp VAR Byte
Bytes1 VAR Byte(4)
Bytes2 VAR Byte(4)
Dest = 24
Src = 76
FOR i = 0 TO 3
temp = Dest & $F
Dest = Dest >> 4
IF temp < 10 THEN
temp = temp + "0"
ELSE
temp = temp - 10 + "A"
Bytes1(i) = temp
ENDIF
NEXT
FOR i = 0 TO 3
temp = Src & $F
Src = Src >> 4
IF temp < 10 THEN
temp = temp + "0"
ELSE
temp = temp - 10 + "A"
Bytes2(i) = temp
ENDIF
NEXT
CheckSum = $FF + (-($4E + $30 + $54 + $49 + $9 + $30 + $30 + Bytes1 + $9 + $30 + $30 + Bytes2)//$100) + 1
DEBUG HEX2 CheckSum, CR
END
Example:
Variable = '0024'
Calculations need to use the number '$30 $30 $32 $34'
Are we trying to over complicate this with all the calculations or are they actually nessisary?
The "+ Bytes1" and "+ Bytes2" won't work as you might expect. The best way to do this is to put the checksum calculation in the loops, so after "Bytes1 ( i ) = temp" put "checksum = checksum·- temp". Similarly, after "Bytes2( i ) = temp" put "checksum = checksum·- temp".· Initialize checksum (like to $FF) somewhere before the loops.· You don't need the "// $100" because the "HEX2" will ignore bits beyond the least significant 8 bits.
Post Edited (Mike Green) : 6/28/2008 1:02:21 AM GMT
'{$STAMP BS2}
'{$PBASIC 2.5}
Dest VAR Byte
Src VAR Byte
CheckSum VAR Byte
i VAR Nib
temp VAR Byte(4)
Bytes1 VAR Byte(4)
Bytes2 VAR Byte(4)
Main:
Dest = 24
Src = 76
CheckSum = $FF
FOR i = 0 TO 3
temp = Dest & $F
Dest = Dest >> 4
IF temp < 10 THEN
temp = temp + "0"
ELSE
temp = temp - 10 + "A"
Bytes1(i) = temp
CheckSum = CheckSum - temp
ENDIF
NEXT
FOR i = 0 TO 3
temp = Src & $F
Src = Src >> 4
IF temp < 10 THEN
temp = temp + "0"
ELSE
temp = temp - 10 + "A"
Bytes2(i) = temp
CheckSum = CheckSum - temp
ENDIF
NEXT
CheckSum = CheckSum + $12D
DEBUG HEX2 CheckSum, CR
END
The "Bytes1" and "Bytes2" arrays are for use in your output statements instead of using "HEX4". If you'd prefer to use "HEX4", then you don't need the arrays or the statements that set them. The two loops just do the HEX4 conversion storing the 4 characters in "Bytes1" or "Bytes2" and including those characters in "checksum".
I'm a little confused about "dest" and "src".· You allow 4 hexadecimal digits for these (16 bits), yet declare them as byte variables which only hold 8 bits.· Two of the hexadecimal digits will always be "0"s.
Post Edited (Mike Green) : 6/28/2008 1:42:55 AM GMT
Mike, Also, I would like to thank you for all your help with this so far and in the future. You are highly valued by the Parallax Community!
When you say "answer" do you mean the DEBUG output?
When I hand calculate it with the following values I end up with the following answers.· I know the hand calculations are correct because they actually work when I calculate it outside of the program and input just the answer....
Dest Variable = 24 (decimal)
Src Variable = 76 (decimal)
Answer = 33 33 (hex) (51 51 in decimal)
Dest Variable = 24 (decimal)
Src Variable = 69 (decimal)
Answer = 34 31 (hex) (52 49 in decimal)
I looked through the forums for a snippet... and when I didn't find one, I decided I could tackle it myself... I hope this helps someone.
Mike, would the checksum method have been easier?
this converts HEX to a byte:
i = serstr(4) ' process requested value
GOSUB BCD_TO_HEX '
value = x * 16
i = serstr(5)
GOSUB BCD_TO_HEX
value = value + x 'value is now converted
this converts a 4 character HEX value to a word (eeprom_add):
i = serstr(7)
GOSUB BCD_TO_HEX
eeprom_add.HIGHBYTE = x *16
i = serstr(8)
GOSUB BCD_TO_HEX
eeprom_add.HIGHBYTE = eeprom_add.HIGHBYTE + x
i= serstr(9)
GOSUB BCD_TO_HEX
eeprom_add.LOWBYTE = x * 16
i = serstr(10)
GOSUB BCD_TO_HEX
eeprom_add.LOWBYTE = eeprom_add.LOWBYTE + x
WRITE eeprom_add, value
the subroutine that makes the conversion from HEX to decimal (I should've named this HEX_TO_BCD)
BCD_TO_HEX:
'this converts one serial byte (i)to an integer (x)
LOOKDOWN i ,[noparse][[/noparse]48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70], x
RETURN
SolarBlitz