TCP/IP data read/write in 4PPC70 display

Hi,

I am trying to send the data for 4PPC70 display through TCP/IP socket and reading the data from embedded card which I have develop for machine.

When I am connecting my embedded card with my PLC, my automation studio 4.12 gets disconnected and I am not getting to monitor the logic.

So please can anyone suggest whats the issue.

I would really appreciate the efforts for resolving the issue.

Thanks & Regards,
Shrenik

Hi, I can imagine basically two causess. Either CPU load is 100% and there is no idle time. AS is communication with C70 and all targets generally in idle time.
→ move task with TCPIP communication to the lowest priority task class
→ check the logic, maybe you have inside infinite loop or something similar?

second problem could be that your target is restarted to service mode. But if this would be a reason then connection should be reestablished after while and you could see error message in the logger.

Are you able to connected to C70 using sdm? access from any browser, using url:

ipaddress/sdm

If so, then check logger and CPU usage.

1 Like

Hi,

as Jaroslav I would also guess “too less idle time”.

There is often a tendency to implement TCP/IP communication in a task class with a low cycle time and high tolerance time (e.g. TC#8 default).

If the execution time of the task is then longer than the configured cycle time, the entire idle time of the PLC is used. This can also affect communication with the AS, for example.

In this case, it is a good idea to configure a “Task class Idle Time” so that communication is still possible at all.

image

https://help.br-automation.com/#/en/4/projectmanagement%2Fsystemconfiguration%2Fsg4%2Fcpu%2Fprojectorganisation_systemconfiguration_sg4_cpu_timing.html

Is the PLC perhaps a TCP server? In this case, it is conceivable that it is ‘bombarded’ with frames by the embedded board.

There may also be a hardware problem that is paralyzing the Ethernet communication as a whole.

1 Like


Kindly check the sdm file of my plc.

Thanks & Regards,
Shrenik

that doesn’t look critical. But this page also only shows a static moment.
And without a complete dump file we only see a very small picture.

We need more information from you.

  • the web server is available at all times ?
  • AS communication is available, but as soon as the board is plugged in, it is lost ?
  • even if the board is not powered itself ?
  • Which TCP/IP communication are we using to talk to the board? Who is server, who is client, UDP or Tcp, which ports are used ? Which IP addresses are used etc.
  • Does the problem disappear if the task for TCP communication on the PLC is deactivated ?
1 Like

Dear Christoph,

As I have kept my plc as TCP server and when I am connecting my embedded board with plc through ethernet switch then PLC is getting online and sometimes it is getting offline.

I don’t understand what’s the issue.

Thanks & Regards,
Shrenik

Dear Christoph,

As per your queries please find the comments

  1. Web server is on.
  2. AS communication is available but when board is plug AS communication is there but when I do the monitor mode at that communication lost
    3.Board is power itself when there is no communication between board and PLC
    4.AS TCP/IP and my plc is server and board is client, ethernet port IF2 of 4PPC70 is used for communication. IP address of PLC is 192.168.0.9 and IP address of Board is 192.168.0.10
  3. If I disable the TCP task then my PLC is RUN mode and I can do the Monitor mode of the programme.

Follow the below link for downloading the video.

Thanks & Regards,
Shrenik

ok, thanks for the info.
Unfortunately the link is blocked in company’s network.

  • which task class is used for the TCP communication ?
    and
  • what is the configuration for this taskclass (cycle time, tolerance time).

Dear Christoph,

Kindly refer the attached image for your ref.

Thanks & Regards,
Shrenik


You have a very high tolerance time configured.

If your board now keeps the ‘tcp’ task busy, the CPU load will increase.
And since AS communication runs with lower priority than application tasks it will be interrupted during this time. Once all the application tasks are done it will continue.

Once you move the TCP task to a low task class, you will probably also get a cycle time violation.

So the question is why the task needs so much time when the board is sending.

There might be an issue when evaluating the received data. Always end a task as soon as possible to give control back to the scheduler.

Hi,

I checked the video and I’m pretty sure, your problem is based on a memory violation, for example writing data to array / buffer with a too big size.

Because in video I see in the watch, that at a bool variable there’s the remark “illegal boolean value”. This must not happen under normal condition and is a strong indicator that memory ist overwritten accidently.

The loose of the connection can be a follow-up error, for example if the overwritten memory is used by the communication driver.

1 Like

Dear Alexander,

Thanks for your reply.

Instead of array I can used variables that will be ok.

Thanks & Regards,
Shrenik

Dear Christoph,

So let me know how much time I have to configure in my plc.

Thanks & Regards,
Shrenik

Hi Shrenik,

of course it’s ok to use arrays, structures, and so on.
But for example always check the declaration and/or by code, if the limits / size are not violated.
There could be other reasons also, for example memcopying from a source bigger then the destination.

There are already some useful posts with hints how to find rhe root causes for memoty violation here in the community, but sorry I can’t link them right now because writing at my mobile phone :wink:

Best regards!

Hi Shrenik,

that depends on your application code, no general answer is possible.

If CPU load is the reason for this issue means that this ‘tcp’ task takes several seconds to run which is not a fine solution. Try to rewrite this.

In some cases it helps to configure the “Task class Idle Time” I mentioned.

Can you share your ‘tcp’ task, please.

Dear Christoph,

Kindly find the below tcp task for your reference.

/* ------------------------------------------------------------------------------------------------------------
example for AsTCP- library
connect with ‘tcpclient.py’. Multiple connections in parallel are possible.
---------------------------------------------------------------------------------------------------------------*/

#define _REPLACE_CONST

/*
using _REPLACE_CONST enables defining constants in *.var files
and automatically creates #defines from them.

on the other hand, this leads to a warning 6424 being generated which
can be suppressed by adding 
	-W 6424
to 'Additional build options' (either to complete project or 'tcp' task only) 

*/

#ifdef _DEFAULT_INCLUDES
#include <AsDefault.h>
#endif
#include <bur/plctypes.h>
//#include <AsString.h>

char* p_step_str;
char* p_step_str_old;

char tt=0;
char sel_ip=0;
#define WARPING_KP_IP “192.168.0.10”
#define BEAMING_KP_IP “192.168.0.11”
#define MAIN_PANEL_IP “192.168.0.12”
#define LEASING_PANEL_IP “192.168.0.13”
#define HYDRAULIC_PANEL_IP “192.168.0.14”
#define DEBUG_PORT_IP “192.168.0.17”

#define WARPING_KP 1
#define BEAMING_KP 2
#define MAIN_PANEL 3
#define LEASING_PANEL 4
#define HYDRAULIC_PANEL 5
#define DEBUG_PORT 6

/* --------------------------------------------------------------------------------------------------------
startup after powerfail

*/

void _INIT Initialisierung( void ){

/* this could be useful when task is overloaded... */
brsmemset( (UDINT) &open, 0, sizeof(open) );
brsmemset( (UDINT) &close, 0, sizeof(close) );
brsmemset( (UDINT) &server, 0, sizeof(server) );
brsmemset( (UDINT) &getipaddr, 0, sizeof(getipaddr) );

brsmemset( (UDINT) &client, 0, sizeof(client) );


welcome_message = (USINT*) "Shreenathji Industries\nPress\n'1' for first message\n'2' for second message\n'3' to abort connection\n";
first_message = (USINT*) "Hi test\n";



second_message = (USINT*) "Hi Donald Duck\n";

server.enable = 1;

getipaddr.enable = 1;
getipaddr.pDevice = (UDINT) "IF2";
getipaddr.pIPAddr = (UDINT) myip;
getipaddr.Len = sizeof(myip);

step = SERVER_OPEN;
p_step_str = "INIT_UP";
p_step_str_old = 0;

}

/* --------------------------------------------------------------------------------------------------------
cyclic code

*/

char dd=0;
void _CYCLIC Zyklisch( void ){
int i;

CfgGetIPAddr( &getipaddr );
if( getipaddr.status == 0 ){
	getipaddr.enable = 0;
}


switch( step ){
case SERVER_OPEN:
	p_step_str = "TcpOpen()";
	open.enable = 1;
	open.pIfAddr = 0;
	open.port = PORT;
	open.options = tcpOPT_REUSEADDR ;
	TcpOpen( &open );
	if( open.status == 0 ){
		server.ident = open.ident;
		server.backlog = 10;
		server.pIpAddr = (UDINT) tempstring;
		step = SERVER_RUNNING;
	}
	else if( open.status != ERR_FUB_BUSY ){
		brsstrcpy( (UDINT) errstring, (UDINT) "error TcpOpen()" );
		error = open.status;
		step = SERVER_ERROR;
	}
	break;


case SERVER_RUNNING:
	p_step_str = "server is running";
	TcpServer( &server );
	if( server.status == 0 ){  /* a new client has connected */
		for( i = 0; i < MAX_CLIENTS; ++i ){
			if( !client[i].connected ){
				client[i].connected = 1;
				brsstrcpy( (UDINT) client[i].addr, (UDINT) tempstring );
				client[i].recv.ident = server.identclnt;
				client[i].portclnt = server.portclnt;
				client[i].recv.enable = 1;
				client[i].recv.pData = (UDINT) client[i].receive_buffer;
				client[i].recv.datamax = sizeof(client[i].receive_buffer);
				client[i].recv.flags = 0;
				client[i].send.ident = server.identclnt;
				//client[i].send.pData = (UDINT) welcome_message;
				//client[i].send.datalen = brsstrlen( (UDINT) welcome_message );
				//client[i].send.enable = 1;
				client[i].close.enable = 0;
				client[i].close.ident = server.identclnt;
				break;
			}
		}
	}

	/* Noodle through all clients */
	for( i = 0; i < MAX_CLIENTS; ++i ){

		/* receive data... */
		TcpRecv( &client[i].recv );

		if( client[i].recv.status == tcpERR_NOT_CONNECTED || client[i].recv.status == tcpERR_INVALID_IDENT || client[i].recv.status == tcpERR_SYSTEM ){
			client[i].close.enable = 1;
		}
		else if( client[i].recv.status == 0 ){
			if( client[i].recv.recvlen != 0 ){
				client[i].data_received = 1; /* Flag: Data has been received */
            }
            else if( client[i].recv.recvlen == 0 ){  /* Remote station has closed write direction */
                client[i].close.enable = 1;
            }
            
		}


		/* Process input data ...*/
			if( client[i].data_received && client[i].send.enable == 0 ){  /* Data has arrived and send buffer is free */
				client[i].data_received = 0;
				
				if(!strcmp(client[i].addr,WARPING_KP_IP))			sel_ip=WARPING_KP;
				else if(!strcmp(client[i].addr,BEAMING_KP_IP))		sel_ip=BEAMING_KP;
				else if(!strcmp(client[i].addr,MAIN_PANEL_IP))		sel_ip=MAIN_PANEL;
				else if(!strcmp(client[i].addr,LEASING_PANEL_IP))	sel_ip=LEASING_PANEL;
				else if(!strcmp(client[i].addr,HYDRAULIC_PANEL_IP))	sel_ip=HYDRAULIC_PANEL;
				else if(!strcmp(client[i].addr,DEBUG_PORT_IP))		sel_ip=DEBUG_PORT;
				else sel_ip=250;

				switch(sel_ip)
				{
					case WARPING_KP:
						
					//	if(client[i].recv.recvlen==39 && client[i].receive_buffer[0]=='$' && client[i].receive_buffer[1]==',' && client[i].receive_buffer[2]=='K')
						{
							Warping_Keypad_KEYS[0]=	client[i].receive_buffer[4]-0x30;
							Warping_Keypad_KEYS[1]=	client[i].receive_buffer[6]-0x30;
							Warping_Keypad_KEYS[2]=	client[i].receive_buffer[8]-0x30;
							Warping_Keypad_KEYS[3]=	client[i].receive_buffer[10]-0x30;
							Warping_Keypad_KEYS[4]=	client[i].receive_buffer[12]-0x30;
							Warping_Keypad_KEYS[5]=	client[i].receive_buffer[14]-0x30;
							Warping_Keypad_KEYS[6]=	client[i].receive_buffer[16]-0x30;
							Warping_Keypad_KEYS[7]=	client[i].receive_buffer[18]-0x30;
							Warping_Keypad_KEYS[8]=	client[i].receive_buffer[20]-0x30;
							Warping_Keypad_KEYS[9]=	client[i].receive_buffer[22]-0x30;
							Warping_Keypad_KEYS[10]=	client[i].receive_buffer[24]-0x30;
							Warping_Keypad_KEYS[11]=	client[i].receive_buffer[26]-0x30;
							Warping_Keypad_KEYS[12]=	client[i].receive_buffer[28]-0x30;
							Warping_Keypad_KEYS[13]=	client[i].receive_buffer[30]-0x30;
							Warping_Keypad_KEYS[14]=	client[i].receive_buffer[32]-0x30;
							//34 & 35 Are CRC
						}	
						for(dd=0;dd<15;dd++)
						{
							Warping_Keypad_LED[dd]=Warping_Keypad_KEYS[dd];
					}
							
						
						GenBuf[0]='$';
						GenBuf[1]=',';
						GenBuf[2]='L';
						GenBuf[3]=',';
						GenBuf[4]=Warping_Keypad_LED[0]+0x30;
						GenBuf[5]=',';
						GenBuf[6]=Warping_Keypad_LED[1]+0x30;
						GenBuf[7]=',';
						GenBuf[8]=Warping_Keypad_LED[2]+0x30;
						GenBuf[9]=',';
						GenBuf[10]=Warping_Keypad_LED[3]+0x30;
						GenBuf[11]=',';
						GenBuf[12]=Warping_Keypad_LED[4]+0x30;
						GenBuf[13]=',';
						GenBuf[14]=Warping_Keypad_LED[5]+0x30;
						GenBuf[15]=',';
						GenBuf[16]=Warping_Keypad_LED[6]+0x30;
						GenBuf[17]=',';
						GenBuf[18]=Warping_Keypad_LED[7]+0x30;
						GenBuf[19]=',';
						GenBuf[20]=Warping_Keypad_LED[8]+0x30;
						GenBuf[21]=',';
						GenBuf[22]=Warping_Keypad_LED[9]+0x30;
						GenBuf[23]=',';
						GenBuf[24]=Warping_Keypad_LED[10]+0x30;
						GenBuf[25]=',';
						GenBuf[26]=Warping_Keypad_LED[11]+0x30;
						GenBuf[27]=',';
						GenBuf[28]=Warping_Keypad_LED[12]+0x30;
						GenBuf[29]=',';
						GenBuf[30]=Warping_Keypad_LED[13]+0x30;
						GenBuf[31]=',';
						GenBuf[32]=Warping_Keypad_LED[14]+0x30;
						GenBuf[33]=',';
						GenBuf[34]='x';
						GenBuf[35]='x';
						GenBuf[36]=',';
						GenBuf[37]='#';
						GenBuf[38]='\n';
					
						//strcpy(first_message,"Dat_Reced\n");
						client[i].send.pData = (UDINT) GenBuf;
						client[i].send.datalen = brsstrlen( (UDINT) client[i].send.pData );
						client[i].send.enable = 1;
							
							//strcpy(first_message,"WARPING_KP\n");
							//client[i].send.pData = (UDINT) first_message;
							//client[i].send.datalen = brsstrlen( (UDINT) client[i].send.pData );
							//client[i].send.enable = 1;
						break;
					
						case BEAMING_KP:
							strcpy(first_message,"BEAMING_KP\n");
						client[i].send.pData = (UDINT) first_message;
						client[i].send.datalen = brsstrlen( (UDINT) client[i].send.pData );
						client[i].send.enable = 1;
						break;
				
						case MAIN_PANEL:
							strcpy(first_message,"MAIN_PANEL\n");
						client[i].send.pData = (UDINT) first_message;
						client[i].send.datalen = brsstrlen( (UDINT) client[i].send.pData );
						client[i].send.enable = 1;
						break;
				
						case LEASING_PANEL:
							strcpy(first_message,"DEBUG_PORT\n");
						client[i].send.pData = (UDINT) first_message;
						client[i].send.datalen = brsstrlen( (UDINT) client[i].send.pData );
						client[i].send.enable = 1;
						break;
				
						case HYDRAULIC_PANEL:
							strcpy(first_message,"HYDRAULIC_PANEL\n");
						client[i].send.pData = (UDINT) first_message;
						client[i].send.datalen = brsstrlen( (UDINT) client[i].send.pData );
						client[i].send.enable = 1;							
						break;
				
						case DEBUG_PORT:

#ifdef AT
//Warping
//$,A,K1,K2,…K15,CRC,# – Received by PLC
//$,B,L1,L2…L15,CRC,# – Send By PLC
if(client[i].receive_buffer[0]==‘$’ && client[i].receive_buffer[1]==‘,’ && client[i].receive_buffer[2]==‘K’)
{
/*GenBuf[0]= client[i].receive_buffer[4]-0x30;
GenBuf[1]= client[i].receive_buffer[6]-0x30;
GenBuf[2]= client[i].receive_buffer[8]-0x30;
GenBuf[3]= client[i].receive_buffer[10]-0x30;
GenBuf[4]= client[i].receive_buffer[12]-0x30;
GenBuf[5]= client[i].receive_buffer[14]-0x30;
GenBuf[6]= client[i].receive_buffer[16]-0x30;
GenBuf[7]= client[i].receive_buffer[18]-0x30;
GenBuf[8]= client[i].receive_buffer[20]-0x30;
GenBuf[9]= client[i].receive_buffer[22]-0x30;
GenBuf[10]= client[i].receive_buffer[24]-0x30;
GenBuf[11]= client[i].receive_buffer[26]-0x30;
GenBuf[12]= client[i].receive_buffer[28]-0x30;
GenBuf[13]= client[i].receive_buffer[30]-0x30;
GenBuf[14]= client[i].receive_buffer[32]-0x30;
GenBuf[15]= client[i].receive_buffer[34]; //CRC
GenBuf[15]= client[i].receive_buffer[35]; //CRC
*/

								Warp_On_Pb=	client[i].receive_buffer[4]-0x30;
								//Warp_Cente=	client[i].receive_buffer[6]-0x30;
								Warp_Fwd1=	client[i].receive_buffer[8]-0x30;
								Warp_Rev1=	client[i].receive_buffer[10]-0x30;
								Tscr_Uc_Slow=	client[i].receive_buffer[12]-0x30;
								Cr_W_Start=	client[i].receive_buffer[14]-0x30;
								Cr_W_Stop=	client[i].receive_buffer[16]-0x30;
								Cr_W_Inch=	client[i].receive_buffer[18]-0x30;
								WB_Mc_Left=	client[i].receive_buffer[20]-0x30;
								WB_Mc_Righ=	client[i].receive_buffer[22]-0x30;
								Reset_On_Pb=	client[i].receive_buffer[24]-0x30;
								Creel_Left_side=	client[i].receive_buffer[26]-0x30;
								Creel_Right_side=	client[i].receive_buffer[28]-0x30;
								Lease_Up=	client[i].receive_buffer[30]-0x30;
								Lease_Dn=	client[i].receive_buffer[32]-0x30;
						
							}
						//sprintf(GenBuf,"$,B,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,CC,#\0",O_Warp_ON,Warp_Centre_Led,O_Warp_Fwd,O_Warp_Rev,UC_Slow,Warp_Start_Led,Warp_Stop_Led,Warp_Inch_Led,Warp_Left_Led,Warp_Right_Led,O_Mc_Reset,Creel_Left_Led,Creel_Right_Led,Lease_Up_Led,Lease_Dn_Led);
						GenBuf[0]='$';
						GenBuf[1]=',';
						GenBuf[2]='A';
						GenBuf[3]=',';
						GenBuf[4]=O_Warp_ON+0x30;
						GenBuf[5]=',';
						GenBuf[6]=Warp_Centre_Led+0x30;
						GenBuf[7]=',';
						GenBuf[8]=O_Warp_Fwd+0x30;
						GenBuf[9]=',';
						GenBuf[10]=O_Warp_Rev+0x30;
						GenBuf[11]=',';
						GenBuf[12]=UC_Slow+0x30;
						GenBuf[13]=',';
						GenBuf[14]=Warp_Start_Led+0x30;
						GenBuf[15]=',';
						GenBuf[16]=Warp_Stop_Led+0x30;
						GenBuf[17]=',';
						GenBuf[18]=Warp_Inch_Led+0x30;
						GenBuf[19]=',';
						GenBuf[20]=Warp_Left_Led+0x30;
						GenBuf[21]=',';
						GenBuf[22]=Warp_Right_Led+0x30;
						GenBuf[23]=',';
						GenBuf[24]=O_Mc_Reset+0x30;
						GenBuf[25]=',';
						GenBuf[26]=Creel_Left_Led+0x30;
						GenBuf[27]=',';
						GenBuf[28]=Creel_Right_Led+0x30;
						GenBuf[29]=',';
						GenBuf[30]=Lease_Up_Led+0x30;
						GenBuf[31]=',';
						GenBuf[32]=Lease_Dn_Led+0x30;
						GenBuf[33]=',';
						GenBuf[34]='#';
						GenBuf[35]='\0';
					
						//strcpy(first_message,"Dat_Reced\n");
						client[i].send.pData = (UDINT) GenBuf;
						client[i].send.datalen = brsstrlen( (UDINT) client[i].send.pData );
						client[i].send.enable = 1;
					
					/*strcpy(first_message,"DEBUG_PORT\n");
					client[i].send.pData = (UDINT) first_message;
					client[i].send.datalen = brsstrlen( (UDINT) client[i].send.pData );
					client[i].send.enable = 1;*/
	#endif				
						break;
				
						default:
							strcpy(first_message,"UNKNOWN_PORT\n");
						client[i].send.pData = (UDINT) first_message;
						client[i].send.datalen = brsstrlen( (UDINT) client[i].send.pData );
						client[i].send.enable = 1;
						break;
					}
		}
				/*
			switch( client[i].receive_buffer[0] ){
			case '1':
				client[i].send.pData = (UDINT) first_message;
				client[i].send.datalen = brsstrlen( (UDINT) client[i].send.pData );
				client[i].send.enable = 1;
				break;

			case '2':
//						O_Warp_ON = Warp_On_Pb;
//						O_Warp_ON1 = DIGITAL_OUTPUT[0];
						GenBuf[0]='$';
						GenBuf[1]=',';
						GenBuf[2]= Warp_On_Pb+0x30;
						GenBuf[3]=',';
						GenBuf[4]=DIGITAL_OUTPUT[1]+0x30;
						GenBuf[5]=',';
						GenBuf[6]='#';
						GenBuf[7]='\n';
						GenBuf[8]='\0';
				client[i].send.pData = (UDINT) GenBuf;
				client[i].send.datalen = brsstrlen( (UDINT) client[i].send.pData );
				client[i].send.enable = 1;
						
						if(tt==0)	tt=1;
						else
						{
							tt=0; 
						}
						MachineData.W_A_Man_Bi=tt;
				break;

			case '3':
                client[i].send.pData = (UDINT) "bye, bye\n";
                client[i].send.datalen = brsstrlen( (UDINT) client[i].send.pData ); 
                client[i].send.enable = 1;                                   
				client[i].close.enable = 1;
				break;
			}
		}*/


		/* send output data */
		TcpSend( &client[i].send );
		if( client[i].send.status == 0 ){ /* sent successfully */
			client[i].send.enable = 0;
		}
		else if( (client[i].send.status != ERR_FUB_BUSY) && (client[i].send.status != ERR_FUB_ENABLE_FALSE) ){ /* error */
			client[i].send.enable = 0;
		}


		/* Release socket when connection is lost */
		TcpClose( &client[i].close );
        if( client[i].close.enable == 1 && client[i].close.status == 0 ){
           brsmemset( (UDINT) &client[i], 0, sizeof(CLIENT_typ) );
        }            
	} /* end for( i = 0; i < MAX_CLIENTS... */

	break;




case SERVER_ERROR:
	p_step_str = "error";

	break;

}




if( p_step_str != p_step_str_old ){
	p_step_str_old = p_step_str;
	brsstrcpy( (UDINT) step_str, (UDINT) p_step_str );
}

}

/* --------------------------------------------------------------------------------------------------------
is called on overload of the task

*/

void _EXIT Exit( void ){
int i;

for( i = 0; i < MAX_CLIENTS; ++i ){
	do	
		TcpClose( &client[i].close );
	while( client[i].close.status == ERR_FUB_BUSY );
}

do {
	close.enable = 1;
	close.ident = open.ident;
	close.how = 0;
	TcpClose( &close );
}
while( close.status == ERR_FUB_BUSY );

}

Thanks & Regards,
Shrenik

Hi Shrenik,

uuh, why didn’t you just export the task and attach it :slight_smile:

working in C language can end up in many memory leaks if you not program very carefully.

so, please

  • disconnect your board
  • set a breakpoint at this row:
  • activate the debugger (e.g. monitor mode on and press the ‘bug’ icon)
  • connect your board again
  • follow the code by pressing F10

Secondly:
Are you aware that TCP/IP works with ‘streams’ ?
When the board sends a ‘telegram’, it is not guaranteed to be complete in a PLC cycle. In this case you must first collect all the characters belonging to this ‘telegram’. And of course you can’t wait in the Automation Runtime, you have to program a state machine.
This can result in complex code.

In contrast, UDP/IP works with ‘datagrams’. These should be received in one go. This may make your code simpler.

Dear Christoph,

As per your suggestion it would be better to go with UDP /IP task.

As I have downloaded the task in my project but I want to know how to cross check whether the UDP is working ok or not.
Can we use Hercules software for reading/writing data using UDP. Let me know your thoughts .

Code for your ref.
void _INIT Initialisierung( void )
{
brsmemset( (UDINT) &open, 0, sizeof(open) );
brsmemset( (UDINT) &close, 0, sizeof(close) );
brsmemset( (UDINT) &recv, 0, sizeof(recv) );
brsmemset( (UDINT) &send, 0, sizeof(send) );

open.enable = 1;
open.options = 0;//udpOPT_REUSEPORT;
open.port = PORT;  /* receive port */
open.pIfAddr = 0; 
UdpOpen( &open );

recv.enable = 1;
recv.ident = open.ident;
recv.pData = (UDINT) &receive_buffer; 
recv.pIpAddr = (UDINT) sender_ip_addr;
recv.datamax = sizeof(receive_buffer);

send.enable = 1;
send.ident = open.ident;
send.flags = 0; 
send.pData = (UDINT) send_buffer;
send.datalen = 0;

}

/* --------------------------------------------------------------------------------------------------------
cyclic code

*/

void _CYCLIC Zyklisch( void )
{
UdpRecv( &recv );

if( recv.status == 0 ){
	brsstrcpy( (UDINT) send_buffer, (UDINT) "echo: " );
	brsstrcat( (UDINT) send_buffer, (UDINT) receive_buffer );
	brsmemset( (UDINT) receive_buffer, 0 , sizeof(receive_buffer) );
	send.datalen = brsstrlen( (UDINT) send_buffer );
	send.pHost = (UDINT) sender_ip_addr; /* return back to sender */
	send.port = recv.port;
	send.enable = 1;
}
  
UdpSend( &send );
if( send.enable && send.status != ERR_FUB_BUSY ){
    send.enable = 0;
	brsmemset( (UDINT) send_buffer, 0 , sizeof(send_buffer) );		
}

}

/* --------------------------------------------------------------------------------------------------------
is called when overloading the task

*/

void _EXIT Exit( void ){
close.enable = 1;
close.ident = open.ident;
do {
UdpClose( &close );
}
while( close.status == 65535 );

}

My purpose is to connect my embedded card with 4PPC70 display through ethernet to read/write the data. Also in embedded card there are 15 keys and 15 leds which means there 15 digital inputs from embedded card to 4PPC70 & 15 digital outputs for 4PPC70 to embedded card.

I hope you understand my concern and I would really appreciate your support.

Thanks & Regards,
Shrenik

Hi Shrenik,

My purpose is to connect my embedded card with 4PPC70 display through ethernet to read/write the data

if your board supports UDP that should be easier to implement. And it should not be very difficult. As you can see the code is less compared to TCP. If your ethernet is unsave you should take datagram loss into account since UDP has no layer for that.

Can we use Hercules software

this one : Hercules SETUP utility | HW-group.com ? Yep. They say it speaks UDP, sounds good. But I don’t download it to avoid the fights with our IT admins.
So I prefer a simple Python script and Wireshark. But Hercules might be simpler to use.