Skip to content
This repository has been archived by the owner on Sep 27, 2023. It is now read-only.

Commit

Permalink
Fix Remote Receiver Overflow for ESP8266 (#348)
Browse files Browse the repository at this point in the history
* Remote Receiver Improvements

* Improvements
  • Loading branch information
OttoWinter committed Jan 2, 2019
1 parent 28ecb38 commit 1747085
Show file tree
Hide file tree
Showing 17 changed files with 90 additions and 50 deletions.
5 changes: 3 additions & 2 deletions src/esphomelib/remote/lg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,13 @@ bool LGReceiver::matches(RemoteReceiveData *data) {
return this->data_ == data_ && this->nbits_ == res.nbits;
}

void LGDumper::dump(RemoteReceiveData *data) {
bool LGDumper::dump(RemoteReceiveData *data) {
auto res = decode_lg(data);
if (!res.valid)
return;
return false;

ESP_LOGD(TAG, "Received LG: data=0x%08X, nbits=%d", res.data, res.nbits);
return true;
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/esphomelib/remote/lg.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class LGReceiver : public RemoteReceiver {

class LGDumper : public RemoteReceiveDumper {
public:
void dump(RemoteReceiveData *data) override;
bool dump(RemoteReceiveData *data) override;
};
#endif

Expand Down
5 changes: 3 additions & 2 deletions src/esphomelib/remote/nec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,13 @@ bool NECReceiver::matches(RemoteReceiveData *data) {

return this->address_ == decode.address && this->command_ == decode.command;
}
void NECDumper::dump(RemoteReceiveData *data) {
bool NECDumper::dump(RemoteReceiveData *data) {
auto decode = decode_nec(data);
if (!decode.valid)
return;
return false;

ESP_LOGD(TAG, "Received NEC: address=0x%04X, command=0x%04X", decode.address, decode.command);
return true;
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/esphomelib/remote/nec.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class NECReceiver : public RemoteReceiver {

class NECDumper : public RemoteReceiveDumper {
public:
void dump(RemoteReceiveData *data) override;
bool dump(RemoteReceiveData *data) override;
};
#endif

Expand Down
5 changes: 3 additions & 2 deletions src/esphomelib/remote/panasonic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,13 @@ PanasonicReceiver::PanasonicReceiver(const std::string &name, uint16_t address,

}

void PanasonicDumper::dump(RemoteReceiveData *data) {
bool PanasonicDumper::dump(RemoteReceiveData *data) {
auto decode = decode_panasonic(data);
if (!decode.valid)
return;
return false;

ESP_LOGD(TAG, "Received Panasonic: address=0x%04X, command=0x%08X", decode.address, decode.command);
return true;
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/esphomelib/remote/panasonic.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class PanasonicReceiver : public RemoteReceiver {

class PanasonicDumper : public RemoteReceiveDumper {
public:
void dump(RemoteReceiveData *data) override;
bool dump(RemoteReceiveData *data) override;
};
#endif

Expand Down
7 changes: 6 additions & 1 deletion src/esphomelib/remote/raw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ RawTransmitter::RawTransmitter(const std::string &name,
#endif

#ifdef USE_REMOTE_RECEIVER
void RawDumper::dump(RemoteReceiveData *data) {
bool RawDumper::dump(RemoteReceiveData *data) {
char buffer[256];
uint32_t buffer_offset = 0;
buffer_offset += sprintf(buffer, "Received Raw: ");
Expand Down Expand Up @@ -63,6 +63,11 @@ void RawDumper::dump(RemoteReceiveData *data) {
if (buffer_offset != 0) {
ESP_LOGD(TAG, "%s", buffer);
}

return true;
}
bool RawDumper::secondary_() {
return true;
}
bool RawReceiver::matches(RemoteReceiveData *data) {
for (int32_t val : this->data_) {
Expand Down
4 changes: 3 additions & 1 deletion src/esphomelib/remote/raw.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ class RawReceiver : public RemoteReceiver {

class RawDumper : public RemoteReceiveDumper {
public:
void dump(RemoteReceiveData *data) override;
bool dump(RemoteReceiveData *data) override;

bool secondary_() override;
};
#endif

Expand Down
6 changes: 5 additions & 1 deletion src/esphomelib/remote/rc_switch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ RCSwitchTypeDReceiver::RCSwitchTypeDReceiver(const std::string &name,
RCSwitchProtocol::type_d_code(group, device, state, &this->code_, &this->nbits_);
}

void RCSwitchDumper::dump(RemoteReceiveData *data) {
bool RCSwitchDumper::dump(RemoteReceiveData *data) {
bool ret = false;
for (uint8_t i = 1; i <= 7; i++) {
data->reset_index();
uint32_t out_data;
Expand All @@ -233,8 +234,11 @@ void RCSwitchDumper::dump(RemoteReceiveData *data) {

buffer[out_nbits] = '\0';
ESP_LOGD(TAG, "Received RCSwitch: protocol=%u data='%s'", i, buffer);
ret = true;
}
}

return ret;
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/esphomelib/remote/rc_switch.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class RCSwitchTypeDReceiver : public RCSwitchRawReceiver {

class RCSwitchDumper : public RemoteReceiveDumper {
public:
void dump(RemoteReceiveData *data) override;
bool dump(RemoteReceiveData *data) override;
};
#endif

Expand Down
4 changes: 2 additions & 2 deletions src/esphomelib/remote/rc_switch_protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ bool RCSwitchProtocol::expect_sync(RemoteReceiveData *data) const {
return true;
}
bool RCSwitchProtocol::decode(RemoteReceiveData *data, uint32_t *out_data, uint8_t *out_nbits) const {
if (!this->expect_sync(data))
return false;
// ignore if sync doesn't exist
this->expect_sync(data);

*out_data = 0;
for (*out_nbits = 1; *out_nbits < 32; *out_nbits += 1) {
Expand Down
72 changes: 46 additions & 26 deletions src/esphomelib/remote/remote_receiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,16 +196,7 @@ void RemoteReceiverComponent::loop() {
return;

RemoteReceiveData data(this, &this->temp_);
bool found_decoder = false;
for (auto *decoder : this->decoders_) {
if (decoder->process_(&data))
found_decoder = true;
}

if (!found_decoder) {
for (auto *dumper : this->dumpers_)
dumper->process_(&data);
}
this->process_(&data);
}
}
void RemoteReceiverComponent::decode_rmt_(rmt_item32_t *item, size_t len) {
Expand Down Expand Up @@ -283,7 +274,7 @@ void RemoteReceiverComponent::decode_rmt_(rmt_item32_t *item, size_t len) {

#ifdef ARDUINO_ARCH_ESP8266

void ICACHE_RAM_ATTR RemoteReceiverComponent::gpio_intr() {
void ICACHE_RAM_ATTR HOT RemoteReceiverComponent::gpio_intr() {
const uint32_t now = micros();
// If the lhs is 1 (rising edge) we should write to an uneven index and vice versa
const uint32_t next = (this->buffer_write_at_ + 1) % this->buffer_size_;
Expand All @@ -294,6 +285,10 @@ void ICACHE_RAM_ATTR RemoteReceiverComponent::gpio_intr() {
return;

this->buffer_[this->buffer_write_at_ = next] = now;

if (next == this->buffer_read_at_) {
this->overflow_ = true;
}
}

void RemoteReceiverComponent::setup() {
Expand Down Expand Up @@ -322,7 +317,7 @@ void RemoteReceiverComponent::dump_config() {
LOG_PIN(" Pin: ", this->pin_);
if (this->pin_->digital_read()) {
ESP_LOGW(TAG, "Remote Receiver Signal starts with a HIGH value. Usually this means you have to "
"invert the signal using 'inverted: True' !");
"invert the signal using 'inverted: True' in the pin schema!");
}
ESP_LOGCONFIG(TAG, " Buffer Size: %u", this->buffer_size_);
ESP_LOGCONFIG(TAG, " Tolerance: %u%%", this->tolerance_);
Expand All @@ -335,6 +330,13 @@ void RemoteReceiverComponent::dump_config() {
}

void RemoteReceiverComponent::loop() {
if (this->overflow_) {
this->buffer_read_at_ = this->buffer_write_at_;
this->overflow_ = false;
ESP_LOGW(TAG, "Data is coming in too fast! Try increasing the buffer size.");
return;
}

// copy write at to local variables, as it's volatile
const uint32_t write_at = this->buffer_write_at_;
const uint32_t dist = (this->buffer_size_ + write_at - this->buffer_read_at_) % this->buffer_size_;
Expand Down Expand Up @@ -362,7 +364,7 @@ void RemoteReceiverComponent::loop() {
for (uint32_t i = 0; prev != write_at; i++) {
int32_t delta = this->buffer_[this->buffer_read_at_] - this->buffer_[prev];
if (uint32_t(delta) >= this->idle_us_) {
ESP_LOGW(TAG, "Data is coming in too fast!");
// already found a space longer than idle. There must have been two pulses
break;
}

Expand All @@ -377,18 +379,8 @@ void RemoteReceiverComponent::loop() {
this->temp_.push_back(this->idle_us_ * multiplier);

RemoteReceiveData data(this, &this->temp_);
bool found_decoder = false;
for (auto *decoder : this->decoders_) {
if (decoder->process_(&data))
found_decoder = true;
}

if (!found_decoder) {
for (auto *dumper : this->dumpers_)
dumper->process_(&data);
}
this->process_(&data);
}

#endif

RemoteReceiver *RemoteReceiverComponent::add_decoder(RemoteReceiver *decoder) {
Expand All @@ -410,6 +402,31 @@ void RemoteReceiverComponent::set_filter_us(uint8_t filter_us) {
void RemoteReceiverComponent::set_idle_us(uint32_t idle_us) {
this->idle_us_ = idle_us;
}
void RemoteReceiverComponent::process_(RemoteReceiveData *data) {
bool found_decoder = false;
for (auto *decoder : this->decoders_) {
if (decoder->process_(data))
found_decoder = true;
}

if (!found_decoder) {
bool found = false;

for (auto *dumper : this->dumpers_) {
if (!dumper->secondary_()) {
if (dumper->process_(data)) {
found = true;
}
}
}

for (auto *dumper : this->dumpers_) {
if (!found && dumper->secondary_()) {
dumper->process_(data);
}
}
}
}

RemoteReceiver::RemoteReceiver(const std::string &name)
: BinarySensor(name) {
Expand All @@ -426,10 +443,13 @@ bool RemoteReceiver::process_(RemoteReceiveData *data) {
}
return false;
}
bool RemoteReceiveDumper::secondary_() {
return false;
}

void RemoteReceiveDumper::process_(RemoteReceiveData *data) {
bool RemoteReceiveDumper::process_(RemoteReceiveData *data) {
data->reset_index();
this->dump(data);
return this->dump(data);
}

} // namespace remote
Expand Down
10 changes: 7 additions & 3 deletions src/esphomelib/remote/remote_receiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,11 @@ class RemoteReceiver : public binary_sensor::BinarySensor {

class RemoteReceiveDumper {
public:
virtual void dump(RemoteReceiveData *data) = 0;
virtual bool dump(RemoteReceiveData *data) = 0;

void process_(RemoteReceiveData *data);
bool process_(RemoteReceiveData *data);

virtual bool secondary_();
};

class RemoteReceiverComponent : public RemoteControlComponentBase, public Component {
Expand All @@ -124,6 +126,8 @@ class RemoteReceiverComponent : public RemoteControlComponentBase, public Compon
void set_filter_us(uint8_t filter_us);
void set_idle_us(uint32_t idle_us);

void process_(RemoteReceiveData *data);

protected:
friend RemoteReceiveData;

Expand All @@ -143,13 +147,13 @@ class RemoteReceiverComponent : public RemoteControlComponentBase, public Compon
volatile uint32_t buffer_write_at_;
/// The position last read from
uint32_t buffer_read_at_{0};
bool overflow_{false};
void gpio_intr();
#endif

#ifdef ARDUINO_ARCH_ESP32
uint32_t buffer_size_{10000};
#endif
// On ESP8266, we can
#ifdef ARDUINO_ARCH_ESP8266
uint32_t buffer_size_{1000};
HighFrequencyLoopRequester high_freq_;
Expand Down
5 changes: 3 additions & 2 deletions src/esphomelib/remote/samsung.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,13 @@ bool SamsungReceiver::matches(RemoteReceiveData *data) {
return this->data_ == decode.data;
}

void SamsungDumper::dump(RemoteReceiveData *data) {
bool SamsungDumper::dump(RemoteReceiveData *data) {
auto decode = decode_samsung(data);
if (!decode.valid)
return;
return false;

ESP_LOGD(TAG, "Received Samsung: data=0x%08X", decode.data);
return true;
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/esphomelib/remote/samsung.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class SamsungReceiver : public RemoteReceiver {

class SamsungDumper : public RemoteReceiveDumper {
public:
void dump(RemoteReceiveData *data) override;
bool dump(RemoteReceiveData *data) override;
};
#endif

Expand Down
5 changes: 3 additions & 2 deletions src/esphomelib/remote/sony.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,13 @@ bool SonyReceiver::matches(RemoteReceiveData *data) {
return decode.valid && this->data_ == decode.data && this->nbits_ == decode.nbits;
}

void SonyDumper::dump(RemoteReceiveData *data) {
bool SonyDumper::dump(RemoteReceiveData *data) {
auto decode = decode_sony(data);
if (!decode.valid)
return;
return false;

ESP_LOGD(TAG, "Received Sony: data=0x%08X, nbits=%d", decode.data, decode.nbits);
return true;
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/esphomelib/remote/sony.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class SonyReceiver : public RemoteReceiver {

class SonyDumper : public RemoteReceiveDumper {
public:
void dump(RemoteReceiveData *data) override;
bool dump(RemoteReceiveData *data) override;
};
#endif

Expand Down

0 comments on commit 1747085

Please sign in to comment.