Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
sdk:dio2modbustcp [2015/05/12 08:06]
fachet
sdk:dio2modbustcp [2015/05/13 14:28]
fachet
Line 1: Line 1:
 ====== Access to the digital I/Os via Modbus TCP ====== ====== Access to the digital I/Os via Modbus TCP ======
-<code c dio2modbustcp.are>/​* DESC: This script can be used to access to the digital I/Os via Modbus TCP+<code c dio2modbustcp.are>​ 
 +/* DESC: This script can be used to access to the digital I/Os via Modbus TCP
  * Copyright (C) 2015 NetModule AG, Switzerland  * Copyright (C) 2015 NetModule AG, Switzerland
- ​* ​supports ​Read Coil Status (FC01)Read Input Status (FC02) ​and Force Single Coil (FC05)+ * 
 + ​* ​  ​Commands: ​   
 + ​* ​    Read Coil Status (FC01) 
 + ​* ​    Read Input Status (FC02) 
 + ​* ​    Read Input Register (FC04) 
 + ​* ​    Force Single Coil (FC05) 
 + ​* ​    Write Multiple Coils (FC15) 
 + ​* ​       ​
  ​* ​  ​Mapping: ​  ​* ​  ​Mapping: ​
- ​* ​    ​Coil(digital I/O): 1=out1, 2=out2 + ​* ​    ​Coil ​status(digital I/O): 1=out1, 2=out2 
- ​* ​    ​Input(digital In): 1=in1, 2=in2 + ​* ​    ​Input ​satus(digital In): 1=in1, 2=in2   
 + ​* ​    Input register : 1=temperature 2=mobile 1 rsrp 
 + *
  */  */
  
 TCP_PORT ​   = 1502;  // sdk port must be higher than 1024 TCP_PORT ​   = 1502;  // sdk port must be higher than 1024
 SLAVEID ​    = 7; SLAVEID ​    = 7;
 +
 +int set_io(int adr, int dat)
 +{
 +  ret = 0;
 +  switch (adr) { //switch on address ​
 +    case 0:
 +      if (dat == 0)
 +        nb_dio_set("​out1",​ 0);
 +      else
 +        nb_dio_set("​out1",​ 1);
 +      break;
 +    case 1:
 +      if (dat == 0)
 +        nb_dio_set("​out2",​ 0);
 +      else
 +        nb_dio_set("​out2",​ 1);
 +      break;
 +    default:
 +    ret = -1;
 +    break; ​   ​
 +    }
 +  return ret;
 +}
  
 if ((fd = socket(AF_INET,​ SOCK_STREAM,​ IPPROTO_TCP)) < 0) {  if ((fd = socket(AF_INET,​ SOCK_STREAM,​ IPPROTO_TCP)) < 0) { 
-    ​printf("​Unable to open socket\n"​);​ +  ​printf("​Unable to open socket\n"​);​ 
-    exit(1); ​+  exit(1); ​
  
 if (bind(fd, TCP_PORT, ""​) < 0) { if (bind(fd, TCP_PORT, ""​) < 0) {
-    ​printf("​Unable to bind port %d\n", TCP_PORT);  +  ​printf("​Unable to bind port %d\n", TCP_PORT);  
-    exit(2); ​+  exit(2); ​
  
 if (listen(fd, 1) < 0) { if (listen(fd, 1) < 0) {
-    ​printf("​Unable to listen\n"​);​  +  ​printf("​Unable to listen\n"​);​  
-    exit(3);  +  exit(3);  
-+}  
- +
 cfd = -1;  cfd = -1; 
 for(;;) { for(;;) {
-    ​if (cfd == -1) +  ​if (cfd == -1) 
-    +  
-        if ((cfd = accept(fd)) < 0) { +    if ((cfd = accept(fd)) < 0) { 
-            printf("​accept failed\n"​);​ +      printf("​accept failed\n"​);​ 
-            continue; +      continue;
-        } +
-        if (nb_modbus_register(cfd,​ MODBUS_TYPE_TCP) < 0) {  +
-            printf("​Unable to register client (%s)\n",​ nb_modbus_last_error());​ +
-            close(cfd);  +
-            cfd = -1; +
-            continue; +
-        }+
     }     }
-    if ((r = nb_modbus_receive(cfd)) == NULL) { +    ​if (nb_modbus_register(cfd,​ MODBUS_TYPE_TCP) < 0) {  
-        printf("​Unable to receive request (%s)\n",​ nb_modbus_last_error());​+      printf("​Unable to register client (%s)\n",​ nb_modbus_last_error());​ 
 +      close(cfd);  
 +      cfd = -1; 
 +      continue; 
 +    } 
 +  } 
 +   
 +  ​if ((r = nb_modbus_receive(cfd)) == NULL) { 
 +    printf("​Unable to receive request (%s)\n",​ nb_modbus_last_error());​ 
 +    nb_modbus_unregister(cfd);​  
 +    close(cfd);  
 +    cfd = -1;  
 +    continue; 
 +  }  
 +   
 +  if (r[6] != SLAVEID) 
 +    continue; // not for us  
 +   
 +  cmd = r[7]; // command 
 +  switch (cmd) { // write commands  
 +    case 5: // write to a single coil 
 +      addr = r[8]<<​8 + r[9]; 
 +      data = r[10]<<​8 + r[11]; 
 +      if (set_io(addr,​ data) == -1) 
 +        continue; // error 
 +      break; 
 +    case 15: // write to multiple coils 
 +      addr = r[8]<<​8 + r[9]; 
 +      cnt = r[10]<<​8 + r[11]; 
 +      for (i = 0; i < cnt; i ++) 
 +        if (set_io(addr+i,​ (int) (r[13+i/8] & 1<<​(i%256))) == -1) 
 +          continue; // error 
 +      break; 
 +  }    
 +     
 +  switch (cmd) { // reply for all commands 
 +    case 1: // read coil status 
 +    case 2: // read input status 
 +    case 5: // write to a single coil 
 +    case 4: // read input register 
 +    case 15: // write to multiple coils 
 +      syst = nb_status("​system"​);​ 
 +      wwan = nb_status("​wwan"​);​ 
 +      resp = mkstruct( 
 +        "​bits",​ mkarray(nb_dio_get("​out1"​),​ nb_dio_get("​out2"​)),​ 
 +        "​ibits",​ mkarray(nb_dio_get("​in1"​),​ nb_dio_get("​in2"​)),​ 
 +        "​regs",​ mkarray(),​ 
 +        "​iregs",​ mkarray((int)syst.TEMPERATURE,​ (int)wwan.MOBILE1_RSRP) 
 +      ); 
 +      if (nb_modbus_reply(cfd,​ r, resp) < 0) { 
 +        printf("​Unable to reply%s)\n",​ nb_modbus_last_error());​
         nb_modbus_unregister(cfd); ​         nb_modbus_unregister(cfd); ​
         close(cfd); ​         close(cfd); ​
         cfd = -1;          cfd = -1; 
         continue;         continue;
-    ​}  +      ​
-    if (r[6] == SLAVEID) {  +      break; 
-        switch (r[7]) { // command +  }
-            case 1: // read coil status +
-            case 2: // read input status +
-                ​break; ​// no write action, only reply needed +
-            case 5: // write to a single coil +
-                addr = r[8]<<​8 + r[9]; +
-                data = r[10]<<​8 + r[11]; +
-                switch (addr) { //switch on address  +
-                    case 0: +
-                        if (data == 0) +
-                            nb_dio_set("​out1",​ 0); +
-                        else +
-                            nb_dio_set("​out1",​ 1); +
-                        break; +
-                    case 1: +
-                        if (data == 0) +
-                            nb_dio_set("​out2",​ 0); +
-                        else +
-                            nb_dio_set("​out2",​ 1); +
-                        break; +
-                } +
-                break; +
-        }    +
-        // reply for all commands +
-        resp = mkstruct( +
-            "​bits",​ mkarray(nb_dio_get("​in1"​),​ nb_dio_get("​in2"​)),​ +
-            "​ibits",​ mkarray(nb_dio_get("​out1"​),​ nb_dio_get("​out2"​)),​ +
-            "​regs",​ mkarray(),​ +
-            "​iregs",​ mkarray() +
-        ); +
-        if (nb_modbus_reply(cfd,​ r, resp) < 0) +
-        { +
-            printf("​Unable to reply%s)\n",​ nb_modbus_last_error());​ +
-            nb_modbus_unregister(cfd);​  +
-            close(cfd);  +
-            cfd = -1;  +
-            continue; +
-        }  +
-    }+
 }    }   
- 
 /* not reached */ /* not reached */
 </​code>​ </​code>​