{"id":13893878,"url":"https://github.com/RobTillaart/ML8511","last_synced_at":"2025-07-17T08:31:15.991Z","repository":{"id":45315622,"uuid":"273905264","full_name":"RobTillaart/ML8511","owner":"RobTillaart","description":"Arduino library for ML8511 UV sensor","archived":false,"fork":false,"pushed_at":"2024-09-12T15:22:56.000Z","size":44,"stargazers_count":13,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-11T18:14:46.443Z","etag":null,"topics":["arduino","sensor","uv"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RobTillaart.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"RobTillaart","custom":"https://www.paypal.me/robtillaart"}},"created_at":"2020-06-21T13:02:29.000Z","updated_at":"2025-05-22T04:26:36.000Z","dependencies_parsed_at":"2024-09-12T19:50:43.118Z","dependency_job_id":"669edbd6-20e3-4d19-9b71-62af3fa44889","html_url":"https://github.com/RobTillaart/ML8511","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/RobTillaart/ML8511","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FML8511","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FML8511/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FML8511/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FML8511/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RobTillaart","download_url":"https://codeload.github.com/RobTillaart/ML8511/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RobTillaart%2FML8511/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265585293,"owners_count":23792714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","sensor","uv"],"created_at":"2024-08-06T18:01:18.843Z","updated_at":"2025-07-17T08:31:15.745Z","avatar_url":"https://github.com/RobTillaart.png","language":"C++","funding_links":["https://github.com/sponsors/RobTillaart","https://www.paypal.me/robtillaart"],"categories":["C++"],"sub_categories":[],"readme":"\n[![Arduino CI](https://github.com/RobTillaart/ML8511/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)\n[![Arduino-lint](https://github.com/RobTillaart/ML8511/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/ML8511/actions/workflows/arduino-lint.yml)\n[![JSON check](https://github.com/RobTillaart/ML8511/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/ML8511/actions/workflows/jsoncheck.yml)\n[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/ML8511.svg)](https://github.com/RobTillaart/ML8511/issues)\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/ML8511/blob/master/LICENSE)\n[![GitHub release](https://img.shields.io/github/release/RobTillaart/ML8511.svg?maxAge=3600)](https://github.com/RobTillaart/ML8511/releases)\n[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/ML8511.svg)](https://registry.platformio.org/libraries/robtillaart/ML8511)\n\n\n# ML8511\n\nArduino library for the ML8511 UV sensor.\n\n\n## Warning\n\n**Always take precautions as UV radiation can cause sunburn, eye damage and other severe problems**.\n\nDo not expose yourself to the sun as UV source too long.\n\nWhen using artificial UV light (TL LED laser a.o.) use appropriate shielding.\n\n\n## Description\n\nML8511 - UV sensor - library for Arduino UNO. \n\n- 3V3 Sensor so do **NOT** connect to 5V directly.\n- do not forget to connect the EN to either an enablePIN or to 3V3 (constantly enabled).\n\n\nUse of an external ADC see below.\n\n\n### Related\n\n- https://github.com/RobTillaart/TSL235R  pulse based irradiance variant.\n- https://github.com/RobTillaart/TSL260R  analog IR irradiance variant.\n- https://github.com/RobTillaart/AnalogUVSensor\n- https://github.com/RobTillaart/LTR390_DFR  UV sensor (DF Robotics edition)\n- https://github.com/RobTillaart/LTR390_RT  UV sensor\n- https://github.com/RobTillaart/ML8511  UV sensor\n- https://learn.sparkfun.com/tutorials/ml8511-uv-sensor-hookup-guide\n- https://en.wikipedia.org/wiki/Ultraviolet_index\n\n\n### Breakout\n\n```\n//        +-------+--+\n//    VIN |o      +-+|  mounting hole\n//    3V3 |o      +-+|\n//    GND |o         |\n//    OUT |o         |\n//     EN |o       S |  Sensor\n//        +----------+\n```\n\n\n## Operational\n\nAs the sensor / breakout is 3V3 one need to connect to Arduino 3V3.\nThe library converts the **analogRead()** to voltages, and it uses a\nreference of 5.0 Volt == 1023 steps as default.\n\nIf one wants to use another ratio e.g. 3.3 volts == 4095 steps, one\ncan set those with **setVoltagePerStep()**.\n\n```cpp\n    ML8511 light(A0, 7);\n    light.setVoltagePerStep(3.3, 4095);\n```\n\nIt is possible to always enable the sensor by connecting the EN pin to 3V3.\nThe value of the enablePin in the constructor should then be omitted \nor set to a negative value.\n\nWhen connecting to an Arduino UNO one can use the 3V3 of the Arduino to power the sensor. \nHowever it is not possible to connect the enable pin directly to the sensor. \nUse a voltage divider (10K + 20K) to convert the 5 Volts to ~3.3 Volts.\n\n\n## Interface\n\n```cpp\n#include \"ML8511.h\"\n```\n\n### Constructor\n\n- **ML8511(uint8_t analogPin, uint8_t enablePin = 0xFF)** Constructor, \nif enable is connected to 3V3 constantly one does not need to set the enablePin parameter.\n\n\n### Core\n\n- **float getUV(uint8_t energyMode = HIGH)** returns mW per cm2, energyMode = HIGH or LOW.\nenergyMode = LOW will disable the sensor after each read.\nFunction blocks for (at least) 1 millisecond if sensor is disabled.\n- **float voltage2mW(float voltage)** returns mW per cm2 from voltage. \nCan be used when one uses an external ADC e.g. ADS1115\nFormula is based upon the graph in the datasheet page 4 (at 25 Celsius)\n- **bool setVoltsPerStep(float voltage, uint32_t steps)** to calibrate the **internal** ADC used. \nIf one of the parameters voltage or steps is \u003c= 0 the function returns false.\nThen the previous set value or the default of 5 volts 1023 steps is used.\nThis function has no meaning for an external ADC.\n- **float getVoltsPerStep()** idem.\n\n\n### Enable / disable\n\nThese functions only work if the enable pin is set in the constructor.\n\n- **bool enable()** manually enable the device. \nReturns false if enable pin not set.\n- **bool disable()** manually disable the device. \nReturns false if enable pin not set.\n- **bool isEnabled()** returns the enabled status.\nReturns true  if enable pin not set as it cannot be disabled.\n\n\n### Experimental\n\nWARNING: USE WITH CARE\n\n- **float estimateDUVindex(float mWcm2)** input in mW per cm2.\nTypically returns a value between 0 and ~15(?)\nReturns zero if the parameter mWcm2 \u003c= 0.0.\n- **bool setDUVfactor(float factor)** set the conversion factor.\nReturns false if the factor \u003c 0.01 (hard coded minimum).\nThis factor can be used to sort of calibrate a system if a medium \n(e.g. glass) is between sensor and UV source \n- **float getDUVfactor()** returns the set conversion factor (default 1.61)\n\nSee below (Experimental DUVindex) how to determine the DUV factor for your sensor.\n\n_Note: \nThe UV index can be very high, in La Paz, Bolivia, one of the highest cities in the world\nthe DUV index can go above 20. See link below.\nThis is really extreme and it is unknown how the ML8511 sensor (and this library) \nbehaves under such conditions, and how long the sensor would survive.\nDatasheet goes up to 15 mW per cm2, with a default DUVfactor of ~1.61 \nthe measurements could handle DUV of ~24 in theory._\n\nhttps://edition.cnn.com/2021/11/03/americas/bolivia-heatwave-highlands-intl/index.html\n\n\n## Sensor sensitivity\n\nIndoors there is very little or no UV light so use a known UV source like \na black-light or go outside in the sun.\n\nThe formula to convert the ADC reading to mW cm^2 is based upon the graph \nshown in the datasheet. As I have no reference source to calibrate the library\nthe accuracy is limited at best. If you know of a calibrated source please let me know.\n\nThe sensor has its peak sensitivity ( \u003e80% ) from λ = 300-380 nm \nwith an absolute peak at λ = 365 nm.\n\n\n## Experimental DUVindex\n\nNote: this library is **NOT** calibrated so **USE AT OWN RISK**\n\nThe DUV index can be used for warning for sunburn etc.\n\n\n### DUV index table\n\nBased upon https://en.wikipedia.org/wiki/Ultraviolet_index,  \n\n\n|  DUV INDEX  |  Description  |  Colour  |\n|:-----------:|:--------------|:---------|\n|    0 - 2    |   LOW         |  GREEN   |\n|    3 - 5    |   MODERATE    |  YELLOW  |\n|    6 - 7    |   HIGH        |  ORANGE  |\n|    8 - 10   |   VERY HIGH   |  RED     |\n|    11+      |   EXTREME     |  PURPLE  |\n\n\nColour codes are indicative to be used in a user interface.\nA more elaborated colour scheme may be made with map2colour.\n- https://github.com/RobTillaart/map2colour\n\n\n### Calibrate estimateDUVindex()\n\nTo calibrate the **estimateDUVindex()** function one needs to determine the DUVfactor. \nTo do this you need an external reference e.g. a local or nearby weather station. \nYou need to make multiple measurements during the (preferably unclouded) day and \ncalculate the factor.\n\n```\n             DUV from weather station\nDUVfactor = --------------------------\n                     getUV();\n```\n\nYou do this e.g. once per hour, so you get multiple values.\nYou can then average them to have a single factor.\n\nHardcode this found value in the library (in the constructor) or better\nuse the **setDUVfactor(factor)** call in **setup()** to calibrate your sensor.\n\nIt might be useful to calibrate the DUV factor on different moments of the \nday to correct for the angle of inclination. One might need to adjust this\nduring measurements by using e.g. an RTC = real time clock.\n\n\n## Version info\n\n### 0.1.5 and before\n\nThe formula for the experimental **estimateDUVindex(mWcm2)** is based on\nthe following facts / assumptions:\n- (fact) The sensor cannot differentiate between wavelengths, \nso integration with different weights is not possible.\n- (assumption) All the UV is radiated at λ = 300 nm. \nThis is the most lethal the sensor can sense \u003e 80%.\n- (choice) All the UV is accounted for 100% for the whole value. \n(Erythemal action spectrum) \nAs we cannot differentiate wavelengths, this is the safest choice.\n\n### 0.1.6 \n\nThe formula is simplified to a single factor that the user needs to determine.\nBelow is described how to do the calibration.\n\n## External ADC\n\n**float voltage2mW(float voltage)** can be used for an external ADC e.g ADS1015,\nADS1115 or one of the (fast) MCP_ADC's.\n\n- https://github.com/RobTillaart/ADS1X15 \n- https://github.com/RobTillaart/MCP_ADC\n\n\n## More about UV\n\nhttps://en.wikipedia.org/wiki/Ultraviolet_index\n\n\n## Future\n\n#### Must\n\n- improve documentation\n- refactor / reorganize readme.md\n\n#### Should\n\n- test more platforms\n- investigate in calibration\n\n#### Could\n\n- get unit tests up and running\n- math for duration of exposure\n  - Converting from mW/cm2  ==\u003e Joule / s / cm2\n  - integrate sum of multiple measurements.\n  - experimental example?\n\n#### Wont\n\n- investigate serial communication with UV led and UV sensor\n  - however fun experiment.\n- check performance (mainly ADC dependent)\n- add base class without enable code?\n\n\n## Support\n\nIf you appreciate my libraries, you can support the development and maintenance.\nImprove the quality of the libraries by providing issues and Pull Requests, or\ndonate through PayPal or GitHub sponsors.\n\nThank you,\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRobTillaart%2FML8511","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FRobTillaart%2FML8511","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRobTillaart%2FML8511/lists"}