libmodbus rtu on rs485 seems do not transmit

123 views
Skip to first unread message

Fabio Rossoni

unread,
May 3, 2022, 1:54:42 AM5/3/22
to libmodbus
Hello,
i'm using libmodbus 3.1.6 on OpenWrt 21 the following simple rtu master program seems do not transmit on  rs485 interface.
#include .....
.......
int main(int argc, char **argv)
{
    //Create a new RTU context with proper serial parameters (in this example,
    //device name /dev/ttyS0, baud rate 9600, no parity bit, 8 data bits, 1 stop bit)
    modbus_t *ctx = modbus_new_rtu("/dev/rs485", 9600, 'N', 8, 1);
    if (!ctx) {
        fprintf(stderr, "Failed to create the context: %s\n", modbus_strerror(errno));
        exit(1);
    }

    if(modbus_set_debug(ctx, TRUE) < 0)
                              printf("Error on setting debug mode (%s)\n",modbus_strerror(errno));

    if (modbus_connect(ctx) == -1) {
        fprintf(stderr, "Unable to connect: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        exit(1);
    }
/* START ADD */
     if( modbus_rtu_set_serial_mode(ctx,MODBUS_RTU_RS485 ) < 0 ){
         printf("Error on setting RS485 (%s)\n",modbus_strerror(errno));
     }
      int i=modbus_rtu_get_serial_mode(ctx);
      if(i == MODBUS_RTU_RS232 )
          printf("serial type is RS232\n");
      else if( i == MODBUS_RTU_RS485)
          printf("serial type is RS485\n");

      i=modbus_rtu_get_rts(ctx);
      if(i == MODBUS_RTU_RTS_NONE )
                printf("RTS NONE\n");
            else if( i == MODBUS_RTU_RTS_UP)
                printf("RTS UP\n");
            else if (i == MODBUS_RTU_RTS_DOWN)
                printf("RTS DOWN\n");

/* End Add */

    //Set the Modbus address of the remote slave (to 3)
    modbus_set_slave(ctx, 3);


    uint16_t reg[5];// will store read registers values

    //Read 5 holding registers starting from address 10
    int num = modbus_read_registers(ctx, 10, 5, reg);
    if (num != 5) {// number of read registers is not the one expected
        fprintf(stderr, "Failed to read: %s\n", modbus_strerror(errno));
    }

    modbus_close(ctx);
    modbus_free(ctx);
}


The environment is correct due to the fact that the other following small program that do not use libmodbus work correct

struct serial_rs485 rs485conf;
struct serial_rs485 rs485conf_orig;

int main(void) {
  char dev[] = "/dev/rs485";
 // [4E][03][00][14][00][01][CA][31]
  char buffer_to_send[] = { 0x4E, 0x03, 0x00, 0x14, 0x00, 0x01, 0xCA, 0x31 };
  int  baudrate = B9600;

  int fd = 0;
      fd = open (dev, O_RDWR);
          if (fd < 0) {
              printf("SerialPort opening failed.\n");
              return -1;
          }

          if (ioctl (fd, TIOCGRS485, &rs485conf_orig) < 0) {
            printf("SerialPort orig config get failed.\n");
            return -1;
          }

          /* Enable RS485 mode: */
          rs485conf.flags |= SER_RS485_ENABLED;

          /* Set logical level for RTS pin equal to 1 when sending: */
          //rs485conf.flags |= SER_RS485_RTS_ON_SEND;
          /* or, set logical level for RTS pin equal to 0 when sending: */
          rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);

          /* Set logical level for RTS pin equal to 1 after sending: */
          //rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
          /* or, set logical level for RTS pin equal to 0 after sending: */
          rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);

          /* Set rts delay before send, if needed: */
          rs485conf.delay_rts_before_send = 0;

          /* Set rts delay after send, if needed: */
          rs485conf.delay_rts_after_send = 0;

          /* Set this flag if you want to receive data even whilst sending data */
          //rs485conf.flags |= SER_RS485_RX_DURING_TX;

          if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
              printf("SerialPort config failed.\n");
              return -1;
          }
          struct termios option;
          struct termios orig;
          tcgetattr(fd, &option);

          cfsetospeed(&option, B9600); /* baud rate */
          option.c_cflag &= ~PARENB; /* no parity */
          option.c_cflag &= ~CSTOPB; /* 1 stop bit */
          option.c_cflag &= ~CSIZE;
          option.c_cflag |= CS8 | CLOCAL; /* 8 bits */
          option.c_lflag = ICANON; /* canonical mode */
          option.c_oflag &= ~OPOST; /* raw output */

          tcsetattr(fd, TCSANOW, &option); /* apply the settings */
          tcflush(fd, TCOFLUSH);
          printf("SerialPort loaded fd %d\n", fd);

      // Send buffer_to_send content to RS485
        if (write(fd, buffer_to_send, sizeof(buffer_to_send)) != sizeof(buffer_to_send)) {
          printf("ERROR! write() failed \r\n");
        }

        orig.c_cflag &= ~HUPCL;        // This to release the RTS after close
        tcsetattr(fd, TCSANOW, &orig); // Restore the previous serial config

        if (ioctl (fd, TIOCSRS485, &rs485conf_orig) < 0) {
              printf("SerialPort config reset failed.\n");
              return -1;
          }

        close(fd);

  //return fd;
  }
Where i'm wrong ? 

Thanks for your support.
Reg
Fabio

Reply all
Reply to author
Forward
0 new messages