Files
2025-03-01 14:24:56 -06:00

112 lines
3.0 KiB
C++

#include "tfmini.h"
#include <esphome/core/log.h>
namespace esphome {
namespace tfmini {
static const char *const TAG = "tfmini";
static const uint8_t HEADER = 0x59; // frame header of data package
void TFMiniSensor::setup() {
this->set_timeout(50, [this]() { this->setup_internal_(); });
}
void TFMiniSensor::setup_internal_() {
// Configure standard 9-byte output format (cm)
const uint8_t standard_mode[5] = {0x5A, 0x05, 0x05, 0x01, 0x65};
this->write_array(standard_mode, 5);
delay(100);
// Set refresh rate to 100Hz (1000/0x0A = 100)
const uint8_t rate100[6] = {0x5A, 0x06, 0x03, 0x0A, 0x00, 0x6D};
this->write_array(rate100, 6);
delay(100);
// Save the settings
const uint8_t save_setting[4] = {0x5A, 0x04, 0x11, 0x6F};
this->write_array(save_setting, 4);
// Wait for the sensor to come back online
delay(1000);
this->flush();
ESP_LOGD(TAG, "TFMini setup completed");
}
void TFMiniSensor::loop() {
while (this->available() >= 9) {
if (this->read() != HEADER) {
continue;
}
if (this->read() != HEADER) {
continue;
}
uint8_t data[7];
if (!this->read_array(data, 7)) {
continue;
}
// Verify checksum
uint8_t checksum = HEADER + HEADER;
for (size_t i = 0; i < 6; i++) {
checksum += data[i];
}
if (checksum != data[6]) {
ESP_LOGW(TAG, "TFMini checksum error");
continue;
}
// Extract distance data (first two bytes)
uint16_t distance_cm = data[0] | (data[1] << 8);
// Extract signal strength (next two bytes)
uint16_t strength = data[2] | (data[3] << 8);
// Extract temperature (next two bytes)
float temperature = (data[4] | (data[5] << 8)) / 8.0f - 256.0f;
// Only publish valid readings
if (strength < 100) {
ESP_LOGW(TAG, "TFMini signal strength too low: %u", strength);
continue;
}
// Convert to requested unit
float distance_value;
if (this->distance_unit_ == METERS) {
distance_value = distance_cm / 100.0f;
ESP_LOGD(TAG, "Distance: %.2f m, Strength: %u, Temperature: %.1f °C",
distance_value, strength, temperature);
} else {
distance_value = distance_cm;
ESP_LOGD(TAG, "Distance: %d cm, Strength: %u, Temperature: %.1f °C",
distance_cm, strength, temperature);
}
// Publish all values
this->publish_state(distance_value);
if (this->strength_sensor_ != nullptr) {
this->strength_sensor_->publish_state(strength);
}
if (this->temperature_sensor_ != nullptr) {
this->temperature_sensor_->publish_state(temperature);
}
return;
}
}
void TFMiniSensor::dump_config() {
ESP_LOGCONFIG(TAG, "TFMini:");
LOG_SENSOR(" ", "Distance", this);
ESP_LOGCONFIG(TAG, " Distance Unit: %s", this->distance_unit_ == METERS ? "meters" : "centimeters");
LOG_SENSOR(" ", "Signal Strength", this->strength_sensor_);
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
this->check_uart_settings(115200);
}
} // namespace tfmini
} // namespace esphome