[技术讨论] Modbus TCP通信问题!

[复制链接]
864|2
 楼主| cookiedemo1019 发表于 2020-11-19 13:27 | 显示全部楼层 |阅读模式
本帖最后由 cookiedemo1019 于 2020-11-19 13:30 编辑

本人最近尝试使用NUC977与PLC之间进行通信, 测试PC端使用模拟软件,Modbus Poll和Modbus Slave测试,但是发现一个奇怪的问题:
1. PLC作为Server,NUC977作为Client,同时Modbus Poll检测通信结果,可以通信;
2. NUC977作为Server,PLC作为Client,同时Modbus Poll检测通信结果,可以通信;
3. Nuc977作为Server,另一个NUC977作为Client,作为Client的NUC977读取不到数据,但是Modbus Poll可以正确读取到结果,通信失败。
想请教一下有没有使用过libmodbus的大神,给点建议,这中间哪里出了问题??附上NUC977的Modbus代码。
PS:PLC和PC模拟测均是使用很久的厂家提供代码,应该不存在问题。http://whycan.com/t_5568.html%20(%E5%87%BA%E5%A4%84:%E5%93%87%E9%85%B7%E5%BC%80%E5%8F%91%E8%80%85%E7%A4%BE%E5%8C%BA%E3%80%90Nuvoton%20N32905/N32926/NUC972/N9H20/N9H26/N9H30%E3%80%91)]WhyCan Forum(哇酷开发者社区)同步帖子[/url]
Server端代码

  1. void *modbusTcp_process(void *arg)
  2. {
  3.     uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];
  4.     int master_socket;
  5.     int rc;
  6.     fd_set refset;
  7.     fd_set rdset;
  8.     /* Maximum file descriptor number */
  9.     int fdmax;

  10.     ctx = modbus_new_tcp("192.168.150.159", 502);
  11.     printf("Modbus Context Created OK!\n");
  12.     mb_mapping = modbus_mapping_new(MODBUS_MAX_READ_BITS,
  13.                                     MODBUS_MAX_WRITE_BITS,
  14.                                     MODBUS_MAX_READ_REGISTERS,
  15.                                     MODBUS_MAX_WRITE_REGISTERS);
  16.     if (mb_mapping == NULL)
  17.     {
  18.         fprintf(stderr, "Failed to allocate the mapping: %s\n",
  19.                 modbus_strerror(errno));
  20.         modbus_free(ctx);
  21.         exit(-1);
  22.     }

  23.     server_socket = modbus_tcp_listen(ctx, NB_CONNECTION);
  24.     if (server_socket == -1)
  25.     {
  26.         fprintf(stderr, "Unable to listen TCP connection\n");
  27.         modbus_free(ctx);
  28.         exit(-1);
  29.     }

  30.     signal(SIGINT, close_sigint);

  31.     /* Clear the reference set of socket */
  32.     FD_ZERO(&refset);
  33.     /* Add the server socket */
  34.     FD_SET(server_socket, &refset);

  35.     /* Keep track of the max file descriptor */
  36.     fdmax = server_socket;

  37.     for (;;)
  38.     {
  39.         rdset = refset;
  40.         
  41.         if (select(fdmax + 1, &rdset, NULL, NULL, NULL) == -1)
  42.         {
  43.             perror("Server select() failure.");
  44.             close_sigint(1);
  45.         }

  46.         /* Run through the existing connections looking for data to be
  47.             * read */
  48.         for (master_socket = 0; master_socket <= fdmax; master_socket++)
  49.         {

  50.             if (!FD_ISSET(master_socket, &rdset))
  51.             {
  52.                 continue;
  53.             }

  54.             if (master_socket == server_socket)
  55.             {
  56.                 /* A client is asking a new connection */
  57.                 socklen_t addrlen;
  58.                 struct sockaddr_in clientaddr;
  59.                 int newfd;

  60.                 /* Handle new connections */
  61.                 addrlen = sizeof(clientaddr);
  62.                 memset(&clientaddr, 0, sizeof(clientaddr));
  63.                 newfd = accept(server_socket, (struct sockaddr *)&clientaddr, &addrlen);
  64.                 if (newfd == -1)
  65.                 {
  66.                     perror("Server accept() error");
  67.                 }
  68.                 else
  69.                 {
  70.                     FD_SET(newfd, &refset);

  71.                     if (newfd > fdmax)
  72.                     {
  73.                         /* Keep track of the maximum */
  74.                         fdmax = newfd;
  75.                     }
  76.                     printf("New connection from %s:%d on socket %d\n",
  77.                            inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port, newfd);
  78.                 }
  79.             }
  80.             else
  81.             {
  82.                 modbus_set_socket(ctx, master_socket);
  83.                 rc = modbus_receive(ctx, query);
  84.                 if (rc > 0)
  85.                 {
  86.                     update_modbusmapping(mb_mapping);
  87.                     modbus_reply(ctx, query, rc, mb_mapping);
  88.                 }
  89.                 else if (rc == -1)
  90.                 {
  91.                     /* This example server in ended on connection closing or
  92.                         * any errors. */
  93.                     printf("Connection closed on socket %d\n", master_socket);
  94.                     close(master_socket);

  95.                     /* Remove from reference set */
  96.                     FD_CLR(master_socket, &refset);

  97.                     if (master_socket == fdmax)
  98.                     {
  99.                         fdmax--;
  100.                     }
  101.                 }
  102.             }
  103.         }
  104.     }
  105. }

Client端代码
  1. void *modbusTcp_process(void *arg){
  2.         modbus_t *ctx;

  3.     char index = 0;
  4.     float fl1;
  5.         int i=0;
  6.     /* TCP 127.0.0.1 port 502*/
  7.     ctx = modbus_new_tcp("192.168.150.159", 502);
  8.         if (modbus_set_slave(ctx, 1) == -1)
  9.     {
  10.         fprintf(stderr, "Invalid slave ID\n");
  11.         modbus_free(ctx);
  12.         exit(-1);
  13.     }
  14.     if (modbus_connect(ctx) == -1)
  15.     {
  16.         fprintf(stderr, "Modbus connect failed: %s\n",
  17.                 modbus_strerror(errno));
  18.         modbus_free(ctx);
  19.         exit(-1);
  20.     }
  21.         while(1){
  22.                 modbus_read_registers(ctx, WT_START_ADDR,
  23.                         24, modbusDataBuf);
  24.                 printf("Read hold rigister %d.\n",sizeof(modbusDataBuf));
  25.                 //ModbudDataPrase(modbusDataBuf);
  26.                 ModbusReceived = 1;
  27.                 //debug_LoadData_print();
  28.                 for(i=0;i<12;i++)
  29.                         printf("modbusDataBuf%d %7d\n",i,modbusDataBuf[i]);

  30.         index++;
  31.         }

  32.     /*turn off connect*/
  33.     modbus_close(ctx);
  34.     modbus_free(ctx);
  35. }


 楼主| cookiedemo1019 发表于 2020-11-19 17:19 | 显示全部楼层
大论坛里面没人么
steelen 发表于 2020-11-20 10:31 | 显示全部楼层
本帖最后由 steelen 于 2020-11-20 10:35 编辑

用wireshark抓报文看看
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部