Problem interfacing XIAO-ESP32C6 to RD-03E radar module (uart, Serial1)

Hi there,

So using the code tags above " </> " just paste it in there, will yield better results and higher quality help .

So looking at this you are close but conflated some stuff…
Your not explicitly setting up com port 1 correctly for hardware serial.
only software serial for the assignable ports can be used,

// testRD03E radar sensor
// JCL, 4June2025
// Rd-03D mmWave Radar: Multi-Human Tracking with Distance, Speed & Positioning

#define RX_PIN D2
#define TX_PIN D3
#define BAUD_RATE 256000
#define BUFFER_BYTES 64

// Variables
uint8_t RX_BUF[BUFFER_BYTES] = {0};
uint8_t RX_count = 0;
uint8_t RX_temp = 0;

// Single-Target Detection Commands
uint8_t Single_Target_Detection_CMD[12] = {0xFD, 0xFC, 0xFB, 0xFA, 0x02, 0x00, 0x80, 0x00, 0x04, 0x03, 0x02, 0x01};
// Multi-Target Detection Command
uint8_t Multi_Target_Detection_CMD[12] = {0xFD, 0xFC, 0xFB, 0xFA, 0x02, 0x00, 0x90, 0x00, 0x04, 0x03, 0x02, 0x01};

void setup() {
Serial.begin(115200); // Debugging info to Serial Monitor
delay(500);

Serial1.begin(BAUD_RATE, SERIAL_8N1, RX_PIN, TX_PIN);
Serial1.setRxBufferSize(BUFFER_BYTES);

Serial.println("RD-03D Radar Module Initialized");

// Send single-target detection command
Serial1.write(Single_Target_Detection_CMD, sizeof(Single_Target_Detection_CMD));

Serial.println("Single-target detection mode activated.");
delay(500);

// Send multi-target detection command
// Serial1.write(Multi_Target_Detection_CMD, sizeof(Single_Target_Detection_CMD));
// Serial.println("Multi-target detection mode activated.");
// delay(1000);

RX_count = 0;
Serial1.flush();
}

void loop() {
// Read data from Serial1
while (Serial1.available()) {
//if (Serial1.available() > 0) {
RX_temp = Serial1.read();
RX_BUF[RX_count++] = RX_temp;

    // Prevent buffer overflow
    if (RX_count >= sizeof(RX_BUF)) {
        RX_count = sizeof(RX_BUF) - 1;
    }

    // Check for end of frame (0xCC, 0x55)
    if ((RX_count > 1) && (RX_BUF[RX_count - 1] == 0xCC) && (RX_BUF[RX_count - 2] == 0x55)) {
        processRadarData();
    }
}
}

void processRadarData() {
printBuffer();
memset(RX_BUF, 0x00, sizeof(RX_BUF)); // Reset buffer and counter
RX_count = 0;
}

// Function to print buffer contents
void printBuffer() {
Serial.print("RX_BUF: “);
for (int i = 0; i < RX_count; i++) {
Serial.print(“0x”);
if (RX_BUF[i] < 0x10) Serial.print(“0”); // Add leading zero for single-digit hex values
Serial.print(RX_BUF[i], HEX);
Serial.print(” ");
}
Serial.println();
}

You may want to take a look, I had something similar. and did it this way… YMMV

https://forum.seeedstudio.com/t/reading-distance-using-esp32-and-seeed-24ghz-human-static-lite-sensor/275885/6?u=pj_glasso
for a general rule though, I follow this understanding…
they are not all the same , USE a hardware UART ports whenver High Speed or timing is more critical, i.e. Serial for USB, Serial1 for D7 & D6
Those are assigned UARTS, Software_Serial Allows you to use any GPIO pins as a comport pair,via BIT_Banging but some limits are obvious doing it this way.

Hardware + Software Serial on ESP32 (C3/S3/C6)

#include <HardwareSerial.h>
#include <SoftwareSerial.h>

// Hardware Serial on UART1 (TX = GPIO10, RX = GPIO9 for example)
HardwareSerial Serial1(1);  // Use UART1

// Software Serial on arbitrary GPIOs (TX = GPIO6, RX = GPIO7 here)
SoftwareSerial mySoftSerial(6, 7);  // TX, RX

void setup() {
  // USB Serial for debug
  Serial.begin(115200);
  delay(1000);
  Serial.println("=== Serial Ports Example ===");

  // Start Hardware Serial1
  Serial1.begin(9600, SERIAL_8N1, 9, 10);  // RX = 9, TX = 10
  Serial.println("Hardware Serial1 started on GPIO9/10");

  // Start Software Serial
  mySoftSerial.begin(9600);
  Serial.println("Software Serial started on GPIO6/7");
}

void loop() {
  // Send message out both ports
  Serial1.println("Hello from HardwareSerial1");
  mySoftSerial.println("Hello from SoftwareSerial");

  delay(1000);
}

:warning: Notes:

  • You can remap UART pins using Serial1.begin(baud, config, rxPin, txPin) on ESP32.
  • Avoid using GPIOs 0, 1, 3, or others with boot functions unless you know they’re safe on your board.
  • For the Xiao ESP32C3/S3, UART1 and UART2 are available depending on your board config.
  • SoftwareSerial can be flaky on higher baud rates—best kept at 9600–19200 for stable use.

Try yours like this, and get back …

#include <HardwareSerial.h>

#define RX_PIN 2   // Adjust for your board C6 is GPIO02 &GPIO21 for D2 & D3 if the pin macros are not supported.
#define TX_PIN 21
#define BAUD_RATE 256000
#define BUFFER_BYTES 64

uint8_t RX_BUF[BUFFER_BYTES] = {0};
uint8_t RX_count = 0;

// Command frame
uint8_t Single_Target_Detection_CMD[12] = {
  0xFD, 0xFC, 0xFB, 0xFA,
  0x02, 0x00, 0x80, 0x00,
  0x04, 0x03, 0x02, 0x01
};

void setup() {
  Serial.begin(115200);
  delay(500);

  Serial1.begin(BAUD_RATE, SERIAL_8N1, RX_PIN, TX_PIN);
  Serial1.setRxBufferSize(BUFFER_BYTES);

  Serial.println("RD-03D Radar Module Initialized");
  Serial1.write(Single_Target_Detection_CMD, sizeof(Single_Target_Detection_CMD));
  Serial.println("Single-target detection mode activated.");

  RX_count = 0;
  Serial1.flush();
}

void loop() {
  while (Serial1.available()) {
    uint8_t RX_temp = Serial1.read();
    RX_BUF[RX_count++] = RX_temp;

    if (RX_count >= sizeof(RX_BUF)) RX_count = sizeof(RX_BUF) - 1;

    if (RX_count > 1 && RX_BUF[RX_count - 2] == 0x55 && RX_BUF[RX_count - 1] == 0xCC) {
      processRadarData();
    }
  }
}

void processRadarData() {
  Serial.print("RX_BUF: ");
  for (int i = 0; i < RX_count; i++) {
    if (RX_BUF[i] < 0x10) Serial.print("0");
    Serial.print(RX_BUF[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
  RX_count = 0;
  memset(RX_BUF, 0, sizeof(RX_BUF));
}

HTH
GL :slight_smile: PJ :v:

1 Like