arendst / Tasmota

Alternative firmware for ESP8266 and ESP32 based devices with easy configuration using webUI, OTA updates, automation using timers or rules, expandability and entirely local control over MQTT, HTTP, Serial or KNX. Full documentation at
https://tasmota.github.io/docs
GNU General Public License v3.0
21.85k stars 4.75k forks source link

veml6070 UV light sensor add UV Index Level #3844

Closed mike2nl closed 5 years ago

mike2nl commented 5 years ago

Have you look for this feature in other issues and in the wiki?

Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is.

Describe the solution you'd like A clear and concise description of what you want to happen.

Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

Additional context Add any other context or screenshots about the feature request here.

(Please, remember to close the issue when the problem has been addressed)

Frogmore42 commented 5 years ago

The data sheet from Vishay makes it clear the table lookup for the conversion is going to depend on the integration time (which Tasmota can probably figure out) and the value of the resistor that is on the board. This value would need to be provided to Tasmota, or assumed. If assumed, it will be wrong for some implementations. This means there should be storage allocated and a method provided to save and set and show the resistor value.

mike2nl commented 5 years ago

@Frogmore42 Your idea is a good one. On the other side it needs more memory and i think i know (i hope) Theo enough in my short time of tasmota that he would say: please don't do it, but i can be wrong.

@all 1st i have added a fixed table now by hand calculated based on three different books and a friend of mine. He is a professor and has helped me out to get it right in the first way. Now the calculation is based on that and it works like a charm with a solar light source which i could lean for two weeks now. Jesus that thing is fun with white and yellow leds. Looks very expensive and i have to handle it with great care.

What works now with a little help from andrethomas ;-) for a return value. Because i stood in the front of all trees in my garden but i could not see them.

Next about the IT time which is fixed on 500ms (IT4) and in wont change it. Why..

Next part is the suspend and wakeup issue. I have a report in my hands of the design team which was working for the mini satelite cubes which where let out of the ISS and fall back to earth. Some of them where designed to meassure light. That report is not public but on personal visits i can show him. Please understand because i have signed a non disclosure. What important is that the senosr has a short lifetime when it comes to 24/7 messaauring times. It is something inside the sensor what it makes him old while using. Another point is when you using the sensor and cpu on Lipo battery you need to shut it down to spare power. But in this case it's the lifetime issue and how the production process of that PCB was done. The flor time of 168h based on MSL-3 according to J-STD-020 means that we don't know what is done with that tiny little smd sensor friend. So go safe.

You can find that suspend and wakeup procedure in many projects on github for that sensor. So i will take a look at the report again what they say about the procedure and qill compare with the many different ways which are used outside tasmota.

Testing hardware: 3x Wemos D1 (not mini) 3x VEML6070, ordered in three different shops (ali express, local and Adafruit)

SO that´s all for this time. And thanks for understanding about the longer text...

mike2nl commented 5 years ago

Short upadate over the progess. LIttle screenshot what is shown right now on the web page. It's not the end a good start and more is comming. Figure 1: 1st

TBD, upcomming version:

TBD, in later versions:

Jason2866 commented 5 years ago

Nice progress! My suggestion for: Value UV Index -- Low -- Mid -- High -- Danger -- Burn Mybe you could color it: Low and Mid green, High yellow, Danger and Burn red

Maybe UV Power in mW/cm2 ?

My suggestion for UV Level -> UV Raw or just not showing in standard setup.

P.S. Should 4495 uW/cm2 not be a UV Index < 1 ?

mike2nl commented 5 years ago

@Jason2866 Very good ideas... The UV Index text value will i take today in coding. Love the way of thinking...simple and good.

The coloring is something what i tought about in the last night, but i could not figure out how to do that in tasmota because there is no place in the web server to do so. But i love the idea to have a little colored square or arrow what angles with the level. I can be wrong, so then hit me, softly

There is a different calculation but that's depending on V++ and Rset and other conditions.

When you will messaure more sientific you need a complete different sensor. Addional you must know the time of the year, current local time (GMT+i) and and the angle (degrees) in which the sensor is directed to the sun and the view angle of the sensor self. Further you need some other information and these are given by the nearest goverment of aerospace institute. Further i have the lastest uv calculation table from meteo.lcd.lu and www.iuva.org. Both are well know in that sector.

