This commit is contained in:
Anton Viktorov 2024-03-14 19:09:54 +01:00
parent a04c9724cc
commit f58bb249c4
3 changed files with 96 additions and 43 deletions

View file

@ -121,6 +121,10 @@ void AS7343Component::setup() {
this->setup_gain(this->gain_);
// enable led false ?
this->enable_spectral_measurement(true);
this->state_ = State::IDLE;
}
void AS7343Component::dump_config() {
@ -170,14 +174,54 @@ void log13_s(const char *TAG, const char *str, const std::array<const char *, 13
}
void AS7343Component::update() {
this->enable_spectral_measurement(true);
this->read_all_channels();
this->enable_spectral_measurement(false);
this->calculate_basic_counts();
if (this->is_ready() && this->state_ == State::IDLE) {
ESP_LOGV(TAG, "Update: Initiating new data collection");
log13_s(TAG, "Channel", CHANNEL_NAMES);
log13_f(TAG, "Nm", CHANNEL_NM);
log13_d(TAG, "Counts", this->readings_.raw_counts);
// this->enable_spectral_measurement(true);
this->readings_.millis_start = millis();
this->state_ = State::COLLECTING_DATA;
} else {
ESP_LOGV(TAG, "Update: Component not ready yet");
}
}
void AS7343Component::loop() {
if (this->is_ready()) {
switch (this->state_) {
case State::IDLE:
// doing nothing, having best time
break;
case State::COLLECTING_DATA:
if (this->is_data_ready()) {
this->read_all_channels();
log13_s(TAG, "Channel", CHANNEL_NAMES);
log13_f(TAG, "Nm", CHANNEL_NM);
log13_d(TAG, "Counts", this->readings_.raw_counts);
this->state_ = State::DATA_COLLECTED;
} else if (millis() - this->readings_.millis_start > 30 * 1000) {
ESP_LOGW(TAG, "Data collection timeout (30s)");
this->state_ = State::IDLE;
} else {
// just do nothing, wait for data
}
break;
case State::DATA_COLLECTED:
// apply modifications
// publish
this->calculate_and_publish();
this->state_ = State::IDLE;
break;
}
}
}
void AS7343Component::calculate_and_publish() {
this->calculate_basic_counts();
uint16_t max_adc = this->get_maximum_spectral_adc_();
uint16_t highest_adc = this->get_highest_value(this->readings_.raw_counts);
@ -193,18 +237,6 @@ void AS7343Component::update() {
ESP_LOGD(TAG, " ,ASTEP, %u,", this->readings_.astep);
ESP_LOGD(TAG, " ,TINT , %.2f,", this->readings_.t_int);
// ESP_LOGD(TAG, ",nm, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, ", CHANNEL_NM[0],
// CHANNEL_NM[1], CHANNEL_NM[2], CHANNEL_NM[3], CHANNEL_NM[4], CHANNEL_NM[5], CHANNEL_NM[6], CHANNEL_NM[7],
// CHANNEL_NM[8], CHANNEL_NM[9], CHANNEL_NM[10], CHANNEL_NM[11], CHANNEL_NM[12]);
// ESP_LOGD(TAG, ",counts, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, ",
// this->channel_readings_[CHANNEL_IDX[0]], this->channel_readings_[CHANNEL_IDX[1]],
// this->channel_readings_[CHANNEL_IDX[2]], this->channel_readings_[CHANNEL_IDX[3]],
// this->channel_readings_[CHANNEL_IDX[4]], this->channel_readings_[CHANNEL_IDX[5]],
// this->channel_readings_[CHANNEL_IDX[6]], this->channel_readings_[CHANNEL_IDX[7]],
// this->channel_readings_[CHANNEL_IDX[8]], this->channel_readings_[CHANNEL_IDX[9]],
// this->channel_readings_[CHANNEL_IDX[10]], this->channel_readings_[CHANNEL_IDX[11]],
// this->channel_readings_[CHANNEL_IDX[12]]);
float irradiance;
float irradiance_photopic;
float lux;
@ -292,12 +324,10 @@ void AS7343Component::update() {
if (this->nir_ != nullptr) {
this->nir_->publish_state(normalized_readings[11]);
}
// if (this->clear_ != nullptr) {
// float clear = (this->channel_readings_[AS7343_CHANNEL_CLEAR] + this->channel_readings_[AS7343_CHANNEL_CLEAR_0] +
// this->channel_readings_[AS7343_CHANNEL_CLEAR_1]) /
// 3;
// this->clear_->publish_state(clear);
// }
if (this->clear_ != nullptr) {
float clear = (this->readings_.basic_counts[AS7343_CHANNEL_CLEAR]);
this->clear_->publish_state(clear);
}
if (this->saturated_ != nullptr) {
this->saturated_->publish_state(this->readings_saturated_);
}
@ -431,12 +461,10 @@ bool AS7343Component::read_all_channels() {
AS7343_CHANNEL_405_F1, AS7343_CHANNEL_425_F2, AS7343_CHANNEL_450_FZ, AS7343_CHANNEL_475_F3,
AS7343_CHANNEL_515_F4, AS7343_CHANNEL_555_FY, AS7343_CHANNEL_550_F5, AS7343_CHANNEL_600_FXL,
AS7343_CHANNEL_640_F6, AS7343_CHANNEL_690_F7, AS7343_CHANNEL_745_F8, AS7343_CHANNEL_855_NIR,
AS7343_CHANNEL_CLEAR};
AS7343_CHANNEL_CLEAR_0};
std::array<uint16_t, AS7343_NUM_CHANNELS_MAX> data;
this->wait_for_data();
AS7343RegStatus status{0};
status.raw = this->reg((uint8_t) AS7343Registers::STATUS).get();
ESP_LOGD(TAG, "Status 0x%02x, sint %d, fint %d, aint %d, asat %d", status.raw, status.sint, status.fint, status.aint,
@ -458,6 +486,10 @@ bool AS7343Component::read_all_channels() {
this->readings_.raw_counts[i] = data[CHANNEL_MAP[i]];
}
ESP_LOGD(TAG, "Clear = %d, Fd = %d", data[AS7343_CHANNEL_CLEAR], data[AS7343_CHANNEL_FD]);
ESP_LOGD(TAG, "Clear_0 = %d, Fd_0 = %d", data[AS7343_CHANNEL_CLEAR_0], data[AS7343_CHANNEL_FD_0]);
ESP_LOGD(TAG, "Clear_1 = %d, Fd_1 = %d", data[AS7343_CHANNEL_CLEAR_1], data[AS7343_CHANNEL_FD_1]);
this->readings_.gain = astatus.again_status;
this->readings_.gain_x = get_gain_multiplier(this->readings_.gain);
this->readings_.atime = get_atime();
@ -469,18 +501,6 @@ bool AS7343Component::read_all_channels() {
return ret;
}
bool AS7343Component::wait_for_data(uint16_t timeout) {
for (uint16_t time = 0; time < timeout; time++) {
if (this->is_data_ready()) {
return true;
}
delay(1);
}
return false;
}
bool AS7343Component::is_data_ready() {
AS7343RegStatus2 status2{0};
status2.raw = this->reg((uint8_t) AS7343Registers::STATUS2).get();

View file

@ -15,6 +15,7 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice {
void dump_config() override;
float get_setup_priority() const override;
void update() override;
void loop() override;
void set_f1_sensor(sensor::Sensor *f1_sensor) { f1_ = f1_sensor; }
void set_f2_sensor(sensor::Sensor *f2_sensor) { f2_ = f2_sensor; }
@ -57,8 +58,10 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice {
void calculate_ppfd(float &ppfd);
void calculate_irradiance(float &irradiance, float &irradiance_photopic, float &lux);
bool wait_for_data(uint16_t timeout = 1000);
bool is_data_ready();
void calculate_and_publish();
bool enable_power(bool enable);
bool enable_spectral_measurement(bool enable);
@ -69,6 +72,25 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice {
uint16_t swap_bytes(uint16_t data);
protected:
//
// Internal state machine, used to split all the actions into
// small steps in loop() to make sure we are not blocking execution
//
enum class State : uint8_t {
NOT_INITIALIZED,
INITIAL_SETUP_COMPLETED,
IDLE,
COLLECTING_DATA,
COLLECTING_DATA_AUTO,
DATA_COLLECTED,
ADJUSTMENT_NEEDED,
ADJUSTMENT_IN_PROGRESS,
READY_TO_APPLY_ADJUSTMENTS,
READY_TO_PUBLISH_PART_1,
READY_TO_PUBLISH_PART_2,
READY_TO_PUBLISH_PART_3
} state_{State::NOT_INITIALIZED};
void set_bank_for_reg_(AS7343Registers reg = AS7343Registers::ENABLE);
bool bank_{false};
bool readings_saturated_{false};
@ -106,6 +128,7 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice {
float gain_x;
float t_int;
uint32_t millis_start;
} readings_;
float get_tint_();

View file

@ -11,6 +11,7 @@ from esphome.const import (
ICON_BRIGHTNESS_5,
STATE_CLASS_MEASUREMENT,
UNIT_LUX,
UNIT_PERCENT,
)
@ -69,7 +70,7 @@ GAIN_OPTIONS = {
SENSOR_SCHEMA = cv.maybe_simple_value(
sensor.sensor_schema(
unit_of_measurement=UNIT_COUNTS,
unit_of_measurement=UNIT_PERCENT,
icon=ICON_BRIGHTNESS_5,
accuracy_decimals=0,
device_class=DEVICE_CLASS_ILLUMINANCE,
@ -95,7 +96,16 @@ CONFIG_SCHEMA = (
cv.Optional(CONF_F7): SENSOR_SCHEMA,
cv.Optional(CONF_F8): SENSOR_SCHEMA,
cv.Optional(CONF_NIR): SENSOR_SCHEMA,
cv.Optional(CONF_CLEAR): SENSOR_SCHEMA,
cv.Optional(CONF_CLEAR): cv.maybe_simple_value(
sensor.sensor_schema(
unit_of_measurement=UNIT_COUNTS,
icon=ICON_BRIGHTNESS_5,
accuracy_decimals=5,
device_class=DEVICE_CLASS_ILLUMINANCE,
state_class=STATE_CLASS_MEASUREMENT,
),
key=CONF_NAME,
),
cv.Optional(CONF_GAIN, default="X8"): cv.enum(GAIN_OPTIONS),
cv.Optional(CONF_ATIME, default=29): cv.int_range(min=0, max=255),
cv.Optional(CONF_ASTEP, default=599): cv.int_range(min=0, max=65534),