Closed DonBower closed 3 years ago
nope, they are unitless 'counts' - some sensors give lux or uvi - these do not. they just measure 'how much light the sensors got' which can then be calibrated against a known source if you want.
@jedgarpark did you come up with a rough count-to-UVI metric?
@ladyada @DonBower The CircuitPython library defaults the board to 3x gain, 16-bit values where a count of 95 is one UVI. This doesn't include the cloud, window, or altitude factors. And, it'll be different if you set to a different gain/bit-depth. @CedarGroveStudios said he may be looking into adding the conversion to the library.
@ladyada @DonBower @jedgarpark The datasheet indicates a linear relationship between the factors that JP mentioned. I had planned to suggest a UVI getter for the library but don't have a sensor on-hand to test. JP: can I send you a modified library for testing? ... sometime this evening. I have quite a few drifts of fresh snow to clear today.
@CedarGroveStudios that sounds great, happy to test. No hurry -- beware the ice weasels
I’ll be happy to share results from an end user perspective.
After further reading, there may be an issue with the library's 100ms integration time default versus the 25ms acquisition time for 16-bit data. Since I'm anticipating a few troubleshooting steps, it'll be a more efficient use of time if I have one in-hand. They're currently out-of-stock. I'll place an order when they become available.
I'm thinking that the rule of thumb of 1 UVI = 95 counts @ 16-bit, x3 gain, 100ms integration is okay for now since the relationship between the count value, irradiation level (uW/cm^2), and UVI is purported to be linear. JP's empirical tests using that factor showed that the count values were approximately within range.
No ice weasel surprises today.
@ladyada @jedgarpark @CedarGroveStudios From what I can glean from the code, and I am somewhat speculating here because I don't have experience in writing drivers, it appears that I have all the defaults you mentioned above set for my sensor:
>>> print(ltr.gain)
1
>>> print(ltr.resolution)
4
>>> print(ltr.measurement_delay)
2
So to check for understanding, with these settings, the ltr.uvs
value is expressed in uW/cm^2, and if I divide that by 95, i can get a UV Index number. Do I have that correct?
FYI, in the EPAs guide to the UV Index, document page 5, it states One UV Index unit is equivalent to 25 milliWatts per square meter.
25mW/m^2 (isn't this 2.5uw/cm^2?)
@DonBower @ladyada @jedgarpark: Yes, you discovered the values used to set the internal registers to the driver library defaults. The "decoder rings" for the classes Gain, Resolution, and Measurement_Delay look like this:
Gain Register_Value
1X 0
3X 1 (library default)
6X 2
9X 3
18X 4
Resolution Register_Value
20-bit 0
19-bit 1
18-bit 2
17-bit 3
16-bit 4 (library default)
13-bit 5
Measurement_Delay Register Value
25ms 0
50ms 1
100ms 2 (library default)
200ms 3
500ms 4
1000ms 5
2000ms 6
The default Measurement_Delay of 100ms (the manufacturer instead calls this Measurement Rate as well as Integration Time) is 4 times longer than the measurement rate needed for 16-bit resolution. I don't know if that factor has an effect on the accumulation of "counts" when reading UV irradiance.
And yes, I also found in various sources that a UV Index of 1.0 is equivalent to the irradiance level of 25mW/m^2
which indeed is equal to 2.5uW/cm^2
as you noted. For the LTR-390UV running at 18X/20-bit/400ms
, that's a count value of about 25 (using Fig. 4.5), quite a bit different than the 2300 counts/UVI
sensitivity listed in Fig 4.6 and Table 4.5 for 1 UVI at 18X/20-bit
. Hence my confusion.
I think with some sleuthing and a stable UV light source, it will be possible to determine an approach to calculating the UV Index equivalent within the driver library.
@DonBower @ladyada @jedgarpark:
Just completed an update of the library to include UVI and Lux. The revision also includes a window_factor
parameter to accommodate window transmission light loss (defaults to 1.0 = clear or no glass).
The UVI and Lux calculations were taken directly from the data sheet. I assume that the sensor is factory calibrated, but I don't have a calibrated UV or Lux source to use to verify. Please test the new library in your environment and let me know if the results are reasonable.
To read UVI and Lux using the sensor's default 3x gain and 16-bit resolution default:
import busio
import board
import adafruit_ltr390
i2c = busio.I2C(board.SCL, board.SDA)
ltr = adafruit_ltr390.LTR390(i2c)
print("UVI: ", ltr.uvi, "Lux: ", ltr.lux)
To set the window transmission factor to other than the default 1.0:
ltr.window_factor = 1.1
The updated library can be found in my fork: https://github.com/CedarGroveStudios/Adafruit_CircuitPython_LTR390
@CedarGroveStudios ooh can ya submit a PR?
@ladyada yes. done.
Bryan's code challenged my thinking a little -- well, a lot actually. It was a very worthwhile opportunity.
@ladyada Would you like me to update the LTR390 learning guide to include the new parameters or work it through Bryan?
@CedarGroveStudios if you're up for it, it would be greatly appreciated we added you as a guide contributor!
Happy to do so. I'll work on it late tonight.
@ladyada Completed. Had a little time during lunch to update the guide.
I just noticed that the most recent bundle doesn't include the updated LTR390 library so the guide will be out-of-sync until that happens. Can it be easily expedited?
it'll take a day - thats normal and OK :)
@DonBower I think this was resolved in release 1.1.0 :). Let me know if that is not the case. Thanks https://github.com/adafruit/Adafruit_CircuitPython_LTR390/releases/tag/1.1.0
@jposada202020 yes, I have adjusted my code:
def printLight():
if hasTSL:
thisIR = tsl.infrared
thisVis = tsl.visible/1000
else:
thisIR = 0
thisVis = 0
if hasLTR:
thisUV = ltr.uvs
thisUVi = ltr.uvi
if thisVis == 0:
thisVis = ltr.lux * 1000
if hasTSL and hasLTR:
print(f'IR/Visable/UVI.....: {thisIR:1,d} / {thisVis:1,.0f} / {thisUV:1,d} '[:40])
elif hasLTR:
print(f'Visable/UVI........: {thisVis:1,.0f} / {thisUV:1,d} '[:40])
elif hasTSL:
print(f'IR/Visable.........: {thisIR:1,d} / {thisVis:1,.0f} '[:40])
This looks like I have the right multiplcation. You can see the whole project here: https://github.com/DonBower/HamGoBox
Interesting project, do you use ham radio as a weather
station? another question you mention in the readme the sensor installation, is for these particular set of sensors or in general? Thanks for the info, if nobody has any other comment I think we could close the issue. Thanks :)
The radio and the weather station are not connected, but because the radio is used in remote locations, I want to be able to monitor conditions. Thanks!
The examples refer to ltr.uvs and ltr.light, but I am having difficulty expressing these values. Are they in milliwatts per square centimeter (mW/cm2), or millijoules per square centimeter (mJ/cm2), or some other factor. It is apparent from the Update uv_index to uvs commit, the .uvs was thought to be a UV Index, but I cannot find what the new unit of measurement is. In Short, what do these two numbers represent?