ESPHome  2023.11.6
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 
6 namespace esphome {
7 namespace servo {
8 
9 static const char *const TAG = "servo";
10 
11 uint32_t global_servo_id = 1911044085ULL; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
12 
14  ESP_LOGCONFIG(TAG, "Servo:");
15  ESP_LOGCONFIG(TAG, " Idle Level: %.1f%%", this->idle_level_ * 100.0f);
16  ESP_LOGCONFIG(TAG, " Min Level: %.1f%%", this->min_level_ * 100.0f);
17  ESP_LOGCONFIG(TAG, " Max Level: %.1f%%", this->max_level_ * 100.0f);
18  ESP_LOGCONFIG(TAG, " auto detach time: %" PRIu32 " ms", this->auto_detach_time_);
19  ESP_LOGCONFIG(TAG, " run duration: %" PRIu32 " ms", this->transition_length_);
20 }
21 
22 void Servo::loop() {
23  // check if auto_detach_time_ is set and servo reached target
24  if (this->auto_detach_time_ && this->state_ == STATE_TARGET_REACHED) {
25  if (millis() - this->start_millis_ > this->auto_detach_time_) {
26  this->detach();
27  this->start_millis_ = 0;
28  this->state_ = STATE_DETACHED;
29  ESP_LOGD(TAG, "Servo detached on auto_detach_time");
30  }
31  }
32  if (this->target_value_ != this->current_value_ && this->state_ == STATE_ATTACHED) {
33  if (this->transition_length_) {
34  float new_value;
35  float travel_diff = this->target_value_ - this->source_value_;
36  uint32_t target_runtime = abs((int) ((travel_diff) * this->transition_length_ * 1.0f / 2.0f));
37  uint32_t current_runtime = millis() - this->start_millis_;
38  float percentage_run = current_runtime * 1.0f / target_runtime * 1.0f;
39  if (percentage_run > 1.0f) {
40  percentage_run = 1.0f;
41  }
42  new_value = this->target_value_ - (1.0f - percentage_run) * (this->target_value_ - this->source_value_);
43  this->internal_write(new_value);
44  } else {
45  this->internal_write(this->target_value_);
46  }
47  }
48  if (this->target_value_ == this->current_value_ && this->state_ == STATE_ATTACHED) {
50  this->start_millis_ = millis(); // set current stamp for potential auto_detach_time_ check
51  ESP_LOGD(TAG, "Servo reached target");
52  }
53 }
54 
55 void Servo::write(float value) {
56  value = clamp(value, -1.0f, 1.0f);
57  if (this->target_value_ == value)
58  this->internal_write(value);
59  this->target_value_ = value;
60  this->source_value_ = this->current_value_;
61  this->state_ = STATE_ATTACHED;
62  this->start_millis_ = millis();
63  ESP_LOGD(TAG, "Servo new target: %f", value);
64 }
65 
66 void Servo::internal_write(float value) {
67  value = clamp(value, -1.0f, 1.0f);
68  float level;
69  if (value < 0.0) {
70  level = lerp(-value, this->idle_level_, this->min_level_);
71  } else {
72  level = lerp(value, this->idle_level_, this->max_level_);
73  }
74  this->output_->set_level(level);
75  if (this->target_value_ == this->current_value_) {
76  this->save_level_(level);
77  }
78  this->current_value_ = value;
79 }
80 
81 } // namespace servo
82 } // namespace esphome
uint8_t state_
Definition: servo.h:56
uint32_t transition_length_
Definition: servo.h:54
void save_level_(float v)
Definition: servo.h:46
void write(float value)
Definition: servo.cpp:55
float target_value_
Definition: servo.h:57
float lerp(float completion, float start, float end)
Linearly interpolate between start and end by completion (between 0 and 1).
Definition: helpers.cpp:87
uint32_t start_millis_
Definition: servo.h:60
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
Definition: helpers.h:92
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
void set_level(float state)
Set the level of this float output, this is called from the front-end.
float current_value_
Definition: servo.h:59
uint32_t auto_detach_time_
Definition: servo.h:53
void loop() override
Definition: servo.cpp:22
void internal_write(float value)
Definition: servo.cpp:66
output::FloatOutput * output_
Definition: servo.h:48
uint32_t global_servo_id
Definition: servo.cpp:11
float source_value_
Definition: servo.h:58
void dump_config() override
Definition: servo.cpp:13
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7