stephane / libmodbus

A Modbus library for Linux, Mac OS, FreeBSD and Windows
http://libmodbus.org
GNU Lesser General Public License v2.1
3.44k stars 1.75k forks source link

ModbusTCP communication over two RaspberryPi, master and slave #691

Open bsav98 opened 1 year ago

bsav98 commented 1 year ago

Hi! I'm trying to communicate over two Raspberry Pi. There is code for master :

include

include

include

int main(int argc, char argv[]) { modbus_t ctx; uint16_t tab_reg[64]; int rc;

ctx = modbus_new_tcp("192.168.100.104", 502); // 192.168.100.104 is IP address of master RaspberryPi 
modbus_connect(ctx); 

rc = modbus_read_registers(ctx, 0, 10, tab_reg); 

if (rc == 10) { 
    printf("Read registers: "); 
    for (int i=0; i<10; i++) { 
        printf("%d ", tab_reg[i]); 
    } 
    printf("\n"); 
} else { 
    fprintf(stderr, "Failed to read registers: %s\n", modbus_strerror(errno)); 
} 

modbus_close(ctx); 
modbus_free(ctx); 
return 0; 

} There is slave:

include

include

include <modbus/modbus.h>

int main(int argc, char argv[]) { modbus_t ctx; modbus_mapping_t *mb_mapping; int socket;

ctx = modbus_new_tcp("0.0.0.0", 502); 
mb_mapping = modbus_mapping_new(0, 0, 100, 0); 

socket = modbus_tcp_listen(ctx, 1); 
modbus_tcp_accept(ctx, &socket); 

for (;;) { 
    uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH]; 
    int rc; 

    rc = modbus_receive(ctx, query); 
    if (rc > 0) { 
        modbus_reply(ctx, query, rc, mb_mapping); 
    } else if (rc == -1) { 
        break; 
    } 
} 

printf("Quit the loop: %s\n", modbus_strerror(errno)); 

modbus_mapping_free(mb_mapping); 
modbus_close(ctx); 
modbus_free(ctx); 

return 0; 

}

When I run master side, i get error connection refused , like there is even no connection. Please some help,very gratefull!

dglover commented 1 year ago

In your master code (actually client in tcp), are you entering the ip address of the server? (your comment mentions that it is the ip of the master. It should be the server you are connecting to, the one running your slave code.)

I have tried it now two ways:

For the master, I also added to have it print a float stored in the first two registers, to verify it is reading from my actual device. I also tried with your original slave.c and also using NULL instead of "0.0.0.0" for the ip. Both allowed the master to connect and read.

bsav98 commented 1 year ago

Would you send me your master and slave code, please?

dglover commented 1 year ago

The code has very little changed from your code.

Here are the files for you. https://gist.github.com/dglover/8182802db8bf248854d138bbbc98f1d1

The ip address in the master code should be the ip address where the slave code is running.

bsav98 commented 1 year ago

I still getting error, how your network is configured?Please explain me how you running scripts.Thank you very much.My master has IP 192.168.100.104 and slave device has IP 192.168.100.102.

dglover commented 1 year ago

The network is a standard network, both devices are connected directly to a switch, connected to a router. Both have a static ip.

In the following image, it shows two terminal windows. On the left is the computer, running Ubuntu. On the right is an arm processor running linux (buildroot).
ubuntu - 192.168.0.203 buildroot - 192.168.0.33 The order of the commands is added in red to show what happens when running the master before the slave. Note, the device on the right is running as root, the slave program must be run as root. (it gave an error on ubuntu when run without sudo as seen at 6. I have also updated the previous gist to allow giving the target ip and port on the command line for ease of showing the example. image

Here is the wireshark capture for the same period. image

bsav98 commented 1 year ago

@dglover thank you very much. One last question :D how do you know that your server have two float values, as you say?