Incoming string from over IP
arbelaezc
Posts: 12
Hi,
I am controlling some devices through and extron serial controller over IP. When I am receiving strings from the remote devices and viewing them from the Diagnostics tab in Netlinx, i am only getting back the response one byte at a time instead on the entire string in one line. I created string buffers and am still getting the issue.
So, if I increment the vol by 1, in Diagnostics i am expecting to get a string response in one line like this:
Instead, I am getting this:
Any suggestions? Sorry if my code might not make sense but I tried to paste only the essential things and avoid having you the entire code. Thanks in advance for any help.
Cristhian
I am controlling some devices through and extron serial controller over IP. When I am receiving strings from the remote devices and viewing them from the Diagnostics tab in Netlinx, i am only getting back the response one byte at a time instead on the entire string in one line. I created string buffers and am still getting the issue.
DEFINE_DEVICE //------------------------------------------- dvMASTER = 0:1:13 //NI-900 controller (* EXTRON IPL T S6 IP SERIAL CONTROLLER *) dvPROJ1 = 0:4:13 //238 Projector dvMIXER1 = 0:5:13 //238 Mixer dvPROJ2 = 0:6:13 //239 Projector dvMIXER2 = 0:7:13 //239 Mixer DEFINE_VARIABLE //----------------------------------------- (* PROJECTOR VARIABLES *) PERSISTENT INTEGER nPROJ1_PWR PERSISTENT INTEGER nPROJ2_PWR VOLATILE INTEGER nPROJ1_MUTE VOLATILE INTEGER nPROJ2_MUTE DEVCHAN dcPROJ_STATUS[]={ {dvTP1,4},{dvTP1,5}, {dvTP2,4},{dvTP2,5} } DEVCHAN dcVIDEO[]={ {dvTP1,6},{dvTP1,7},{dvTP1,8},{dvTP1,9}, //TP1 {dvTP2,6},{dvTP2,7},{dvTP2,8},{dvTP2,9} //TP2 } DEVCHAN dcAUDIO[]={ {dvTP1,10},{dvTP1,11}, //TP1 {dvTP2,10},{dvTP2,11} //TP2 } (* MIXER VARIABLES *) NON_VOLATILE INTEGER nMIXER1_VOL NON_VOLATILE INTEGER nMIXER2_VOL NON_VOLATILE INTEGER nMIXER1_MUTE NON_VOLATILE INTEGER nMIXER2_MUTE DEVCHAN dcVOL[]={ {dvTP1,12},{dvTP1,13},{dvTP1,14}, {dvTP2,12},{dvTP2,13},{dvTP2,14} } (* OTHER VARIABLES *) VOLATILE INTEGER nCLIENT_ONLINE[4] VOLATILE CHAR sDEV4[10] DEV dIP_DEV[]={ dvPROJ1,dvMIXER1,dvPROJ2,dvMIXER2 } DEFINE_MUTUALLY_EXCLUSIVE //------------------------------- //--------SUBROUTINE/FUNCTION DEFINITIONS GO BELOW-------// DEFINE_FUNCTION fnCLIENT_OPEN() { IF(nCLIENT_ONLINE[4] == FALSE){ IP_CLIENT_OPEN(dIP_DEV[4].PORT,IPTLS6_ADDR,COM4,1) } WAIT 1 {} } DEFINE_FUNCTION CHAR fnVOL_CTRL(INTEGER nCASE){ SWITCH(nCASE){ CASE 1:{ //TP1 vol up IF(nMIXER1_VOL < MAX_VOL_LVL OR nMIXER1_VOL == MIN_VOL_LVL){ nMIXER1_VOL++ SEND_STRING dIP_DEV[2],"ITOA(nMIXER1_VOL),'V'" SEND_LEVEL dvTP1,1,nMIXER1_VOL } } CASE 2:{ //TP1 vol down IF(nMIXER1_VOL > MIN_VOL_LVL OR nMIXER1_VOL == MAX_VOL_LVL){ nMIXER1_VOL-- SEND_STRING dIP_DEV[2],"ITOA(nMIXER1_VOL),'V'" SEND_LEVEL dvTP1,1,nMIXER1_VOL } } CASE 3:{ //TP1 mute IF(nMIXER1_MUTE == FALSE){ nMIXER1_MUTE = TRUE SEND_STRING dIP_DEV[2],"sMIXER_CMDS[OUT_MUTE]" } ELSE{ nMIXER1_MUTE = FALSE SEND_STRING dIP_DEV[2],"sMIXER_CMDS[OUT_UNMUTE]" SEND_LEVEL dvTP1,1,nMIXER1_VOL } } CASE 4:{ //TP2 vol up IF(nMIXER2_VOL < MAX_VOL_LVL OR nMIXER2_VOL == MIN_VOL_LVL){ nMIXER2_VOL++ SEND_STRING dIP_DEV[4],"ITOA(nMIXER2_VOL),'V'" SEND_LEVEL dvTP2,1,nMIXER2_VOL } } CASE 5:{ //TP2 vol down IF(nMIXER2_VOL > MIN_VOL_LVL OR nMIXER2_VOL == MAX_VOL_LVL){ nMIXER2_VOL-- SEND_STRING dIP_DEV[4],"ITOA(nMIXER2_VOL),'V'" SEND_LEVEL dvTP2,1,nMIXER2_VOL } } CASE 6:{ //TP2 mute IF(nMIXER2_MUTE == FALSE){ nMIXER2_MUTE = TRUE SEND_STRING dIP_DEV[4],"sMIXER_CMDS[OUT_MUTE]" } ELSE{ nMIXER2_MUTE = FALSE SEND_STRING dIP_DEV[4],"sMIXER_CMDS[OUT_UNMUTE]" } } } } DEFINE_START //-------------------------------------------- (* STARTUP SETTINGS *) fnCLIENT_OPEN() nMIXER2_VOL = DEF_VOL_LVL SEND_STRING dIP_DEV[4],"ITOA(nMIXER2_VOL),'V'" SEND_LEVEL dvTP2,1,nMIXER2_VOL WAIT 1 { IP_CLIENT_CLOSE(dIP_DEV[4].PORT) } CREATE_BUFFER dIP_DEV[4],sDEV4[10] DEFINE_EVENT //-------------------------------------------- (* CLIENT STATUS *) DATA_EVENT[dIP_DEV[4]]{ ONLINE:{ nCLIENT_ONLINE[4] = TRUE SEND_STRING 0,"'COM4 ONLINE'" } OFFLINE:{ nCLIENT_ONLINE[4] = FALSE SEND_STRING 0,"'COM4 OFFLINE'" } STRING:{ sDEV4 = DATA.TEXT SEND_STRING 0,"sDEV4" SEND_COMMAND dvTP2,"'^TXT,59,0,',sDEV4" } ONERROR:{ SEND_STRING 0,"ITOA(DATA.NUMBER)" } } BUTTON_EVENT[dcVOL]{ //audio ramping & mute PUSH:{ STACK_VAR INTEGER nINDEX nINDEX = GET_LAST(dcVOL) fnCLIENT_OPEN() fnVOL_CTRL(nINDEX) TO[dcVOL[nINDEX]] } HOLD[1,REPEAT]:{ STACK_VAR INTEGER nINDEX nINDEX = GET_LAST(dcVOL) fnVOL_CTRL(nINDEX) } }
So, if I increment the vol by 1, in Diagnostics i am expecting to get a string response in one line like this:
Line 23: Vol43$0D
Instead, I am getting this:
Line 23: V Line 24: o Line 25: l Line 25: 4 Line 26: 3 Line 27: $0D
Any suggestions? Sorry if my code might not make sense but I tried to paste only the essential things and avoid having you the entire code. Thanks in advance for any help.
Cristhian
0
Comments
Paul
Agreed.
If you know the string will always end with a carriage return, you should buffer the text until you have one and then remove it and continue to parse.
Sent from my iPhone using Tapatalk
There is documentation of this somewhere but I do not feel like looking it up. Buffer parsing from IP devices is a little different than for RS232. Try it this way. Keep the string data event, but leave it empty. This may seem odd but it is necessary. In the OFFLINE data event, do your buffer parsing, from the buffer variable you created in DEFINE_START and not from data.text. And if you are expecting a $0D at the end of every complete string than do it like:
while(find_string(sDEV4,"$0D",1))
{
char sParseData[100];
sParseData = remove_string(sDEV4,"$0D",1)
// do what you need to do with sParseData
}
I'd recommend not parsing in the offline event.
Something along the lines of
If there is no end delimiter , I'll put in a slight delay before evaluating, copy the chunk of string that I think might be right and not delete the whole message until I'm sure I got it straight.
That's my opinion. If you don't like it, I have others...
On the downside if your delimeter spans more than 1 data event you're screwed if you do it this way and in that case you have to find_string in MyBuffer.
I am keeping all devices online and when the connections times out, they will go offline. I really only need to parse the string for the projector for lamp hours, current input, and power status. I will review my code and make the edits per the posters input. I appreciate the info and will keep everyone posted.
Thanks ericmedley! My strings are now coming in one line at a time. Appreciate the help!