фиксы до работы с перемычкой вместо оптики

This commit is contained in:
2026-08-05 18:28:17 +03:00
parent e5c8c45dcc
commit c4c9167df1
17 changed files with 263 additions and 85 deletions

View File

@@ -19,11 +19,15 @@ bool PulseReceiver::begin() {
queue_ = xQueueCreate(16, sizeof(SymbolBlock));
rmt_rx_channel_config_t cfg = {};
cfg.clk_src = RMT_CLK_SRC_DEFAULT; cfg.resolution_hz = CAPTURE_RESOLUTION_HZ;
cfg.mem_block_symbols = 512; cfg.gpio_num = static_cast<gpio_num_t>(GPIO_RX);
cfg.gpio_num = static_cast<gpio_num_t>(GPIO_RX);
cfg.flags.invert_in = RX_SIGNAL_INVERTED;
#if CONFIG_IDF_TARGET_ESP32S3
cfg.mem_block_symbols = 512;
cfg.flags.with_dma = true;
#else
// C3 has 48 RMT symbols per channel and no RMT DMA. A request for 512
// consumes all available blocks and fails with "no free rx channels".
cfg.mem_block_symbols = RMT_MIN_RECEIVE_SYMBOLS;
cfg.flags.with_dma = false; // C3 uses hardware RMT ping-pong partial reception
#endif
if (!queue_ || rmt_new_rx_channel(&cfg, &channel_) != ESP_OK) return false;
@@ -42,13 +46,20 @@ bool PulseReceiver::begin() {
bool PulseReceiver::start(uint32_t expectedHz) {
resetStream();
#if OPTICAL_USE_RMT_DMA
// In partial RX mode the callback is delivered when this user buffer fills.
// Keep chunks near 5 ms so low-frequency input is reported before NO SIGNAL.
uint64_t symbols = (static_cast<uint64_t>(expectedHz) * RMT_TARGET_CHUNK_US + 999999ULL) / 1000000ULL;
if (symbols < RMT_MIN_RECEIVE_SYMBOLS) symbols = RMT_MIN_RECEIVE_SYMBOLS;
if (symbols > RMT_MAX_RECEIVE_SYMBOLS) symbols = RMT_MAX_RECEIVE_SYMBOLS;
receiveChunkSymbols_ = static_cast<uint16_t>(symbols);
if (rmt_enable(channel_) != ESP_OK) return false;
rmt_receive_config_t cfg = {};
cfg.signal_range_min_ns = 20;
const uint64_t maxNs = 4000000000ULL / (expectedHz ? expectedHz : 1);
cfg.signal_range_max_ns = maxNs > 100000000ULL ? 100000000UL : static_cast<uint32_t>(maxNs);
cfg.flags.en_partial_rx = true;
if (rmt_receive(channel_, dmaBuffer_, sizeof(dmaBuffer_), &cfg) != ESP_OK) {
if (rmt_receive(channel_, receiveBuffer_,
receiveChunkSymbols_ * sizeof(receiveBuffer_[0]), &cfg) != ESP_OK) {
rmt_disable(channel_); return false;
}
#else
@@ -86,7 +97,11 @@ bool PulseReceiver::consumeEdge(const Edge &e, PulsePeriod &out) {
out = {rise_, period, active}; rise_ = tick; haveFall_ = false;
return true;
}
if (!haveRise_ || haveFall_) { overflow_ = true; return false; }
// Reception can begin in the middle of a HIGH pulse. In that case the first
// observable edge is falling and there is no complete period to validate.
// Ignore only this leading partial pulse and synchronize on the next rise.
if (!haveRise_) return false;
if (haveFall_) { overflow_ = true; return false; }
fall_ = tick; haveFall_ = true; return false;
}