Sign in to follow this  
Followers 0
rota

cross-platform desktop application

2 posts in this topic

hi i need a helping hand with the following problem: I am working on some cross-platform desktop application . I develop it in C++ with usage of Qt and already implemented PC side Omron FINS TCP protocol driver via sockets ( QTcpSocket ). When I read from register via FINS protocol - I receive right response within 30ms ok , but when I write to plc's registers - there is no response from the plc - socket timeout error ( QAbstractSocket error code = 5 ). Code for reading from register ( function receives reg_addr - address of a register and updates value ): bool fins_read_reg(int reg_addr,int *value); --> *** static unsigned char fins_cmnd[MAX_MSG], fins_resp[MAX_MSG], fins_tcp_header[MAX_HEADER]; static unsigned char fins_send_frame[34], fins_receive_frame[32]; static int sendlen, recvlen; //char sid = 0; if(sid > 0xFF) sid = 0; if(f!=0) { fprintf(f,"BEGIN TO READ \n"); fprintf(f," reg_addr = %d \n",reg_addr); fprintf(f," value = %d \n",*value); } /* SEND FINS/TCP COMMAND*/ /* * GENERATE FINS COMMAND FRAME */ fins_send_frame[0] = 'F'; /* Header */ fins_send_frame[1] = 'I'; fins_send_frame[2] = 'N'; fins_send_frame[3] = 'S'; fins_send_frame[4] = 0x00; /* Length */ fins_send_frame[5] = 0x00; fins_send_frame[6] = 0x00; fins_send_frame[7] = 18+8; /*Length of data from Command up to end of FINS frame */ //why 8 + 18? fins_send_frame[8] = 0x00; /* Command */ fins_send_frame[9] = 0x00; fins_send_frame[10] = 0x00; fins_send_frame[11] = 0x02; fins_send_frame[12] = 0x00; /* Error Code */ fins_send_frame[13] = 0x00; fins_send_frame[14] = 0x00; fins_send_frame[15] = 0x00; //command: fins_send_frame[16] = 0x80; /* ICF */ //put 0x00 - response required //was 0x80 fins_send_frame[17] = 0x00; /* RSV */ fins_send_frame[18] = 0x03; /* GCT */ fins_send_frame[19] = 0x00; /* DNA */ fins_send_frame[20] = srv_node_no; /* DA1 *//* Ethernet Unit FINS NODE NUMBER*/ //FF for broadcast fins_send_frame[21] = 0x00; /* DA2 */ fins_send_frame[22] = 0x00; /* SNA */ fins_send_frame[23] = cli_node_no; /* SA1 *//* WS FINS NODE NUMBER OBTAINED AUTOMATICALLY*/ fins_send_frame[24] = 0x00; /* SA2 */ fins_send_frame[25] = sid; //++sid; /* SID */ fins_send_frame[26] = 0x01; /* MRC */ //1 fins_send_frame[27] = 0x01; /* SRC */ //read // change to read: fins_send_frame[28] = memory_area_designation_code(reg_addr); /* VARIABLE TYPE: DM*/ if(f!=0) { fprintf(f,"FINS/TCP memory area designation code = %d \n",fins_cmnd[28]); } if(memory_area_designation_code(reg_addr) == 0xB0) //-0x0c000 { fins_send_frame[29] = (unsigned char)((reg_addr-0x0C000)>>8); /* READ START ADDRESS:*/ fins_send_frame[30] = (unsigned char)((reg_addr-0x0C000)&0xFF); //low register if(f!=0) { fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); } } if(memory_area_designation_code(reg_addr) == 0xB1) //-0x0DE00 { fins_send_frame[29] = (unsigned char)((reg_addr-0x0DE00)>>8); /* READ START ADDRESS:*/ fins_send_frame[30] = (unsigned char)((reg_addr-0x0DE00)&0xFF); if(f!=0) { fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); } } if(memory_area_designation_code(reg_addr) == 0x82) //-0x10000 { fins_send_frame[29] = (unsigned char)((reg_addr-0x10000)>>8); /* READ START ADDRESS:*/ fins_send_frame[30] = (unsigned char)((reg_addr-0x10000)&0xFF); if(f!=0) { fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); } } if(memory_area_designation_code(reg_addr) == 0xB3) //-0x0BA00 { fins_send_frame[29] = (unsigned char)((reg_addr-0x0BA00)>>8); /* READ START ADDRESS:*/ fins_send_frame[30] = (unsigned char)((reg_addr-0x0BA00)&0xFF); if(f!=0) { fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); } } fins_send_frame[31] = 0x00;//bit number //number of words to read: fins_send_frame[32] = 0x00; /* WORDS READ: 1*/ fins_send_frame[33] = 0x01; /* SEND FINS/TCP COMMAND*/ sendlen = 34; sc.write((const char*)fins_send_frame,sendlen); if(sc.waitForBytesWritten(RESP_TIMEOUT)) { if(f!=0) { fprintf(f,"2.FINS send frame for command succ. sended, length = %d \n",sendlen); } } else { if(f!=0) { fprintf(f,"2.error in sending FINS send frame of command %d \n",sc.error()); } return false; } //lets try to get response here if(sc.waitForReadyRead(RESP_TIMEOUT)) { if(f!=0) { fprintf(f,"2.received %d \n",recvlen = sc.bytesAvailable()); } sc.read((char*)fins_receive_frame,recvlen); //print received header: if(f!=0) { for(int i =0;i<recvlen;i++) { fprintf(f,"2.* received fins_receive_frame[%d] = %d \n",i,fins_receive_frame); } } //check for errors: if(((int)fins_receive_frame[28] == 0) && ((int)fins_receive_frame[29] == 0) ) { //command sent ok sid++; //lets get value: *value = (int)((0x0000|fins_receive_frame[30])<<8) + (int)(0x00FF&fins_receive_frame[31]); if(f!=0) { //lets get value: fprintf(f,"2.* value = %d \n",value); } return true; } else { //there were errors when sending *value = 0; if(f!=0) { //lets get value: fprintf(f,"fields 28 and 29 are not null \n"); } return false; } } else { //can't get response - error: //no response: if(f!=0) { fprintf(f,"2.no response %d \n",sc.error()); } return true; } *** Code snippet of writing to register ( function receives reg_addr - address of a register and value to put to that register ): *** bool fins_write_reg(int reg_addr,const int value); --> static unsigned char fins_cmnd[MAX_MSG], fins_resp[MAX_MSG], fins_tcp_header[MAX_HEADER]; static unsigned char fins_send_frame[36], fins_receive_frame[30]; static unsigned char srv_node_no, cli_node_no; static int sendlen, recvlen; // char sid = 0; if(sid > 0xFF) sid = 0; if(f!=0) { fprintf(f,"BEGIN TO WRITE \n"); fprintf(f," reg_addr = %d \n",reg_addr); fprintf(f," value = %d \n",value); } /* SEND FINS/TCP COMMAND*/ /* * GENERATE FINS COMMAND FRAME */ //fins header body fins_send_frame[0] = 'F'; /* Header */ fins_send_frame[1] = 'I'; fins_send_frame[2] = 'N'; fins_send_frame[3] = 'S'; fins_send_frame[4] = 0x00; /* Length */ fins_send_frame[5] = 0x00; fins_send_frame[6] = 0x00; fins_send_frame[7] = 0x1C; //20+8; //8+18; /*Length of data from Command up to end of FINS frame */ fins_send_frame[8] = 0x00; /* Command */ fins_send_frame[9] = 0x00; fins_send_frame[10] = 0x00; fins_send_frame[11] = 0x02; fins_send_frame[12] = 0x00; /* Error Code */ fins_send_frame[13] = 0x00; fins_send_frame[14] = 0x00; fins_send_frame[15] = 0x00; //fins command body fins_send_frame[16] = 0x80; /* ICF */ fins_send_frame[17] = 0x00; /* RSV */ fins_send_frame[18] = 0x02; /* GCT */ fins_send_frame[19] = 0x00; /* DNA */ fins_send_frame[20] = srv_node_no; /* DA1 *//* Ethernet Unit FINS NODE NUMBER*/ fins_send_frame[21] = 0x00; /* DA2 */ fins_send_frame[22] = 0x00; /* SNA */ fins_send_frame[23] = cli_node_no; /* SA1 *//* WS FINS NODE NUMBER AUTOMATICALLY*/ fins_send_frame[24] = 0x00; /* SA2 */ fins_send_frame[25] = sid; /* SID */ fins_send_frame[26] = 0x01; /* MRC */ //1 fins_send_frame[27] = 0x02; /* SRC */ //1 - write // change to write: fins_send_frame[28] = memory_area_designation_code(reg_addr); /* VARIABLE TYPE: DM*/ if(f!=0) { fprintf(f,"memory area designation code = %d \n",memory_area_designation_code(reg_addr)); } if(memory_area_designation_code(reg_addr) == 0xB0) //-0x0c000 { fins_send_frame[29] = (unsigned char)((reg_addr - 0x0c000)>>8); /* WRITE START ADDRESS:*/ fins_send_frame[30] = (unsigned char)((reg_addr - 0x0c000)&0xFF); if(f!=0) { fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); } } if(memory_area_designation_code(reg_addr) == 0xB1) //-0x0DE00 { fins_send_frame[29] = (unsigned char)((reg_addr - 0x0DE00)>>8); /* WRITE START ADDRESS:*/ fins_send_frame[30] = (unsigned char)((reg_addr - 0x0DE00)&0xFF); if(f!=0) { fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); } } if(memory_area_designation_code(reg_addr) == 0x82) //-0x10000 { fins_send_frame[29] = (unsigned char)((reg_addr - 0x10000)>>8); /* WRITE START ADDRESS:*/ fins_send_frame[30] = (unsigned char)((reg_addr - 0x10000)&0xFF); if(f!=0) { fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); } } if(memory_area_designation_code(reg_addr) == 0xB3) //-0x0BA00 { fins_send_frame[29] = (unsigned char)((reg_addr - 0x0BA00)>>8); /* WRITE START ADDRESS:*/ fins_send_frame[30] = (unsigned char)((reg_addr - 0x0BA00)&0xFF); if(f!=0) { fprintf(f,"fins_send_frame[29] = %d \n",fins_send_frame[29]); fprintf(f,"fins_send_frame[30] = %d \n",fins_send_frame[30]); } } fins_send_frame[31] = 0x00;//bit number //number of words to read: fins_send_frame[32] = 0x00; /* number of data words */ fins_send_frame[33] = 0x01; //putting actual write value: fins_send_frame[34] = (unsigned char)(value >> 8); //high byte fins_send_frame[35] = (unsigned char)(value&0xFF); //low byte //displaying what is written: if(f!=0) { fprintf(f,"fins_send_frame[34] = %d \n",fins_send_frame[34]); fprintf(f,"fins_send_frame[35] = %d \n",fins_send_frame[35]); } sendlen = 36; /* SEND FINS/TCP COMMAND*/ sc.write((const char*)fins_send_frame,sendlen); if(sc.waitForBytesWritten(RESP_TIMEOUT)) { if(f!=0) { fprintf(f,"2.FINS tcp send frame for command succ. sended, length = %d \n",sendlen); } } else { if(f!=0) { fprintf(f,"2.error in sending FINS tcp send frame of command %d \n",sc.error()); } return false; } //sc.flush(); //lets try to get response here : if(sc.waitForReadyRead(RESP_TIMEOUT)) // here it is RESPONSE TIMEOUT ERROR { if(f!=0) { fprintf(f,"2.received %d \n",recvlen = sc.bytesAvailable()); } sc.read((char*)fins_receive_frame,recvlen); if(f!=0) { for(int i =0;i<recvlen;i++) { fprintf(f,"2.received fins_receive_frame[%d] = %d \n",i,fins_receive_frame); } } //basic check - no error if(((int)fins_receive_frame[28] == 0) && ((int)fins_receive_frame[29] == 0)) { //command sent ok sid++; if(f!=0) { fprintf(f,"receive response does not contain errors"); } return true; } else { //there were errors when sending if(f!=0) { fprintf(f,"receive response contains errors"); } return false; } } else //cannot receive response { if(f!=0) { fprintf(f,"3.no response %d \n",sc.error()); } return true; } *** where f - is some temporary log file pointer sc - QTcpSocket instance that send/receives FINS commands PLC: CP1L-L14DT1-D Ethernet option board : CP1W-CIF41 memory area designation code function: int FinsOverEthCP::memory_area_designation_code(const int addr) { // area codes if(addr>0x0BFFF&&addr<0x0D800) //B0 , CIO area return 0xB0; if(addr>0x0DDFF&&addr<0xE000) //work area return 0xB1; //TODO: clarified code , from memory area designation codes table if(addr>0xFFFF&&addr<0x18000) //DM area return 0x82; if(addr>0xB9FF&&addr<0xBC00) //A448 - A959 return 0xB3; else return 0x80; //CIO,LR,HR,AR area } When I tested the command using Multiway software - the response is received and value putted to register , but the same with QTcpSocket and the error, why? My question to you: Have you such problem come up when you run your FINS driver? Why no response situation can be while FINS write to register command is formed ok? If yes how to overcome/fix? Thanks in advance.

Share this post


Link to post
Share on other sites
your length is wrong. length is calculated after the length hex value eg: FINS 00 00 00 xx (..............all things here...........) xx is the amount of the hex inside the bracket.

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