mirror of
https://github.com/esphome/esphome.git
synced 2026-10-20 04:56:48 +00:00
Round detection ranges like before, restore the 0 0 fallback and test the command text
This commit is contained in:
@@ -20,6 +20,8 @@ static constexpr float LATENCY_STEP_S = 0.025f;
|
||||
PROGMEM_STRING_TABLE(BusyActions, "", "configure range config", "configure output latency",
|
||||
"configure sensor startup behavior", "factory reset", "", "", "set led mode",
|
||||
"set uart output mode", "set sensitivity");
|
||||
static_assert(BusyActions::COUNT == static_cast<size_t>(CommandType::COMMAND_TYPE_SENSITIVITY) + 1,
|
||||
"BusyActions needs one entry per CommandType");
|
||||
|
||||
void DfrobotSen0395Component::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "Dfrobot Mmwave Radar:");
|
||||
@@ -64,10 +66,13 @@ void DfrobotSen0395Component::enqueue_det_range_cfg(float min1, float max1, floa
|
||||
for (size_t i = 0; i < 8; i += 2) {
|
||||
in_use = in_use && values[i] >= 0 && values[i + 1] >= 0;
|
||||
for (size_t j = i; j < i + 2; j++) {
|
||||
// rintf rounds halves to even, like the "%.0f" the sensor command was formatted with before
|
||||
steps[j] = in_use ? static_cast<int16_t>(clamp(rintf(values[j] / DET_RANGE_STEP_M), 0.0f, 32767.0f)) : -1;
|
||||
steps[j] = in_use ? static_cast<int16_t>(clamp(roundf(values[j] / DET_RANGE_STEP_M), 0.0f, 32767.0f)) : -1;
|
||||
}
|
||||
}
|
||||
if (steps[0] < 0) {
|
||||
ESP_LOGW(TAG, "Invalid detection range, using 0 0");
|
||||
steps[0] = steps[1] = 0;
|
||||
}
|
||||
if (this->enqueue(CommandType::COMMAND_TYPE_DET_RANGE_CFG))
|
||||
memcpy(this->det_range_steps_, steps, sizeof(steps));
|
||||
}
|
||||
@@ -98,7 +103,7 @@ bool DfrobotSen0395Component::run_command_(const Command &cmd, uint32_t now) {
|
||||
if (!this->cmd_sent_) {
|
||||
if (now - this->ts_last_cmd_sent_ > duration) {
|
||||
char buf[64]; // "detRangeCfg -1" + 8 * " 32767" + null
|
||||
this->format_command_(cmd, buf, sizeof(buf));
|
||||
this->format_command(cmd, buf, sizeof(buf));
|
||||
ESP_LOGD(TAG, "Sending command: %s", buf);
|
||||
this->write_str(buf);
|
||||
this->ts_last_cmd_sent_ = now;
|
||||
@@ -147,7 +152,7 @@ static size_t append_cfg_key(char *buf, size_t size, size_t pos) {
|
||||
return buf_append_str(buf, size, pos, " 0x45670123 0xCDEF89AB 0x956128C6 0xDF54AC89");
|
||||
}
|
||||
|
||||
void DfrobotSen0395Component::format_command_(const Command &cmd, char *buf, size_t size) {
|
||||
void DfrobotSen0395Component::format_command(const Command &cmd, char *buf, size_t size) const {
|
||||
buf[0] = '\0';
|
||||
switch (cmd.type) {
|
||||
case CommandType::COMMAND_TYPE_POWER:
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace esphome::dfrobot_sen0395 {
|
||||
static constexpr uint8_t MMWAVE_READ_BUFFER_LENGTH = 255;
|
||||
static constexpr uint8_t COMMAND_QUEUE_SIZE = 20;
|
||||
|
||||
// Keep in sync with the BUSY_ACTIONS table in dfrobot_sen0395.cpp
|
||||
// Keep in sync with the BusyActions table in dfrobot_sen0395.cpp
|
||||
enum class CommandType : uint8_t {
|
||||
COMMAND_TYPE_POWER,
|
||||
COMMAND_TYPE_DET_RANGE_CFG,
|
||||
@@ -106,6 +106,8 @@ class DfrobotSen0395Component final : public uart::UARTDevice, public Component
|
||||
void enqueue_saved_setting(CommandType type, bool value);
|
||||
/// Queue a sensor reset
|
||||
void reset_system() { this->enqueue(CommandType::COMMAND_TYPE_RESET_SYSTEM); }
|
||||
/// Write the text sent to the sensor for cmd into buf
|
||||
void format_command(const Command &cmd, char *buf, size_t size) const;
|
||||
|
||||
protected:
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
@@ -124,7 +126,8 @@ class DfrobotSen0395Component final : public uart::UARTDevice, public Component
|
||||
StaticRingBuffer<Command, COMMAND_QUEUE_SIZE> cmd_queue_;
|
||||
uint32_t ts_last_cmd_sent_{0};
|
||||
// Values of the queued range and latency commands, in the sensor's steps of 0.15 m and 0.025 s.
|
||||
// A later command replaces them, which leaves the sensor in the same final state.
|
||||
// A later command replaces them, which leaves the sensor in the same final state. One replaced while its
|
||||
// command waits for a reply makes that command's log and any retry use the newer values.
|
||||
int16_t det_range_steps_[8]{};
|
||||
uint16_t latency_steps_[2]{};
|
||||
|
||||
@@ -134,7 +137,6 @@ class DfrobotSen0395Component final : public uart::UARTDevice, public Component
|
||||
bool run_command_(const Command &cmd, uint32_t now);
|
||||
/// Handle a reply to a sent command; true when the command is done
|
||||
bool handle_reply_(const Command &cmd);
|
||||
void format_command_(const Command &cmd, char *buf, size_t size);
|
||||
|
||||
void set_detected_(bool detected);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <string>
|
||||
#include "esphome/components/dfrobot_sen0395/dfrobot_sen0395.h"
|
||||
|
||||
namespace esphome::dfrobot_sen0395::testing {
|
||||
|
||||
// The text each command sends, as the per-command classes sent it before the queue held plain values.
|
||||
class FormatCommandTest : public ::testing::Test {
|
||||
protected:
|
||||
std::string format(CommandType type, uint8_t arg = 0) {
|
||||
char buf[64];
|
||||
this->radar_.format_command({type, arg}, buf, sizeof(buf));
|
||||
return buf;
|
||||
}
|
||||
|
||||
DfrobotSen0395Component radar_;
|
||||
};
|
||||
|
||||
TEST_F(FormatCommandTest, FixedCommands) {
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_POWER, true), "sensorStart");
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_POWER, false), "sensorStop");
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_FACTORY_RESET),
|
||||
"factoryReset 0x45670123 0xCDEF89AB 0x956128C6 0xDF54AC89");
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_SAVE_CFG), "saveCfg 0x45670123 0xCDEF89AB 0x956128C6 0xDF54AC89");
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_RESET_SYSTEM), "resetSystem");
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_LED_MODE, true), "setLedMode 1 0");
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_LED_MODE, false), "setLedMode 1 1");
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_UART_OUTPUT, true), "setUartOutput 1 1");
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_UART_OUTPUT, false), "setUartOutput 1 0");
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_SENSOR_CFG_START, true), "sensorCfgStart 1");
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_SENSOR_CFG_START, false), "sensorCfgStart 0");
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_SENSITIVITY, 7), "setSensitivity 7");
|
||||
}
|
||||
|
||||
TEST_F(FormatCommandTest, DetectionRangeSegments) {
|
||||
this->radar_.enqueue_det_range_cfg(0.3f, 1.2f, -1, -1, -1, -1, -1, -1);
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_DET_RANGE_CFG), "detRangeCfg -1 2 8");
|
||||
this->radar_.enqueue_det_range_cfg(0.0f, 1.5f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 9.0f);
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_DET_RANGE_CFG), "detRangeCfg -1 0 10 13 20 27 33 40 60");
|
||||
// Segments stop at the first one with a negative bound
|
||||
this->radar_.enqueue_det_range_cfg(0.0f, 1.5f, 2.0f, -1, 4.0f, 5.0f, 6.0f, 9.0f);
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_DET_RANGE_CFG), "detRangeCfg -1 0 10");
|
||||
}
|
||||
|
||||
TEST_F(FormatCommandTest, DetectionRangeRoundsHalfStepsUp) {
|
||||
// 0.075 m is half a 0.15 m step
|
||||
this->radar_.enqueue_det_range_cfg(0.0f, 0.075f, -1, -1, -1, -1, -1, -1);
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_DET_RANGE_CFG), "detRangeCfg -1 0 1");
|
||||
}
|
||||
|
||||
TEST_F(FormatCommandTest, DetectionRangeNegativeFirstSegmentFallsBack) {
|
||||
this->radar_.enqueue_det_range_cfg(-1, 3.0f, -1, -1, -1, -1, -1, -1);
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_DET_RANGE_CFG), "detRangeCfg -1 0 0");
|
||||
}
|
||||
|
||||
TEST_F(FormatCommandTest, Latency) {
|
||||
this->radar_.enqueue_set_latency(0.0f, 2.5f);
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_SET_LATENCY), "setLatency 0.000 2.500");
|
||||
this->radar_.enqueue_set_latency(0.0125f, 0.0374f);
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_SET_LATENCY), "setLatency 0.025 0.025");
|
||||
this->radar_.enqueue_set_latency(1638.375f, 5000.0f);
|
||||
EXPECT_EQ(this->format(CommandType::COMMAND_TYPE_SET_LATENCY), "setLatency 1638.375 1638.375");
|
||||
}
|
||||
|
||||
} // namespace esphome::dfrobot_sen0395::testing
|
||||
Reference in New Issue
Block a user