So as i said: it's a 1st attemp to get more out of the sensor and there is a lot more. But step by step otherwise the code writing will hang it selfs up in reading, waiting, reading again and get lots of errors.

But i stay open for suggestions and think about the amount of drivers we have and the needed space when more then one driver is active. E.g. for a very good weather station you need possible 6 or 7 drivers. But i tink that is more a thing for a stand alone esp8266 application.

So let it come and we discusse it here, i think. Good to know that there are some poeple who thinking twice before eating ;-).

Addon: I had messaured 30 minutes ago a value of 15155μW/cm2, that is converted 0.015155W/m2 Then look in table which i added here. Not 100% but very near. So you are right about < 1 and i have to look again in the code. Possible some littel errors. But first i have to change to float values to be shure that nothing is lost in calculations. table

mike2nl commented 5 years ago

@Jason2866 So as i said i take the advise with me Jason. Thank You:

define D_UV_INDEX_1 "Low" // sun->fun

define D_UV_INDEX_2 "Mid" // sun->glases advised

define D_UV_INDEX_3 "High" // sun->glases a must

define D_UV_INDEX_4 "Danger" // sun->skin burns lite once

define D_UV_INDEX_5 "BurnL1/2" // sun->skin burns level 1..2

define D_UV_INDEX_6 "BurnL3" // sun->skin burns with level 3, autsch

define D_UV_INDEX_7 "Unknown" // out of range

The information behind the // comes from the medical information about sun issues

I saw it right now: Maybe UV Power in mW/cm2 ?

My suggestion for UV Level -> UV Raw or just not showing in standard setup.

Jason2866 commented 5 years ago

I read this article: https://de.wikipedia.org/wiki/UV-Index and that was the reason for my suggest for mW/cm2

And YES if you go further a lot of math.... and to make it even more complicated you could use Latitude and Longitude for your calculations ;-) They are already there...

mike2nl commented 5 years ago

@Jason2866 define USE_VEML6070_SHOW_RAW is done ;-).

-> I read this article: https://de.wikipedia.org/wiki/UV-Index -> and that was the reason for my suggest for mW/cm2 I know that one and a good one but he tells not all. And yes it looks like wrong, but not smaller. WHen you look at the table for W/m2 it was to low. Possible i have to take the raw value for the calculation and don't divide it. For the UV Index i have to take the smaller one or change the calculation a little bit. Take the raw and re-calculate and then divide and all in float.

But for this: const char HTTP_SNS_UV_LEVEL[] PROGMEM = "%s{s}VEML6070 " D_UV_LEVEL "{m}%d " D_UNIT_INCREMENTS "{e}";

Have i to cahnge that to: "{m}%f " D_UNIT_INCREMENTS , right? You know i have forgotten to much, so help in that is welcome.

The other things is:

ifdef USE_DOMOTICZ

  if (0 == tele_period) DomoticzSensor(DZ_ILLUMINANCE, uvlevel);

endif // USE_DOMOTICZ

-> and to make it even more complicated you could use Latitude and Longitude for your calculations ;-) You are really a funny guy. Do you mean that i have nothing else todo? ;-)

Jason2866 commented 5 years ago

He @mike2nl you are right dont take me too serious :-) And sorry for programing i cant help you. I am a programing noob! And that do i mean serious.

mike2nl commented 5 years ago

@Frogmore42 and @all Short Update: The VEML6070 is a very good and linear sensor based on the used technic. Based on that i have now a base coefficiant for resistor input in the user_config.h (must be in Ohm, not KiloOhm) to fill a UV-raw-value table automaticly with calculation values for UV Index and UV power.

Will test this for the next two days. Hopefully we get some automatic in the first step. Later we can use LATITUDE & LONGITUDE so as the angle of the mounted sensor.

Jesus what a lot of math work. ;-)

Frogmore42 commented 5 years ago

There will be math!

mike2nl commented 5 years ago

@all: So more than a little update about the progress.

1st - Thank You to andrethomas about you hit me, softly ;-), to the right direction about Serial.print function. It was unknown for me in that range because in industrial automation you have tracing, profiling, debugging, watch, and monitor tools for variable checks. Much and big tools i used now for more then 25 years. So something new to learn. Thank's Andre!

Whats working right now:

