mirror of
https://github.com/esphome/esphome.git
synced 2026-01-10 04:00:51 -07:00
[pca9685] Allow to disable the phase balancer for PCA9685 (#9792)
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import i2c
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_EXTERNAL_CLOCK_INPUT, CONF_FREQUENCY, CONF_ID
|
||||
from esphome.const import (
|
||||
CONF_EXTERNAL_CLOCK_INPUT,
|
||||
CONF_FREQUENCY,
|
||||
CONF_ID,
|
||||
CONF_PHASE_BALANCER,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ["i2c"]
|
||||
MULTI_CONF = True
|
||||
@@ -9,6 +14,12 @@ MULTI_CONF = True
|
||||
pca9685_ns = cg.esphome_ns.namespace("pca9685")
|
||||
PCA9685Output = pca9685_ns.class_("PCA9685Output", cg.Component, i2c.I2CDevice)
|
||||
|
||||
phase_balancer = pca9685_ns.enum("PhaseBalancer", is_class=True)
|
||||
PHASE_BALANCERS = {
|
||||
"none": phase_balancer.NONE,
|
||||
"linear": phase_balancer.LINEAR,
|
||||
}
|
||||
|
||||
|
||||
def validate_frequency(config):
|
||||
if config[CONF_EXTERNAL_CLOCK_INPUT]:
|
||||
@@ -30,6 +41,9 @@ CONFIG_SCHEMA = cv.All(
|
||||
cv.frequency, cv.Range(min=23.84, max=1525.88)
|
||||
),
|
||||
cv.Optional(CONF_EXTERNAL_CLOCK_INPUT, default=False): cv.boolean,
|
||||
cv.Optional(CONF_PHASE_BALANCER, default="linear"): cv.enum(
|
||||
PHASE_BALANCERS
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
@@ -43,5 +57,6 @@ async def to_code(config):
|
||||
if CONF_FREQUENCY in config:
|
||||
cg.add(var.set_frequency(config[CONF_FREQUENCY]))
|
||||
cg.add(var.set_extclk(config[CONF_EXTERNAL_CLOCK_INPUT]))
|
||||
cg.add(var.set_phase_balancer(config[CONF_PHASE_BALANCER]))
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
@@ -105,7 +105,18 @@ void PCA9685Output::loop() {
|
||||
const uint16_t num_channels = this->max_channel_ - this->min_channel_ + 1;
|
||||
const uint16_t phase_delta_begin = 4096 / num_channels;
|
||||
for (uint8_t channel = this->min_channel_; channel <= this->max_channel_; channel++) {
|
||||
uint16_t phase_begin = (channel - this->min_channel_) * phase_delta_begin;
|
||||
uint16_t phase_begin;
|
||||
switch (this->balancer_) {
|
||||
case PhaseBalancer::NONE:
|
||||
phase_begin = 0;
|
||||
break;
|
||||
case PhaseBalancer::LINEAR:
|
||||
phase_begin = (channel - this->min_channel_) * phase_delta_begin;
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "Unknown phase balancer %d", static_cast<int>(this->balancer_));
|
||||
return;
|
||||
}
|
||||
uint16_t phase_end;
|
||||
uint16_t amount = this->pwm_amounts_[channel];
|
||||
if (amount == 0) {
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
namespace esphome {
|
||||
namespace pca9685 {
|
||||
|
||||
enum class PhaseBalancer {
|
||||
NONE = 0x00,
|
||||
LINEAR = 0x01,
|
||||
};
|
||||
|
||||
/// Inverts polarity of channel output signal
|
||||
extern const uint8_t PCA9685_MODE_INVERTED;
|
||||
/// Channel update happens upon ACK (post-set) rather than on STOP (endTransmission)
|
||||
@@ -47,6 +52,7 @@ class PCA9685Output : public Component, public i2c::I2CDevice {
|
||||
void loop() override;
|
||||
void set_extclk(bool extclk) { this->extclk_ = extclk; }
|
||||
void set_frequency(float frequency) { this->frequency_ = frequency; }
|
||||
void set_phase_balancer(PhaseBalancer balancer) { this->balancer_ = balancer; }
|
||||
|
||||
protected:
|
||||
friend PCA9685Channel;
|
||||
@@ -60,6 +66,7 @@ class PCA9685Output : public Component, public i2c::I2CDevice {
|
||||
float frequency_;
|
||||
uint8_t mode_;
|
||||
bool extclk_ = false;
|
||||
PhaseBalancer balancer_ = PhaseBalancer::LINEAR;
|
||||
|
||||
uint8_t min_channel_{0xFF};
|
||||
uint8_t max_channel_{0x00};
|
||||
|
||||
@@ -2,6 +2,7 @@ pca9685:
|
||||
i2c_id: i2c_bus
|
||||
frequency: 500
|
||||
address: 0x0
|
||||
phase_balancer: linear
|
||||
|
||||
output:
|
||||
- platform: pca9685
|
||||
|
||||
Reference in New Issue
Block a user