PLEASE NOTE: This article is obsolete or related to a discontinued product.

How to use the RS485 interface

This article shows how to configure the serial port ttyS3 on the FOX Board LX to operate as RS485 half duplex interface

RS485 basic hardware interface

The schematic below is the simplest RS485 interface suitable for FOX Board LX. This interface is included in the FOXZB add-on board (see ).


Simple half duplex RS485 interface for the FOX Board LX

The only serial port enabled to work as RS485 is the /dev/ttyS3.

To use correctly the RS485 interface chip we need to configure the serial port driver in the Phrozen SDK to manage the RTS3 signals (Request To Send) to enable the TX section (DE pin) only when data are transmitted on TXD3 line (Transmit Data) as shown in this image.

To enable the RS485 support use make kernelconfig command and enable:

Drivers for built-in interfaces --->
  [*] RS-485 support

then generate the new flash image and transfer it to the FOX Board LX (How to reflash a FOX Board).

Example of C code to transmit data

Here is a basic example on how to transmit a sequence of chars (in this case 0x55 0x00 0x55) over the RS485 line.
// rs485tx.c
// Basic example of RS485 half duplex transmission

#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <asm/ioctls.h>
#include <errno.h>
#include <termios.h>  

// Control struct for setting the port in 485 mode
struct rs485_ctrl {
  unsigned short rts_on_send;
  unsigned short rts_after_sent;
  unsigned int  delay_rts_before_send;
  unsigned short enabled;
};
 
// his struct is only needed if we would like to write with ioctl()
struct rs485_wrt {
  unsigned short outc_size;
  unsigned char *outc;
};
 
int main(void) {
  char dev[] = "/dev/ttyS3";
  char buffer_to_send[] = { 0x55, 0x00, 0x55 };
  int  baudrate = B9600;

  struct rs485_ctrl ctrl485;
  int status;
  int fd;
  struct termios ti;
  struct termios ti_prev;
  
  // Open the serial port
  fd = open(dev, O_RDWR|O_NONBLOCK);
  if (fd < 0) {
    printf("ERROR! Failed to open %s\n", dev);
    return -1;
  }
 
  // Set the serial port in 485 mode
  ctrl485.rts_on_send = 0;           // It means that DE is at 3.3 volt on send
  ctrl485.rts_after_sent = 1;        // It means that DE is at 0 volt on send
  ctrl485.delay_rts_before_send = 0; // DE will be active at same time of data
  ctrl485.enabled = 1;
  status = ioctl(fd, TIOCSERSETRS485, &ctrl485);  
  if (status) {
    printf("ERROR PORT 1! TIOCSERSETRS485 failed %i", status);
    return -1;
  }
 
  tcgetattr(fd, &ti_prev);    // Save the previous serial config
  tcgetattr(fd, &ti);         // Read the previous serial config
  cfsetospeed(&ti,baudrate);  // Set the TX baud rate
  cfsetispeed(&ti,baudrate);  // Set the RX baud rate

  cfmakeraw(&ti);
  tcsetattr(fd, TCSANOW, &ti);  // Set the new serial config
 
  // 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");
  }

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

  return 0;
}

Credits

Many thanks for their contributes to:

Related link

Download