Some more information: The sensor we use is not the best one. All these sensors who say they messaure the UV-A, UV-B or UV-C emitting values meeassure the light intesity. So we calculate, lets say over the thumb with the quatlity of these types of sensors. But when i compare the leaned UV source with the calculated values based on the coefficient, it looks good. Better then all the values given for public uv meters that you can buy on ebay, aliexpress or self for 100$ in the nearest shop. A real Spektrorradometer costs you hundreds and self thousends of dollars. So be friendly to our little guy and me ;-) when the value sometimes shows something else then your nearest weather station tells you. I mean not the personal weather stations you can log into that weather information system, i mean the real once. I wrote that i had worked some time in a light laboratory but never so deep as the things i have learned now the last 10 days. The math around all these things is not so high placed as i thought it was. It's simply some little more complexe arrays or '*'or '/'calculations. But very important it is Yoda says: to calculate all things first by hand and then you calculate it in reverse order to see in the sience right or you thoughts are wrong. That was the most eye opening part of the project until now.

...more to come...

mike2nl commented 5 years ago

@all I forgot the most interesting thing. http://www.segurancaetrabalho.com.br/download/uv_index_karel_vanicek.pdf

That document is interesting for all you you because it describes many things around UV Index. Found by a intensvie google search. There you will find why i have added the index level 15 also and by advise from my friend.

In the updated driver all calculations are based on Karel Vanicek, forgot that to say, sorry.

mike2nl commented 5 years ago

Last Update i think: All is working so far. Suspend and wake up is added and tested with uA meter. Last tests tomorrow morning with two settings in the user_config and then update my fork from tasmota, add the new stuff and viola the PR gets out.

Hopefully Theo has then a little bit time to look at it. A friend of mine in germany has tested now the last version an hour ago and it works very well. So hold the thumb and possible i can close the issue or better new ideas thread here in one or two days.

ascillato commented 5 years ago

Great :+1:

mike2nl commented 5 years ago

So PR is out. Hopefully Theo has some time to look in it. When PR is done i will let stay the issue open for two more days, then i will close it

mike2nl commented 5 years ago
andrethomas commented 5 years ago

Use of the sensor: when the UV Index comes to high call all family members back inside the house, then close and lock all doors automaticly, so nobody can go out ;-).

LOL

mike2nl commented 5 years ago

@arendst @andrethomas @Jason2866 @ascillato

About the very well meaned comments of Theo i started to thinking and searching. I had read the veml6070 driver again, against the xsns_23_sdm120.ini xsns_29_mcp230xx.ino xsns_24_si1145.ino xsns_32_MPU_6050.ino, also with the old function FUNC_PREP_BEFORE_TELEPERIOD

So then i have done some thinking again and some copy and paste and some text. The number following in the text is one type of working with flow. There are different ones yes, but i know that way very well, old military style. 40 years ago. Jesus i'm too old.

Here are my ideas and please hit me softly again when this is wrong, because i have nothing found in the wiki. No document what descriped what we have todo and what not. Possible is my lets say mistake a good start to have one document. So here it comes based on the veml6070 driver.

boolean Xsns24(byte function) { boolean result = false;

if (i2c_flg) { switch (function) { case FUNC_INIT: VEML6070Init(); break; case FUNC_EVERY_SECOND: VEML6070Update(); break; case FUNC_JSON_APPEND: VEML6070Show(1); break;

ifdef USE_WEBSERVER

  case FUNC_WEB_APPEND:
    VEML6070Show(0);
    break;

endif // USE_WEBSERVER

}

} return result; }

1 In FUNC_INIT i call 1.1 Veml6070Detect(); 1.2 return-break

2 In FUNC_EVERY_SECOND i call 2.1 Veml6070Update() 2.1.1 in Veml6070Update() i call 2.1.1.1 Veml6070ModeCmd(1) = wakeup 2.1.1.2 Veml6070Detect() 2.1.1.3 Veml6070ReadUv() 2.1.1.4 Veml6070UvRiskLevel(uvlevel) 2.1.1.5 Veml6070UvPower(uvrisk) 2.1.1.6 Veml6070ModeCmd(0) = suspend 2.1.2 return 2.2 return-break

3 in FUNC_JSON_APPEND i call 3.1 Veml6070Show(1) 3.2 return-break

4 in FUNC_WEB_APPEND i call 4.1 Veml6070Show(0) 4.2 return-break

So and now hit me with new ideas, wrong done idea and Theo you too please. I know you have nearly no time but we need it. You have seen it on my msitake and in that way possible everyone can learn something new. Possible a wiki page with infos like mine. So go...

