mirror of
https://github.com/esphome/esphome.git
synced 2025-04-16 15:50:28 +01:00
138 lines
4.5 KiB
C++
138 lines
4.5 KiB
C++
#include "qwiic_pir.h"
|
|
#include "esphome/core/log.h"
|
|
|
|
namespace esphome {
|
|
namespace qwiic_pir {
|
|
|
|
static const char *const TAG = "qwiic_pir";
|
|
|
|
void QwiicPIRComponent::setup() {
|
|
ESP_LOGCONFIG(TAG, "Setting up Qwiic PIR...");
|
|
|
|
// Verify I2C communcation by reading and verifying the chip ID
|
|
uint8_t chip_id;
|
|
|
|
if (!this->read_byte(QWIIC_PIR_CHIP_ID, &chip_id)) {
|
|
ESP_LOGE(TAG, "Failed to read the chip's ID");
|
|
|
|
this->error_code_ = ERROR_COMMUNICATION_FAILED;
|
|
this->mark_failed();
|
|
|
|
return;
|
|
}
|
|
|
|
if (chip_id != QWIIC_PIR_DEVICE_ID) {
|
|
ESP_LOGE(TAG, "Unknown chip ID, is this a Qwiic PIR?");
|
|
|
|
this->error_code_ = ERROR_WRONG_CHIP_ID;
|
|
this->mark_failed();
|
|
|
|
return;
|
|
}
|
|
|
|
if (!this->write_byte_16(QWIIC_PIR_DEBOUNCE_TIME, this->debounce_time_)) {
|
|
ESP_LOGE(TAG, "Failed to configure debounce time.");
|
|
|
|
this->error_code_ = ERROR_COMMUNICATION_FAILED;
|
|
this->mark_failed();
|
|
|
|
return;
|
|
}
|
|
|
|
if (this->debounce_mode_ == NATIVE_DEBOUNCE_MODE) {
|
|
// Publish the starting raw state of the PIR sensor
|
|
// If NATIVE mode, the binary_sensor state would be unknown until a motion event
|
|
if (!this->read_byte(QWIIC_PIR_EVENT_STATUS, &this->event_register_.reg)) {
|
|
ESP_LOGE(TAG, "Failed to read initial sensor state.");
|
|
|
|
this->error_code_ = ERROR_COMMUNICATION_FAILED;
|
|
this->mark_failed();
|
|
|
|
return;
|
|
}
|
|
|
|
this->publish_state(this->event_register_.raw_reading);
|
|
}
|
|
}
|
|
|
|
void QwiicPIRComponent::loop() {
|
|
// Read Event Register
|
|
if (!this->read_byte(QWIIC_PIR_EVENT_STATUS, &this->event_register_.reg)) {
|
|
ESP_LOGW(TAG, "Failed to communicate with sensor");
|
|
|
|
return;
|
|
}
|
|
|
|
if (this->debounce_mode_ == HYBRID_DEBOUNCE_MODE) {
|
|
// Use a combination of the raw sensor reading and the device's event detection to determine state
|
|
// - The device is hardcoded to use a debounce time of 1 ms in this mode
|
|
// - Any event, even if it is object_removed, implies motion was active since the last loop, so publish true
|
|
// - Use ESPHome's built-in filters for debouncing
|
|
this->publish_state(this->event_register_.raw_reading || this->event_register_.event_available);
|
|
|
|
if (this->event_register_.event_available) {
|
|
this->clear_events_();
|
|
}
|
|
} else if (this->debounce_mode_ == NATIVE_DEBOUNCE_MODE) {
|
|
// Uses the device's firmware to debounce the signal
|
|
// - Follows the logic of SparkFun's example implementation:
|
|
// https://github.com/sparkfun/SparkFun_Qwiic_PIR_Arduino_Library/blob/master/examples/Example2_PrintPIRStatus/Example2_PrintPIRStatus.ino
|
|
// (accessed July 2023)
|
|
// - Is unreliable at detecting an object being removed, especially at debounce rates even slightly large
|
|
if (this->event_register_.event_available) {
|
|
// If an object is detected, publish true
|
|
if (this->event_register_.object_detected)
|
|
this->publish_state(true);
|
|
|
|
// If an object has been removed, publish false
|
|
if (this->event_register_.object_removed)
|
|
this->publish_state(false);
|
|
|
|
this->clear_events_();
|
|
}
|
|
} else if (this->debounce_mode_ == RAW_DEBOUNCE_MODE) {
|
|
// Publishes the raw PIR sensor reading with no further logic
|
|
// - May miss a very short motion detection if the ESP's loop time is slow
|
|
this->publish_state(this->event_register_.raw_reading);
|
|
}
|
|
}
|
|
|
|
void QwiicPIRComponent::dump_config() {
|
|
ESP_LOGCONFIG(TAG, "Qwiic PIR:");
|
|
|
|
if (this->debounce_mode_ == RAW_DEBOUNCE_MODE) {
|
|
ESP_LOGCONFIG(TAG, " Debounce Mode: RAW");
|
|
} else if (this->debounce_mode_ == NATIVE_DEBOUNCE_MODE) {
|
|
ESP_LOGCONFIG(TAG, " Debounce Mode: NATIVE");
|
|
ESP_LOGCONFIG(TAG, " Debounce Time: %ums", this->debounce_time_);
|
|
} else if (this->debounce_mode_ == HYBRID_DEBOUNCE_MODE) {
|
|
ESP_LOGCONFIG(TAG, " Debounce Mode: HYBRID");
|
|
}
|
|
|
|
switch (this->error_code_) {
|
|
case NONE:
|
|
break;
|
|
case ERROR_COMMUNICATION_FAILED:
|
|
ESP_LOGE(TAG, " Communication with Qwiic PIR failed!");
|
|
break;
|
|
case ERROR_WRONG_CHIP_ID:
|
|
ESP_LOGE(TAG, " Qwiic PIR has wrong chip ID - please verify you are using a Qwiic PIR");
|
|
break;
|
|
default:
|
|
ESP_LOGE(TAG, " Qwiic PIR error code %d", (int) this->error_code_);
|
|
break;
|
|
}
|
|
|
|
LOG_I2C_DEVICE(this);
|
|
LOG_BINARY_SENSOR(" ", "Qwiic PIR Binary Sensor", this);
|
|
}
|
|
|
|
void QwiicPIRComponent::clear_events_() {
|
|
// Clear event status register
|
|
if (!this->write_byte(QWIIC_PIR_EVENT_STATUS, 0x00))
|
|
ESP_LOGW(TAG, "Failed to clear events on sensor");
|
|
}
|
|
|
|
} // namespace qwiic_pir
|
|
} // namespace esphome
|