Unable to Extract Data from a String and Save to Variables
Dear forum,
I am having problems extracting data from a string. For example, I have the following string:
Where every value between a comma "," is a reading from a sensor and I have to store it in variables so it would be like
sensor1 := 486
Temp1 := 21
sensor2 := 786
.
.
sensorn := 7666
Now, any suggestions in how to extract the values from the string and save them into variables?
This is the code that I have so far:
I am attaching the entire project as a zip file.
Thank you for your collaboration guys!!
I am having problems extracting data from a string. For example, I have the following string:
input := string"486,21,786,45561,.....,5444,12,7666"
Where every value between a comma "," is a reading from a sensor and I have to store it in variables so it would be like
sensor1 := 486
Temp1 := 21
sensor2 := 786
.
.
sensorn := 7666
Now, any suggestions in how to extract the values from the string and save them into variables?
This is the code that I have so far:
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
VAR
byte databuffer[100]
OBJ
pst : "Parallax Serial Terminal"
nums : "Simple_Numbers"
str : "STRINGS2"
PUB Start | index, index2, input, length, packet_length
pst.start(9600)
''Example string
input := string("1254,23,7854,2111,112,")
length := strsize(input)
packet_length := length
pst.Str(String("Input string format = "))
pst.str(input)
pst.newline
databuffer[length] := ","
repeat index from length to 0
databuffer[index - 1] := get_char(input, index - 1)
repeat while (index2 < packet_length)
pst.char(databuffer[index2++])
waitcnt(clkfreq / 10 + cnt)
pst.newline
pub get_char(p_str, n)
'' Returns nth character from str at p_str
if (n < strsize(p_str))
return byte[p_str][n]
else
return "?"
I am attaching the entire project as a zip file.
Thank you for your collaboration guys!!

Comments
You might consider running through the string replacing each comma as it is detected with a null ($00) to delimit it as the leftmost string at a "current string address" (see CLIB101 in the OBEX for a set of semi-standard C string manipulation functions), then decimalize it (see Simple Numbers also in the OBEX). Thereafter update the "current string address" by the length of the string last processed and repeat until out of data.
Not sophisticated but it will work.
dat TestStr byte "486,21,786,45561,5444,12,7666", 0 pub main | idx, p_field setup term.rx ' open PST, enable, press a key term.tx(term#CLS) fields := str.fields(@TestStr, ",") term.str(string("Fields = ")) term.dec(fields) repeat 2 term.tx(13) repeat idx from 0 to fields-1 p_field := str.field_pntr(@TestStr, idx, ",") param0[idx] := str.asc2val(p_field) term.str(string("param")) term.tx("0" + idx) term.str(string(" = ")) term.dec(param0[idx]) term.tx(13)Dear JonnyMac,
Thank you for your response, it was really helpful Let me show you my approach, I created a loop so that I can receive n amount of variables, as long as it is within 100 bytes. I am using two objects that contain methods for string manipulation, but when I save the values, I get the wrong results. Please check the code below, I am also attaching my entire project. Thank you for your help!
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ pst : "Parallax Serial Terminal" XB : "Xbee_Object V2.0" str : "STRINGS2" nums : "Simple_Numbers" str2 : "ASCII0_STREngine_1" VAR byte databuffer[100] PUB Main | ptr, lsb, msb, og, length, index, index2, output[5], offset, lsb2 pst.start(9600) og := string("123,4114,2,551,23,") length := strsize(og) pst.Str(String("Packet received = ")) pst.Str(og) pst.newline pst.Str(String("Packet length = ")) pst.dec(length) pst.newline pst.Str(String("Initial offset = ")) pst.dec(offset) pst.newline pst.newline pst.newline '' Creating loops to manage any string packet size repeat index from length to 0 databuffer[index - 1] := get_char(og, index - 1) repeat 5 '' I should know in advance how many variables '' to receive, in this case it is 5 offset := str.charpos(og, ",", offset, length) pst.Str(String("Comma location = ")) pst.dec(offset) pst.newline lsb := offset - 1 repeat index2 from msb to lsb output[ptr] := str2.buildstring(databuffer[index2]) output[ptr] := str2.builtstring(output[ptr]) msb := offset + 1 pst.str(output[ptr]) '' This should print each reading in its variable' ptr++ '' output[0]=123, output[1]=4114, and so on, but it does not pst.newline pst.str(og) '' Printing packet again just to check if it did pst.newline '' not change pst.newline waitcnt(clkfreq + cnt) '''''''''''''''' '' Printing again to double check! pst.newline pst.str(output[0]) pst.newline pst.str(output[1]) pst.newline pst.str(output[2]) pst.newline pst.str(output[3]) pst.newline pst.str(output[4]) pub get_char(p_str, n) '' Returns nth character from str at p_str if (n < strsize(p_str)) return byte[p_str][n] else return "?"Hi JonnyMac,
I have been out because I was hospitalized due to a UTI, but I guess I am used to it since I am quadriplegic. I wanted to take the time to thank you for your code, I included it in my code and it worked perfectly, I have problems when I transfer float values, but it is ok. I shared my code with you not because I wanted you to correct it, but because I wanted to share my beginner's work. Now, I was finally capable of:
- Reading the infrared pulses from a power meter.
- Measure current, voltage, rms current, rms voltage and power factor of the 3 phases of the power meter (mcp3208 a2d converter for the sensors)
- Time stamp the data with a ds1307.
- Store values in a SD card.
- Finally send the data wirelessly thru a Zigbee API mesh network, and receive it in the coordinator side.
One again, thank you for your collaboration!!