Улучшения
- улушчено отображение на OLED - убраны настройки шага частоты и количества повторов - сделан перебор только реализуемых частот - увеличена точность, на 1МГц 1.25%, в остальных до 1% - точное измерение TOTAL TIME
This commit is contained in:
@@ -3,24 +3,26 @@
|
||||
#include <string.h>
|
||||
|
||||
bool Measurement::start(float hz, float duty, float tolerance, uint32_t timeMs,
|
||||
uint8_t repeats, uint8_t settleCycles) {
|
||||
uint8_t settleCycles) {
|
||||
if (!task_ && xTaskCreate(taskEntry, "optical-rx", 4096, this, 4, &task_) != pdPASS) return false;
|
||||
expectedHz_ = static_cast<uint32_t>(hz + 0.5f);
|
||||
if (!expectedHz_ || !timeMs || !repeats || repeats > 10 ||
|
||||
!makePeriodLimits(expectedHz_, duty, tolerance, receiver_.tickHz(), limits_) ||
|
||||
!receiver_.start(expectedHz_)) return false;
|
||||
repeats_ = repeats; settleCycles_ = settleCycles; settleLeft_ = settleCycles;
|
||||
expectedDutyPct_ = duty;
|
||||
tolerance = effectiveTolerancePct(tolerance);
|
||||
if (!expectedHz_ || !timeMs ||
|
||||
!receiver_.start(expectedHz_, expectedDutyPct_)) return false;
|
||||
if (!makePeriodLimits(expectedHz_, duty, tolerance, receiver_.tickHz(), limits_)) {
|
||||
receiver_.stop(); return false;
|
||||
}
|
||||
settleCycles_ = settleCycles; settleLeft_ = settleCycles;
|
||||
stepTimeMs_ = (timeMs + MEASUREMENT_PROGRESS_STEPS - 1U) / MEASUREMENT_PROGRESS_STEPS;
|
||||
stepTicks_ = static_cast<uint64_t>(receiver_.tickHz()) * timeMs /
|
||||
(1000ULL * MEASUREMENT_PROGRESS_STEPS);
|
||||
if (!stepTicks_) stepTicks_ = 1;
|
||||
totalSteps_ = repeats * MEASUREMENT_PROGRESS_STEPS;
|
||||
currentStep_ = currentRepeat_ = 0;
|
||||
stats_.reset(); memset(repeatPeriods_, 0, sizeof(repeatPeriods_));
|
||||
currentStep_ = 0;
|
||||
stats_.reset();
|
||||
publishStats();
|
||||
measurementStartTick_ = deadlineTick_ = 0; startedMs_ = millis();
|
||||
measurementStartMs_ = lastPeriodMs_ = 0;
|
||||
currentRepeat_ = 0;
|
||||
expectedPeriodMs_ = static_cast<uint32_t>((1000ULL + expectedHz_ - 1U) / expectedHz_);
|
||||
if (!expectedPeriodMs_) expectedPeriodMs_ = 1;
|
||||
state_ = MeasureState::SETTLING;
|
||||
@@ -45,17 +47,16 @@ void Measurement::fail(FailReason reason) {
|
||||
receiver_.stop(); state_ = MeasureState::FAIL;
|
||||
}
|
||||
|
||||
void Measurement::completeStep() {
|
||||
void Measurement::completeMeasurement() {
|
||||
receiver_.stop();
|
||||
stats_.droppedItems += receiver_.takeDroppedItems();
|
||||
if (receiver_.overflowed()) { fail(FailReason::GLITCH); return; }
|
||||
++currentStep_;
|
||||
publishStats();
|
||||
if (currentStep_ < totalSteps_) {
|
||||
if (++currentStep_ < MEASUREMENT_PROGRESS_STEPS) {
|
||||
state_ = MeasureState::STEP_READY;
|
||||
return;
|
||||
}
|
||||
for (uint8_t i = 0; i < repeats_; ++i) if (!repeatPeriods_[i]) {
|
||||
if (!stats_.periods) {
|
||||
fail(FailReason::TOO_FEW_PERIODS); return;
|
||||
}
|
||||
state_ = MeasureState::PASS;
|
||||
@@ -91,16 +92,14 @@ MeasureState Measurement::processOnce() {
|
||||
if (!settleLeft_) {
|
||||
measurementStartTick_ = period.startTick + period.periodTicks;
|
||||
deadlineTick_ = measurementStartTick_ + stepTicks_;
|
||||
currentRepeat_ = currentStep_ / MEASUREMENT_PROGRESS_STEPS;
|
||||
measurementStartMs_ = lastPeriodMs_ = millis(); state_ = MeasureState::RUNNING;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const uint64_t endTick = period.startTick + period.periodTicks;
|
||||
if (period.startTick < measurementStartTick_) continue; // leading incomplete period
|
||||
if (endTick > deadlineTick_) { completeStep(); return state_; } // trailing incomplete period
|
||||
++repeatPeriods_[currentRepeat_];
|
||||
const FailReason r = evaluatePeriodFast(period, receiver_.tickHz(), limits_, currentRepeat_ + 1, stats_);
|
||||
if (endTick > deadlineTick_) { completeMeasurement(); return state_; } // trailing incomplete period
|
||||
const FailReason r = evaluatePeriodFast(period, receiver_.tickHz(), limits_, 1, stats_);
|
||||
if (r != FailReason::NONE) { fail(r); return state_; }
|
||||
}
|
||||
}
|
||||
@@ -113,11 +112,18 @@ MeasureState Measurement::processOnce() {
|
||||
if (state_ == MeasureState::SETTLING && millis() - startedMs_ > settleTimeout) fail(FailReason::NO_SIGNAL);
|
||||
if (state_ == MeasureState::RUNNING && measurementStartTick_) {
|
||||
const uint32_t now = millis();
|
||||
const uint32_t edgeTimeoutMs = expectedPeriodMs_ * NO_SIGNAL_TIMEOUT_PERIODS + 2;
|
||||
if (now - measurementStartMs_ < stepTimeMs_ && now - lastPeriodMs_ > edgeTimeoutMs) {
|
||||
// RMT reports a block only after its user buffer has filled. At 1 kHz the
|
||||
// minimum 48-symbol C3 block contains roughly 48 PWM periods and therefore
|
||||
// arrives much later than the old 8-period timeout. Do not call that
|
||||
// normal batching delay a lost edge.
|
||||
const uint32_t batchPeriods = receiver_.receiveChunkSymbols();
|
||||
const uint32_t batchTimeoutMs = expectedPeriodMs_ * (batchPeriods + NO_SIGNAL_TIMEOUT_PERIODS) + 2U;
|
||||
const uint32_t edgeTimeoutMs = expectedPeriodMs_ * NO_SIGNAL_TIMEOUT_PERIODS + 2U;
|
||||
const uint32_t receiveTimeoutMs = batchTimeoutMs > edgeTimeoutMs ? batchTimeoutMs : edgeTimeoutMs;
|
||||
if (now - measurementStartMs_ < stepTimeMs_ && now - lastPeriodMs_ > receiveTimeoutMs) {
|
||||
fail(FailReason::LOST_EDGE); return state_;
|
||||
}
|
||||
if (now - measurementStartMs_ > stepTimeMs_ + expectedPeriodMs_ + 2) completeStep();
|
||||
if (now - measurementStartMs_ > stepTimeMs_ + expectedPeriodMs_ + 2) completeMeasurement();
|
||||
}
|
||||
return state_;
|
||||
}
|
||||
@@ -126,7 +132,7 @@ MeasureState Measurement::update() { return state_; }
|
||||
|
||||
bool Measurement::continueAfterDisplay() {
|
||||
if (state_ != MeasureState::STEP_READY) return false;
|
||||
if (!receiver_.start(expectedHz_)) {
|
||||
if (!receiver_.start(expectedHz_, expectedDutyPct_)) {
|
||||
fail(FailReason::UNSUPPORTED);
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user