mirror of
https://github.com/esphome/esphome.git
synced 2025-01-09 14:21:46 +01:00
more experiments
This commit is contained in:
parent
ac155e6353
commit
63cfcc8725
4 changed files with 2036 additions and 879 deletions
|
@ -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,7 +48,7 @@ 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,
|
||||
static constexpr float CHANNEL_ENERGY_CONTRIBUTION[NUM_USEFUL_CHANNELS] = {0.069385773,
|
||||
0.04848841,
|
||||
0.114486525,
|
||||
0.059160501,
|
||||
|
@ -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);
|
||||
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];
|
||||
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;
|
||||
}
|
||||
lux = irradiance / 0.0079;
|
||||
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];
|
||||
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]);
|
||||
}
|
||||
// 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
|
||||
|
|
|
@ -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
|
@ -139,6 +139,5 @@ union AS7343RegAStatus {
|
|||
} __attribute__((packed));
|
||||
};
|
||||
|
||||
|
||||
} // namespace as7343
|
||||
} // namespace esphome
|
||||
|
|
Loading…
Reference in a new issue