mirror of
https://github.com/esphome/esphome.git
synced 2025-10-15 23:17:54 +02:00
[qmc5883l] Added drdy_pin option to allow it to run max rate (#10901)
Co-authored-by: Lamer Mortification <lamer_mortification@yahoo.com> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
This commit is contained in:
parent
e55df1babc
commit
7147479f90
@ -8,6 +8,7 @@ namespace esphome {
|
||||
namespace qmc5883l {
|
||||
|
||||
static const char *const TAG = "qmc5883l";
|
||||
|
||||
static const uint8_t QMC5883L_ADDRESS = 0x0D;
|
||||
|
||||
static const uint8_t QMC5883L_REGISTER_DATA_X_LSB = 0x00;
|
||||
@ -32,6 +33,10 @@ void QMC5883LComponent::setup() {
|
||||
}
|
||||
delay(10);
|
||||
|
||||
if (this->drdy_pin_) {
|
||||
this->drdy_pin_->setup();
|
||||
}
|
||||
|
||||
uint8_t control_1 = 0;
|
||||
control_1 |= 0b01 << 0; // MODE (Mode) -> 0b00=standby, 0b01=continuous
|
||||
control_1 |= this->datarate_ << 2;
|
||||
@ -64,6 +69,7 @@ void QMC5883LComponent::setup() {
|
||||
high_freq_.start();
|
||||
}
|
||||
}
|
||||
|
||||
void QMC5883LComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "QMC5883L:");
|
||||
LOG_I2C_DEVICE(this);
|
||||
@ -77,11 +83,20 @@ void QMC5883LComponent::dump_config() {
|
||||
LOG_SENSOR(" ", "Z Axis", this->z_sensor_);
|
||||
LOG_SENSOR(" ", "Heading", this->heading_sensor_);
|
||||
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
|
||||
LOG_PIN(" DRDY Pin: ", this->drdy_pin_);
|
||||
}
|
||||
|
||||
float QMC5883LComponent::get_setup_priority() const { return setup_priority::DATA; }
|
||||
|
||||
void QMC5883LComponent::update() {
|
||||
i2c::ErrorCode err;
|
||||
uint8_t status = false;
|
||||
|
||||
// If DRDY pin is configured and the data is not ready return.
|
||||
if (this->drdy_pin_ && !this->drdy_pin_->digital_read()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Status byte gets cleared when data is read, so we have to read this first.
|
||||
// If status and two axes are desired, it's possible to save one byte of traffic by enabling
|
||||
// ROL_PNT in setup and reading 7 bytes starting at the status register.
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/core/hal.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace qmc5883l {
|
||||
@ -33,6 +34,7 @@ class QMC5883LComponent : public PollingComponent, public i2c::I2CDevice {
|
||||
float get_setup_priority() const override;
|
||||
void update() override;
|
||||
|
||||
void set_drdy_pin(GPIOPin *pin) { drdy_pin_ = pin; }
|
||||
void set_datarate(QMC5883LDatarate datarate) { datarate_ = datarate; }
|
||||
void set_range(QMC5883LRange range) { range_ = range; }
|
||||
void set_oversampling(QMC5883LOversampling oversampling) { oversampling_ = oversampling; }
|
||||
@ -51,6 +53,7 @@ class QMC5883LComponent : public PollingComponent, public i2c::I2CDevice {
|
||||
sensor::Sensor *z_sensor_{nullptr};
|
||||
sensor::Sensor *heading_sensor_{nullptr};
|
||||
sensor::Sensor *temperature_sensor_{nullptr};
|
||||
GPIOPin *drdy_pin_{nullptr};
|
||||
enum ErrorCode {
|
||||
NONE = 0,
|
||||
COMMUNICATION_FAILED,
|
||||
|
@ -1,8 +1,12 @@
|
||||
import logging
|
||||
|
||||
from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import i2c, sensor
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ADDRESS,
|
||||
CONF_DATA_RATE,
|
||||
CONF_FIELD_STRENGTH_X,
|
||||
CONF_FIELD_STRENGTH_Y,
|
||||
CONF_FIELD_STRENGTH_Z,
|
||||
@ -21,6 +25,10 @@ from esphome.const import (
|
||||
UNIT_MICROTESLA,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_DRDY_PIN = "drdy_pin"
|
||||
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
qmc5883l_ns = cg.esphome_ns.namespace("qmc5883l")
|
||||
@ -52,6 +60,18 @@ QMC5883LOversamplings = {
|
||||
}
|
||||
|
||||
|
||||
def validate_config(config):
|
||||
if (
|
||||
config[CONF_UPDATE_INTERVAL].total_milliseconds < 15
|
||||
and CONF_DRDY_PIN not in config
|
||||
):
|
||||
_LOGGER.warning(
|
||||
"[qmc5883l] 'update_interval' is less than 15ms and 'drdy_pin' is "
|
||||
"not configured, this may result in I2C errors"
|
||||
)
|
||||
return config
|
||||
|
||||
|
||||
def validate_enum(enum_values, units=None, int=True):
|
||||
_units = []
|
||||
if units is not None:
|
||||
@ -88,7 +108,7 @@ temperature_schema = sensor.sensor_schema(
|
||||
state_class=STATE_CLASS_MEASUREMENT,
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(QMC5883LComponent),
|
||||
@ -104,29 +124,25 @@ CONFIG_SCHEMA = (
|
||||
cv.Optional(CONF_FIELD_STRENGTH_Z): field_strength_schema,
|
||||
cv.Optional(CONF_HEADING): heading_schema,
|
||||
cv.Optional(CONF_TEMPERATURE): temperature_schema,
|
||||
cv.Optional(CONF_DRDY_PIN): pins.gpio_input_pin_schema,
|
||||
cv.Optional(CONF_DATA_RATE, default="200hz"): validate_enum(
|
||||
QMC5883LDatarates, units=["hz", "Hz"]
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x0D))
|
||||
.extend(i2c.i2c_device_schema(0x0D)),
|
||||
validate_config,
|
||||
)
|
||||
|
||||
|
||||
def auto_data_rate(config):
|
||||
interval_sec = config[CONF_UPDATE_INTERVAL].total_milliseconds / 1000
|
||||
interval_hz = 1.0 / interval_sec
|
||||
for datarate in sorted(QMC5883LDatarates.keys()):
|
||||
if float(datarate) >= interval_hz:
|
||||
return QMC5883LDatarates[datarate]
|
||||
return QMC5883LDatarates[200]
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
cg.add(var.set_oversampling(config[CONF_OVERSAMPLING]))
|
||||
cg.add(var.set_datarate(auto_data_rate(config)))
|
||||
cg.add(var.set_datarate(config[CONF_DATA_RATE]))
|
||||
cg.add(var.set_range(config[CONF_RANGE]))
|
||||
if CONF_FIELD_STRENGTH_X in config:
|
||||
sens = await sensor.new_sensor(config[CONF_FIELD_STRENGTH_X])
|
||||
@ -143,3 +159,6 @@ async def to_code(config):
|
||||
if CONF_TEMPERATURE in config:
|
||||
sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
|
||||
cg.add(var.set_temperature_sensor(sens))
|
||||
if CONF_DRDY_PIN in config:
|
||||
pin = await cg.gpio_pin_expression(config[CONF_DRDY_PIN])
|
||||
cg.add(var.set_drdy_pin(pin))
|
||||
|
@ -17,5 +17,7 @@ sensor:
|
||||
temperature:
|
||||
name: QMC5883L Temperature
|
||||
range: 800uT
|
||||
data_rate: 200Hz
|
||||
oversampling: 256x
|
||||
update_interval: 15s
|
||||
drdy_pin: ${drdy_pin}
|
||||
|
@ -1,5 +1,6 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO16
|
||||
sda_pin: GPIO17
|
||||
drdy_pin: GPIO18
|
||||
|
||||
<<: !include common.yaml
|
||||
|
@ -1,5 +1,6 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO5
|
||||
sda_pin: GPIO4
|
||||
drdy_pin: GPIO6
|
||||
|
||||
<<: !include common.yaml
|
||||
|
@ -1,5 +1,6 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO5
|
||||
sda_pin: GPIO4
|
||||
drdy_pin: GPIO6
|
||||
|
||||
<<: !include common.yaml
|
||||
|
@ -1,5 +1,6 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO16
|
||||
sda_pin: GPIO17
|
||||
drdy_pin: GPIO18
|
||||
|
||||
<<: !include common.yaml
|
||||
|
@ -1,5 +1,6 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO5
|
||||
sda_pin: GPIO4
|
||||
drdy_pin: GPIO2
|
||||
|
||||
<<: !include common.yaml
|
||||
|
@ -1,5 +1,6 @@
|
||||
substitutions:
|
||||
scl_pin: GPIO5
|
||||
sda_pin: GPIO4
|
||||
drdy_pin: GPIO2
|
||||
|
||||
<<: !include common.yaml
|
||||
|
Loading…
x
Reference in New Issue
Block a user