mirror of
https://github.com/esphome/esphome.git
synced 2025-10-16 07:27:50 +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 {
|
namespace qmc5883l {
|
||||||
|
|
||||||
static const char *const TAG = "qmc5883l";
|
static const char *const TAG = "qmc5883l";
|
||||||
|
|
||||||
static const uint8_t QMC5883L_ADDRESS = 0x0D;
|
static const uint8_t QMC5883L_ADDRESS = 0x0D;
|
||||||
|
|
||||||
static const uint8_t QMC5883L_REGISTER_DATA_X_LSB = 0x00;
|
static const uint8_t QMC5883L_REGISTER_DATA_X_LSB = 0x00;
|
||||||
@ -32,6 +33,10 @@ void QMC5883LComponent::setup() {
|
|||||||
}
|
}
|
||||||
delay(10);
|
delay(10);
|
||||||
|
|
||||||
|
if (this->drdy_pin_) {
|
||||||
|
this->drdy_pin_->setup();
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t control_1 = 0;
|
uint8_t control_1 = 0;
|
||||||
control_1 |= 0b01 << 0; // MODE (Mode) -> 0b00=standby, 0b01=continuous
|
control_1 |= 0b01 << 0; // MODE (Mode) -> 0b00=standby, 0b01=continuous
|
||||||
control_1 |= this->datarate_ << 2;
|
control_1 |= this->datarate_ << 2;
|
||||||
@ -64,6 +69,7 @@ void QMC5883LComponent::setup() {
|
|||||||
high_freq_.start();
|
high_freq_.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QMC5883LComponent::dump_config() {
|
void QMC5883LComponent::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "QMC5883L:");
|
ESP_LOGCONFIG(TAG, "QMC5883L:");
|
||||||
LOG_I2C_DEVICE(this);
|
LOG_I2C_DEVICE(this);
|
||||||
@ -77,11 +83,20 @@ void QMC5883LComponent::dump_config() {
|
|||||||
LOG_SENSOR(" ", "Z Axis", this->z_sensor_);
|
LOG_SENSOR(" ", "Z Axis", this->z_sensor_);
|
||||||
LOG_SENSOR(" ", "Heading", this->heading_sensor_);
|
LOG_SENSOR(" ", "Heading", this->heading_sensor_);
|
||||||
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
|
LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
|
||||||
|
LOG_PIN(" DRDY Pin: ", this->drdy_pin_);
|
||||||
}
|
}
|
||||||
|
|
||||||
float QMC5883LComponent::get_setup_priority() const { return setup_priority::DATA; }
|
float QMC5883LComponent::get_setup_priority() const { return setup_priority::DATA; }
|
||||||
|
|
||||||
void QMC5883LComponent::update() {
|
void QMC5883LComponent::update() {
|
||||||
i2c::ErrorCode err;
|
i2c::ErrorCode err;
|
||||||
uint8_t status = false;
|
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.
|
// 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
|
// 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.
|
// ROL_PNT in setup and reading 7 bytes starting at the status register.
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/components/sensor/sensor.h"
|
#include "esphome/components/sensor/sensor.h"
|
||||||
#include "esphome/components/i2c/i2c.h"
|
#include "esphome/components/i2c/i2c.h"
|
||||||
|
#include "esphome/core/hal.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace qmc5883l {
|
namespace qmc5883l {
|
||||||
@ -33,6 +34,7 @@ class QMC5883LComponent : public PollingComponent, public i2c::I2CDevice {
|
|||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
void update() override;
|
void update() override;
|
||||||
|
|
||||||
|
void set_drdy_pin(GPIOPin *pin) { drdy_pin_ = pin; }
|
||||||
void set_datarate(QMC5883LDatarate datarate) { datarate_ = datarate; }
|
void set_datarate(QMC5883LDatarate datarate) { datarate_ = datarate; }
|
||||||
void set_range(QMC5883LRange range) { range_ = range; }
|
void set_range(QMC5883LRange range) { range_ = range; }
|
||||||
void set_oversampling(QMC5883LOversampling oversampling) { oversampling_ = oversampling; }
|
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 *z_sensor_{nullptr};
|
||||||
sensor::Sensor *heading_sensor_{nullptr};
|
sensor::Sensor *heading_sensor_{nullptr};
|
||||||
sensor::Sensor *temperature_sensor_{nullptr};
|
sensor::Sensor *temperature_sensor_{nullptr};
|
||||||
|
GPIOPin *drdy_pin_{nullptr};
|
||||||
enum ErrorCode {
|
enum ErrorCode {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
COMMUNICATION_FAILED,
|
COMMUNICATION_FAILED,
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from esphome import pins
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components import i2c, sensor
|
from esphome.components import i2c, sensor
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_ADDRESS,
|
CONF_ADDRESS,
|
||||||
|
CONF_DATA_RATE,
|
||||||
CONF_FIELD_STRENGTH_X,
|
CONF_FIELD_STRENGTH_X,
|
||||||
CONF_FIELD_STRENGTH_Y,
|
CONF_FIELD_STRENGTH_Y,
|
||||||
CONF_FIELD_STRENGTH_Z,
|
CONF_FIELD_STRENGTH_Z,
|
||||||
@ -21,6 +25,10 @@ from esphome.const import (
|
|||||||
UNIT_MICROTESLA,
|
UNIT_MICROTESLA,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
CONF_DRDY_PIN = "drdy_pin"
|
||||||
|
|
||||||
DEPENDENCIES = ["i2c"]
|
DEPENDENCIES = ["i2c"]
|
||||||
|
|
||||||
qmc5883l_ns = cg.esphome_ns.namespace("qmc5883l")
|
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):
|
def validate_enum(enum_values, units=None, int=True):
|
||||||
_units = []
|
_units = []
|
||||||
if units is not None:
|
if units is not None:
|
||||||
@ -88,7 +108,7 @@ temperature_schema = sensor.sensor_schema(
|
|||||||
state_class=STATE_CLASS_MEASUREMENT,
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
)
|
)
|
||||||
|
|
||||||
CONFIG_SCHEMA = (
|
CONFIG_SCHEMA = cv.All(
|
||||||
cv.Schema(
|
cv.Schema(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(QMC5883LComponent),
|
cv.GenerateID(): cv.declare_id(QMC5883LComponent),
|
||||||
@ -104,29 +124,25 @@ CONFIG_SCHEMA = (
|
|||||||
cv.Optional(CONF_FIELD_STRENGTH_Z): field_strength_schema,
|
cv.Optional(CONF_FIELD_STRENGTH_Z): field_strength_schema,
|
||||||
cv.Optional(CONF_HEADING): heading_schema,
|
cv.Optional(CONF_HEADING): heading_schema,
|
||||||
cv.Optional(CONF_TEMPERATURE): temperature_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(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):
|
async def to_code(config):
|
||||||
var = cg.new_Pvariable(config[CONF_ID])
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
await cg.register_component(var, config)
|
await cg.register_component(var, config)
|
||||||
await i2c.register_i2c_device(var, config)
|
await i2c.register_i2c_device(var, config)
|
||||||
|
|
||||||
cg.add(var.set_oversampling(config[CONF_OVERSAMPLING]))
|
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]))
|
cg.add(var.set_range(config[CONF_RANGE]))
|
||||||
if CONF_FIELD_STRENGTH_X in config:
|
if CONF_FIELD_STRENGTH_X in config:
|
||||||
sens = await sensor.new_sensor(config[CONF_FIELD_STRENGTH_X])
|
sens = await sensor.new_sensor(config[CONF_FIELD_STRENGTH_X])
|
||||||
@ -143,3 +159,6 @@ async def to_code(config):
|
|||||||
if CONF_TEMPERATURE in config:
|
if CONF_TEMPERATURE in config:
|
||||||
sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
|
sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
|
||||||
cg.add(var.set_temperature_sensor(sens))
|
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:
|
temperature:
|
||||||
name: QMC5883L Temperature
|
name: QMC5883L Temperature
|
||||||
range: 800uT
|
range: 800uT
|
||||||
|
data_rate: 200Hz
|
||||||
oversampling: 256x
|
oversampling: 256x
|
||||||
update_interval: 15s
|
update_interval: 15s
|
||||||
|
drdy_pin: ${drdy_pin}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
substitutions:
|
substitutions:
|
||||||
scl_pin: GPIO16
|
scl_pin: GPIO16
|
||||||
sda_pin: GPIO17
|
sda_pin: GPIO17
|
||||||
|
drdy_pin: GPIO18
|
||||||
|
|
||||||
<<: !include common.yaml
|
<<: !include common.yaml
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
substitutions:
|
substitutions:
|
||||||
scl_pin: GPIO5
|
scl_pin: GPIO5
|
||||||
sda_pin: GPIO4
|
sda_pin: GPIO4
|
||||||
|
drdy_pin: GPIO6
|
||||||
|
|
||||||
<<: !include common.yaml
|
<<: !include common.yaml
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
substitutions:
|
substitutions:
|
||||||
scl_pin: GPIO5
|
scl_pin: GPIO5
|
||||||
sda_pin: GPIO4
|
sda_pin: GPIO4
|
||||||
|
drdy_pin: GPIO6
|
||||||
|
|
||||||
<<: !include common.yaml
|
<<: !include common.yaml
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
substitutions:
|
substitutions:
|
||||||
scl_pin: GPIO16
|
scl_pin: GPIO16
|
||||||
sda_pin: GPIO17
|
sda_pin: GPIO17
|
||||||
|
drdy_pin: GPIO18
|
||||||
|
|
||||||
<<: !include common.yaml
|
<<: !include common.yaml
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
substitutions:
|
substitutions:
|
||||||
scl_pin: GPIO5
|
scl_pin: GPIO5
|
||||||
sda_pin: GPIO4
|
sda_pin: GPIO4
|
||||||
|
drdy_pin: GPIO2
|
||||||
|
|
||||||
<<: !include common.yaml
|
<<: !include common.yaml
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
substitutions:
|
substitutions:
|
||||||
scl_pin: GPIO5
|
scl_pin: GPIO5
|
||||||
sda_pin: GPIO4
|
sda_pin: GPIO4
|
||||||
|
drdy_pin: GPIO2
|
||||||
|
|
||||||
<<: !include common.yaml
|
<<: !include common.yaml
|
||||||
|
Loading…
x
Reference in New Issue
Block a user