Hello,
I am trying to run an Schneider altivar atv312 motor box from Opensuse 42.3 (linux 4.4.76-1-default #1 SMP), with libmodbus 3.1.4 compiled from source.
Dmesg reports the adapter as
[ 913.493470] usb 1-6: new full-speed USB device number 8 using xhci_hcd
[ 913.622119] usb 1-6: New USB device found, idVendor=067b, idProduct=2303
[ 913.622122] usb 1-6: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 913.622123] usb 1-6: Product: USB-Serial Controller
[ 913.622124] usb 1-6: Manufacturer: Prolific Technology Inc.
[ 913.622456] pl2303 1-6:1.0: pl2303 converter detected
[ 913.623031] usb 1-6: pl2303 converter now attached to ttyUSB0
When I run my test program (pasted below) i get:
New OK
Opening /dev/ttyUSB0 at 19200 bauds (E, 8, 1)
Connect OK
set ser fail: -2
Set ser: Inappropriate ioctl for device
Ser mode = 0
Slave OK
Read regs 3201
[01][03][0C][81][00][01][D7][72]
Waiting for a confirmation...
ERROR Connection timed out: select
ERROR modbus_read_registers single (-1)
Address = 3201
I have modified the modbus_rtu_set_serial_mode() function in modbus-rtu.c to give different return values at different places and found that the error happens here:
if (mode == MODBUS_RTU_RS485) {
rs485conf.flags = SER_RS485_ENABLED;
if (ioctl(ctx->s, TIOCSRS485, &rs485conf) < 0) {
return -2;
}
Any idea how I could fix this?
My test program is made from some examples I found and looks like this:
/*
*testmodbus.c
*
* MC okt 2017
*
* gcc testmodbus.c -o testmodbus `pkg-config --cflags --libs libmodbus`
*
*/
#include <stdio.h>
#include <modbus.h>
#include <errno.h>
int main()
{
modbus_t *mb;
int er;
mb=modbus_new_rtu("/dev/ttyUSB0",19200,'E',8,1);
if (mb==NULL)
{
printf("new fail\n"); perror("New");
}
else printf("New OK\n");
modbus_set_debug(mb,TRUE);
if (modbus_connect(mb) == -1)
{
fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
modbus_free(mb);
return -1;
}
else printf("Connect OK\n");
er=modbus_rtu_set_serial_mode(mb,MODBUS_RTU_RS485);
if (er<0)
{
printf("set ser fail: %d\n",er); perror("Set ser");
}
else printf("Set ser OK\n");
printf("Ser mode = %d\n",modbus_rtu_get_serial_mode(mb));
er=modbus_set_slave(mb, 1); //altivar default = 1 (COM menu, adr)
if (er<0)
{
printf("slave fail\n"); perror("Slave");
}
else printf("Slave OK\n");
int rc,addr,nb_fail;
uint16_t tab_rq_registers[256];
uint16_t tab_rp_registers[256];
addr=3201;
tab_rq_registers[0]=0;
/*
printf("Write reg %d\n",addr);
rc = modbus_write_register(mb, addr, tab_rq_registers[0]);
//rc = modbus_write_registers(ctx, addr, nb, tab_rq_registers);
if (rc != 1) //if (rc!=nb)
{
printf("ERROR modbus_write_register (%d)\n", rc);
printf("Address = %d, value = %d (0x%X)\n", addr, tab_rq_registers[0], tab_rq_registers[0]);
nb_fail++;
}
else
*/
{
printf("Read regs %d\n",addr);
rc = modbus_read_registers(mb, addr, 1, tab_rp_registers);
if (rc != 1)
{
printf("ERROR modbus_read_registers single (%d)\n", rc);
printf("Address = %d\n", addr);
nb_fail++;
}
else
{
if (tab_rq_registers[0] != tab_rp_registers[0])
{
printf("ERROR modbus_read_registers single\n");
printf("Address = %d, value = %d (0x%X) != %d (0x%X)\n", addr, tab_rq_registers[0], tab_rq_registers[0],tab_rp_registers[0], tab_rp_registers[0]);
nb_fail++;
}
}
}
modbus_free(mb);
printf("\n\n");
}