mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	tcs34725: Remove IR compensation and improve illuminance and color temperature handling in extreme conditions (#7492)
This commit is contained in:
		| @@ -73,12 +73,10 @@ float TCS34725Component::get_setup_priority() const { return setup_priority::DAT | |||||||
|  *  @return Color temperature in degrees Kelvin |  *  @return Color temperature in degrees Kelvin | ||||||
|  */ |  */ | ||||||
| void TCS34725Component::calculate_temperature_and_lux_(uint16_t r, uint16_t g, uint16_t b, uint16_t c) { | void TCS34725Component::calculate_temperature_and_lux_(uint16_t r, uint16_t g, uint16_t b, uint16_t c) { | ||||||
|   float r2, g2, b2; /* RGB values minus IR component */ |  | ||||||
|   float sat; /* Digital saturation level */ |   float sat; /* Digital saturation level */ | ||||||
|   float ir;         /* Inferred IR content */ |  | ||||||
|  |  | ||||||
|   this->illuminance_ = 0;  // Assign 0 value before calculation |   this->illuminance_ = NAN; | ||||||
|   this->color_temperature_ = 0; |   this->color_temperature_ = NAN; | ||||||
|  |  | ||||||
|   const float ga = this->glass_attenuation_;            // Glass Attenuation Factor |   const float ga = this->glass_attenuation_;            // Glass Attenuation Factor | ||||||
|   static const float DF = 310.f;                        // Device Factor |   static const float DF = 310.f;                        // Device Factor | ||||||
| @@ -87,6 +85,9 @@ void TCS34725Component::calculate_temperature_and_lux_(uint16_t r, uint16_t g, u | |||||||
|   static const float B_COEF = -0.444f;                  // |   static const float B_COEF = -0.444f;                  // | ||||||
|   static const float CT_COEF = 3810.f;                  // Color Temperature Coefficient |   static const float CT_COEF = 3810.f;                  // Color Temperature Coefficient | ||||||
|   static const float CT_OFFSET = 1391.f;                // Color Temperatuer Offset |   static const float CT_OFFSET = 1391.f;                // Color Temperatuer Offset | ||||||
|  |   static const float MAX_ILLUMINANCE = 100000.0f;       // Cap illuminance at 100,000 lux | ||||||
|  |   static const float MAX_COLOR_TEMPERATURE = 15000.0f;  // Maximum expected color temperature in Kelvin | ||||||
|  |   static const float MIN_COLOR_TEMPERATURE = 1000.0f;   // Maximum reasonable color temperature in Kelvin | ||||||
|  |  | ||||||
|   if (c == 0) { |   if (c == 0) { | ||||||
|     return; |     return; | ||||||
| @@ -137,45 +138,48 @@ void TCS34725Component::calculate_temperature_and_lux_(uint16_t r, uint16_t g, u | |||||||
|   if (c >= sat) { |   if (c >= sat) { | ||||||
|     if (this->integration_time_auto_) { |     if (this->integration_time_auto_) { | ||||||
|       ESP_LOGI(TAG, "Saturation too high, sample discarded, autogain ongoing"); |       ESP_LOGI(TAG, "Saturation too high, sample discarded, autogain ongoing"); | ||||||
|  |       return; | ||||||
|     } else { |     } else { | ||||||
|       ESP_LOGW( |  | ||||||
|           TAG, |  | ||||||
|           "Saturation too high, sample with saturation %.1f and clear %d treat values carefully or use grey filter", |  | ||||||
|           sat, c); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   /* AMS RGB sensors have no IR channel, so the IR content must be */ |  | ||||||
|   /* calculated indirectly. */ |  | ||||||
|   ir = ((r + g + b) > c) ? (r + g + b - c) / 2 : 0; |  | ||||||
|  |  | ||||||
|   /* Remove the IR component from the raw RGB values */ |  | ||||||
|   r2 = r - ir; |  | ||||||
|   g2 = g - ir; |  | ||||||
|   b2 = b - ir; |  | ||||||
|  |  | ||||||
|   // discarding super low values? not recemmonded, and avoided by using auto gain. |  | ||||||
|   if (r2 == 0) { |  | ||||||
|     // legacy code |  | ||||||
|     if (!this->integration_time_auto_) { |  | ||||||
|       ESP_LOGW(TAG, |       ESP_LOGW(TAG, | ||||||
|                "No light detected on red channel, switch to auto gain or adjust timing, values will be unreliable"); |                "Saturation too high, sample with saturation %.1f and clear %d lux/color temperature cannot reliably " | ||||||
|  |                "calculated, reduce integration/gain or use a grey filter.", | ||||||
|  |                sat, c); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Lux Calculation (DN40 3.2) |   // Lux Calculation (DN40 3.2) | ||||||
|  |  | ||||||
|   float g1 = R_COEF * r2 + G_COEF * g2 + B_COEF * b2; |   float g1 = R_COEF * (float) r + G_COEF * (float) g + B_COEF * (float) b; | ||||||
|   float cpl = (this->integration_time_ * this->gain_) / (ga * DF); |   float cpl = (this->integration_time_ * this->gain_) / (ga * DF); | ||||||
|   this->illuminance_ = g1 / cpl; |  | ||||||
|  |   this->illuminance_ = std::max(g1 / cpl, 0.0f); | ||||||
|  |  | ||||||
|  |   if (this->illuminance_ > MAX_ILLUMINANCE) { | ||||||
|  |     ESP_LOGW(TAG, "Calculated illuminance greater than limit (%f), setting to NAN", this->illuminance_); | ||||||
|  |     this->illuminance_ = NAN; | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (r == 0) { | ||||||
|  |     ESP_LOGW(TAG, "Red channel is zero, cannot compute color temperature"); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // Color Temperature Calculation (DN40) |   // Color Temperature Calculation (DN40) | ||||||
|   /* A simple method of measuring color temp is to use the ratio of blue */ |   /* A simple method of measuring color temp is to use the ratio of blue */ | ||||||
|   /* to red light, taking IR cancellation into account. */ |   /* to red light. */ | ||||||
|   this->color_temperature_ = (CT_COEF * b2) / /** Color temp coefficient. */ |  | ||||||
|                                  r2 + |   this->color_temperature_ = (CT_COEF * (float) b) / (float) r + CT_OFFSET; | ||||||
|                              CT_OFFSET; /** Color temp offset. */ |  | ||||||
|  |   // Ensure the color temperature stays within reasonable bounds | ||||||
|  |   if (this->color_temperature_ < MIN_COLOR_TEMPERATURE) { | ||||||
|  |     ESP_LOGW(TAG, "Calculated color temperature value too low (%f), setting to NAN", this->color_temperature_); | ||||||
|  |     this->color_temperature_ = NAN; | ||||||
|  |   } else if (this->color_temperature_ > MAX_COLOR_TEMPERATURE) { | ||||||
|  |     ESP_LOGW(TAG, "Calculated color temperature value too high (%f), setting to NAN", this->color_temperature_); | ||||||
|  |     this->color_temperature_ = NAN; | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void TCS34725Component::update() { | void TCS34725Component::update() { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user