UV Index with LTR390-UV sensor

Hi.
I am working on a DIY weather station and right now I am trying to add LTR390-UV sensor to it.
Everything is connected to NodeMCU ESP32 and that fine seems to be working fine (I think).
My ESPHome config for that sensor is as follows (I am using TCA9548A I2C multiplexer):

sensor:
  - platform: ltr390
    i2c_id: multiplex0channel1
    uv:
      name: "UV"
    uv_index:
      name: "UV Index"
    light:
      name: "Light"
    ambient_light:
      name: "Ambient Light"
    resolution: 19
    gain: X3
    window_correction_factor: 1
    update_interval: 5s

While I am plying with the config everything currently sits outside on my garden table. It is a fairly gray day (sky is covered in clouds) - according to various sources the UV Index should be between 3-4.
My Sensor is reporting the following values:
Ambient Light: 121,012
Light: 12,106 lux
UV: 164
UV Index: 0.07217

The ambient light/light values seems OKish as far as I can tell looking at various online sources.
However the UV and UVI values are way off what is reported right now for my location.

The sensor is not covered with anything - that is another thing I need to figure out - what sensor cover to use so it does not affect the measurements.

Any ideas why the values are so wrong?
Any one out here have any experiences with this sensor?
Thanks

I just started with this sensor and am getting (using defaults) on my window sill in direct sun.

Daylight: 52428.60156 lx
Ambient Light: 262143.00000
UV Index: 0.14000 UVI
UV: 322.00000

UV Index should be 6.5 right now.

I have the Waveshare UV (C) board with LTR390-UV-01 sensor.

For the glass you want Far UV Grade Fused Silica Quartz. This is frequently sold in 30mm squares. I have one and it does not affect the readings from quick testing. My regular windows reduce UVI reading by one decimal place (0.14 → 0.014).

Plan on installing this in a weather station so the readings will probably change.

looks like your UV Index value is equally weird

Sadly enough I have the same weird index values…

I have the same weird index values. And I think I figured out the issues. I opened an issue in the esphome github, the details are there:

Until it is fixed in the esphome depository, here are the possible workarounds:

workaround 1:
The resolution config does not work, so leave it at 18-bit default.
The UVI calculation depends on the resolution config and gain config, so calculate your own using this formula:
UVI = ( uv / 2300 * wfac ) * 4 * ( 18 / gain )
The first part is the original formula.
The x 4 is to adjust for being at default 18-bit resolution instead of 20-bit.
The x 18 / gain is to adjust for actual gain configured vs x18 gain assumed in the original formula.

workaround 2:
Use the esphome external components method to override the ltr390 component.

Set up the external component by downloading the ltr390 files from the esphome github, you should get 4 files in the ltr390 directory. Overwrite the ltr390.cpp file by the file I attached in the opened issue above (the attached file should be renamed to ltr390.cpp).

1 Like

It would be great if they could fix that, I would love to include that sensor in my new irrigation controller

Does this lamda look right?
Also, are the wfac and gain correct assuming I’m not changing any of the defaults?
I’m still getting UVI values about 1/4 what is published for my zip code.

    lambda: |-
      const float wfac = 1.0;   // wfac
      const float gain = 3.0;   // gain
      return ( ((id(${devicename}_UV).state * wfac) / 2300) * 4 * ( 18 / gain ));

I haven’t read all the comments but I want to remmenber that the LTR390 UV measure doesn’t return the index, the index must be calculated.

Hi,

i’m trying this workaround, but it’s failing with:

Failed config

sensor.ltr390: [source <unicode string>:373]
  platform: ltr390
  uv_index: 
    name: Weather Station ltr390 UV index
    id: ltr390_uv_index
  uv: 
    name: Weather Station ltr390 uvs
    id: ltr390_uvs
    
    [lambda] is an invalid option for [uv]. Please check the indentation.
    lambda: |-
      float wfac = 1.0;   // wfac
      float gain = 3.0;   // gain
      return ( ((id(ltr390_uvs).state * wfac) / 2300) * 4 * ( 18 / gain ));
  light: 
    name: Weather Station ltr390 light
    id: ltr390_light
  ambient_light: 
    name: Weather Station ltr390 ambient light
    id: ltr390_ambient_light
  resolution: 20
  update_interval: 10s

for the sniplet.

# UV and Ambient Light
  - platform: ltr390
    uv_index:
      name: "${friendly_name} ltr390 UV index"
      id: ltr390_uv_index
    uv:
      name: "${friendly_name} ltr390 uvs"
      id: ltr390_uvs
      lambda: |-
        float wfac = 1.0;   // wfac
        float gain = 3.0;   // gain
        return ( ((id(ltr390_uvs).state * wfac) / 2300) * 4 * ( 18 / gain ));
    light:
      name: "${friendly_name} ltr390 light"  
      id: ltr390_light
    ambient_light:
      name: "${friendly_name} ltr390 ambient light"
      id: ltr390_ambient_light
    resolution: 20
    update_interval: 10s

