This commit is contained in:
Anton Viktorov 2024-03-01 17:49:53 +01:00
parent 56237937ff
commit ac155e6353
4 changed files with 72 additions and 91 deletions

View file

@ -24,10 +24,11 @@ static constexpr float CHANNEL_BASIC_CORRECTIONS[NUM_USEFUL_CHANNELS] = {
1.055464349, 1.043509797, 1.029576268, 1.0175052, 1.00441899, 0.987356499, 0.957597044, 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}; 0.995863485, 1.014628964, 0.996500814, 0.933072749, 1.052236338, 0.999570232};
static const float OFFSETS[NUM_USEFUL_CHANNELS] = {0.000281, 0.000281, 0.000281, 0.000281, 0.000281, 0.000281,
0.000281, 0.000281, 0.000422, 0.000281, 0.000422, 0.000281};
static constexpr float CHANNEL_NM[NUM_USEFUL_CHANNELS] = {405, 425, 450, 475, 515, 555, 550, static constexpr float CHANNEL_NM[NUM_USEFUL_CHANNELS] = {405, 425, 450, 475, 515, 555, 550,
600, 640, 690, 745, 855, 718}; 600, 640, 690, 745, 855, 718};
// 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_NM_WIDTH[NUM_USEFUL_CHANNELS] = {30, 22, 55, 30, 40, 100, 35, 80, 50, 55, 60, 54, 0}; static constexpr float CHANNEL_NM_WIDTH[NUM_USEFUL_CHANNELS] = {30, 22, 55, 30, 40, 100, 35, 80, 50, 55, 60, 54, 0};
// Irradiation in mW/m² per basic count // Irradiation in mW/m² per basic count
@ -40,6 +41,8 @@ static constexpr float PHOTON_ENERGIES[NUM_USEFUL_CHANNELS] = {
4.9048E-19f, 4.67399E-19f, 4.41432E-19f, 4.18199E-19f, 3.85718E-19f, 3.57918E-19f, 3.61172E-19f, 4.9048E-19f, 4.67399E-19f, 4.41432E-19f, 4.18199E-19f, 3.85718E-19f, 3.57918E-19f, 3.61172E-19f,
3.31074E-19f, 3.10382E-19f, 2.87891E-19f, 2.66637E-19f, 2.32333E-19f, 2.76664E-19f}; 3.31074E-19f, 3.10382E-19f, 2.87891E-19f, 2.66637E-19f, 2.32333E-19f, 2.76664E-19f};
// 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_CONTRIBUTION[NUM_USEFUL_CHANNELS] = {0.069385773,
0.04848841, 0.04848841,
0.114486525, 0.114486525,
@ -54,16 +57,6 @@ static constexpr float CHANNEL_CONTRIBUTION[NUM_USEFUL_CHANNELS] = {0.069385773,
0.059160501, 0.059160501,
0}; 0};
// constexpr std::array<float, NUM_USEFUL_CHANNELS> fill_photon_energy() {
// std::array<float, NUM_USEFUL_CHANNELS> v{0};
// for(int i = 0; i < NUM_USEFUL_CHANNELS; ++i) {
// v[i] = CHANNEL_NM[i]> 0 ? CONST_H * CONST_C / (CHANNEL_NM[i] * 1e9) : 0;
// }
// return v;
// }
// constexpr std::array<float, NUM_USEFUL_CHANNELS> v = fill_photon_energy();
void AS7343Component::setup() { void AS7343Component::setup() {
ESP_LOGCONFIG(TAG, "Setting up AS7343..."); ESP_LOGCONFIG(TAG, "Setting up AS7343...");
LOG_I2C_DEVICE(this); LOG_I2C_DEVICE(this);
@ -123,6 +116,8 @@ void AS7343Component::dump_config() {
LOG_SENSOR(" ", "F8", this->f8_); LOG_SENSOR(" ", "F8", this->f8_);
LOG_SENSOR(" ", "NIR", this->nir_); LOG_SENSOR(" ", "NIR", this->nir_);
LOG_SENSOR(" ", "Clear", this->clear_); LOG_SENSOR(" ", "Clear", this->clear_);
LOG_SENSOR(" ", "Clear", this->clear_);
LOG_SENSOR(" ", "Clear", this->clear_);
} }
float AS7343Component::get_setup_priority() const { return setup_priority::DATA; } float AS7343Component::get_setup_priority() const { return setup_priority::DATA; }
@ -157,10 +152,10 @@ void AS7343Component::update() {
float irradiance; float irradiance;
float lux; float lux;
this->calculate_irradiance(tint_ms, gain_x, irradiance, lux, gain); this->calculate_irradiance(tint_ms, gain_x, irradiance, lux, gain);
ESP_LOGD(TAG, " ,Irradiance, %f, W/m^2", irradiance); ESP_LOGD(TAG, " ,Irradiance, %f, W/m²", irradiance);
ESP_LOGD(TAG, " ,Lux solar , %f, lx", lux); ESP_LOGD(TAG, " ,Lux solar , %f, lx", lux);
float par = this->calculate_ppfd(tint_ms, gain_x, gain); float ppfd = this->calculate_ppfd(tint_ms, gain_x, gain);
ESP_LOGD(TAG, " ,PAR , %.2f", par); ESP_LOGD(TAG, " ,PPFD , %.2f, µmol/sm²", ppfd);
if (this->illuminance_ != nullptr) { if (this->illuminance_ != nullptr) {
this->illuminance_->publish_state(lux); this->illuminance_->publish_state(lux);
@ -170,6 +165,10 @@ void AS7343Component::update() {
this->irradiance_->publish_state(irradiance); this->irradiance_->publish_state(irradiance);
} }
if (this->ppfd_ != nullptr) {
this->ppfd_->publish_state(ppfd);
}
// for (uint8_t i = 0; i < NUM_USEFUL_CHANNELS; i++) { // for (uint8_t i = 0; i < NUM_USEFUL_CHANNELS; i++) {
// this->channel_readings_[CHANNEL_IDX[1]] /= CHANNEL_SENS[i] * 65535; // this->channel_readings_[CHANNEL_IDX[1]] /= CHANNEL_SENS[i] * 65535;
// } // }
@ -216,6 +215,9 @@ void AS7343Component::update() {
3; 3;
this->clear_->publish_state(clear); this->clear_->publish_state(clear);
} }
if (this->saturated_ != nullptr) {
this->saturated_->publish_state(this->readings_saturated_);
}
} }
AS7343Gain AS7343Component::get_gain() { AS7343Gain AS7343Component::get_gain() {
@ -254,8 +256,10 @@ bool AS7343Component::setup_astep(uint16_t astep) {
return this->write_byte_16((uint8_t) AS7343Registers::ASTEP_LSB, swap_bytes(astep)); return this->write_byte_16((uint8_t) AS7343Registers::ASTEP_LSB, swap_bytes(astep));
} }
static const float OFFSETS[NUM_USEFUL_CHANNELS] = {0.000281, 0.000281, 0.000281, 0.000281, 0.000281, 0.000281, bool AS7343Component::change_gain(AS7343Gain gain) {
0.000281, 0.000281, 0.000422, 0.000281, 0.000422, 0.000281}; 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 AS7343Component::calculate_ppfd(float tint_ms, float gain_x, AS7343Gain gain) {
float par = 0; float par = 0;
@ -316,6 +320,7 @@ bool AS7343Component::read_channels(uint16_t *data) {
if (astatus.asat_status) { if (astatus.asat_status) {
ESP_LOGW(TAG, "AS7343 affected by analog or digital saturation. Readings are not reliable."); ESP_LOGW(TAG, "AS7343 affected by analog or digital saturation. Readings are not reliable.");
} }
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, this->channel_readings_, AS7343_NUM_CHANNELS);
} }

View file

@ -9,57 +9,6 @@
namespace esphome { namespace esphome {
namespace as7343 { namespace as7343 {
static const uint8_t AS7341_CONFIG = 0x70;
static const uint8_t AS7341_LED = 0x74;
static const uint8_t AS7341_ENABLE = 0x80;
static const uint8_t AS7341_ATIME = 0x81;
static const uint8_t AS7341_WTIME = 0x83;
static const uint8_t AS7341_AUXID = 0x90;
static const uint8_t AS7341_REVID = 0x91;
static const uint8_t AS7341_ID = 0x92;
static const uint8_t AS7341_STATUS = 0x93;
// static const uint8_t AS7341_CH0_DATA_L = 0x95;
// static const uint8_t AS7341_CH0_DATA_H = 0x96;
// static const uint8_t AS7341_CH1_DATA_L = 0x97;
// static const uint8_t AS7341_CH1_DATA_H = 0x98;
// static const uint8_t AS7341_CH2_DATA_L = 0x99;
// static const uint8_t AS7341_CH2_DATA_H = 0x9A;
// static const uint8_t AS7341_CH3_DATA_L = 0x9B;
// static const uint8_t AS7341_CH3_DATA_H = 0x9C;
// static const uint8_t AS7341_CH4_DATA_L = 0x9D;
// static const uint8_t AS7341_CH4_DATA_H = 0x9E;
// static const uint8_t AS7341_CH5_DATA_L = 0x9F;
// static const uint8_t AS7341_CH5_DATA_H = 0xA0;
// static const uint8_t AS7341_STATUS2 = 0xA3;
// static const uint8_t AS7341_CFG1 = 0xAA; ///< Controls ADC Gain
// static const uint8_t AS7341_CFG6 = 0xAF; // Stores SMUX command
// static const uint8_t AS7341_CFG9 = 0xB2; // Config for system interrupts (SMUX, Flicker detection)
// static const uint8_t AS7341_ASTEP = 0xCA; // LSB
// static const uint8_t AS7341_ASTEP_MSB = 0xCB; // MSB
// enum AS7343AdcChannel {
// AS7343_ADC_CHANNEL_0,
// AS7343_ADC_CHANNEL_1,
// AS7343_ADC_CHANNEL_2,
// AS7343_ADC_CHANNEL_3,
// AS7343_ADC_CHANNEL_4,
// AS7343_ADC_CHANNEL_5,
// };
// enum AS7343SmuxCommand {
// AS7343_SMUX_CMD_ROM_RESET, ///< ROM code initialization of SMUX
// AS7343_SMUX_CMD_READ, ///< Read SMUX configuration to RAM from SMUX chain
// AS7343_SMUX_CMD_WRITE, ///< Write SMUX configuration from RAM to SMUX chain
// };
class AS7343Component : public PollingComponent, public i2c::I2CDevice { class AS7343Component : public PollingComponent, public i2c::I2CDevice {
public: public:
void setup() override; void setup() override;
@ -82,6 +31,8 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice {
void set_clear_sensor(sensor::Sensor *clear_sensor) { clear_ = clear_sensor; } void set_clear_sensor(sensor::Sensor *clear_sensor) { clear_ = clear_sensor; }
void set_illuminance_sensor(sensor::Sensor *sensor) { illuminance_ = sensor; } void set_illuminance_sensor(sensor::Sensor *sensor) { illuminance_ = sensor; }
void set_irradiance_sensor(sensor::Sensor *sensor) { irradiance_ = sensor; } void set_irradiance_sensor(sensor::Sensor *sensor) { irradiance_ = sensor; }
void set_ppfd_sensor(sensor::Sensor *sensor) { ppfd_ = sensor; }
void set_saturation_sensor(sensor::Sensor *sensor) { this->saturated_ = sensor; }
void set_gain(AS7343Gain gain) { gain_ = gain; } void set_gain(AS7343Gain gain) { gain_ = gain; }
void set_gain(esphome::optional<unsigned int> g); void set_gain(esphome::optional<unsigned int> g);
@ -96,19 +47,15 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice {
bool setup_atime(uint8_t atime); bool setup_atime(uint8_t atime);
bool setup_astep(uint16_t astep); bool setup_astep(uint16_t astep);
bool change_gain(AS7343Gain gain);
float get_gain_multiplier(AS7343Gain gain); float get_gain_multiplier(AS7343Gain gain);
// uint16_t read_channel(AS7343AdcChannel channel);
bool read_channels(uint16_t *data); bool read_channels(uint16_t *data);
float calculate_ppfd(float tint_ms, float gain_x, AS7343Gain gain); 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); void calculate_irradiance(float tint_ms, float gain_x, float &irradiance, float &lux, AS7343Gain gain);
float calculate_spectre_(); float calculate_spectre_();
// void set_smux_low_channels(bool enable);
// bool set_smux_command(AS7343SmuxCommand command);
// void configure_smux_low_channels();
// void configure_smux_high_channels();
// bool enable_smux();
bool wait_for_data(uint16_t timeout = 1000); bool wait_for_data(uint16_t timeout = 1000);
bool is_data_ready(); bool is_data_ready();
bool enable_power(bool enable); bool enable_power(bool enable);
@ -123,6 +70,7 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice {
protected: protected:
void set_bank_for_reg_(AS7343Registers reg = AS7343Registers::ENABLE); void set_bank_for_reg_(AS7343Registers reg = AS7343Registers::ENABLE);
bool bank_{false}; bool bank_{false};
bool readings_saturated_{false};
sensor::Sensor *f1_{nullptr}; sensor::Sensor *f1_{nullptr};
sensor::Sensor *f2_{nullptr}; sensor::Sensor *f2_{nullptr};
@ -139,6 +87,9 @@ class AS7343Component : public PollingComponent, public i2c::I2CDevice {
sensor::Sensor *clear_{nullptr}; sensor::Sensor *clear_{nullptr};
sensor::Sensor *illuminance_{nullptr}; sensor::Sensor *illuminance_{nullptr};
sensor::Sensor *irradiance_{nullptr}; sensor::Sensor *irradiance_{nullptr};
sensor::Sensor *ppfd_{nullptr};
sensor::Sensor *saturated_{nullptr};
sensor::Sensor *bf1_{nullptr}; sensor::Sensor *bf1_{nullptr};
sensor::Sensor *bf2_{nullptr}; sensor::Sensor *bf2_{nullptr};

View file

@ -5,19 +5,19 @@ namespace esphome {
namespace as7343 { namespace as7343 {
const float AS7343_GAIN_CORRECTION[13][12+1] PROGMEM = { 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.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},// 0.5x
{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.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},// 1x
{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.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},// 2x
{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.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},// 4x
{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.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},// 8x
{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.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},// 16x
{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.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},// 32x
{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.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},// 64x
{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.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},// 128x
{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.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},// 256x
{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},// 512x
{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},// 1024x
{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},// 2048x
}; };

View file

@ -39,11 +39,14 @@ CONF_F8 = "f8"
CONF_NIR = "nir" CONF_NIR = "nir"
CONF_CLEAR = "clear" CONF_CLEAR = "clear"
CONF_IRRADIANCE = "irradiance" CONF_IRRADIANCE = "irradiance"
CONF_DIGITAL_SATURATION = "digital_saturation" CONF_PPFD = "ppfd"
CONF_ANALOG_SATURATION = "analog_saturation" CONF_SATURATION = "saturation"
UNIT_COUNTS = "#" UNIT_COUNTS = "#"
UNIT_IRRADIANCE = "W/m²" UNIT_IRRADIANCE = "W/m²"
UNIT_PPFD = "µmol/sm²"
ICON_SATURATION = "mdi:weather-sunny-alert"
AS7343_GAIN = as7343_ns.enum("AS7343Gain") AS7343_GAIN = as7343_ns.enum("AS7343Gain")
GAIN_OPTIONS = { GAIN_OPTIONS = {
@ -67,7 +70,7 @@ SENSOR_SCHEMA = cv.maybe_simple_value(
sensor.sensor_schema( sensor.sensor_schema(
unit_of_measurement=UNIT_COUNTS, unit_of_measurement=UNIT_COUNTS,
icon=ICON_BRIGHTNESS_5, icon=ICON_BRIGHTNESS_5,
accuracy_decimals=4, accuracy_decimals=0,
device_class=DEVICE_CLASS_ILLUMINANCE, device_class=DEVICE_CLASS_ILLUMINANCE,
state_class=STATE_CLASS_MEASUREMENT, state_class=STATE_CLASS_MEASUREMENT,
), ),
@ -115,6 +118,26 @@ CONFIG_SCHEMA = (
), ),
key=CONF_NAME, key=CONF_NAME,
), ),
cv.Optional(CONF_PPFD): cv.maybe_simple_value(
sensor.sensor_schema(
unit_of_measurement=UNIT_PPFD,
icon=ICON_BRIGHTNESS_5,
accuracy_decimals=0,
device_class=DEVICE_CLASS_ILLUMINANCE,
state_class=STATE_CLASS_MEASUREMENT,
),
key=CONF_NAME,
),
cv.Optional(CONF_SATURATION): cv.maybe_simple_value(
sensor.sensor_schema(
unit_of_measurement=UNIT_COUNTS,
icon=ICON_SATURATION,
accuracy_decimals=0,
device_class=DEVICE_CLASS_ILLUMINANCE,
state_class=STATE_CLASS_MEASUREMENT,
),
key=CONF_NAME,
),
} }
) )
.extend(cv.polling_component_schema("60s")) .extend(cv.polling_component_schema("60s"))
@ -137,6 +160,8 @@ SENSORS = {
CONF_CLEAR: "set_clear_sensor", CONF_CLEAR: "set_clear_sensor",
CONF_ILLUMINANCE: "set_illuminance_sensor", CONF_ILLUMINANCE: "set_illuminance_sensor",
CONF_IRRADIANCE: "set_irradiance_sensor", CONF_IRRADIANCE: "set_irradiance_sensor",
CONF_PPFD: "set_ppfd_sensor",
CONF_SATURATION: "set_saturation_sensor",
} }