ESPHome  2022.6.3
remote_transmitter_esp8266.cpp
Go to the documentation of this file.
1 #include "remote_transmitter.h"
2 #include "esphome/core/log.h"
4 
5 #ifdef USE_ESP8266
6 
7 namespace esphome {
8 namespace remote_transmitter {
9 
10 static const char *const TAG = "remote_transmitter";
11 
13  this->pin_->setup();
14  this->pin_->digital_write(false);
15 }
16 
18  ESP_LOGCONFIG(TAG, "Remote Transmitter...");
19  ESP_LOGCONFIG(TAG, " Carrier Duty: %u%%", this->carrier_duty_percent_);
20  LOG_PIN(" Pin: ", this->pin_);
21 }
22 
23 void RemoteTransmitterComponent::calculate_on_off_time_(uint32_t carrier_frequency, uint32_t *on_time_period,
24  uint32_t *off_time_period) {
25  if (carrier_frequency == 0) {
26  *on_time_period = 0;
27  *off_time_period = 0;
28  return;
29  }
30  uint32_t period = (1000000UL + carrier_frequency / 2) / carrier_frequency; // round(1000000/freq)
31  period = std::max(uint32_t(1), period);
32  *on_time_period = (period * this->carrier_duty_percent_) / 100;
33  *off_time_period = period - *on_time_period;
34 }
35 
37  const uint32_t current_time = micros();
38  if (this->target_time_ == 0) {
39  this->target_time_ = current_time;
40  } else if (this->target_time_ > current_time) {
41  delayMicroseconds(this->target_time_ - current_time);
42  }
43 }
44 
45 void RemoteTransmitterComponent::mark_(uint32_t on_time, uint32_t off_time, uint32_t usec) {
46  this->await_target_time_();
47  this->pin_->digital_write(true);
48 
49  const uint32_t target = this->target_time_ + usec;
50  if (this->carrier_duty_percent_ < 100 && (on_time > 0 || off_time > 0)) {
51  while (true) { // Modulate with carrier frequency
52  this->target_time_ += on_time;
53  if (this->target_time_ >= target)
54  break;
55  this->await_target_time_();
56  this->pin_->digital_write(false);
57 
58  this->target_time_ += off_time;
59  if (this->target_time_ >= target)
60  break;
61  this->await_target_time_();
62  this->pin_->digital_write(true);
63  }
64  }
65  this->target_time_ = target;
66 }
67 
69  this->await_target_time_();
70  this->pin_->digital_write(false);
71  this->target_time_ += usec;
72 }
73 
74 void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t send_wait) {
75  ESP_LOGD(TAG, "Sending remote code...");
76  uint32_t on_time, off_time;
77  this->calculate_on_off_time_(this->temp_.get_carrier_frequency(), &on_time, &off_time);
78  this->target_time_ = 0;
79  for (uint32_t i = 0; i < send_times; i++) {
80  for (int32_t item : this->temp_.get_data()) {
81  if (item > 0) {
82  const auto length = uint32_t(item);
83  this->mark_(on_time, off_time, length);
84  } else {
85  const auto length = uint32_t(-item);
86  this->space_(length);
87  }
88  App.feed_wdt();
89  }
90  this->await_target_time_(); // wait for duration of last pulse
91  this->pin_->digital_write(false);
92 
93  if (i + 1 < send_times)
94  this->target_time_ += send_wait;
95  }
96 }
97 
98 } // namespace remote_transmitter
99 } // namespace esphome
100 
101 #endif
virtual void digital_write(bool value)=0
RemoteTransmitData temp_
Use same vector for all transmits, avoids many allocations.
Definition: remote_base.h:218
void calculate_on_off_time_(uint32_t carrier_frequency, uint32_t *on_time_period, uint32_t *off_time_period)
virtual void setup()=0
uint32_t IRAM_ATTR HOT micros()
Definition: core.cpp:28
const std::vector< int32_t > & get_data() const
Definition: remote_base.h:34
void send_internal(uint32_t send_times, uint32_t send_wait) override
Application App
Global storage of Application pointer - only one Application can exist.
Definition: a4988.cpp:4
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
Definition: core.cpp:29
void mark_(uint32_t on_time, uint32_t off_time, uint32_t usec)