Shifting Right or Left, proper command? - WORKING!
Joms
Posts: 279
I am trying to combine two seperate hex charactors into one 'two-place' hex, but can not seem to make the shift left/right work the way I want. Do I need to decode these to bitwise then shift left/right first? Or would I use a lookup table in this application?
I can get this to debug properlly and work, however I want to try and use them in calculations as a single variable. For example, I want a variable that would now contain '8A' in hex or '138' in dec.
Thanks in advance for the help...
Post Edited (Joms) : 4/21/2009 12:47:27 AM GMT
mystr[noparse][[/noparse]21] := 56 'debugs as 8 mystr[noparse][[/noparse]22] := 65 'debugs as A Debug.tx(mystr[noparse][[/noparse]21]) Debug.tx(mystr[noparse][[/noparse]22]) Debug.tx(13)
I can get this to debug properlly and work, however I want to try and use them in calculations as a single variable. For example, I want a variable that would now contain '8A' in hex or '138' in dec.
Thanks in advance for the help...
Post Edited (Joms) : 4/21/2009 12:47:27 AM GMT
Comments
so where is your code where you tried to bitshift it ?
best regards
Stefan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
www.tdswieter.com
my_byte:=((mystr[noparse][[/noparse]21] & $47) - constant( 'a' - 10 ) ) << 4
else
my_byte:=(mystr[noparse][[/noparse]21] - '0') << 4
if mystr[noparse][[/noparse]22]>'@'
my_byte|=(mystr[noparse][[/noparse]22] & $47) - constant( 'a' - 10 )
else
my_byte|=mystr[noparse][[/noparse]22] - '0'
or
my_byte := lookdown( my_byte[noparse][[/noparse]21]&$4f: '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f') << 4
my_byte |= lookdown( my_byte[noparse][[/noparse]22]&$4f: '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f')
The & $4f is for converting uppercase letters to lowercase. So, this conversion will work for both.
I have the mystr[noparse][[/noparse]21] & [noparse][[/noparse]22] debuging properly as I would suspect they would, however still having the problems with the lookup table section.
Timothy - Just want to make sure, ascii is the same thing as a charactor, right? so "0" as ascii should be equal to "48" as a decimal?
The result I am looking for in the variable 'src_total' should be $8A or 138 as a decimal.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propalyzer: Propeller PC Logic Analyzer
http://forums.parallax.com/showthread.php?p=788230
So, for the values 0-9 it returns "0" - "9" as ascii value.
You have to use lookdown, which returns the index of the place where it found the value.
<<8 shifts a number 8 bits to the left. Have a look at the binary representation of bytes:
$8A = %1000 1010
So, when you decode the 8 you have to shift it 4 bits to the left to get it to the right position.
Thanks, jazzed ... that's the problem in my code ... the lookdown should use the uppercase letters.
Ahh .. and another small bug .. lookdownz is our friend here, as the ascii value $30 = "0" is at the first place of the list and should return index 0.
Another example ... $35 = "5" is at the sixth place of the list and should return index 5.
$41 = "A" is at the eleventh place of the list and should return index 10.
Post Edited (MagIO2) : 4/17/2009 7:34:21 PM GMT
Anyways, when I run your lookdown commands I get an error. It is because of the ' around each letter, the program things that it is a comment. I am going to try replacing the all the ' with ". I will let you know what happens....
EDIT: Didn't fix it... Here is the code I am at now and just get zero's...
Post Edited (Joms) : 4/17/2009 7:39:02 PM GMT
It has to be $7f. And the list has to be with uppercase letters.
This works fine except when I get above 9, then it just shows 0 where it should display a A. However, it does work correctly when I get to 16 it will display a 10, which is correct.
QUESTION - It will not allow me to put a 'a,b,c,d,e,f' inplace of the '10,11,12,13,14,15' on the lookdown table. How do I need to format that part correctly?
I am posting the correct code I used below so that other people can see it, and it is semi documented so if somebody runs accross this post they will know the solution...
Here is the problem.... When I call on this section of code I would expect to receive the the same thing as when I debug it inside the pub, but I don't... This is what I am using to call on the Pub called GetSource...
The above will show up as a 113 in the PST software when I debug.... Am I missing something here? I would expect it to be the same?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propalyzer: Propeller PC Logic Analyzer
http://forums.parallax.com/showthread.php?p=788230
Thanks for checking my work...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swieter, E.I.
www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, 3.0" LCD Composite video display, eProto for SunSPOT
www.tdswieter.com
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propalyzer: Propeller PC Logic Analyzer
http://forums.parallax.com/showthread.php?p=788230
$30, $30, $30, $30 = 0000
$30, $30, $30, $31 = 0001
$30, $30, $30, $36 = 0006
$30, $30, $38, $41 = 008A
I think you get the idea now...· I completely understand the part of learning from others code.· I printed out the whole prop manual and referance guide and do use that alot, but I have problems actually building code from that.· I spend quite a bit of time searching the forums and reading through old posts where people were asking code questions.· That is one of the reasons I like to post the code after I figure out the solution to the problem, so someone else can learn from it also...
AS AN UPDATE - I am still having problems getting the number to transfer between the two spin files.· I still havn't analizyed the problem completely to ask any concrete questions...
therefore you can use the code from PUB RxHexof the Extended_FDSerial-object
this codesnippet assumes that datain[noparse][[/noparse] ] is a bytearray containing the characters as ASCII-coded hexadecimal digits
where the least digit is in dataIn[noparse][[/noparse] 0 ]
In you case variable "NoOfDigits" would be 4
best regards
Stefan
replace place:=1 with place:=0
replace * place with << place
and replace place := place * 16 with place +=4
In the if I'd use the trick as shown above to convert to uppercase. Then you only need one if for the letters A-F.
If you can rely on the fact that the string only contains 0-9 and A-F or a-f, you can do the if statement easier (and faster)
if dataIn[noparse][[/noparse]x] =<"9"
value := value + (DataIn[noparse][[/noparse]x]-"0")<<place
else
value := value + (DataIn[noparse][[/noparse]x]&$4f-constant("a"+10))<<place
If transmission errors are possible you can use the code above or you can check errors during transmission (where you might have some time left to check) and skip conversion completely.
(Just to show some ways to do it faster and smaller ;o)
Ex:
"12345" as a string convert to
12345 as a value.
Most languages have a Val statement. I need the equivalent in spin language.
Ex:
print Val("12345") or x = Val("12345")
I need this because my gps reports altitude as a string
Ex:
$GPGGA 1963.7
as meters and I want to convert that to feet. To do so I need the string for altitude needs to be a value I can work with.
Any help ?
Thanks Tim !
very good improvement !
after seeing your version I ask myself why the author did it not that way
(hm - maybe for easier u nderstanding of the code
@Earl,
sometimes the solution is in a SPIN-file you might be already using
the Extended_FDSerial-object provides two methods for this
PUB rxDec : Value | place, ptr, x
PUB rxDecTime(ms) :Value | place, ptr, x, temp
which receive a string and convert it to a number
you can use this as a template to use it with other bytearrays used for storing strings
best regards
Stefan
If someone could please take a look at the attached code and let me know where I am going wrong, it would help a ton...
As a note:· The 3 lines of inactive code actually works like I want.· It will debug properly as I need it to, however when I go to use it in the main program I am building, it will not return the right value.· It seems like it is using the Hex value of the charactors in the other parts of the program.· I am assuming this code that I am trying is to help fix that.
Sorry if any of this is hard to understand...
I would have though I would have debugged "138" if I had the code working like it does in the extended FDS object
In your original post you wanted to convert two hex digits. As you said in a reply the lookdownz worked. In your last attachment you try to convert 4 digits. Of course you'd have to extend the code for that. But with the lookdownz there are 2 problems: Code size (because of the list of elements) and runtime (because the PASM code behind has to loop over the list to find the index). To reduce code size you could do the conversion of a 4 digit number in a loop as well:
The problem in you current repeat loop is:
This should be [noparse][[/noparse]x] instead.
As I already said in a previous post, this can be optimized in several steps. As a first step I would use shifting instead of multiplication because it's much faster:
And depending on the reliability of the transmission of the digits, you can·do the checks a bit weaker but faster:
·Hope it helps.
Post Edited (MagIO2) : 4/20/2009 9:46:08 PM GMT
Now, something else interesting, in the 'slow' code I got kinda working, it will only do one position of numbers. What I mean is it will·work correctly from 0 to 15, however instead of going to '16' in dec or '10' in hex, it will start back at 0 and count up again. I do not see where this is happening, because by using the 'place += 4, that should shift everything over 1 byte, correct?
Also, I added the 'value := 0", otherwise it would count up everytime the program ran...
Post Edited (Joms) : 4/20/2009 10:24:27 PM GMT
place := 0
and
repeat x from 22 to 19 ' no step
and
value := value + (... << place) ' three occurrences
You want to left shift by 0, 4, 8, 12 because each hex digit is 4 bits.
The repeat loop is funny when counting down. It subtracts the step, so a negative step goes the wrong way.
As your code still uses the range-check I suppose you want to be sure the string to be converted had no (obvious) transfer errors. As such that's ok, but if you find such an error (say by mistake you have a "k" in your mystr) what will happen? The code simply skips this digit, which means it looks like a 0 has been send. Instead you should stop conversion and drop that value. That can be achieved by having an else in each if which sets a faulty-flag and ends the loop.
Outside of the loop you can check the faulty-flag and skip whatever you want to do with "value" or trigger retransmission - whatever makes sense in such an error-case.
I wonder if that conversion would work as well (assuming we don't have transmission problems). No if at all.
value:=0
place:=0
repeat x from 22 to 19
·value |= ((mystr[noparse][[/noparse]x]|%00100000)-"0"-(mystr[noparse][[/noparse]x]>"9")&("a"-"0"+10)) << place
·place+=4
mystr[noparse][[/noparse]x]|%00100000 converts the current digit to lowercase if it is a letter. If it is a number it does not change anything.
%00110010 = 2
%00100000 bitwise or of that will still be 2
%01000001 = A
%00100000 bitwise or is %00110001 = a
So, after that we can be sure that we have either "0"-"9" or "a"-"f". We subtract "0" by default.
(mystr[noparse][[/noparse]x]>"9") this is a boolean expression returning 0 for false or -1 for true. -1 is %11111111_11111111_11111111_11111111.
(0 & something) = 0
(-1 & something) = something
Usually in our if statement from digits having "a"-"f" we subtrace "a" and add 10 to get the value of "a" as number. As we already subtracted "0" we only need to subtract the difference. So, our something is
"a"-"0"+10
If you put that calculation in a constant(), then it's done during compile-time and not during runtime.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propalyzer: Propeller PC Logic Analyzer
http://forums.parallax.com/showthread.php?p=788230