And now not all at the same time ;-)

Another point what not know:

arendst commented 5 years ago

This is becoming a Sisyphus task....

You have it almost nailed down. I just want to add some more background.

In FUNC_INIT, only executed at startup the connected sensor is being detected and a detection flag (sensor_type) is set for future actions.

In the FUNC_EVERY_SECOND up to four actions can be performed: 1) if a sensor needs an action which takes a long time, like more than 100mS, the action will be started here for future follow-up. Using the uptime variable for testing like (uptime &1) will happen every 2 seconds. An example is the DS18B20 driver where readings (conversions they call it) can take up to 800mS from the initial request. 2) if a sensor needed the previous action it is now time to gather the information and store it in a safe place to be used by FUNC_JSON_APPEND and/or FUNC_WEB_APPEND. Using the else function of the previous test (uptime &1) will happen every 2 seconds too but just 1 second later than the previous action. 3) If a sensor does not respond for 10 times the sensor detection flag could be reset which will stop further processing until the sensor is re-detected. Currently I do not use this as some users complaint about loosing sensors for what ever reason. 4) here comes the redetect function in action. By executing this once every 100 seconds (94 == (uptime %100)) a re-attached sensor can be detected without a restart of Tasmota. The 94 should be different for every sensor driver to make sure not all sensors start detection at the same time. Using the drivers index number should be a good starting point.

I guess the main actions for now is to find out how long it takes for the sensor to present it's data once requested. If that takes more than 100mSec I suggest to start using the FUNC_EVERY_SECOND approach I documented above.

Phew, it's starting to look like your write-ups ;-)

BTW for better examples look at the low numbered sensor drivers as they were already un-FUNC_PREP_BEFORE_TELEPERIOD-ed. Sorry for the once you looked at. They are either not updated or use a very different way of doing things. I suggest to take a look at sensor drivers 05, 06, 07, 08, 09 and 10.

andrethomas commented 5 years ago

@arendst

Phew, it's starting to look like your write-ups

Not in vain - I was updating the sensor API and added some of your Sisyphus to it ;)

mike2nl commented 5 years ago

@arendst @Jason2866 @andrethomas @ascillato Oh yeah, we come closer and closer.

Theo, you wrote: -> I guess the main actions for now is to find out how long it takes for the sensor to present it's data once requested.

Thanks Theo, for the detailed information.

arendst commented 5 years ago

@mike2nl when you enable the debug tools there is a timing option available to measure how long the driver takes to provide info.

To use it needs another course though ;-).

Look for file xdrv_99_debug.ino.

mike2nl commented 5 years ago

Theo you wrote: -> Phew, it's starting to look like your write-ups ;-) Ha, ha , then you have not seen my code for the port in rotterdam. There i have made a write-up, ha, ha.

mike2nl commented 5 years ago

@arendst Hi Theo, next write-up ;-)... i had taken a deeper look in the xsns sensor drivers 05, 06, 07, 08, 09 and 10. It's about the FUNC_EVERY_SECOND case.

Some of the drivers using the index number 90, 91 and 92. One of them uses no index number, he use: if (uptime &1) and one use: if (sht_type && !(uptime %4)).

So he detects again in that case the sensor to be sure he is still there, OK. And goes that wrong he writes an error - AddLogMissed, OK. Current max_miss is 5:

define SENSOR_MAX_MISS 5

So my index number is then 11, means for me then: if (11 == (uptime %100)) {

The rest is combine some code for calculation and go on to test used times to get data. I had done that in version 1.0.0.1 already to see how much time i need for suspend and wakeup. So that is not a big deal to find out what's going on

mike2nl commented 5 years ago

so, it looks like mit is done so far. For the one who needs Domotica values, we have to talk about it. Please open then an issue. Json and web server output so as needed: "VEML6070":{"UvLevel":6212,"UvIndex":8.32,"UvIndexText":Danger,"UvPower":0.208}}

Tested it with an OLED display from 128x64 pixel with the driver for I2C. And that works too with all values on screen.

From time to time i will put some updates. E.g. LAT and LONG calculations and with a little servo and two light intensity sensors we can calculate the angle too. But i think that goes a little bit to far.

So have fun and some feedback is allways welcome. And Thank You to the tasmota team for the help i needed to get some i stay in the front of the trees solution. So enough wood for the winter i have ;-). And now i will close the issue.