This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Using the nRF9160 to send and receive data over RS485 (using uart?)

Hello,

I'm pretty new to rtos and totally new to nordic's nRF9160. I've been trying to get this working all day and can't really seem to figure it out based on the resources I have found so far.

So my goal is to connect using rs485 to an external board with a bunch of sensors and controls, which receives commands and emits a status whenever something changes or is requested.

For this I'm using a max485 which should convert RS485 to TTL.

Is there any tutorials on this matter or examples? I couldn't really find any complete examples on this.

I currently have the following PIN layout:

P0.19 -> RE/DE, which controls whether to send or receive data.

P0.18 -> R0 -> RX

P0.17 -> D1 -> TX

I've also added a overlay file containing:

&uart1 {
	status = "ok";
	current-speed = <115200>;
	tx-pin = <18>;
	rx-pin = <17>;
	rts-pin = <20>;
	cts-pin = <21>;
};

And the portion of my code doing the RS485 things is:

#include <device.h>
#include <drivers/gpio.h>
#include <stdio.h>
#include <string.h>
#include <uart.h>
#include <zephyr.h>

// General stuff
#define GPIO_PORT "GPIO_0"
#define UART_PORT "UART_1"

// RS485
#define RS485_TRANSMIT       1
#define RS485_RECEIVE        0
#define RS485_SWITCH_PIN     19

static u8_t uart_buf[1024];

void uart_cb(struct device *x) {
  uart_irq_update(x);
  int data_length = 0;

  if (uart_irq_rx_ready(x)) {
    data_length = uart_fifo_read(x, uart_buf, sizeof(uart_buf));
    uart_buf[data_length] = 0;

    printk("Data received: %s\n", uart_buf);
  }
}

void main(void) {
  struct device *uart = device_get_binding(UART_PORT);
  struct device *gpio = device_get_binding(GPIO_PORT);

  if (!uart) {
    printk("[UART] Failed to get device!\n");
  }

  if (!gpio) {
    printk("[GPIO] Failed to get device!\n");
  }

  uart_irq_callback_set(uart, uart_cb);
  uart_irq_rx_enable(uart);
  printk("UART Listening for data...\n");
  
  // Set RS485 into receive mode
  gpio_pin_configure(gpio, RS485_SWITCH_PIN, GPIO_DIR_OUT);
  gpio_pin_write(gpio, RS485_SWITCH_PIN, RS485_RECEIVE);

  while (1) {
    if (uart_irq_tx_ready(uart)) {
      u8_t command[5] = {0x02, 0x00, 0x31, 0x03, 0x36};

      printk("Sending command...\n");
      uart_fifo_fill(uart, command, strlen(command));
      
      k_sleep(100);
    }
  }
}

Related