Home AMX User Forum NetLinx Studio
Options

DATA via COMM port

Good morning, Masters!

What should be procedure for correct data processing?
I want to analyze string coming from device via COMM port.
If the answer has not come, it is necessary to repeat request or to do something else.
It will be more clear if I give a code.
Notwithstanding what time has expired a body of WAIT is never started so timeOut is FALSE always.
And buffer=='' too. It is independent of the answer comes or not.


PROGRAM_NAME='Main'

DEFINE_DEVICE
dvDEVICE = 5001:1:1;
dvIO = 5001:9:1;
DEFINE_VARIABLE

integer timeOut;
char buffer[1024];

DEFINE_EVENT
CHANNEL_EVENT [dvIO,1]
{
ON:
{
timeOut=FALSE;
SEND_STRING dvDEVICE,"$02,'0','7','C','D','F',$03"

WAIT 10
timeOut=TRUE; //There is no answer from device within sec

while (timeOut==FALSE OR LENGTH_STRING(buffer)); // just waiting answer

if (timeOut==TRUE)
SEND_STRING 0,'Communication problem';
else
SEND_STRING 0,"'Got answer =',buffer";
}
}
DEFINE_START
CREATE_BUFFER dvDEVICE,Buffer;


Thanks.. And Sorry for my ugly English as always.
Alex.

Comments

  • Options
    Spire_JeffSpire_Jeff Posts: 1,917
    I apologize if I miss something, but it's late and I'm out of caffeinated beverages!

    Ummm, I think what you need to do is something like this:
    PROGRAM_NAME='Main'
    
    DEFINE_CONSTANT
    INTEGER TIMEOUTTIME = 100  //10th of a second
    CHAR START_OF_RESPONSE[2] =  {$02,'R'}
    CHAR END_OF_RESPONSE[1]   =  {$03}
    
    DEFINE_DEVICE
    dvDEVICE = 5001:1:1;
    dvIO = 5001:9:1;
    
    DEFINE_VARIABLE
    integer timeOut;
    char buffer[1024];
    
    DEFINE_CALL 'SEND DATA'
    {
        SEND_STRING dvDEVICE,"$02,'0','7','C','D','F',$03"
    		WAIT TIMEOUTTIME 'RESEND DATA' CALL 'SEND DATA'
    }
    
    DEFINE_EVENT
    CHANNEL_EVENT [dvIO,1]
    {
    	ON:
    		{
    			CALL 'SEND DATA'
    		}
    
    }
    
    DATA_EVENT[dvDEVICE]
    {
    	STRING:
    	{
    		STACK_VAR CHAR RESPONSE[50]
    		STACK_VAR INTEGER EXPECTED_RESPONSE
    		
    		WHILE(FIND_STRING(buffer,START_OF_RESPONSE,1) && FIND_STRING(buffer,END_OF_RESPONSE,2))
    		{
    		 RESPONSE = REMOVE_STRING(buffer,END_OF_RESPONSE,2)
    		 //HANDLE STRING PROCESSING HERE (Set EXPECTED_RESPONSE to TRUE if response is as expected)
    		 
    		}
    		 IF(EXPECTED_RESPONSE)            //cancel sending the command again
    		  CANCEL_WAIT 'RESEND DATA'
    		 ELSE                             //reset timer
    			{
    				CANCEL_WAIT 'RESEND DATA'
    				WAIT TIMEOUTTIME 'RESEND DATA' CALL 'SEND DATA'
    			}
    	}
    }
    DEFINE_START
    CREATE_BUFFER dvDEVICE,Buffer;
    

    I think that will do what you want, but you need to make sure that you set the timeout high enough to make sure you aren't flooding the serial port.

    Jeff
  • Options
    Thank Jeff for the answer, it is very useful example and I will try it today.
  • Options
    DHawthorneDHawthorne Posts: 4,584
    Just an informational note; Jeff included it in his code without explanation, but it's important to name your waits when using them in this kind of application. Unnamed waits will stack up if called before the last expired. Named waits will not call a new iteration if the previous has not been canceled or expired.
  • Options
    GSLogicGSLogic Posts: 562
    Maybe there's another reason I can't see, but it looks like this code could create a loop if the device "dvDEVICE " went offline or you send a command that will not get a DATA_EVENT response back.

    If "CHANNEL_EVENT [dvIO,1]" triggers the "CALL 'SEND DATA'" and no response is sent from the "dvDEVICE", it would go in to a forever loop.

    I would just resend the "CALL 'SEND DATA'" command only if I get a response from the "dvDEVICE" and I know that it is ready to receive a new command.

    DATA_EVENT[dvDEVICE]
    {
        STRING:
        {
    	STACK_VAR CHAR RESPONSE[50]
    	WHILE(FIND_STRING(buffer,START_OF_RESPONSE,1) && FIND_STRING(buffer,END_OF_RESPONSE,2))
    	{
    	    RESPONSE = REMOVE_STRING(buffer,END_OF_RESPONSE,2)
    	    //HANDLE STRING PROCESSING HERE (Set 	
                CALL 'SEND DATA'	 
            }
       }
    }
    
  • Options
    Spire_JeffSpire_Jeff Posts: 1,917
    Gary,

    I agree. My intentions were to give a starting place, not to write a full comm module for the device. I suppose I really should have included a timeout or in the least coded it to resend the command every 10 seconds for the first 5 attempts, then only resend every minute or two until communication is re-established.

    Alex,
    If you need any help with the timeout portion, just ask and I'll see what I can do. Also, it would be really helpful to know the device you are working with and a few more specifics regarding the communication protocol.


    Jeff
  • Options
    GSLogicGSLogic Posts: 562
    Jeff

    That is what I thought, I just posted it in case someone tryed your code and wasn't connected to the device.

    Gary
  • Options
    Check out tech note 616

    http://www.amx.com/techsupport/PDNTechNote.asp?id=616

    The last example in the tech note is one I highly recommend if the data response packet is a reasonable size.

    Brian
Sign In or Register to comment.