Cant get HMMD mmWave talking with ESP32C6 Using Hardware serial

About The Problem

I wanted to explore HMMD mmWave thus I connected the sensor up with esp32c6. For starters, I used the software serial, but the data coming through seemed garbled up. My initial suspect were the high baud rate 115200, thus I switched from Software to Hardware serial.

After switching to hardware serial, although I was able decode and use the data, the data stream seemed to hang after 1-2 messages from the sensor. Hence my problem, in theory the sensor should always send the datastream, but the link seems to break after 1-2 messages when using hardware serial.

About My Setup

  • I’m using vscode with pio and arduino framework.
  • https://github.com/Seeed-Studio/platform-seeedboards.git as platform
  • Sensor is connected to D6/D7

here’s that manufacturer recommends (uses software serial, garbles up data)

#include <SoftwareSerial.h>

SoftwareSerial mySerial(D7, D6); // RX, TX

void sendHexData(String hexString) {
  // Convert hex string to bytes
  int hexStringLength = hexString.length();
  byte hexBytes[hexStringLength / 2];
  for (int i = 0; i < hexStringLength; i += 2) {
    hexBytes[i / 2] = strtoul(hexString.substring(i, i + 2).c_str(), NULL, 16);
  }

  // Send bytes through software serial
  mySerial.write(hexBytes, sizeof(hexBytes));
}

void readSerialData() {
  // Read and print data from software serial
  while (mySerial.available() > 0) {
    char incomingByte = mySerial.read();
    Serial.print(incomingByte);
  }
}

void setup() {
  // Start the serial communication with a baud rate of 115200
  Serial.begin(115200);
  mySerial.begin(115200);

  // Wait for the serial port to initialize
  while (!Serial) {
    delay(100);
  }

  // Hex string to send
  String hex_to_send = "FDFCFBFA0800120000006400000004030201";
  sendHexData(hex_to_send);
}

void loop() {
  // Read and print serial data
  readSerialData();
}

Here’s the code that I’m using (uses hardware serial, data stops coming through after 1-2 messages)

#include <Arduino.h>
#include <HardwareSerial.h>

HardwareSerial mySerial(0); // RX, TX

void sendHexData(String hexString) {
  // Convert hex string to bytes
  int hexStringLength = hexString.length();
  byte hexBytes[hexStringLength / 2];
  for (int i = 0; i < hexStringLength; i += 2) {
    hexBytes[i / 2] = strtoul(hexString.substring(i, i + 2).c_str(), NULL, 16);
  }

  // Send bytes through software serial
  mySerial.write(hexBytes, sizeof(hexBytes));
}

void readSerialData() {
  // Read and print data from software serial
  while (mySerial.available() > 0) {
    char incomingByte = mySerial.read();
    Serial.print(incomingByte);
  }
}

void setup() {
  // Start the serial communication with a baud rate of 115200
  Serial.begin(115200);
  mySerial.begin(115200);

  // Wait for the serial port to initialize
  while (!Serial) {
    delay(100);
  }

  // Hex string to send
  String hex_to_send = "FDFCFBFA0800120000006400000004030201";
  sendHexData(hex_to_send);
}

void loop() {
  // Read and print serial data
  readSerialData();
}

Hi there,

And Welcome Here,

So your not far off, The Hardware Serial needs Hardware flow control enabled on the port. The Hang is when the Receive data (as you see , It BLASTS) Receive Buffer overflows. Software serial or Xon/Xoff Flow control is too slow unless the port speeds are very low.

What’s actually wrong in both sketches

  1. The code is printing binary as if it’s text

This line is a trap:

char incomingByte = mySerial.read();
Serial.print(incomingByte);

the sensor sends binary frames (very likely), a lot of bytes will be non-printable. It will look “garbled” even when it’s correct.

Fix: print hex:

uint8_t b = mySerial.read();
Serial.printf("%02X ", b);

2) The “HardwareSerial mySerial(0)” is probably the wrong UART

On ESP32 Arduino:

  • Serial is typically UART0 (USB/console)
  • Serial1 / Serial2 map to other UARTs

Doing HardwareSerial mySerial(0); can collide with Serial or get weird depending on core/variant.

Fix: use Serial1 (or explicit UART1/2), and map pins explicitly:

#define RX_PIN D7
#define TX_PIN D6
Serial1.begin(115200, SERIAL_8N1, RX_PIN, TX_PIN);

(Also: make sure you didn’t swap RX/TX. Sensor TX must go to ESP RX.)

3)You send the init command once… then maybe the sensor stops because it expects ACK / continuous polling / or it went into a different mode

Many mmWave modules:

  • require a “start streaming” command
  • or they stream only when polled
  • or they stop if their output buffer fills and the host doesn’t drain fast enough

The loop drains, but printing can be slow and block.

Why it “hangs after 1–2 messages” on hardware serial

Common causes:

A) UART pins not actually attached to that UART

If you don’t pass pins in .begin(), ESP32 may use default pins for that UART, not D6/D7.

B) It is saturating output / blocking on prints

If the mmWave sensor streams fast, dumping every byte to USB serial can block long enough that RX FIFO overruns → looks like stream “stops.” :backhand_index_pointing_left: :wink:

C) Buffer too small

ESP32 UART RX buffer can be small depending on core settings.

I would try this suggestion from the LLM

#include <Arduino.h>

#define RX_PIN D7
#define TX_PIN D6
#define BAUD   115200

// init command
static const uint8_t CMD[] = {
  0xFD,0xFC,0xFB,0xFA,0x08,0x00,0x12,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x04,0x03,0x02,0x01
};

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

  Serial.println("UART test start");

  Serial1.begin(BAUD, SERIAL_8N1, RX_PIN, TX_PIN);
  Serial1.setRxBufferSize(4096);     // bigger buffer helps a lot

  delay(200);
  Serial.println("Sending init cmd...");
  Serial1.write(CMD, sizeof(CMD));
}

void loop() {
  static uint32_t last = 0;

  while (Serial1.available()) {
    uint8_t b = Serial1.read();
    Serial.printf("%02X ", b);
    last = millis();
  }

  // newline gap so it’s readable
  if (millis() - last > 50) {
    Serial.println();
    last = millis();
  }

  delay(1);
}

Post up what you find.

HTH
GL :slight_smile: PJ :v: