Array of Bytes to a "String" --- HELP!!!
zlantz
Posts: 136
Ok, so this seems like a simple one, but it is giving me the most trouble.
I am recieving via serial a string of bytes "$1000|1500|1250|2000|<CR>" that is servo position data from my pc. I understand that being sent via serial, it is being received one char at a time, so I can create an array with the bytes myarray[0] = $, myarray[1] = 1, myarray[2] = 0 etc, but I cannot use this data to set my servo position. I need a full string in one var ie servopos1 = 1000, servopos2 = 1500, servopos3 = 1250, servopos4 = 2000.
how do I convert myarray[#] into a "string"?
bytemove just ends up with another array[#] of individual letters.
I have tried recoding the gps readNEMA code, as it is a stream of bytes, no luck.
I have a working parsing code, but it needs a full string (myString := "1000|1500|1250|2000|<CR>") to work.
I am stuck with a one byte array string that wont convert into a full sentence and is the only thing stopping my project.
I am recieving via serial a string of bytes "$1000|1500|1250|2000|<CR>" that is servo position data from my pc. I understand that being sent via serial, it is being received one char at a time, so I can create an array with the bytes myarray[0] = $, myarray[1] = 1, myarray[2] = 0 etc, but I cannot use this data to set my servo position. I need a full string in one var ie servopos1 = 1000, servopos2 = 1500, servopos3 = 1250, servopos4 = 2000.
how do I convert myarray[#] into a "string"?
bytemove just ends up with another array[#] of individual letters.
I have tried recoding the gps readNEMA code, as it is a stream of bytes, no luck.
I have a working parsing code, but it needs a full string (myString := "1000|1500|1250|2000|<CR>") to work.
I am stuck with a one byte array string that wont convert into a full sentence and is the only thing stopping my project.
Comments
I'm thinking - you don't want to convert the incoming byte array to a string. It looks like a packet protocol, where the packet starts with a "$" and ends with a <CR>. In between the positions are 2 byte values - most likely- sent as [LSB][MSB].
For example, the value 1000 decimal is 0x03E8 hexadecimal. When received it looks like [0xE8][0x03].
But that's just a guess since there's no datasheet or reference accompanying the original post.
Con
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
obj
ser : "fullduplexserial"
VAR
PUB Main | mStr, aStr, bStr
ser.start (31, 30, 0, 115200)
aStr := string("ABCD")
repeat
mStr := 0
AddString(mStr, aStr, string("ABcd"))
AddString(mStr, mStr, string("1234"))
AddString(mStr, mStr, string("$"))
AddString(mStr, mStr, string("1"))
AddString(mStr, mStr, string("0"))
AddString(mStr, mStr, string("0"))
AddString(mStr, mStr, string("0"))
AddString(mStr, mStr, string("|"))
ser.str(mStr)
ser.tx(13)
PRI AddString( dstStrPtr, srcStrPtr1, srcStrPtr2 ) | len
len := StrSize(srcStrPtr1)
ByteMove(dstStrPtr, srcStrPtr1, len)
ByteMove(dstStrPtr += len, srcStrPtr2, StrSize(srcStrPtr2)+1) '+1 for zero termination
on to parsing the data and testing with servos.
as for a little more info on how i have it set up:
PC running program that connects to a Raspberry Pi via tcp/ip, sends servo position data and receives sensor data
RPi running serial to ip 2 way redirector. Connected via WiFi. (Couldnt get RN-171 working completely (no data flow))
Prop receives servo data from RPi via serial uart and sends sensor data back
Prop decodes servo position data & updates position.
[ code ]
... Code here
[ / code]
Are you sure the transmitted data is ASCII?
Con
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
obj
ser : "fullduplexserial"
VAR
byte myArray[6]
PUB Main | mStr, aStr, bStr, tmp
ser.start (31, 30, 0, 115200)
aStr := string(" ")
myArray[0] := string("$")
myArray[1] := string("1")
myArray[2] := string("0")
myArray[3] := string("0")
myArray[4] := string("1")
myArray[5] := string("|")
repeat
mStr := 0
AddString(mStr, aStr, myArray[0])
AddString(mStr, mStr, myArray[1])
AddString(mStr, mStr, myArray[2])
AddString(mStr, mStr, myArray[3])
AddString(mStr, mStr, myArray[4])
AddString(mStr, mStr, myArray[5])
ser.str(mStr)
ser.tx(13)
PRI AddString( dstStrPtr, srcStrPtr1, srcStrPtr2 ) | len
len := StrSize(srcStrPtr1)
ByteMove(dstStrPtr, srcStrPtr1, len)
ByteMove(dstStrPtr += len, srcStrPtr2, StrSize(srcStrPtr2)+1) '+1 for zero termination
You can replace your code above with one line: ser.str(string("$1000|1500|1250|2000|",13))
Andy
MCU sends SENSOR data to PC.
At the same time.
the code above was to see if it worked by displaying the rebuilt string on the serial terminal.
in my code, ser.tx sends to propterm and rpi.tx sends to PC
btw im still having problems. that code works fine by itself, but when i join it in my big spin it gets all funky.
depending on how much code is running depends on weather my mcu sends/receives the correct data. one extra ser.tx(13) or anything basic can jam it all up.
but i have PLENTY of free space (nearly 6,000 longs)
i guess now i am having problems building the array from each recieved character. it needs to keep it self in order, $ starts <CR> ends data in the middle.
each time i try something new it garbles all my io data.
from the looks of it, as of right now, i can see the entire line, but it looks like the matrix on propTerm and it takes a while for one whole line to show up... i know its recieving very fast, i can un comment and recomment some code and it displays everything the pc is sending just fine.
This waits for Servo data and then sends the Sensor data back. Not both at the same time. You can use a second cog if you need it at the same time. I find it much simpler to receie and parse the characters in the same methode, than first receive a string and parse it later.
this is not tested, but it compiles...
Andy
As a matter of curiosity, what PC program are you using to send this data? (I do a lot of work with animatronics)
Thank you soo much!
Zack
but exactly how does that handle the parsing?? if i were to change my chars around i would have no clue were to start. (notibly i probibly wont, but would still like to know)
You may want to add a bit of flexibility to your receive and parse routine -- right now it's locked into a specific array and number of servos. Simple changes let you point that code to another/different array, and work with any number of servos.
Cool that it works (no clue what the F in OMFG could mean ;-)
How the parsing works:
First it waits until a "$" is received.
Then it receives every numeric character and "shifts" it in as the lowest digit of the decimal number.
If a not numerical character is received it must be the ending "|" and the decimal value is stored to the ServoData array.
This is repeated 4 times.
The CR is not tested (it is not necessary for the data, but it is useful if you show it on the Terminal).
Andy
Any way you want! -- you wrote the PC program that's sending values.
One thought is to use a different header character to send different groups of values. Of course, you'd have to modify the parser routine as the header character would now be used to determine the destination of values.