ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
tmc2209_sensor.cpp
Go to the documentation of this file.
1#include "tmc2209_sensor.h"
2#include "esphome/core/log.h"
3
4#include <cmath>
5
6namespace esphome::tmc2209 {
7
8ESPHOME_LOG_TAG(TAG, "tmc2209.sensor");
9
11
12// Highest StallGuard result, reached with no load
13static constexpr float STALLGUARD_RESULT_MAX = 510.0f;
14
15static void publish_field(sensor::Sensor *sensor, const optional<uint32_t> &data, const RegisterField &field) {
16 if (sensor == nullptr)
17 return;
18 if (!data.has_value()) {
19 sensor->publish_state(NAN);
20 return;
21 }
22 uint32_t value = TMC22XXStepper::extract_field(*data, field);
23 sensor->publish_state(field.is_signed ? static_cast<float>(static_cast<int32_t>(value)) : static_cast<float>(value));
24}
25
27 if (this->parent_->is_failed())
28 return;
29
30 // Each failed read blocks the loop for the UART timeout. Leave the bus alone while the driver is known to be
31 // unreachable or after the first failed read; the remaining sensors then publish NaN.
32 bool reachable = !this->parent_->is_unreachable();
33 auto read = [this, &reachable](uint8_t reg) -> optional<uint32_t> {
34 if (!reachable)
35 return {};
36 auto data = this->parent_->read_register(reg);
37 reachable = data.has_value();
38 return data;
39 };
40
41 if (this->actual_current_sensor_ != nullptr) {
42 auto drv_status = read(tmc22xx::REG_DRV_STATUS);
43 float current = NAN;
44 if (drv_status.has_value()) {
45 auto scale = static_cast<uint8_t>(TMC22XXStepper::extract_field(*drv_status, tmc22xx::CS_ACTUAL));
46 current = this->parent_->scale_to_current(scale);
47 }
49 }
50
51 // StallGuard only measures the load while the motor turns
52 bool moving = !this->parent_->has_reached_target();
53 if (this->stallguard_result_sensor_ != nullptr || (this->motor_load_sensor_ != nullptr && moving)) {
54 auto sg_result = read(REG_SG_RESULT);
55 publish_field(this->stallguard_result_sensor_, sg_result, SG_RESULT);
56 if (this->motor_load_sensor_ != nullptr) {
57 // 100% is the load at which a stall is reported, where the result drops below twice the threshold
58 float stall_result = 2.0f * this->parent_->get_stallguard_threshold();
59 float load = NAN;
60 if (moving && sg_result.has_value() && stall_result < STALLGUARD_RESULT_MAX) {
61 float result = TMC22XXStepper::extract_field(*sg_result, SG_RESULT);
62 load = (STALLGUARD_RESULT_MAX - result) / (STALLGUARD_RESULT_MAX - stall_result) * 100.0f;
63 }
65 }
66 } else if (this->motor_load_sensor_ != nullptr) {
68 }
69
70 if (this->pwm_scale_sum_sensor_ != nullptr || this->pwm_scale_auto_sensor_ != nullptr) {
71 auto pwm_scale = read(tmc22xx::REG_PWM_SCALE);
72 publish_field(this->pwm_scale_sum_sensor_, pwm_scale, tmc22xx::PWM_SCALE_SUM);
73 publish_field(this->pwm_scale_auto_sensor_, pwm_scale, tmc22xx::PWM_SCALE_AUTO);
74 }
75
76 if (this->pwm_ofs_auto_sensor_ != nullptr || this->pwm_grad_auto_sensor_ != nullptr) {
77 auto pwm_auto = read(tmc22xx::REG_PWM_AUTO);
78 publish_field(this->pwm_ofs_auto_sensor_, pwm_auto, tmc22xx::PWM_OFS_AUTO);
79 publish_field(this->pwm_grad_auto_sensor_, pwm_auto, tmc22xx::PWM_GRAD_AUTO);
80 }
81}
82
84 ESP_LOGCONFIG(TAG, "TMC2209 Sensor:");
85 LOG_UPDATE_INTERVAL(this);
86 LOG_SENSOR(" ", "Actual Current", this->actual_current_sensor_);
87 LOG_SENSOR(" ", "StallGuard Result", this->stallguard_result_sensor_);
88 LOG_SENSOR(" ", "Motor Load", this->motor_load_sensor_);
89 LOG_SENSOR(" ", "PWM Scale Sum", this->pwm_scale_sum_sensor_);
90 LOG_SENSOR(" ", "PWM Scale Auto", this->pwm_scale_auto_sensor_);
91 LOG_SENSOR(" ", "PWM Offset Auto", this->pwm_ofs_auto_sensor_);
92 LOG_SENSOR(" ", "PWM Gradient Auto", this->pwm_grad_auto_sensor_);
93}
94
95} // namespace esphome::tmc2209
bool is_failed() const
Definition component.h:274
Base-class for all sensors.
Definition sensor.h:47
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:65
sensor::Sensor * pwm_grad_auto_sensor_
sensor::Sensor * stallguard_result_sensor_
sensor::Sensor * pwm_scale_auto_sensor_
sensor::Sensor * actual_current_sensor_
sensor::Sensor * pwm_ofs_auto_sensor_
sensor::Sensor * pwm_scale_sum_sensor_
uint8_t get_stallguard_threshold() const
Definition tmc2209.h:35
Base class for Trinamic stepper drivers that are configured over the single wire UART interface.
Definition tmc22xx.h:123
static uint32_t extract_field(uint32_t data, const RegisterField &field)
Definition tmc22xx.cpp:526
bool is_unreachable() const
True while the driver does not answer, until the status poll reads it again (every 10 s).
Definition tmc22xx.h:150
optional< uint32_t > read_register(uint8_t reg)
Definition tmc22xx.cpp:474
float scale_to_current(uint8_t scale)
Convert a current scale (0-31) to A RMS, without analog current scale.
Definition tmc22xx.cpp:404
ESPHOME_LOG_TAG(TAG, "tmc2209.sensor")
static void uint32_t
A bit field inside one register.
Definition tmc22xx.h:15