module: calculate UVA light intensity correctly for rset != RSET_240K

- compensation for rset != RSET_240K was wrong, it increased UVA power/ADC step for rset > RSET_240K
- UVA power/ADC step should have been decreasing as refresh time (sampling time) got longer
- same behavior as with integration_time setting, that works correctly
This commit is contained in:
cn 2019-09-19 01:18:42 +02:00
parent df23b9905b
commit 4eda08a9c9
3 changed files with 24 additions and 22 deletions

View File

@ -19,6 +19,7 @@ Not all functions of the chip are supported, especially not the interrupt handli
In September 2019 it was discovered (and fixed) that:
- previously the sensor was never shutdown between measurements which wastes power but still takes measurements successfully
- the UVA light intensity was calculated wrongly (too high) for `rset != RSET_240K` due to wrong compensation: higher `rset` leads to higher sampling time leads to higher absolute ADC step counts which *should* lead to every ADC step indicating a smaller amount of `W/(m*m)` of UVA power and a higher precision of the final UVA power but it wrongly behaved the opposite way. The `integration_time` worked correctly all the time.
## License

View File

@ -85,9 +85,9 @@ class TestVeml6070(snapshottest.TestCase):
0x38+0: [0x06, 0x06]
})
veml = veml6070.Veml6070()
self.assertEqual(veml.get_uva_light_intensity(), 0x0106 * 0.05625 / 1)
self.assertEqual(veml.get_uva_light_intensity(), 0x0106 * (0.1/0.1125) * 0.05 / 1)
veml.set_integration_time(veml6070.INTEGRATIONTIME_4T)
self.assertEqual(veml.get_uva_light_intensity(), 0x0106 * 0.05625 / 4)
self.assertEqual(veml.get_uva_light_intensity(), 0x0106 * (0.1/0.1125) * 0.05 / 4)
self.assertMatchSnapshot(mockbus._log)
def test_get_refresh_time(self):

View File

@ -23,6 +23,14 @@ INTEGRATIONTIME_4T = 0x03
# Note: 0.1 seconds (100 ms) are applicable for RSET_240K and INTEGRATIONTIME_1T
RSET_TO_REFRESHTIME_SCALE = 0.1 / RSET_240K
# The refresh time in seconds for which NORMALIZED_UVA_SENSITIVITY
# is applicable to a step count
NORMALIZED_REFRESHTIME = 0.1
# The UVA sensitivity in W/(m*m)/step which is applicable to a step count
# normalized to the NORMALIZED_REFRESHTIME, for RSET_240K and INTEGRATIONTIME_1T
NORMALIZED_UVA_SENSITIVITY = 0.05
class Veml6070(object):
def __init__(self, i2c_bus=1, sensor_address=ADDR_L, rset=RSET_270K, integration_time=INTEGRATIONTIME_1T):
@ -60,8 +68,19 @@ class Veml6070(object):
return (msb << 8) | lsb
def get_uva_light_intensity(self):
uv = self.get_uva_light_intensity_raw()
return uv * self.get_uva_light_sensitivity()
"""
returns the UVA light intensity in Watt per square meter (W/(m*m))
"""
raw_data = self.get_uva_light_intensity_raw()
# normalize raw data (step count sampled in get_refresh_time()) into the
# linearly scaled normalized data (step count sampled in 0.1s) for which
# we know the UVA sensitivity
normalized_data = raw_data * NORMALIZED_REFRESHTIME / self.get_refresh_time()
# now we can calculate the absolute UVA power detected combining
# normalized data with known UVA sensitivity for this data
return normalized_data * NORMALIZED_UVA_SENSITIVITY # in W/(m*m)
def get_command_byte(self):
"""
@ -83,21 +102,3 @@ class Veml6070(object):
INTEGRATIONTIME_4T: 4
}
return self.rset * RSET_TO_REFRESHTIME_SCALE * case_refresh_it[self.integration_time]
def get_uva_light_sensitivity(self):
"""
returns UVA light sensitivity in W/(m*m)/step
"""
case_sens_rset = {
RSET_240K: 0.05,
RSET_270K: 0.05625,
RSET_300K: 0.0625,
RSET_600K: 0.125
}
case_sens_it = {
INTEGRATIONTIME_1_2T: 0.5,
INTEGRATIONTIME_1T: 1,
INTEGRATIONTIME_2T: 2,
INTEGRATIONTIME_4T: 4
}
return case_sens_rset[self.rset] / case_sens_it[self.integration_time]