Collision detection on transmit (#31)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
bd36a7e6a3
commit
38629aac52
|
@ -66,6 +66,11 @@ namespace ratgdo {
|
|||
|
||||
void RATGDOComponent::loop()
|
||||
{
|
||||
if (this->transmit_pending_) {
|
||||
if (!this->transmit_packet()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this->obstruction_loop();
|
||||
this->gdo_state_loop();
|
||||
}
|
||||
|
@ -167,7 +172,7 @@ namespace ratgdo {
|
|||
// this->obstruction_state = static_cast<ObstructionState>((byte1 >> 6) & 1);
|
||||
|
||||
if (door_state == DoorState::CLOSED && door_state != prev_door_state) {
|
||||
this->transmit(Command::GET_OPENINGS);
|
||||
this->send_command(Command::GET_OPENINGS);
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Status: door=%s light=%s lock=%s",
|
||||
|
@ -204,7 +209,7 @@ namespace ratgdo {
|
|||
} else if (cmd == Command::MOTION) {
|
||||
this->motion_state = MotionState::DETECTED;
|
||||
if (*this->light_state == LightState::OFF) {
|
||||
this->transmit(Command::GET_STATUS);
|
||||
this->send_command(Command::GET_STATUS);
|
||||
}
|
||||
ESP_LOGD(TAG, "Motion: %s", MotionState_to_string(*this->motion_state));
|
||||
} else if (cmd == Command::SET_TTC) {
|
||||
|
@ -368,12 +373,12 @@ namespace ratgdo {
|
|||
|
||||
void RATGDOComponent::query_status()
|
||||
{
|
||||
transmit(Command::GET_STATUS);
|
||||
send_command(Command::GET_STATUS);
|
||||
}
|
||||
|
||||
void RATGDOComponent::query_openings()
|
||||
{
|
||||
transmit(Command::GET_OPENINGS);
|
||||
send_command(Command::GET_OPENINGS);
|
||||
}
|
||||
|
||||
/************************* DOOR COMMUNICATION *************************/
|
||||
|
@ -385,18 +390,39 @@ namespace ratgdo {
|
|||
* The opener requires a specific duration low/high pulse before it will accept
|
||||
* a message
|
||||
*/
|
||||
void RATGDOComponent::transmit(Command command, uint32_t data, bool increment)
|
||||
void RATGDOComponent::send_command(Command command, uint32_t data, bool increment)
|
||||
{
|
||||
WirePacket tx_packet;
|
||||
if (!this->transmit_pending_) { // have an untransmitted packet
|
||||
this->encode_packet(command, data, increment, this->tx_packet_);
|
||||
} else {
|
||||
// unlikely this would happed, we're ensuring any pending packet
|
||||
// is transmitted each loop before doing anyting else
|
||||
ESP_LOGW(TAG, "Have untransmitted packet, ignoring command: %s", Command_to_string(command));
|
||||
}
|
||||
this->transmit_packet();
|
||||
}
|
||||
|
||||
bool RATGDOComponent::transmit_packet()
|
||||
{
|
||||
auto now = micros64();
|
||||
while (micros64() - now < 1300) {
|
||||
if (this->input_gdo_pin_->digital_read()) {
|
||||
ESP_LOGD(TAG, "Collision detected, waiting to send packet");
|
||||
this->transmit_pending_ = true;
|
||||
return false;
|
||||
}
|
||||
delayMicroseconds(200);
|
||||
}
|
||||
|
||||
this->encode_packet(command, data, increment, tx_packet);
|
||||
this->output_gdo_pin_->digital_write(true); // pull the line high for 1305 micros so the
|
||||
// door opener responds to the message
|
||||
delayMicroseconds(1305);
|
||||
this->output_gdo_pin_->digital_write(false); // bring the line low
|
||||
|
||||
delayMicroseconds(1260); // "LOW" pulse duration before the message start
|
||||
this->sw_serial_.write(tx_packet, PACKET_LENGTH);
|
||||
this->sw_serial_.write(this->tx_packet_, PACKET_LENGTH);
|
||||
this->transmit_pending_ = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RATGDOComponent::sync()
|
||||
|
@ -414,7 +440,7 @@ namespace ratgdo {
|
|||
ESP_LOGD(TAG, "Triggering sync failed actions.");
|
||||
this->sync_failed = true;
|
||||
};
|
||||
this->transmit(Command::GET_OPENINGS);
|
||||
this->send_command(Command::GET_OPENINGS);
|
||||
return RetryResult::RETRY;
|
||||
}
|
||||
} else {
|
||||
|
@ -422,7 +448,7 @@ namespace ratgdo {
|
|||
ESP_LOGD(TAG, "Triggering sync failed actions.");
|
||||
this->sync_failed = true;
|
||||
};
|
||||
this->transmit(Command::GET_STATUS);
|
||||
this->send_command(Command::GET_STATUS);
|
||||
return RetryResult::RETRY;
|
||||
}
|
||||
},
|
||||
|
@ -556,48 +582,48 @@ namespace ratgdo {
|
|||
{
|
||||
data |= (1 << 16); // button 1 ?
|
||||
data |= (1 << 8); // button press
|
||||
this->transmit(Command::OPEN, data, false);
|
||||
this->send_command(Command::OPEN, data, false);
|
||||
set_timeout(100, [=] {
|
||||
auto data2 = data & ~(1 << 8); // button release
|
||||
this->transmit(Command::OPEN, data2);
|
||||
this->send_command(Command::OPEN, data2);
|
||||
});
|
||||
}
|
||||
|
||||
void RATGDOComponent::light_on()
|
||||
{
|
||||
this->light_state = LightState::ON;
|
||||
this->transmit(Command::LIGHT, data::LIGHT_ON);
|
||||
this->send_command(Command::LIGHT, data::LIGHT_ON);
|
||||
}
|
||||
|
||||
void RATGDOComponent::light_off()
|
||||
{
|
||||
this->light_state = LightState::OFF;
|
||||
this->transmit(Command::LIGHT, data::LIGHT_OFF);
|
||||
this->send_command(Command::LIGHT, data::LIGHT_OFF);
|
||||
}
|
||||
|
||||
void RATGDOComponent::toggle_light()
|
||||
{
|
||||
this->light_state = light_state_toggle(*this->light_state);
|
||||
this->transmit(Command::LIGHT, data::LIGHT_TOGGLE);
|
||||
this->send_command(Command::LIGHT, data::LIGHT_TOGGLE);
|
||||
}
|
||||
|
||||
// Lock functions
|
||||
void RATGDOComponent::lock()
|
||||
{
|
||||
this->lock_state = LockState::LOCKED;
|
||||
this->transmit(Command::LOCK, data::LOCK_ON);
|
||||
this->send_command(Command::LOCK, data::LOCK_ON);
|
||||
}
|
||||
|
||||
void RATGDOComponent::unlock()
|
||||
{
|
||||
this->lock_state = LockState::UNLOCKED;
|
||||
this->transmit(Command::LOCK, data::LOCK_OFF);
|
||||
this->send_command(Command::LOCK, data::LOCK_OFF);
|
||||
}
|
||||
|
||||
void RATGDOComponent::toggle_lock()
|
||||
{
|
||||
this->lock_state = lock_state_toggle(*this->lock_state);
|
||||
this->transmit(Command::LOCK, data::LOCK_TOGGLE);
|
||||
this->send_command(Command::LOCK, data::LOCK_TOGGLE);
|
||||
}
|
||||
|
||||
LightState RATGDOComponent::get_light_state() const
|
||||
|
|
|
@ -131,7 +131,8 @@ namespace ratgdo {
|
|||
void gdo_state_loop();
|
||||
uint16_t decode_packet(const WirePacket& packet);
|
||||
void obstruction_loop();
|
||||
void transmit(Command command, uint32_t data = 0, bool increment = true);
|
||||
void send_command(Command command, uint32_t data = 0, bool increment = true);
|
||||
bool transmit_packet();
|
||||
void encode_packet(Command command, uint32_t data, bool increment, WirePacket& packet);
|
||||
void print_packet(const WirePacket& packet) const;
|
||||
|
||||
|
@ -183,6 +184,10 @@ namespace ratgdo {
|
|||
void subscribe_sync_failed(std::function<void(bool)>&& f);
|
||||
|
||||
protected:
|
||||
// tx data
|
||||
bool transmit_pending_ {false};
|
||||
WirePacket tx_packet_;
|
||||
|
||||
RATGDOStore isr_store_ {};
|
||||
SoftwareSerial sw_serial_;
|
||||
|
||||
|
|
Loading…
Reference in New Issue