more experiments

This commit is contained in:
Anton Viktorov 2024-03-04 22:00:23 +01:00
parent ac155e6353
commit 63cfcc8725
4 changed files with 2036 additions and 879 deletions

View file

@ -17,6 +17,11 @@ static constexpr uint8_t CHANNEL_IDX[NUM_USEFUL_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};
// pimoroni
static constexpr float CHANNEL_COMPENSATION_GAIN[NUM_USEFUL_CHANNELS] = {1.84, 6.03, 4.88, 13.74, 3.37, 2.82, 6.72,
2.22, 3.17, 1.95, 12.25, 1.00, 1};
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};
@ -34,7 +39,7 @@ static constexpr float CHANNEL_NM_WIDTH[NUM_USEFUL_CHANNELS] = {30, 22, 55, 30,
// Irradiation in mW/m² per basic count
static constexpr float CHANNEL_IRRAD_MW_PER_BASIC_COUNT[NUM_USEFUL_CHANNELS] = {
767.5101757, 2512.765376, 2034.308898, 5730.41039, 1404.780643, 1177.586336, 2803.31385,
923.8726968, 1322.666667, 811.8520699, 5106.962963, 417.0131368, 4416.832833};
923.8726968, 1322.666667, 811.8520699, 5106.962963, 417.0131368, 78.70319635};
// E = h*c/lambda
static constexpr float PHOTON_ENERGIES[NUM_USEFUL_CHANNELS] = {
@ -43,19 +48,19 @@ static constexpr float PHOTON_ENERGIES[NUM_USEFUL_CHANNELS] = {
// static constexpr float CHANNEL_CONTRIB[NUM_USEFUL_CHANNELS] = {
// 0.0603622, 0.0442656, 0.110664, 0.0603622, 0.0804829, 0.201207, 0.0704225, 0.160966, 0.100604, 0.110664, 0};
static constexpr float CHANNEL_CONTRIBUTION[NUM_USEFUL_CHANNELS] = {0.069385773,
0.04848841,
0.114486525,
0.059160501,
0.072754014,
0.168776203,
0.059608686,
0.124894391,
0.073180307,
0.074665125,
0.075439565,
0.059160501,
0};
static constexpr float CHANNEL_ENERGY_CONTRIBUTION[NUM_USEFUL_CHANNELS] = {0.069385773,
0.04848841,
0.114486525,
0.059160501,
0.072754014,
0.168776203,
0.059608686,
0.124894391,
0.073180307,
0.074665125,
0.075439565,
0.059160501,
0};
void AS7343Component::setup() {
ESP_LOGCONFIG(TAG, "Setting up AS7343...");
@ -85,6 +90,8 @@ void AS7343Component::setup() {
cfg20.auto_smux = 0b11;
this->reg((uint8_t) AS7343Registers::CFG20) = cfg20.raw;
this->direct_config_3_chain_();
this->setup_atime(this->atime_);
this->setup_astep(this->astep_);
this->setup_gain(this->gain_);
@ -123,7 +130,12 @@ void AS7343Component::dump_config() {
float AS7343Component::get_setup_priority() const { return setup_priority::DATA; }
void AS7343Component::update() {
this->read_channels(this->channel_readings_);
// this->optimizer_(1000);
// delay(20);
this->enable_spectral_measurement(true);
this->read_18_channels(this->channel_readings_);
this->enable_spectral_measurement(false);
AS7343Gain gain = get_gain();
uint8_t atime = get_atime();
@ -132,10 +144,13 @@ void AS7343Component::update() {
float tint_ms = (1 + atime) * (1 + astep) * 2.78 / 1000; // us to ms
float gain_x = get_gain_multiplier(gain);
float tint2_ms = this->get_tint_();
ESP_LOGD(TAG, " ,Gain , %.1f,X", gain_x);
ESP_LOGD(TAG, " ,ATIME, %u,", atime);
ESP_LOGD(TAG, " ,ASTEP, %u,", astep);
ESP_LOGD(TAG, " ,TINT , %.2f,", tint_ms);
ESP_LOGD(TAG, " ,TINT2 , %.2f,", tint2_ms);
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],
@ -169,52 +184,55 @@ void AS7343Component::update() {
this->ppfd_->publish_state(ppfd);
}
// for (uint8_t i = 0; i < NUM_USEFUL_CHANNELS; i++) {
// this->channel_readings_[CHANNEL_IDX[1]] /= CHANNEL_SENS[i] * 65535;
// }
float normalized_readings[NUM_USEFUL_CHANNELS];
for (uint8_t i = 0; i < NUM_USEFUL_CHANNELS; i++) {
normalized_readings[i] = this->channel_readings_[CHANNEL_IDX[i]];
normalized_readings[i] /= CHANNEL_SENS[i];
normalized_readings[i] *= CHANNEL_SENS[0] / 655.35f;
}
if (this->f1_ != nullptr) {
this->f1_->publish_state(this->channel_basic_readings_[AS7343_CHANNEL_405_F1]);
this->f1_->publish_state(normalized_readings[0]);
}
if (this->f2_ != nullptr) {
this->f2_->publish_state(this->channel_basic_readings_[AS7343_CHANNEL_425_F2]);
this->f2_->publish_state(normalized_readings[1]);
}
if (this->fz_ != nullptr) {
this->fz_->publish_state(this->channel_basic_readings_[AS7343_CHANNEL_450_FZ]);
this->fz_->publish_state(normalized_readings[2]);
}
if (this->f3_ != nullptr) {
this->f3_->publish_state(this->channel_basic_readings_[AS7343_CHANNEL_475_F3]);
this->f3_->publish_state(normalized_readings[3]);
}
if (this->f4_ != nullptr) {
this->f4_->publish_state(this->channel_basic_readings_[AS7343_CHANNEL_515_F4]);
this->f4_->publish_state(normalized_readings[4]);
}
if (this->fy_ != nullptr) {
this->fy_->publish_state(this->channel_basic_readings_[AS7343_CHANNEL_555_FY]);
this->fy_->publish_state(normalized_readings[5]);
}
if (this->f5_ != nullptr) {
this->f5_->publish_state(this->channel_basic_readings_[AS7343_CHANNEL_550_F5]);
this->f5_->publish_state(normalized_readings[6]);
}
if (this->fxl_ != nullptr) {
this->fxl_->publish_state(this->channel_basic_readings_[AS7343_CHANNEL_600_FXL]);
this->fxl_->publish_state(normalized_readings[7]);
}
if (this->f6_ != nullptr) {
this->f6_->publish_state(this->channel_basic_readings_[AS7343_CHANNEL_640_F6]);
this->f6_->publish_state(normalized_readings[8]);
}
if (this->f7_ != nullptr) {
this->f7_->publish_state(this->channel_basic_readings_[AS7343_CHANNEL_690_F7]);
this->f7_->publish_state(normalized_readings[9]);
}
if (this->f8_ != nullptr) {
this->f8_->publish_state(this->channel_basic_readings_[AS7343_CHANNEL_745_F8]);
this->f8_->publish_state(normalized_readings[10]);
}
if (this->nir_ != nullptr) {
this->nir_->publish_state(this->channel_basic_readings_[AS7343_CHANNEL_855_NIR]);
}
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);
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->saturated_ != nullptr) {
this->saturated_->publish_state(this->readings_saturated_);
}
@ -242,31 +260,34 @@ float AS7343Component::get_gain_multiplier(AS7343Gain gain) {
float gainx = ((uint16_t) 1 << (uint8_t) gain);
return gainx / 2;
}
void AS7343Component::set_gain(esphome::optional<unsigned int> g) {
if (g.has_value()) {
this->set_gain(g.value());
}
bool AS7343Component::setup_gain(AS7343Gain gain) {
ESP_LOGD(TAG, "Setup gain %u", (uint8_t) gain);
return this->write_byte((uint8_t) AS7343Registers::CFG1, gain);
}
bool AS7343Component::setup_gain(AS7343Gain gain) { return this->write_byte((uint8_t) AS7343Registers::CFG1, gain); }
bool AS7343Component::setup_atime(uint8_t atime) { return this->write_byte((uint8_t) AS7343Registers::ATIME, atime); }
bool AS7343Component::setup_atime(uint8_t atime) {
ESP_LOGD(TAG, "Setup atime %u", atime);
return this->write_byte((uint8_t) AS7343Registers::ATIME, atime);
}
bool AS7343Component::setup_astep(uint16_t astep) {
ESP_LOGD(TAG, "Setup astep %u", astep);
return this->write_byte_16((uint8_t) AS7343Registers::ASTEP_LSB, swap_bytes(astep));
}
bool AS7343Component::change_gain(AS7343Gain gain) {
this->gain_ = gain;
this->enable_spectral_measurement(false);
return this->write_byte((uint8_t) AS7343Registers::CFG1, gain);
}
float AS7343Component::calculate_ppfd(float tint_ms, float gain_x, AS7343Gain gain) {
float par = 0;
float pfd = 0;
float bc[NUM_USEFUL_CHANNELS] = {0};
float bcc[NUM_USEFUL_CHANNELS] = {0};
for (uint8_t i = 0; i < NUM_USEFUL_CHANNELS; i++) {
for (uint8_t i = 0; i < NUM_USEFUL_CHANNELS - 1; 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];
@ -275,35 +296,56 @@ float AS7343Component::calculate_ppfd(float tint_ms, float gain_x, AS7343Gain ga
continue;
}
float watts = (basic_count - OFFSETS[i]) * CHANNEL_IRRAD_MW_PER_BASIC_COUNT[i] / 1000;
// float irradiance_in_w_per_m2 = basic_count * CHANNEL_IRRAD_MW_PER_BASIC_COUNT[i] /1000 ;
// https://www.berthold.com/en/bioanalytic/knowledge/faq/irradiance-to-photon-flux/
float photon_flux = watts * CHANNEL_NM[i] * 0.836e-2;
photon_flux *= CHANNEL_CONTRIBUTION[i];
par += photon_flux;
float irradiance_in_w_per_m2 = basic_count * CHANNEL_IRRAD_MW_PER_BASIC_COUNT[i] / 10000;
// probably is it not mW/m2 but uW/cm2!!!! so try divide by 10k not 1000
// 1 W/m2 = 100 uW/cm2
// // https://www.berthold.com/en/bioanalytic/knowledge/faq/irradiance-to-photon-flux/
// float photon_flux = watts * CHANNEL_NM[i] * 0.836e-2;
// photon_flux *= CHANNEL_ENERGY_CONTRIBUTION[i];
irradiance_in_w_per_m2 *= CHANNEL_ENERGY_CONTRIBUTION[i];
float photon_count = irradiance_in_w_per_m2 / PHOTON_ENERGIES[i];
float pfd_in_micromols = 1e6f * photon_count / 6.02214179e23f;
pfd += pfd_in_micromols;
}
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_sens_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;
return pfd;
}
void AS7343Component::calculate_irradiance(float tint_ms, float gain_x, float &irradiance, float &lux,
void AS7343Component::calculate_irradiance(float tint_ms, float gain_x, float &irradiance_in_w_per_m2, float &lux,
AS7343Gain gain) {
float irr_band;
for (uint8_t i = 0; i < NUM_USEFUL_CHANNELS; i++) {
float basic_count = this->channel_readings_[CHANNEL_IDX[i]] / (gain_x * tint_ms);
irradiance_in_w_per_m2 = 0;
for (uint8_t i = 0; i < NUM_USEFUL_CHANNELS - 1; i++) {
uint16_t reading = this->channel_readings_[CHANNEL_IDX[i]];
if (reading == 0) {
continue;
}
float basic_count = reading / (gain_x * tint_ms);
ESP_LOGD(TAG, "[%2d] Basic count %f", i, basic_count);
basic_count *= AS7343_GAIN_CORRECTION[(uint8_t) gain][i];
irr_band = (basic_count - OFFSETS[i]) * CHANNEL_IRRAD_MW_PER_BASIC_COUNT[i] / 1000;
irradiance += irr_band * CHANNEL_CONTRIBUTION[i];
ESP_LOGD(TAG, "[%2d] gain corrected %f", i, basic_count);
irr_band = basic_count * CHANNEL_IRRAD_MW_PER_BASIC_COUNT[i] / 10000; // 1000 - if mW/m2, 100 if its uW/cm2
ESP_LOGD(TAG, "[%2d] irradiance %f", i, irr_band);
irradiance_in_w_per_m2 += irr_band * CHANNEL_ENERGY_CONTRIBUTION[i];
ESP_LOGD(TAG, "[%2d] band irradiance %f", i, irr_band * CHANNEL_ENERGY_CONTRIBUTION[i]);
}
lux = irradiance / 0.0079;
// sunlight equivalent
// 1 W/m2 = 116 ± 3 lx solar
// https://www.extrica.com/article/21667/pdf
lux = irradiance_in_w_per_m2 * 116;
}
bool AS7343Component::read_channels(uint16_t *data) {
this->enable_spectral_measurement(true);
bool AS7343Component::read_18_channels(uint16_t *data) {
this->wait_for_data();
AS7343RegStatus status{0};
@ -322,7 +364,7 @@ bool AS7343Component::read_channels(uint16_t *data) {
}
this->readings_saturated_ = astatus.asat_status;
return this->read_bytes_16((uint8_t) AS7343Registers::DATA_O, this->channel_readings_, AS7343_NUM_CHANNELS);
return this->read_bytes_16((uint8_t) AS7343Registers::DATA_O, data, AS7343_NUM_CHANNELS);
}
bool AS7343Component::wait_for_data(uint16_t timeout) {
@ -396,5 +438,300 @@ bool AS7343Component::clear_register_bit(uint8_t address, uint8_t bit_position)
uint16_t AS7343Component::swap_bytes(uint16_t data) { return (data >> 8) | (data << 8); }
void AS7343Component::setup_tint_(float TINT) {
ESP_LOGD(TAG, "Setup tint %.2f", TINT);
uint8_t ATIME = 0x00;
uint16_t ASTEP = 0x0000;
while (true) {
ASTEP = ((TINT / (double) (ATIME + 1)) * 720.0 / 2.0);
if (abs(((ATIME + 1) * (ASTEP + 1) * 2 / 720) - (uint16_t) TINT) <= 1) {
break;
} else {
ATIME += 1;
}
}
this->setup_atime(ATIME);
this->setup_astep(ASTEP);
// this->write_byte((uint8_t)AS7343_ATIME, ATIME);
// this->write_byte((uint8_t)AS7343_ASTEP_LSB, (uint8_t) (ASTEP & 0xFF));
// this->write_byte((uint8_t)AS7343_ASTEP_MSB, (uint8_t) (ASTEP >> 8));
}
float AS7343Component::get_tint_() {
uint16_t ASTEP = this->get_astep();
uint8_t ATIME = this->get_atime();
double TINT = (ASTEP + 1) * (ATIME + 1) * (2.0 / 720.0);
return TINT;
}
void AS7343Component::optimizer_(float max_TINT) {
uint8_t currentGain = 12;
uint16_t FSR = 65535;
float TINT = 182.0;
// AS7343_set_TINT(handle, TINT);
this->setup_tint_(TINT);
uint16_t max_count;
uint16_t min_count;
while (true) {
max_count = 0;
min_count = 0xffff;
this->setup_gain((AS7343Gain) currentGain);
uint16_t data[18];
this->enable_spectral_measurement(true);
this->read_18_channels(data);
this->enable_spectral_measurement(false);
for (uint8_t i = 0; i < 18; i++) {
if (i == 5 || i == 11 || i == 17) {
continue;
}
if (data[i] > max_count) {
max_count = data[i];
}
if (data[i] < min_count) {
min_count = data[i];
}
}
if (max_count > 0xE665) {
if (currentGain == 0) {
// TODO: send optimizer failed due to saturation message
break;
}
currentGain -= 1;
continue;
}
else if (min_count == 0) {
if (currentGain == 12) {
// TODO: send optimizer failed due to saturation message
break;
}
currentGain += 1;
continue;
}
else {
break;
}
}
float counts_expected = (float) max_count;
float multiplier = 0.90;
while (true) {
// set to loop once only, might change the algorithm in the future
max_count = 0;
float exp = (multiplier * (float) FSR - counts_expected);
if (exp < 0) {
break;
}
float temp_TINT = TINT + pow(2, log((multiplier * (float) FSR - counts_expected)) / log(2)) * (2.0 / 720.0);
if (temp_TINT > max_TINT) {
break;
}
this->setup_tint_(temp_TINT);
uint16_t data[18];
this->enable_spectral_measurement(true);
this->read_18_channels(data);
this->enable_spectral_measurement(false);
for (uint8_t i = 0; i < 18; i++) {
if (i == 5 || i == 11 || i == 17) {
continue;
}
if (data[i] > max_count) {
max_count = data[i];
}
}
if (max_count >= multiplier * 0xFFEE) {
multiplier = multiplier - 0.05;
continue;
} else {
TINT = temp_TINT;
}
break;
}
// this->set_gain(currentGain);
this->setup_gain((AS7343Gain) currentGain);
this->setup_tint_(TINT);
}
void AS7343Component::direct_config_3_chain_() {
this->write_byte((uint8_t) AS7343Registers::CFG6, 0x0);
this->write_byte((uint8_t) AS7343Registers::FD_CFG0, 0xa1);
this->write_byte((uint8_t) AS7343Registers::CFG10, 0xf2);
this->write_byte((uint8_t) AS7343Registers::CFG0, 0x10);
this->write_byte((uint8_t) AS7343Registers::CFG1, 0x0c);
this->write_byte((uint8_t) AS7343Registers::CFG8, 0xc8);
this->write_byte((uint8_t) AS7343Registers::CFG20, 0x62);
this->write_byte((uint8_t) AS7343Registers::AGC_GAIN_MAX, 0x99);
this->write_byte((uint8_t) AS7343Registers::FD_TIME_1, 0x64);
this->write_byte((uint8_t) AS7343Registers::FD_TIME_2, 0x21);
this->write_byte((uint8_t) 0xe7, 0x00);
this->write_byte((uint8_t) 0xe4, 0x46);
this->write_byte((uint8_t) 0xe7, 0x04);
this->write_byte((uint8_t) 0xe4, 0x46);
this->write_byte((uint8_t) 0xe7, 0x65);
this->write_byte((uint8_t) 0xe4, 0x46);
this->write_byte((uint8_t) 0xe7, 0x02);
this->write_byte((uint8_t) 0xe4, 0x46);
this->write_byte((uint8_t) 0xe7, 0x00);
this->write_byte((uint8_t) 0xe4, 0x46);
this->write_byte((uint8_t) 0xe7, 0x05);
this->write_byte((uint8_t) 0xe4, 0x46);
this->write_byte((uint8_t) 0xe7, 0x00);
this->write_byte((uint8_t) 0xe4, 0x46);
this->write_byte((uint8_t) 0xe7, 0x01);
this->write_byte((uint8_t) 0xe4, 0x46);
this->write_byte((uint8_t) 0xe7, 0x00);
this->write_byte((uint8_t) 0xe4, 0x46);
this->write_byte((uint8_t) 0xe7, 0x30);
this->write_byte((uint8_t) 0xe4, 0x46);
this->write_byte((uint8_t) 0xe7, 0x00);
this->write_byte((uint8_t) 0xe4, 0x56);
this->write_byte((uint8_t) 0xe7, 0x00);
this->write_byte((uint8_t) 0xe4, 0x56);
this->write_byte((uint8_t) 0xe7, 0x60);
this->write_byte((uint8_t) 0xe4, 0x56);
this->write_byte((uint8_t) 0xe7, 0x20);
this->write_byte((uint8_t) 0xe4, 0x56);
this->write_byte((uint8_t) 0xe7, 0x04);
this->write_byte((uint8_t) 0xe4, 0x56);
this->write_byte((uint8_t) 0xe7, 0x50);
this->write_byte((uint8_t) 0xe4, 0x56);
this->write_byte((uint8_t) 0xe7, 0x03);
this->write_byte((uint8_t) 0xe4, 0x56);
this->write_byte((uint8_t) 0xe7, 0x00);
this->write_byte((uint8_t) 0xe4, 0x56);
this->write_byte((uint8_t) 0xe7, 0x01);
this->write_byte((uint8_t) 0xe4, 0x56);
this->write_byte((uint8_t) 0xe7, 0x05);
this->write_byte((uint8_t) 0xe4, 0x56);
this->write_byte((uint8_t) 0xe7, 0x05);
this->write_byte((uint8_t) 0xe4, 0x66);
this->write_byte((uint8_t) 0xe7, 0x00);
this->write_byte((uint8_t) 0xe4, 0x66);
this->write_byte((uint8_t) 0xe7, 0x60);
this->write_byte((uint8_t) 0xe4, 0x66);
this->write_byte((uint8_t) 0xe7, 0x00);
this->write_byte((uint8_t) 0xe4, 0x66);
this->write_byte((uint8_t) 0xe7, 0x30);
this->write_byte((uint8_t) 0xe4, 0x66);
this->write_byte((uint8_t) 0xe7, 0x00);
this->write_byte((uint8_t) 0xe4, 0x66);
this->write_byte((uint8_t) 0xe7, 0x40);
this->write_byte((uint8_t) 0xe4, 0x66);
this->write_byte((uint8_t) 0xe7, 0x10);
this->write_byte((uint8_t) 0xe4, 0x66);
this->write_byte((uint8_t) 0xe7, 0x20);
this->write_byte((uint8_t) 0xe4, 0x66);
this->write_byte((uint8_t) 0xe7, 0x00);
this->write_byte((uint8_t) 0xe4, 0x66);
// this->write_byte((uint8_t)0x80, 0x11);
}
#define MIN_ASTEP 1
#define MAX_ASTEP 65534
#define MIN_ITIME_US 6
#define MAX_ITIME_US 46602667
#define CONVERSION_FACTOR_MS_TO_US 1000
#define INTEGRATION_TIME_STEP_US_FACTOR 2000
#define INTEGRATION_TIME_STEP_US_DIVIDER 720
/*! Use this macro for signed 64 Bit divisions */
#define DIV64_S64(s64dividend, s64divisor) (s64dividend / s64divisor)
/*! Use this macro for unsigned 64 Bit divisions */
#define DIV64_U64(u64dividend, u64divisor) (u64dividend / u64divisor)
bool AS7343Component::as7352_set_integration_time_us(uint32_t time_us) {
bool result;
int64_t time;
uint8_t atime = 0;
uint16_t astep = 0xFFFF / 2;
int64_t astep_i64;
if (MIN_ITIME_US > time_us || MAX_ITIME_US < time_us) {
return false;
}
time = DIV64_S64((int64_t) time_us * INTEGRATION_TIME_STEP_US_DIVIDER, INTEGRATION_TIME_STEP_US_FACTOR);
time = DIV64_S64(time, ((int64_t) astep + 1));
time -= 1;
if (0 > time) {
atime = 0;
} else if (255 < time) {
atime = 255;
} else {
atime = (uint8_t) time;
}
astep_i64 = DIV64_S64((int64_t) time_us * INTEGRATION_TIME_STEP_US_DIVIDER * 10, INTEGRATION_TIME_STEP_US_FACTOR);
astep_i64 = DIV64_S64(astep_i64, ((int64_t) atime + 1)) + 5;
astep_i64 = DIV64_S64(astep_i64, 10);
astep_i64 -= 1;
if (MIN_ASTEP > astep_i64 || MAX_ASTEP < astep_i64) {
return false;
} else {
astep = (uint16_t) astep_i64;
}
ESP_LOGD(TAG, "for itime %u : atime %u, astep %u", time_us, atime, astep);
this->set_astep(astep);
// if (result)
this->set_atime(atime);
return result;
}
} // namespace as7343
} // namespace esphome

View file

@ -35,7 +35,6 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice {
void set_saturation_sensor(sensor::Sensor *sensor) { this->saturated_ = sensor; }
void set_gain(AS7343Gain gain) { gain_ = gain; }
void set_gain(esphome::optional<unsigned int> g);
void set_atime(uint8_t atime) { atime_ = atime; }
void set_astep(uint16_t astep) { astep_ = astep; }
@ -51,7 +50,7 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice {
float get_gain_multiplier(AS7343Gain gain);
bool read_channels(uint16_t *data);
bool read_18_channels(uint16_t *data);
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_();
@ -109,6 +108,14 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice {
uint8_t atime_;
uint16_t channel_readings_[AS7343_NUM_CHANNELS];
float channel_basic_readings_[AS7343_NUM_CHANNELS];
float get_tint_();
void optimizer_(float max_TINT);
void direct_config_3_chain_();
void setup_tint_(float tint);
public:
bool as7352_set_integration_time_us(uint32_t time_us);
};
} // namespace as7343

File diff suppressed because it is too large Load diff

View file

@ -135,10 +135,9 @@ union AS7343RegAStatus {
AS7343Gain again_status : 4;
uint8_t reserved_4_6 : 3;
uint8_t asat_status : 1;
} __attribute__((packed));
};
} // namespace as7343
} // namespace esphome