UART sending problem

I’m trying to understand how to use the UART library to send data. Also, I don’t understand how the uart callback function is used when sending data.

I have an ESP32 board with two RS485 ports connected to the processor’s UART1 and UART2. Each port receives correctly from another device that generates output only. I have now wired the ports together so I can send data on one and have it received by the other. I have tested both with UART1 sending and UART1 receiving.

Strangely, the data does not come through correctly. The program pasted below attempts to send “Now is the time…” but what is received is “is the time…” cutting off or blanking out the first 4 characters.

I’m wondering if I coded this correctly and would appreciate comments.

Thank you

#include <stdio.h>

#include "mgos.h"
#include "mgos_app.h"
#include "mgos_gpio.h"
#include "mgos_timers.h"
#include "mgos_uart.h"

#define UART_1 1
#define UART_1_RS485_INT 15
#define UART_1_TX_GPIO 17
#define UART_1_RX_GPIO 16

#define UART_2 2
#define UART_2_RS485_INT 13
#define UART_2_TX_GPIO 25
#define UART_2_RX_GPIO 26

#define UART_SPEED 4800

static void timer_cb(void *arg)
{
  static int seq = 0;

  char *pTmp = "Now is the time...\r\n";
  mgos_uart_write(UART_1, pTmp, strlen(pTmp));
  (void) arg;
}

static void uart_dispatcher(int uart_no, void *arg)
{
  static struct mbuf lb = {0};
//  assert(uart_no == UART_1);

  size_t rx_av = mgos_uart_read_avail(uart_no);
  if (rx_av == 0)
  {
    return;
  }

  mgos_uart_read_mbuf(uart_no, &lb, rx_av);

  char tmp[255];
  memcpy(tmp, lb.buf, lb.len);
  tmp[lb.len] = NULL;

  mbuf_remove(&lb, lb.len);

  LOG(LL_INFO, ("%s", tmp));

  (void) arg;
  return;
}

/* Dispatcher for sending - Why is this needed? */
static void uart_dispatcher_tx(int uart_no, void *arg)
{
  static struct mbuf lb = {0};
//  assert(uart_no == UART_1);

  size_t rx_av = mgos_uart_read_avail(uart_no);
  if (rx_av == 0)
  {
    return;
  }

  mgos_uart_read_mbuf(uart_no, &lb, rx_av);

  char tmp[255];
  memcpy(tmp, lb.buf, lb.len);
  tmp[lb.len] = NULL;

  mbuf_remove(&lb, lb.len);
  LOG(LL_INFO, ("%s", tmp));
  (void) arg;
  return;
}

enum mgos_app_init_result mgos_app_init(void)
{
  int uartNum = UART_2;
  int uartRS485Int = UART_2_RS485_INT;
  int gpioTx = UART_2_TX_GPIO;
  int gpioRx = UART_2_RX_GPIO;

  struct mgos_uart_config ucfgRx;
  mgos_uart_config_set_defaults(uartNum, &ucfgRx);
  ucfgRx.baud_rate = UART_SPEED;
  ucfgRx.num_data_bits = 8;
  ucfgRx.parity = MGOS_UART_PARITY_NONE;
  ucfgRx.stop_bits = MGOS_UART_STOP_BITS_1;
  ucfgRx.rx_buf_size = 2048;
  ucfgRx.dev.hd = true;
  ucfgRx.dev.tx_en_gpio = uartRS485Int;
  ucfgRx.dev.tx_en_gpio_val = true;

  ucfgRx.dev.tx_gpio = gpioTx;
  ucfgRx.dev.rx_gpio = gpioRx;

  if (!mgos_uart_configure(uartNum, &ucfgRx))
  {
    LOG(LL_ERROR, (">=====>> Unable to configure UART %d - ABORTING", uartNum));
    mgos_msleep(3000);
    return MGOS_APP_INIT_ERROR;
  }

    struct mgos_uart_config ucfgTx;
    mgos_uart_config_set_defaults(UART_1, &ucfgTx);
    ucfgTx.baud_rate = UART_SPEED;
    ucfgTx.num_data_bits = 8;
    ucfgTx.parity = MGOS_UART_PARITY_NONE;
    ucfgTx.stop_bits = MGOS_UART_STOP_BITS_1;
    ucfgTx.rx_buf_size = 2048;
    ucfgTx.dev.hd = true;
    ucfgTx.dev.tx_en_gpio = UART_1_RS485_INT;
    ucfgTx.dev.tx_en_gpio_val = true;

    ucfgTx.dev.tx_gpio = UART_1_TX_GPIO;
    ucfgTx.dev.rx_gpio = UART_1_RX_GPIO;

    if (!mgos_uart_configure(UART_1, &ucfgTx))
    {
      LOG(LL_ERROR, (">=====>> Unable to configure UART %d - ABORTING", UART_1));
      mgos_msleep(3000);
      return MGOS_APP_INIT_ERROR;
    }

  LOG(LL_INFO, (">=====>> Successfully configured UART"));

  mgos_uart_set_dispatcher(UART_2, uart_dispatcher, NULL);
  mgos_uart_set_rx_enabled(UART_2, true);

  mgos_uart_set_dispatcher(UART_1, uart_dispatcher_tx, NULL);

  LOG(LL_INFO, ("* Ready to receive data"));

  mgos_set_timer(750 /* ms */, true /* repeat */, timer_cb, NULL /* arg */);

  return MGOS_APP_INIT_SUCCESS;
}

I found my problem with this. I had set the code up to use half duplex and was conducting a loopback test with two UARTs using RS422/RS485 transceivers. Switching to full duplex got the loopback test working.