ESPHome 2025.6.0
Loading...
Searching...
No Matches
servo.cpp
Go to the documentation of this file.
1#include "servo.h"
2#include "esphome/core/log.h"
3#include "esphome/core/hal.h"
4#include <cinttypes>
5
6namespace esphome {
7namespace servo {
8
9static const char *const TAG = "servo";
10
11uint32_t global_servo_id = 1911044085ULL; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
12
14 ESP_LOGCONFIG(TAG,
15 "Servo:\n"
16 " Idle Level: %.1f%%\n"
17 " Min Level: %.1f%%\n"
18 " Max Level: %.1f%%\n"
19 " Auto-detach time: %" PRIu32 " ms\n"
20 " Run duration: %" PRIu32 " ms",
21 this->idle_level_ * 100.0f, this->min_level_ * 100.0f, this->max_level_ * 100.0f,
23}
24
26 float v;
27 if (this->restore_) {
29 global_servo_id++;
30 if (this->rtc_.load(&v)) {
31 this->target_value_ = v;
32 this->internal_write(v);
33 this->state_ = STATE_ATTACHED;
34 this->start_millis_ = millis();
35 return;
36 }
37 }
38 this->detach();
39}
40
42 // check if auto_detach_time_ is set and servo reached target
43 if (this->auto_detach_time_ && this->state_ == STATE_TARGET_REACHED) {
44 if (millis() - this->start_millis_ > this->auto_detach_time_) {
45 this->detach();
46 this->start_millis_ = 0;
47 ESP_LOGD(TAG, "Detached on auto_detach_time");
48 }
49 }
50 if (this->target_value_ != this->current_value_ && this->state_ == STATE_ATTACHED) {
51 if (this->transition_length_) {
52 float new_value;
53 float travel_diff = this->target_value_ - this->source_value_;
54 uint32_t target_runtime = abs((int) ((travel_diff) * this->transition_length_ * 1.0f / 2.0f));
55 uint32_t current_runtime = millis() - this->start_millis_;
56 float percentage_run = current_runtime * 1.0f / target_runtime * 1.0f;
57 if (percentage_run > 1.0f) {
58 percentage_run = 1.0f;
59 }
60 new_value = this->target_value_ - (1.0f - percentage_run) * (this->target_value_ - this->source_value_);
61 this->internal_write(new_value);
62 } else {
63 this->internal_write(this->target_value_);
64 }
65 }
66 if (this->target_value_ == this->current_value_ && this->state_ == STATE_ATTACHED) {
68 this->start_millis_ = millis(); // set current stamp for potential auto_detach_time_ check
69 ESP_LOGD(TAG, "Reached target");
70 }
71}
72
73void Servo::write(float value) {
74 value = clamp(value, -1.0f, 1.0f);
75 if ((this->state_ == STATE_DETACHED) && (this->target_value_ == value)) {
76 this->internal_write(value);
77 } else {
78 this->save_level_(value);
79 }
80 this->target_value_ = value;
81 this->source_value_ = this->current_value_;
82 this->state_ = STATE_ATTACHED;
83 this->start_millis_ = millis();
84 ESP_LOGD(TAG, "New target: %f", value);
85}
86
87void Servo::internal_write(float value) {
88 value = clamp(value, -1.0f, 1.0f);
89 float level;
90 if (value < 0.0) {
91 level = lerp(-value, this->idle_level_, this->min_level_);
92 } else {
93 level = lerp(value, this->idle_level_, this->max_level_);
94 }
95 this->output_->set_level(level);
96 this->current_value_ = value;
97}
98
100 this->state_ = STATE_DETACHED;
101 this->output_->set_level(0.0f);
102}
103
104void Servo::save_level_(float v) {
105 if (this->restore_)
106 this->rtc_.save(&v);
107}
108
109} // namespace servo
110} // namespace esphome
bool save(const T *src)
Definition preferences.h:21
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
void set_level(float state)
Set the level of this float output, this is called from the front-end.
uint32_t start_millis_
Definition servo.h:48
void loop() override
Definition servo.cpp:41
uint32_t transition_length_
Definition servo.h:42
void write(float value)
Definition servo.cpp:73
uint32_t auto_detach_time_
Definition servo.h:41
void setup() override
Definition servo.cpp:25
void dump_config() override
Definition servo.cpp:13
output::FloatOutput * output_
Definition servo.h:36
void internal_write(float value)
Definition servo.cpp:87
ESPPreferenceObject rtc_
Definition servo.h:43
void save_level_(float v)
Definition servo.cpp:104
uint32_t global_servo_id
Definition servo.cpp:11
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
ESPPreferences * global_preferences
uint32_t IRAM_ATTR HOT millis()
Definition core.cpp:28
float lerp(float completion, float start, float end)
Linearly interpolate between start and end by completion (between 0 and 1).
Definition helpers.cpp:95
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
Definition helpers.h:102