SEN0599 - Water Depth measuring problem
Sempai 2026-04-22 14:27:17 24 Views1 Replies Hi! I am using SEN0599 for measuring underwater depth…
I want to measure the depth of a two-meter-deep pond.
It works perfectly in the 0–100 cm range, displaying the data accurately in centimeters, but after 100–110 cm, it doesn’t return any data, as if there were no valid readings. What could I be doing wrong? I understand that the water might be dirty or even muddy, but I’ve taken measurements at several points, and the data cuts off at the typical 100–110 cm mark everywhere. What could I be doing wrong in the code?
Translated with DeepL.com (free version)
// SonarDepth.cpp
namespace {
HardwareSerial* port = nullptr;
static const uint32_t SONAR_BAUD = 115200;
static const uint8_t SONAR_TRIGGER_CMD = 0x55;
static const uint32_t SONAR_INTERVAL_MS = 30;
static const uint32_t SONAR_TIMEOUT_MS = 40;
static const uint16_t SONAR_MIN_MM = 50;
static const uint16_t SONAR_MAX_MM = 6000;
enum class ParseResult : uint8_t {
None,
Valid,
Invalid
};
uint32_t lastTriggerMs = 0;
uint32_t requestStartMs = 0;
bool waitingResponse = false;
uint8_t frame[4] = {0};
uint8_t framePos = 0;
static void resetFrameParser()
{
framePos = 0;
}
static void startMeasurement(uint32_t nowMs)
{
if (!port) return;
resetFrameParser();
port->write(SONAR_TRIGGER_CMD);
waitingResponse = true;
requestStartMs = nowMs;
lastTriggerMs = nowMs;
}
static ParseResult parseFrame(uint16_t& rawMm)
{
if (!port) return ParseResult::None;
while (port->available() > 0) {
uint8_t b = (uint8_t)port->read();
if (framePos == 0) {
if (b != 0xFF) continue;
}
frame[framePos++] = b;
if (framePos >= 4) {
resetFrameParser();
uint8_t checksum = (uint8_t)(frame[0] + frame[1] + frame[2]);
if (checksum != frame[3]) {
return ParseResult::Invalid;
}
rawMm = (uint16_t)(((uint16_t)frame[1] << 8) | frame[2]);
if (rawMm < SONAR_MIN_MM || rawMm > SONAR_MAX_MM) {
return ParseResult::Invalid;
}
return ParseResult::Valid;
}
}
return ParseResult::None;
}
}
void SonarDepth::begin(HardwareSerial& serial)
{
port = &serial;
port->begin(SONAR_BAUD);
waitingResponse = false;
requestStartMs = 0;
lastTriggerMs = millis() - SONAR_INTERVAL_MS;
resetFrameParser();
}
void SonarDepth::tick(uint32_t nowMs)
{
if (!port) return;
uint16_t rawMm = 0;
ParseResult pr = parseFrame(rawMm);
if (pr == ParseResult::Valid) {
waitingResponse = false;
} else if (pr == ParseResult::Invalid) {
waitingResponse = false;
}
if (waitingResponse && (uint32_t)(nowMs - requestStartMs) >= SONAR_TIMEOUT_MS) {
waitingResponse = false;
resetFrameParser();
}
if (!waitingResponse && (uint32_t)(nowMs - lastTriggerMs) >= SONAR_INTERVAL_MS) {
startMeasurement(nowMs);
}
}
The setup:
- Microcontroller: STM32F103C8T6
- Using a 6m UART device
- The device is powered directly from the STM32's 5V/GND output
Sempai 