Any advise, please?

The error message makes it clear: you can’t have a lambda here.

See the docs: what are you trying to return? I think you want this in an on_value: section. See here:

Thank you, changed to:

# UV and Ambient Light
  - platform: ltr390
    uv_index:
      name: "${friendly_name} ltr390 UV index"
      id: ltr390_uv_index
    uv:
      name: "${friendly_name} ltr390 uvs"
      id: ltr390_uvs
      on_value: 
        then:
          lambda: |-
            float wfac = 1.0;   // wfac
            float gain = 3.0;   // gain
            return ( ((id(ltr390_uvs).state * wfac) / 2300) * 4 * ( 18 / gain ));
    light:
      name: "${friendly_name} ltr390 light"  
      id: ltr390_light
    ambient_light:
      name: "${friendly_name} ltr390 ambient light"
      id: ltr390_ambient_light
    resolution: 20
    update_interval: 10s

no syntx error, but by compling, error.

Dependency Graph
|-- AsyncTCP-esphome @ 2.0.1
|-- WiFi @ 2.0.0
|-- FS @ 2.0.0
|-- Update @ 2.0.0
|-- ESPAsyncWebServer-esphome @ 3.1.0
|-- DNSServer @ 2.0.0
|-- ESPmDNS @ 2.0.0
|-- noise-c @ 0.1.4
|-- Wire @ 2.0.0
|-- ArduinoJson @ 6.18.5
Compiling .pioenvs/weather-station/src/main.cpp.o
: In lambda function:
:386:71: error: return-statement with a value, in function returning ‘void’ [-fpermissive]
*** [.pioenvs/weather-station/src/main.cpp.o] Error 1
========================== [FAILED] Took 6.12 seconds ==========================

what could i be doing wrong?

You are using on_value: when you should be using filters:, assuming you want to replace the value of the UV entity.

    uv:
      name: "${friendly_name} ltr390 uvs"
      id: ltr390_uvs
      filters: 
        lambda: |-
          float wfac = 1.0;   // wfac
          float gain = 3.0;   // gain
          return (x * wfac / 2300 * 4 * 18 / gain);

Thank you so much!

I’m not having any luck receiving data from my Gravity LTR390-UV. It’s connected to a ESP32ThingPlus using the default pins SDA: GPIO23 and SCL: GPIO22.

I’m at a point where I at least get the device discovered. I have experimented with a few different approaches using code others have found works. What should I expect to see? has anyone any suggestions on how I could test to see if it’s even functional. beginning to think I’ve got a dud sensor.

[14:13:02][C][i2c.arduino:054]:   SDA Pin: GPIO23
[14:13:02][C][i2c.arduino:055]:   SCL Pin: GPIO22
[14:13:02][C][i2c.arduino:056]:   Frequency: 50000 Hz
[14:13:02][C][i2c.arduino:059]:   Recovery: bus successfully recovered
[14:13:02][I][i2c.arduino:069]: Results from i2c bus scan:
[14:13:02][I][i2c.arduino:075]: Found i2c device at address 0x1C

my yaml is as follows:

i2c:
  sda: GPIO23
  scl: GPIO22
  scan: true

sensor:
  - platform: ltr390
    uv:
      name: "UV"
    uv_index:
      name: "UV Index"
    light:
      name: "Light"
    ambient_light:
      name: "Ambient Light"
    resolution: 19
    gain: X3
    window_correction_factor: 1
    update_interval: 5s

Hi, Liteon, the manufacturer of the LTR390 made a revision of the datasheet were he say that UV sensivity for the sensor is not 2300 but 1400 FYI => LTR390/LTR-390UV-01_Final_ DS_V1.4.pdf at main · levkovigor/LTR390 (github.com)

so, to have it right, shall 2300 in the formula ( ((id(ltr390_uvs).state * wfac) / 2300) * 4 * ( 18 / gain )); be replaced by 1400, so ( ((id(ltr390_uvs).state * wfac) / 1400) * 4 * ( 18 / gain ));?

no data. interestingly, no errors. image

In theory yes, I did it on my setup and UVI are now a 30% higher than expected so I think I will stick to 2300

Hi all, chiming in to say that the discussion has been updated over on Github ltr390 light sensor reports very low UVI values and resolution settings not working · Issue #4380 · esphome/issues · GitHub and I’ve submitted a PR to hopefully address the UVI issue.