73 lines
2.2 KiB
C++
73 lines
2.2 KiB
C++
#pragma once
|
|
|
|
#include "esphome/components/light/light_output.h"
|
|
#include "esphome/components/output/float_output.h"
|
|
#include "esphome/core/component.h"
|
|
#include "esphome/core/helpers.h"
|
|
|
|
namespace esphome {
|
|
namespace hbridge {
|
|
|
|
class HBridgeLightOutput : public Component, public light::LightOutput {
|
|
public:
|
|
void set_pina_pin(output::FloatOutput *pina_pin) { this->pina_pin_ = pina_pin; }
|
|
void set_pinb_pin(output::FloatOutput *pinb_pin) { this->pinb_pin_ = pinb_pin; }
|
|
|
|
light::LightTraits get_traits() override {
|
|
auto traits = light::LightTraits();
|
|
traits.set_supported_color_modes({light::ColorMode::COLD_WARM_WHITE});
|
|
traits.set_min_mireds(153);
|
|
traits.set_max_mireds(500);
|
|
return traits;
|
|
}
|
|
|
|
void setup() override { this->disable_loop(); }
|
|
|
|
void loop() override {
|
|
// Only called when both channels are active — alternate H-bridge direction
|
|
// each iteration to multiplex cold and warm white.
|
|
if (!this->forward_direction_) {
|
|
this->pina_pin_->set_level(this->pina_duty_);
|
|
this->pinb_pin_->set_level(0);
|
|
this->forward_direction_ = true;
|
|
} else {
|
|
this->pina_pin_->set_level(0);
|
|
this->pinb_pin_->set_level(this->pinb_duty_);
|
|
this->forward_direction_ = false;
|
|
}
|
|
}
|
|
|
|
float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
|
|
|
void write_state(light::LightState *state) override {
|
|
float new_pina, new_pinb;
|
|
state->current_values_as_cwww(&new_pina, &new_pinb, false);
|
|
|
|
this->pina_duty_ = new_pina;
|
|
this->pinb_duty_ = new_pinb;
|
|
|
|
if (new_pina != 0.0f && new_pinb != 0.0f) {
|
|
// Both channels active — need loop to alternate H-bridge direction
|
|
this->high_freq_.start();
|
|
this->enable_loop();
|
|
} else {
|
|
// Zero or one channel active — drive pins directly, no multiplexing needed
|
|
this->high_freq_.stop();
|
|
this->disable_loop();
|
|
this->pina_pin_->set_level(new_pina);
|
|
this->pinb_pin_->set_level(new_pinb);
|
|
}
|
|
}
|
|
|
|
protected:
|
|
output::FloatOutput *pina_pin_;
|
|
output::FloatOutput *pinb_pin_;
|
|
float pina_duty_{0};
|
|
float pinb_duty_{0};
|
|
bool forward_direction_{false};
|
|
HighFrequencyLoopRequester high_freq_;
|
|
};
|
|
|
|
} // namespace hbridge
|
|
} // namespace esphome
|