Make obstruction detection ignore spurrious detections (#41)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
a1b166e563
commit
fd8e60245e
|
@ -33,15 +33,6 @@ namespace ratgdo {
|
||||||
//
|
//
|
||||||
static const uint8_t MAX_CODES_WITHOUT_FLASH_WRITE = 10;
|
static const uint8_t MAX_CODES_WITHOUT_FLASH_WRITE = 10;
|
||||||
|
|
||||||
void IRAM_ATTR HOT RATGDOStore::isr_obstruction(RATGDOStore* arg)
|
|
||||||
{
|
|
||||||
if (arg->input_obst.digital_read()) {
|
|
||||||
arg->last_obstruction_high = millis();
|
|
||||||
} else {
|
|
||||||
arg->obstruction_low_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RATGDOComponent::setup()
|
void RATGDOComponent::setup()
|
||||||
{
|
{
|
||||||
this->output_gdo_pin_->setup();
|
this->output_gdo_pin_->setup();
|
||||||
|
@ -56,9 +47,8 @@ namespace ratgdo {
|
||||||
this->obstruction_from_status_ = true;
|
this->obstruction_from_status_ = true;
|
||||||
} else {
|
} else {
|
||||||
this->input_obst_pin_->setup();
|
this->input_obst_pin_->setup();
|
||||||
this->isr_store_.input_obst = this->input_obst_pin_->to_isr();
|
|
||||||
this->input_obst_pin_->pin_mode(gpio::FLAG_INPUT);
|
this->input_obst_pin_->pin_mode(gpio::FLAG_INPUT);
|
||||||
this->input_obst_pin_->attach_interrupt(RATGDOStore::isr_obstruction, &this->isr_store_, gpio::INTERRUPT_ANY_EDGE);
|
this->input_obst_pin_->attach_interrupt(RATGDOStore::isr_obstruction, &this->isr_store_, gpio::INTERRUPT_FALLING_EDGE);
|
||||||
}
|
}
|
||||||
this->sw_serial_.begin(9600, SWSERIAL_8N1, this->input_gdo_pin_->get_pin(), this->output_gdo_pin_->get_pin(), true);
|
this->sw_serial_.begin(9600, SWSERIAL_8N1, this->input_gdo_pin_->get_pin(), this->output_gdo_pin_->get_pin(), true);
|
||||||
|
|
||||||
|
@ -309,6 +299,7 @@ namespace ratgdo {
|
||||||
{
|
{
|
||||||
long current_millis = millis();
|
long current_millis = millis();
|
||||||
static unsigned long last_millis = 0;
|
static unsigned long last_millis = 0;
|
||||||
|
static unsigned long last_asleep = 0;
|
||||||
|
|
||||||
// the obstruction sensor has 3 states: clear (HIGH with LOW pulse every 7ms), obstructed (HIGH), asleep (LOW)
|
// the obstruction sensor has 3 states: clear (HIGH with LOW pulse every 7ms), obstructed (HIGH), asleep (LOW)
|
||||||
// the transitions between awake and asleep are tricky because the voltage drops slowly when falling asleep
|
// the transitions between awake and asleep are tricky because the voltage drops slowly when falling asleep
|
||||||
|
@ -316,24 +307,30 @@ namespace ratgdo {
|
||||||
|
|
||||||
// If at least 3 low pulses are counted within 50ms, the door is awake, not obstructed and we don't have to check anything else
|
// If at least 3 low pulses are counted within 50ms, the door is awake, not obstructed and we don't have to check anything else
|
||||||
|
|
||||||
// Every 50ms
|
const long CHECK_PERIOD = 50;
|
||||||
if (current_millis - last_millis > 50) {
|
const long PULSES_LOWER_LIMIT = 3;
|
||||||
// check to see if we got between 3 and 8 low pulses on the line
|
|
||||||
if (this->isr_store_.obstruction_low_count >= 3 && this->isr_store_.obstruction_low_count <= 8) {
|
|
||||||
// obstructionCleared();
|
|
||||||
this->obstruction_state = ObstructionState::CLEAR;
|
|
||||||
|
|
||||||
// if there have been no pulses the line is steady high or low
|
if (current_millis - last_millis > CHECK_PERIOD) {
|
||||||
|
// ESP_LOGD(TAG, "%ld: Obstruction count: %d, expected: %d, since asleep: %ld",
|
||||||
|
// current_millis, this->isr_store_.obstruction_low_count, PULSES_EXPECTED,
|
||||||
|
// current_millis - last_asleep
|
||||||
|
// );
|
||||||
|
|
||||||
|
// check to see if we got more then PULSES_LOWER_LIMIT pulses
|
||||||
|
if (this->isr_store_.obstruction_low_count > PULSES_LOWER_LIMIT) {
|
||||||
|
this->obstruction_state = ObstructionState::CLEAR;
|
||||||
} else if (this->isr_store_.obstruction_low_count == 0) {
|
} else if (this->isr_store_.obstruction_low_count == 0) {
|
||||||
// if the line is high and the last high pulse was more than 70ms ago, then there is an obstruction present
|
// if there have been no pulses the line is steady high or low
|
||||||
if (this->input_obst_pin_->digital_read() && current_millis - this->isr_store_.last_obstruction_high > 70) {
|
if (!this->input_obst_pin_->digital_read()) {
|
||||||
this->obstruction_state = ObstructionState::OBSTRUCTED;
|
|
||||||
// obstructionDetected();
|
|
||||||
} else {
|
|
||||||
// asleep
|
// asleep
|
||||||
|
last_asleep = current_millis;
|
||||||
|
} else {
|
||||||
|
// if the line is high and was last asleep more than 700ms ago, then there is an obstruction present
|
||||||
|
if (current_millis - last_asleep > 700) {
|
||||||
|
this->obstruction_state = ObstructionState::OBSTRUCTED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
last_millis = current_millis;
|
last_millis = current_millis;
|
||||||
this->isr_store_.obstruction_low_count = 0;
|
this->isr_store_.obstruction_low_count = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,12 +86,12 @@ namespace ratgdo {
|
||||||
inline bool operator==(const Command& cmd_e, const uint16_t cmd_i) { return cmd_i == static_cast<uint16_t>(cmd_e); }
|
inline bool operator==(const Command& cmd_e, const uint16_t cmd_i) { return cmd_i == static_cast<uint16_t>(cmd_e); }
|
||||||
|
|
||||||
struct RATGDOStore {
|
struct RATGDOStore {
|
||||||
ISRInternalGPIOPin input_obst;
|
|
||||||
|
|
||||||
int obstruction_low_count = 0; // count obstruction low pulses
|
int obstruction_low_count = 0; // count obstruction low pulses
|
||||||
long last_obstruction_high = 0; // count time between high pulses from the obst ISR
|
|
||||||
|
|
||||||
static void IRAM_ATTR HOT isr_obstruction(RATGDOStore* arg);
|
static void IRAM_ATTR HOT isr_obstruction(RATGDOStore* arg)
|
||||||
|
{
|
||||||
|
arg->obstruction_low_count++;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class RATGDOComponent : public Component {
|
class RATGDOComponent : public Component {
|
||||||
|
|
Loading…
Reference in New Issue