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:
https://github.com/retfie/helium_mapper
What am I missing here ? why cant I make this RS485 module to work ?