Process serial string input?
Just checking before reinventing some wheels...
Getting data input on a P2 pin as TTL serial text.
The data string looks like this:
VAC1=3.99e+01 VAC2=2.17e-01 VAC3=9.04e+02
Is there something already that can turn a string into a float?
Would also be convenient if something could parse this input, but guessing not...
Comments
This probably won't help -- but maybe it will inspire something. Last year I helped a friend who wanted to send floats through serial commands. I used my standard parser to get the chunks out of the string, and then this simple code to convert values from string to float. It doesn't support scientific notation though.
Thanks @JonnyMac, this does look like will help.
tokenizer seems to work.
Zero based token index.
Seems rigged to tokenize on white space.
got the input parsed into three strings now.
Close to having it done...
Actually want to process input from two serial ports. Don't want to waste cogs though.
Fortunately, found the @"Stephen Moraco" 8x serial input code in OBEX:
https://obex.parallax.com/obex/p2-high-speed-8-port-serial-subsystem/
You probably have this sorted, but I knocked this together while having lunch and waiting on the Zoom call. It will take a "parameter=value" string and breaks up the parts, filling strings you specify.
pub parse_cmd_value(p_str, p_cmd, p_val) | i i := find_chr("=", p_str) ' look for separator if (i < 0) ' abort if not found return bytemove(p_cmd, p_str, i) ' copy command to own string byte[p_cmd][i] := 0 i++ ' skip separator bytemove(p_val, p_str+i, strsize(p_str)-i) ' copy value to own string byte[p_val][strsize(p_str)-i] := 0 pub find_chr(c, p_str) : pos '' Return index of first occurance of c in p_str '' -- returns -1 if not found repeat pos from 0 to strsize(p_str)-1 if byte[p_str][pos] == c return return -1
I almost have parsing an FP string in Scientific notation working.
This gets a little long, but -- so far -- seems to work. I added the ability to detect sci-notation and deal with the exponent. I checked the return values using this page:
-- https://www.h-schmidt.net/FloatConverter/IEEE754.html
pub str2fp(p_str) : result | sign, dpflag, d, e, b '' Convert string to floating point '' -- legal characters: "-", "+", "0".."9", ".", "E", "e" repeat ' strip leading spaces if (byte[p_str] == " ") p_str++ else quit sign, dpflag, d := 1.0, false, 1 ' preset locals if (byte[p_str] == "-") ' check for sign sign := -1.0 ' set p_str++ ' skip elseif (byte[p_str] == "+") p_str++ repeat ' get significand b := byte[p_str++] ' get byte from string case b "e", "E", " ", 0 : ' done? quit "0".."9" : result := (result * 10) + (b - "0") ' add new digit if (dpflag) ' past dpoint d *= 10 ' yes, bump divisor "." : if (dpflag == false) ' new decimal point? dpflag := true ' set flag else return 0.0 ' invalid 2nd decimal point other : return 0.0 ' illegal character result := sign *. float(result) /. float(d) if (b <> "e") && (b <> "E") ' done if no exponent return sign, e := 1.0, 0 ' reset for exponent if (byte[p_str] == "-") ' check for exponent sign sign := -1.0 p_str++ elseif (byte[p_str] == "+") p_str++ repeat ' get exponent b := byte[p_str++] case b 0, " " : quit "0".."9" : e := (e * 10) + (b - "0") other : return if (e == 0) ' done if exponent == 0 return ' adjust significand with exponent if (sign == 1.0) result := result *. float(XPower[e]) else result := result /. float(XPower[e]) dat XPower long 1 ' 10 ^ 0 long 10 long 100 long 1_000 long 10_000 long 100_000 long 1_000_000 long 10_000_000 long 100_000_000 long 1_000_000_000 ' 10 ^ 9
For this app, there's a very limited range of exponents possible.
So, just did significand and exponent separately.
Also, turning this Torr floating point value into integer number of milliTorr....
Processed exponent like this:
pub sExponent_To_Factor(p):fac 'Turn exponent into a factor to multiply significand by 'Neet to turn "-03" into 1 and "+03" into 1_000_000 if strcomp(p,string("-03"))==-1 return 1 if strcomp(p,string("-02"))==-1 return 10 if strcomp(p,string("-01"))==-1 return 100 if strcomp(p,string("-00"))==-1 return 1_000 if strcomp(p,string("+00"))==-1 return 1_000 if strcomp(p,string("+01"))==-1 return 10_000 if strcomp(p,string("+02"))==-1 return 100_000 if strcomp(p,string("+03"))==-1 return 1_000_000
Cool.