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
sdk:dio2modbustcp [2015/05/11 16:00]
fachet
sdk:dio2modbustcp [2018/01/24 15:53] (current)
juraschek
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(0,​0),​ 
 +        "​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 +
-                ​break;  +
-            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; +
-        }    +
-        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>​