From deda95f1613c6d1f9630403f748fdf0191d821e0 Mon Sep 17 00:00:00 2001 From: Anton Viktorov Date: Thu, 29 Feb 2024 13:53:21 +0100 Subject: [PATCH] some corrections --- esphome/components/as7343/as7343.cpp | 55 ++++++++++++++----- esphome/components/as7343/as7343.h | 4 +- .../components/as7343/as7343_calibration.cpp | 17 ++++++ .../components/as7343/as7343_calibration.h | 1 + 4 files changed, 60 insertions(+), 17 deletions(-) diff --git a/esphome/components/as7343/as7343.cpp b/esphome/components/as7343/as7343.cpp index 531afc24f7..57cbc88c07 100644 --- a/esphome/components/as7343/as7343.cpp +++ b/esphome/components/as7343/as7343.cpp @@ -20,6 +20,10 @@ static constexpr uint8_t CHANNEL_IDX[NUM_USEFUL_CHANNELS] = { static constexpr float CHANNEL_SENS[NUM_USEFUL_CHANNELS] = {0.19402, 0.26647, 0.35741, 0.41753, 0.52235, 0.59633, 0.56242, 0.65645, 0.68882, 0.79980, 0.70423, 0.40366, 0.38516}; +static constexpr float CHANNEL_BASIC_CORRECTIONS[NUM_USEFUL_CHANNELS] = { + 1.055464349, 1.043509797, 1.029576268, 1.0175052, 1.00441899, 0.987356499, 0.957597044, + 0.995863485, 1.014628964, 0.996500814, 0.933072749, 1.052236338, 0.999570232}; + static constexpr float CHANNEL_NM[NUM_USEFUL_CHANNELS] = {405, 425, 450, 475, 515, 555, 550, 600, 640, 690, 745, 855, 718}; static constexpr float CHANNEL_NM_WIDTH[NUM_USEFUL_CHANNELS] = {30, 22, 55, 30, 40, 100, 35, 80, 50, 55, 60, 54, 0}; @@ -113,7 +117,7 @@ void AS7343Component::update() { uint8_t atime = get_atime(); uint16_t astep = get_astep(); - float tint_ms = (1 + atime) * (1 + astep) * 2.78 / 1000; + float tint_ms = (1 + atime) * (1 + astep) * 2.78 / 1000; // us to ms float gain_x = get_gain_multiplier(gain); ESP_LOGD(TAG, " Gain : %.1fX", gain_x); @@ -132,10 +136,16 @@ void AS7343Component::update() { 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 = this->calculate_par_v2(tint_ms, gain_x); + float irradiance; + float lux; + this->calculate_irradiance(tint_ms, gain_x, irradiance, lux, gain); + ESP_LOGD(TAG, " Irradiance: %f W/m^2", irradiance); + ESP_LOGD(TAG, " Lux solar : %f lx", lux); + float par = this->calculate_ppfd(tint_ms, gain_x, gain); + ESP_LOGD(TAG, " PAR : %.2f", par); if (this->illuminance_ != nullptr) { - this->illuminance_->publish_state(irradiance / 0.0079); + this->illuminance_->publish_state(lux); } if (this->irradiance_ != nullptr) { @@ -222,24 +232,39 @@ bool AS7343Component::setup_astep(uint16_t astep) { return this->write_byte_16((uint8_t) AS7343Registers::ASTEP_LSB, swap_bytes(astep)); } -float AS7343Component::calculate_par_v1() { +float AS7343Component::calculate_ppfd(float tint_ms, float gain_x, AS7343Gain gain) { float par = 0; - for (uint8_t i = 0; i < NUM_USEFUL_CHANNELS; i++) { - par += this->channel_readings_[CHANNEL_IDX[i]] * CHANNEL_SENS[i]; - } - return par; -} - -float AS7343Component::calculate_par_v2(float tint_ms, float gain_x) { - float irradiance = 0; + float bc[NUM_USEFUL_CHANNELS] = {0}; + float bcc[NUM_USEFUL_CHANNELS] = {0}; for (uint8_t i = 0; i < NUM_USEFUL_CHANNELS; i++) { float basic_count = this->channel_readings_[CHANNEL_IDX[i]] / (gain_x * tint_ms); + bc[i] = basic_count * AS7343_GAIN_CORRECTION[(uint8_t) gain][i]; + bcc[i] = basic_count / CHANNEL_SENS[i]; + if (CHANNEL_NM[i] < 400 || CHANNEL_NM[i] > 700) { + continue; + } + + float watts = basic_count * CHANNEL_IRRAD_PER_BASIC_COUNT[i] / 1000; + float photon_flux = watts / PHOTON_ENERGIES[i]; + par += photon_flux; + } + + ESP_LOGD(TAG, "basic counts, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f", bc[0], bc[1], bc[2], bc[3], bc[4], + bc[5], bc[6], bc[7], bc[8], bc[9], bc[10], bc[11]); + ESP_LOGD(TAG, "basic counts corrected, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f", bcc[0], bcc[1], bcc[2], + bcc[3], bcc[4], bcc[5], bcc[6], bcc[7], bcc[8], bcc[9], bcc[10], bcc[11]); + return par; +} + +void AS7343Component::calculate_irradiance(float tint_ms, float gain_x, float &irradiance, float &lux, AS7343Gain gain) { + for (uint8_t i = 0; i < NUM_USEFUL_CHANNELS; i++) { + float basic_count = this->channel_readings_[CHANNEL_IDX[i]] / (gain_x * tint_ms); + basic_count *= AS7343_GAIN_CORRECTION[(uint8_t) gain][i]; irradiance += basic_count * CHANNEL_IRRAD_PER_BASIC_COUNT[i]; } - ESP_LOGD(TAG, " Irradiance: %f W/m^2", irradiance / 1000); - ESP_LOGD(TAG, " Lux solar: %f lx", irradiance / 1000 / 0.0079); - return irradiance; + irradiance /= 1000; + lux = irradiance / 0.0079; } bool AS7343Component::read_channels(uint16_t *data) { diff --git a/esphome/components/as7343/as7343.h b/esphome/components/as7343/as7343.h index 5d50eb00b5..92f90659a5 100644 --- a/esphome/components/as7343/as7343.h +++ b/esphome/components/as7343/as7343.h @@ -99,8 +99,8 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice { float get_gain_multiplier(AS7343Gain gain); // uint16_t read_channel(AS7343AdcChannel channel); bool read_channels(uint16_t *data); - float calculate_par_v1(); - float calculate_par_v2(float tint_ms, float gain_x); + float calculate_ppfd(float tint_ms, float gain_x, AS7343Gain gain); + void calculate_irradiance(float tint_ms, float gain_x, float& irradiance, float& lux, AS7343Gain gain); float calculate_spectre_(); // void set_smux_low_channels(bool enable); diff --git a/esphome/components/as7343/as7343_calibration.cpp b/esphome/components/as7343/as7343_calibration.cpp index 505c0029e9..464b4df9ca 100644 --- a/esphome/components/as7343/as7343_calibration.cpp +++ b/esphome/components/as7343/as7343_calibration.cpp @@ -4,6 +4,23 @@ namespace esphome { namespace as7343 { +const float AS7343_GAIN_CORRECTION[13][12+1] PROGMEM = { +{1.149000,1.100000,1.060000,1.070000,1.063000,1.051000,1.062000,1.056000,1.049000,1.040000,1.080000,1.038000,1.065000}, +{1.090000,1.128000,1.064000,1.071000,1.063000,1.050000,1.068000,1.055000,1.047000,1.039000,1.075000,1.038000,1.085000}, +{1.083000,1.086000,1.062000,1.070000,1.062000,1.049000,1.057000,1.053000,1.045000,1.038000,1.063000,1.037000,1.069000}, +{1.059000,1.068000,1.056000,1.066000,1.058000,1.046000,1.051000,1.051000,1.044000,1.036000,1.059000,1.035000,1.053000}, +{1.100000,1.109000,1.096000,1.108000,1.099000,1.089000,1.091000,1.092000,1.082000,1.078000,1.100000,1.076000,1.088000}, +{1.099000,1.109000,1.096000,1.108000,1.099000,1.089000,1.091000,1.092000,1.082000,1.078000,1.100000,1.075000,1.087000}, +{1.088000,1.096000,1.085000,1.097000,1.087000,1.078000,1.079000,1.080000,1.071000,1.067000,1.087000,1.064000,1.076000}, +{1.083000,1.091000,1.078000,1.090000,1.079000,1.072000,1.072000,1.073000,1.064000,1.062000,1.080000,1.057000,1.069000}, +{1.076000,1.084000,1.072000,1.085000,1.074000,1.066000,1.062000,1.067000,1.055000,1.056000,1.074000,1.051000,1.061000}, +{1.067000,1.074000,1.063000,1.075000,1.064000,1.059000,1.055000,1.058000,1.049000,1.051000,1.064000,1.044000,1.053000}, +{1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000}, +{1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000}, +{1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000,1.000000}, + +}; + const float CALIB[801][12] PROGMEM = { {0.135114,-0.101727,0.057653,-0.032777,0.000594,-0.002664,0.000000,0.002006,-0.000366,0.000036,0.001244,-0.000378}, {0.135793,-0.102238,0.057942,-0.032941,0.000597,-0.002677,0.000000,0.002016,-0.000368,0.000036,0.001251,-0.000380}, diff --git a/esphome/components/as7343/as7343_calibration.h b/esphome/components/as7343/as7343_calibration.h index f98e732642..d287385447 100644 --- a/esphome/components/as7343/as7343_calibration.h +++ b/esphome/components/as7343/as7343_calibration.h @@ -5,6 +5,7 @@ namespace esphome { namespace as7343 { +extern const float AS7343_GAIN_CORRECTION[13][12+1]; extern const float CALIB[801][12]; } // namespace as7343 } // namespace esphome