mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	[ms5611] Re-implement conversion from ADC readings to sensor values (#2665)
This commit is contained in:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							5ff7c8418c
						
					
				
				
					commit
					f310cacd41
				
			| @@ -75,30 +75,48 @@ void MS5611Component::read_pressure_(uint32_t raw_temperature) { | |||||||
|   const uint32_t raw_pressure = (uint32_t(bytes[0]) << 16) | (uint32_t(bytes[1]) << 8) | (uint32_t(bytes[2])); |   const uint32_t raw_pressure = (uint32_t(bytes[0]) << 16) | (uint32_t(bytes[1]) << 8) | (uint32_t(bytes[2])); | ||||||
|   this->calculate_values_(raw_temperature, raw_pressure); |   this->calculate_values_(raw_temperature, raw_pressure); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Calculations are taken from the datasheet which can be found here: | ||||||
|  | // https://www.te.com/commerce/DocumentDelivery/DDEController?Action=showdoc&DocId=Data+Sheet%7FMS5611-01BA03%7FB3%7Fpdf%7FEnglish%7FENG_DS_MS5611-01BA03_B3.pdf%7FCAT-BLPS0036 | ||||||
|  | // Sections PRESSURE AND TEMPERATURE CALCULATION and SECOND ORDER TEMPERATURE COMPENSATION | ||||||
|  | // Variable names below match variable names from the datasheet but lowercased | ||||||
| void MS5611Component::calculate_values_(uint32_t raw_temperature, uint32_t raw_pressure) { | void MS5611Component::calculate_values_(uint32_t raw_temperature, uint32_t raw_pressure) { | ||||||
|   const int32_t d_t = int32_t(raw_temperature) - (uint32_t(this->prom_[4]) << 8); |   const uint32_t c1 = uint32_t(this->prom_[0]); | ||||||
|   float temperature = (2000 + (int64_t(d_t) * this->prom_[5]) / 8388608.0f) / 100.0f; |   const uint32_t c2 = uint32_t(this->prom_[1]); | ||||||
|  |   const uint16_t c3 = uint16_t(this->prom_[2]); | ||||||
|  |   const uint16_t c4 = uint16_t(this->prom_[3]); | ||||||
|  |   const int32_t c5 = int32_t(this->prom_[4]); | ||||||
|  |   const uint16_t c6 = uint16_t(this->prom_[5]); | ||||||
|  |   const uint32_t d1 = raw_pressure; | ||||||
|  |   const int32_t d2 = raw_temperature; | ||||||
|  |  | ||||||
|   float pressure_offset = (uint32_t(this->prom_[1]) << 16) + ((this->prom_[3] * d_t) >> 7); |   // Promote dt to 64 bit here to make the math below cleaner | ||||||
|   float pressure_sensitivity = (uint32_t(this->prom_[0]) << 15) + ((this->prom_[2] * d_t) >> 8); |   const int64_t dt = d2 - (c5 << 8); | ||||||
|  |   int32_t temp = (2000 + ((dt * c6) >> 23)); | ||||||
|  |  | ||||||
|   if (temperature < 20.0f) { |   int64_t off = (c2 << 16) + ((dt * c4) >> 7); | ||||||
|     const float t2 = (d_t * d_t) / 2147483648.0f; |   int64_t sens = (c1 << 15) + ((dt * c3) >> 8); | ||||||
|     const float temp20 = (temperature - 20.0f) * 100.0f; |  | ||||||
|     float pressure_offset_2 = 2.5f * temp20 * temp20; |   if (temp < 2000) { | ||||||
|     float pressure_sensitivity_2 = 1.25f * temp20 * temp20; |     const int32_t t2 = (dt * dt) >> 31; | ||||||
|     if (temp20 < -15.0f) { |     int32_t off2 = ((5 * (temp - 2000) * (temp - 2000)) >> 1); | ||||||
|       const float temp15 = (temperature + 15.0f) * 100.0f; |     int32_t sens2 = ((5 * (temp - 2000) * (temp - 2000)) >> 2); | ||||||
|       pressure_offset_2 += 7.0f * temp15; |     if (temp < -1500) { | ||||||
|       pressure_sensitivity_2 += 5.5f * temp15; |       off2 = (off2 + 7 * (temp + 1500) * (temp + 1500)); | ||||||
|  |       sens2 = sens2 + ((11 * (temp + 1500) * (temp + 1500)) >> 1); | ||||||
|     } |     } | ||||||
|     temperature -= t2; |     temp = temp - t2; | ||||||
|     pressure_offset -= pressure_offset_2; |     off = off - off2; | ||||||
|     pressure_sensitivity -= pressure_sensitivity_2; |     sens = sens - sens2; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   const float pressure = ((raw_pressure * pressure_sensitivity) / 2097152.0f - pressure_offset) / 3276800.0f; |   // Here we multiply unsigned 32-bit by signed 64-bit using signed 64-bit math. | ||||||
|  |   // Possible ranges of D1 and SENS from the datasheet guarantee | ||||||
|  |   // that this multiplication does not overflow | ||||||
|  |   const int32_t p = ((((d1 * sens) >> 21) - off) >> 15); | ||||||
|  |  | ||||||
|  |   const float temperature = temp / 100.0f; | ||||||
|  |   const float pressure = p / 100.0f; | ||||||
|   ESP_LOGD(TAG, "Got temperature=%0.02f°C pressure=%0.01fhPa", temperature, pressure); |   ESP_LOGD(TAG, "Got temperature=%0.02f°C pressure=%0.01fhPa", temperature, pressure); | ||||||
|  |  | ||||||
|   if (this->temperature_sensor_ != nullptr) |   if (this->temperature_sensor_ != nullptr) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user