I’m interested in connecting a device to a combination of RAK4631 and RAK5802 using RS485 interface.
I write the code in the Zephyr environment and I cant seem to make it work.
Here is the source code (main.c):
#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/uart.h>
// chip used in the RS485 module:
// http://file.3peakic.com.cn:8080/product/Datasheet_TP8485E.pdf
// RAK4631 Schematics:
// https://images.docs.rakwireless.com/wisblock/rak4631/datasheet/schematic.png
// RAK5802 Schmatics:
// https://images.docs.rakwireless.com/wisblock/rak5802/datasheet/schematic.png
// Example Arduio code:
// https://github.com/RAKWireless/WisBlock/tree/master/examples/RAK4630/IO/RAK5802_RS485
// RAK4631 UART connected to RS485 module
#define RS485 DEVICE_DT_GET(DT_CHOSEN(uart_rs485))
static const struct device *rs485 = RS485;
static void configure_uicr(void) {
if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) != (UICR_REGOUT0_VOUT_3V3 << UICR_REGOUT0_VOUT_Pos)) {
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {}
NRF_UICR->REGOUT0 =
(NRF_UICR->REGOUT0 & ~((uint32_t)UICR_REGOUT0_VOUT_Msk)) |
(UICR_REGOUT0_VOUT_3V3 << UICR_REGOUT0_VOUT_Pos);
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {}
// System reset is needed to update UICR registers.
NVIC_SystemReset();
}
}
int main(void) {
uint8_t ch = 1;
int ret;
printk("** Starting\n");
// am not sure if I need this or not (?)
configure_uicr();
// echo loop
while (true) {
// poll for input
if ((ret = uart_poll_in(rs485, &ch)) == 0) {
// print what we've got
printk("> 0x%02x\n", ch);
// echo back to peer
uart_poll_out(rs485, ch);
} else if (ret < -1) {
printk("EE Error polling in: %d\n", ret);
k_sleep(K_SECONDS(1));
}
// sleep for 1 ms just for funzies
k_sleep(K_MSEC(1));
}
return 0;
}
Here is the project configuration file (prj.conf):
CONFIG_STDOUT_CONSOLE=y
CONFIG_USB_CDC_ACM=y
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_PRODUCT="RAK4631 Zephyr"
CONFIG_USB_DEVICE_MANUFACTURER="RAKwireless"
CONFIG_USB_DEVICE_VID=0x1915
CONFIG_USB_DEVICE_PID=0x5300
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y
CONFIG_UART_LINE_CTRL=y
# We need to control GPIO pins
CONFIG_GPIO=y
# We need to work with a UART (connected to RS485)
CONFIG_SERIAL=y
Here is the overlay file (rak4631_nrf52840.overlay):
/ {
chosen {
/delete-property/ zephyr,uart-mcumgr;
/* uart1 is used by RS485. */
/delete-property/ zephyr,bt-mon-uart;
/delete-property/ zephyr,bt-c2h-uart;
uart,rs485 = &uart1;
zephyr,console = &cdc_acm_uart0;
};
};
&uart1 {
current-speed = <57600>;
compatible = "nordic,nrf-uarte";
status = "okay";
tp8485e: tp8485e {
compatible = "tp8485e";
enable-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
&zephyr_udc0 {
cdc_acm_uart0: cdc_acm_uart0 {
compatible = "zephyr,cdc-acm-uart";
};
};
I build (with “west build -p always -b rak4631/nrf52840 .” in the app folder)
… and flash (with “west flash”)
… and open a serial terminal to an RS485 dongle I have connected to my desktop (I tested it and it works with other RS485 devices)
… and nothing I type in my terminal makes it through … as if the RAK4631 doesnt get the input.
When I change the code to only write to the UART (loop of only “uart_poll_out()”) I see nothing in the serial terminal.
Some of the code I used in the overlay file was borrowed from:
What am I missing here ? why cant I make this RS485 module to work ?