Need a little help taking a string from the PC and converting it to a floating
I am still working on this code and MIKE GREEN Big thanks.
Now i need to receive a string that contains a number from the PC. something like this Min number (F1 ZZ S -20.32) up to (F1 ZZ S 150.00)
Here is my code that i am using and i may be going about it wrong.
I need a different approach i think
Now i need to receive a string that contains a number from the PC. something like this Min number (F1 ZZ S -20.32) up to (F1 ZZ S 150.00)
Here is my code that i am using and i may be going about it wrong.
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 SPACE = $20 obj SER : "FullDuplexSerialExtended" VAR long Trash long RxString [noparse][[/noparse] 18 ] long String_Counter PUB START SER.start(31, 30, 0, 9600) 'Turn on serial com object repeat STRING_COUNTER := 0 Repeat until ( RxString[noparse][[/noparse]STRING_COUNTER] := Ser.RX) == ")" STRING_COUNTER ++ IF (RxString [noparse][[/noparse] 0 ] == "(") & (RxString [noparse][[/noparse] 1 ] == "F") & (RxString [noparse][[/noparse] 2 ] == "1") & (RxString [noparse][[/noparse] 3 ] == SPACE) & (RxString [noparse][[/noparse] 6 ] == SPACE) ' CHECK FOR THE CONDITION "(F1 " IF (RxString [noparse][[/noparse] 4 ] == "Z") & (RxString [noparse][[/noparse] 5 ] == "Z") & (RxString [noparse][[/noparse] 7 ] == "S")& (RxString [noparse][[/noparse] 8 ] == SPACE) ' CHECK FOR THE CONDITION "ZZ S " IF (RxString [noparse][[/noparse] 9 ] == "-") & (RxString [noparse][[/noparse] 12 ] == ".") ' CHECK FOR THE DECIMAL Trash := (RxString [noparse][[/noparse] 10 ] + RxString [noparse][[/noparse] 11 ] + RxString [noparse][[/noparse] 13 ] + RxString [noparse][[/noparse] 14 ] ) ser.dec(trash) 'TRANSMIT THE NUMBER TO TEST IT IF ( RxString [noparse][[/noparse] 9 ] == "1") & ( RxString [noparse][[/noparse] 12 ] == ".") 'CHECK FOR 0NE HUNDRED Trash := (RxString [noparse][[/noparse] 9 ] + RxString [noparse][[/noparse] 10 ] +RxString [noparse][[/noparse] 11 ] + RxString [noparse][[/noparse] 13 ] + RxString [noparse][[/noparse] 14 ]) ser.dec(trash) ' TRANSMIT THE NUMBER FOR 100.00 IF ( RxString [noparse][[/noparse] 11] == ".") & (String_Counter == 14) ' CHECK THE END OF THE STRING COUNTER Trash := (RxString [noparse][[/noparse] 9 ] + RxString [noparse][[/noparse] 10 ] + RxString [noparse][[/noparse] 12 ] + RxString [noparse][[/noparse] 13 ]) ser.dec(trash) ' TRANSMITT THE NUMBER FOR 20.12
I need a different approach i think
Comments
value := (value * 10) + (character - "0")
If you encounter a decimal point, you then keep track of the number of decimal places, but
continue to accumulate the integer value. Obviously, you're limited to about 10 digits unless
you make special provisions for more, but 10 digits is plenty. Once you find a non-digit or a
second decimal point, you use the number of decimal places to look up a floating point power
of ten in a table. Ten entries is more than enough. You then convert the integer to floating
point and divide by the proper power of ten to get your result.
I don't have the time now to write a sample routine, but I'll try to post something this weekend.
My number system will range from ( -50.00 to 150.00 ) that is all. No more than 2 decimal places at any time. Can you help me understand more on what you mentioned above?
Jazzed: Thanks for the example, it will take me some time to figure out what you are trying to do in the code.
This is one of those cases where a general purpose routine is probably simpler, certainly smaller, and perhaps just as fast as a more limited special case routine.
Try doing what I suggested by hand on paper and see what you get.
just so that grasshopper understands better:
Post Edited (Mike Green) : 6/20/2008 3:55:42 PM GMT
When you do things like this what is it for
1. Whats the (strPtr , filPtr) mean? the rest of this line I understand
2. Is this just a fancy way to make the 2 variables 0 ? or inputs?
Jeez ill have to look at this code for weeks to fully understand it. I mean how can i implement it in my code?
But thanks so far for the help i do appreciate it.
Post Edited (grasshopper) : 6/20/2008 3:36:03 PM GMT
Please read the comment after the PUB. It explains what strPtr and fltPtr are.
Read the Propeller manual in the section on PUB for a description of the syntax of a method declaration.
The stuff in parentheses is a list of parameters to the method. If you have a byte array "str" containing
the string and a long "fltValue" where the floating point value is to go, you'd call s := StrToFloat(@str,@fltValue)
where "s" is a long to hold the address of the terminating character.
The "~" and "~~" are simple ways to set the variables to zero or all-one-bits. Look in the Propeller manual
whenever you see something new. It's all documented with very few exceptions.
The posted code has been corrected to divide by the proper power of 10 if 1 or greater.
my new up dated code below
Am i addressing the method correctly ? "STRTOFLOAT(TEMP,DECNUMBER)" I made your local "value" variable a global variable is this ok or did i mess it up.
Do you understand pointers? These are values that are the address of things.
If you have a byte array like rxDat, this can contain a string, one character per byte.
The address of the byte array is represented as @rxDat.
In general, don't take a local variable and make it a global one unless you understand
exactly what the method is doing with the local variable. Don't modify a library routine
or some example that someone has posted until you understand how it works unchanged.
In the case that you posted, use StrToFloat(@rxDat + 9, @Value)
This is not the same variable used in StrToFloat.
The routine starts scanning at the tenth character position (start + 9).
Post Edited (Mike Green) : 6/20/2008 5:28:23 PM GMT
Thanks so much. I did some more reading in the Prop book and learned what you are speaking about to some extent. My only problem is that you have no return vale that i can see. In this line of code
Should it not be
if so I would then address it as
Please shed some light on this for me
You can look at that character for error checking, scan past it, and call StrToFloat with a new pointer pointing to the next
number in the input stream. You can only return one value from a function, so passing the address of a variable gives a way
for returning additional values from the function. If there's no valid number at the initial string address, the floating point
value will be zero. I assume that you don't call StrToFloat unless you know there's a valid number in the string. You can
check for that by comparing the returned string address with the one you furnish. If they're the same, there was no number
at that address.
If it's more convenient, you can change this all by having the function return the floating point value and passing a single
parameter which is the address of a long containing the address of the string pointer. This string pointer would be updated
by the function to point to the terminating character. This actually might make scanning multiple values easier.
Post Edited (Mike Green) : 6/21/2008 6:11:38 PM GMT
Post Edited (Mike Green) : 6/22/2008 12:15:03 AM GMT