Sign in to follow this  
Followers 0
urvhalt

Ethernet UDP FINS & Winsock 2.2 timeout

4 posts in this topic

I have translated Omrons (Unix/Linux style) FINS example for reading 100 words from D100, to an c-style C++ console application for Microsoft Visual Studio 2012. ( My long-term goal is to write a fast driver for data exchange, one area in, one area out ). CJ2M-CPU35 10.0.1.1, net 1, node 1, unit 1. Workstation: 10.0.0.10, net 1, node 10. Using Wireshark for inspection, i see that my application do send the correct FINS-command. I have also verified that the PLC sends the expected answer back. I put different values in D100 and the they do appear at the forst word in the response data part. The time between command and response is about 6 ms. I have set timeout for reciving to 100ms. * However my program does not see any incoming datagrams. I dont know if my computer simply miss the response or if something else is wrong. I have verified that the process is actually listeningen on 0.0.0.0:9600 (udp) which cover all network interfaces. This might be a winsock programming question ( wrong forum ), but i dont really know until ive found the solution.. Any ideas? Source included below: --------------------------------------------------------------- // read_fins console application // #include "stdafx.h" //Always put first, comments are ok above #pragma comment(lib, "Ws2_32.lib") #ifndef WIN32_LEAN_AND_MEAN //always put before winsock2.h #define WIN32_LEAN_AND_MEAN #endif #include <winsock2.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <stdio.h> #define FINS_UDP_PORT 9600 #define SERV_IP_ADDR "10.0.1.1" // PLC Ethernet Unit IP ADDRESS #define WS_IP_ADDR "10.0.1.10" // our ip addr for listening #define MAX_MSG 2010 // Function declarations void err_exit(char *err_msg); // FINS COMMUNICATIONS SAMPLE PROGRAM int _tmain(int argc, _TCHAR* argv[]) { char fins_cmnd[MAX_MSG],fins_resp[MAX_MSG]; int sendlen; int retval, ws_len, bytes_recieved; char sid=0; int iOptVal = 0; int iOptLen = sizeof (int); int err; WSADATA wsaData; SOCKET sockin, sockout; sockaddr_in ws_addr,cv_addr; // Request Winsock version 2.2 if ((retval = WSAStartup(0x202, &wsaData)) != 0) { fprintf(stderr,"Server: WSAStartup() failed with error %d\n", retval); WSACleanup(); return -1; } // Create sockets if((sockin= socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET) { fprintf(stderr,"Could not create socket"); WSACleanup(); return -1; } if((sockout = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET) { fprintf(stderr,"Could not create socket"); WSACleanup(); return -1; } // Setup work station adress memset(&ws_addr, 0 , sizeof( ws_addr ) ); ws_addr.sin_family=AF_INET; ws_addr.sin_addr.s_addr=htonl(INADDR_ANY); //ws_addr.sin_addr.s_addr = inet_addr(WS_IP_ADDR); //(!SERV_IP_ADDR) ? INADDR_ANY:inet_addr(SERV_IP_ADDR); ws_addr.sin_port=htons(FINS_UDP_PORT); // Port MUST be in Network Byte Order ws_len = sizeof( ws_addr ); //Bind to listen port retval = bind(sockin, (struct sockaddr *) &ws_addr, ws_len); if ( retval != 0 ) { fprintf(stderr,"bind failed: %d\n", WSAGetLastError()); return 1; } //Set timeout - SO_RCVTIMEO iOptVal = 100; //100 mS retval = setsockopt(sockin, SOL_SOCKET, SO_RCVTIMEO, (const char *) &iOptVal, iOptLen); if (retval == SOCKET_ERROR) { fprintf(stderr,"setsockopt failed with error: %u\n", WSAGetLastError()); } // GENERATE MEMORY AREA READ COMMAND *(READ 150 WORDS FROM D00100.) fins_cmnd[0] = static_cast<unsigned char> (0x80); // ICF fins_cmnd[1] = static_cast<unsigned char> (0x00); // RSV fins_cmnd[2] = static_cast<unsigned char> (0x02); // GCT fins_cmnd[3] = static_cast<unsigned char> (0x01); // DNA fins_cmnd[4] = static_cast<unsigned char> (0x01); // DA1 - Ethernet Unit FINS NODE NUMBER fins_cmnd[5] = static_cast<unsigned char> (0x00); // DA2 fins_cmnd[6] = static_cast<unsigned char> (0x01); // SNA - WORK STATION FINS NET NUMBER - 1 fins_cmnd[7] = static_cast<unsigned char> (0x0A); // SA1 - WORK STATION FINS NODE NUMBER - 10 fins_cmnd[8] = static_cast<unsigned char> (0x00); // SA2 - WORK STATION UNIT NUMBER - 0 fins_cmnd[9] = ++sid; // SID fins_cmnd[10] = static_cast<unsigned char> (0x01); // MRC fins_cmnd[11] = static_cast<unsigned char> (0x01); // SRC fins_cmnd[12] = static_cast<unsigned char> (0x82); // VARIABLE TYPE: DM fins_cmnd[13] = static_cast<unsigned char> (0x00); // READ START ADDRESS: 100 fins_cmnd[14] = static_cast<unsigned char> (0x64); fins_cmnd[15] = static_cast<unsigned char> (0x00); fins_cmnd[16] = static_cast<unsigned char> (0x00); // WORDS READ: 150 fins_cmnd[17] = static_cast<unsigned char> (0x96); // Set up adress for PLC cv_addr.sin_family = AF_INET; cv_addr.sin_addr.s_addr = inet_addr(SERV_IP_ADDR); cv_addr.sin_port = htons(FINS_UDP_PORT); CMND_SEND: sendlen = 18; retval = sendto(sockout, (char *) &fins_cmnd, sendlen, 0, (struct sockaddr *)&cv_addr, sizeof(cv_addr)); if (retval == SOCKET_ERROR) { fprintf(stderr,"Server: send() failed: error %d\n", WSAGetLastError()); } //else printf("Server: send() is OK.\n"); // RECEIVE FINS RESPONSE bytes_recieved = recvfrom(sockin,(char *) &fins_resp, sizeof(fins_resp), 0, (struct sockaddr *)&ws_addr, &ws_len); if (bytes_recieved == SOCKET_ERROR) { err = WSAGetLastError(); switch (err) { case WSAETIMEDOUT: fprintf(stderr,"timeout\n"); break; case EINTR: fprintf(stderr,"recieve error\n"); break; case WSAEMSGSIZE: fprintf(stderr,"message to long\n"); break; default: fprintf(stderr,"Server: recv() failed: error %d\n", err); } goto CMND_SEND; } printf("Server: Received datagram from %s\n", inet_ntoa(ws_addr.sin_addr)); printf("recv length %d\n", bytes_recieved); // ILLEGAL RESPONSE LENGTH CHECK if( bytes_recieved < 14 ) { err_exit("FINS length error"); } // DESTINATION ADDRESS CHECK if((fins_cmnd[3]!=fins_resp[6])||(fins_cmnd[4]!=fins_resp[7]) ||(fins_cmnd[5]!=fins_resp[8])) { err_exit("illegal source address error"); } if(fins_cmnd[9]!=fins_resp[9]) // SID CHECK { err_exit("illegal SID error"); } return 0; } // Error processing void err_exit(char *err_msg) { fprintf(stderr,"client: %s %x\n",err_msg,errno); WSACleanup(); exit(1); } ---- end of source --- Edited by urvhalt

Share this post


Link to post
Share on other sites
Can you show me a link where you find an example code for fins communication over tcp/ip from omron? I also want to read data over the ethernet with fins commands.

Share this post


Link to post
Share on other sites

You can read the FINS protocol in W420 and W412 manual.

If you have questions on the FINS protocol, I answer you.

Share this post


Link to post
Share on other sites

I see I failed to follow up on this.   Thank you for your responses.  Kind regards / Patrik 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0