This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
sdk:dio2modbustcp [2015/05/11 15:59] fachet created |
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 ftp2sms.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> |