In this quick tutorial learn how to connect a UV light sensor ML8511 with Arduino or ESP32 microcontrollers and display the value of UV index on LED display by calculating the analog output from the sensor which is directly related to amount of the UV light intensity which is measured in mW / cm2 the sensor detects.
In this tutorial we will interface the sensor with few microcontroller boards with few display modules. So, you can choose any one which suits your requirements.
Table of Contents
What is UV index
The Ultraviolet Index (UV Index or UV Index) is a measure that indicates the intensity of Ultraviolet light radiation in a certain area. These radiations are mainly from sun and in some cases artificial ones. So UV index helps us to know the amount of UV light exposed in an area with a scale starting from 0 which indicates no UV radiation and goes up to 11 and more which represents very high UV light ray radiation. Prolonged exposure to the UV radiation causes severe issues listed below
Some of the damages and risks of being exposed to excessive UV radiation levels are:
- skin cancer and premature aging of the skin
- cataracts and other eye damage
- damage and even suppression of the immune system
- allergies, reactions and development of hypersensitivity.
UV sensor ML5811, How it works?
The ML8511 module from Lapis Semiconductor Co Ltd is an ultraviolet (UV) light sensor, that delivers an analog signal that depends on the amount of UV light it detects. It is used in projects to monitor environmental conditions such as the UV index.
The analog output is linearly related to UV intensity (mW / cm2). This analog signal can be connected to a microcontroller which is capable of converting analog to voltage conversions to detect the level of UV.
UV sensor ML5811 is very light weight, small in size and easy to use. as we all know UV light ranges from 10nm to 400nm. which are divided into UVA ranges from 315-400nm , UVB ranges from 280-315nm and UVC ranges from 100-280nm. Here as lower the wavelength of UV that dangerous they are.
ML5811 can detect UV ranging from 280-390nm which covers the UVA and UVB spectrum.
ML5811 Specifications:
- Operating Voltage: 5V DC
- Analog output
- Wavelength: 280-390nm
- Ultra-low power consumption
- Meteorological applications, skin care, industrial UV level measurement.
ML5811 Pinout:
There can be few versions of ML5811 UV sensor boards like GYML5811
Here the Sensor board has four pins, 3.3 for 3.3v, GND for ground, OUT for Analog signal output, EN is connected to 3.3 as a reference voltage. few board has VIN pin which you can use or ignore.
Method 1: Interfacing ML8511 UV sensor with Arduino and LCD display.
In this method, We are using Arduino as a development board and interfacing with UV sensor ML8511 and display output on LCD display module with or without I2C connection.
Required components:
- UV sensor ML8511
- Arduino Uno board
- LCD display module with I2C
- Few connecting wires
Circuit Diagram interfacing Arduino, UV sensor and LCD display
Connect all the required components by looking at the below schematic diagram.
As per the above circuit diagram connect 4 pins from the ML8511 to Arduino in below order.
- (ML8511) —> (Arduino)
- 3.3 —> 3.3V
- GND —>GND
- OUT —>A0
- EN —>A1, 3.3V
Next connect the LCD display with I2C connector to Arduino in the below order.
- (LCD Display)—>(Arduino)
- GND —>GND
- VCC—>5V
- SDA—>A4
- SCL—>A5
After connecting according to the above tables and circuit diagram, Arduino is ready to upload the code to work as UV index meter.
Here connecting UV sensor with Arduino is little tricky because Analog to Digital conversion completely depends on VCC(Voltage input). Let us assume the VCC as to be 5V but as we are powering up the Arduino board with USB power the value ranges between 4.75V to 5.25V which is not stable and which can make the calculations inaccurate. So in this case to fix the issue, we are using the onboard accurate fixed voltage 3.3V which has the stability with inaccuracy of only 1% as reference.
So by using the 3.3v pin for analog to digital conversion and then comparing it with the reading of the sensor, we can get the accurate reading as long as the board input voltage VCC is greater than 3.4v.
As we know the Analog voltage ADC will give 1023 as output when it reads VCC. So if we read an ADC of 663 with connection of 3.3V, The voltage powering the Arduino is calculated with ratio given below
VCC / 1023 = 3.3V / 663
after calculating we get 5.46v you can verify with a digital multimeter if available.
Now we came to know precisely what VCC is, we can calculate a much more accurate ADC with the UV voltage:
UV_Voltage / uvLevel = 3.3 / refLevel
uvLevel
is what we read from the OUT
pin. refLevel
is what we read on the 3.3V pin. Solving for UV_Voltage
, we can get an accurate reading.
Mapping the UV_Voltage
to intensity of UV is straight forward. No UV light starts at 1V with a maximum of 15mW/cm2 at around 2.8V. Arduino has a built-in map() function, but map() does not work for floats. Contributors at Arduino forums had created a simple mapFloat() function which we can use it here:
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
Source Code:
Copy the below code and paste them in the Arduino IDE and upload the code.
To run this program you need to install a library Liquidcrystal_I2C, If it not installed on your Arduino IDE download from this Link.
#include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,16,2); //Hardware pin definitions int UVOUT = A0; //Output from the sensor int REF_3V3 = A1; //3.3V power on the Arduino board void setup() { Serial.begin(9600); // Initialize the LCD connected lcd. init (); // Turn on the backlight on LCD. lcd. backlight (); pinMode(UVOUT, INPUT); pinMode(REF_3V3, INPUT); Serial.println("ML8511 example"); } void loop() { int uvLevel = averageAnalogRead(UVOUT); int refLevel = averageAnalogRead(REF_3V3); //Use the 3.3V power pin as a reference to get a very accurate output value from sensor float outputVoltage = 3.3 / refLevel * uvLevel; float uvIntensity = mapfloat(outputVoltage, 0.99, 2.8, 0.0, 15.0); //Convert the voltage to a UV intensity level Serial.print("output: "); Serial.print(refLevel); Serial.print("ML8511 output: "); Serial.print(uvLevel); Serial.print(" / ML8511 voltage: "); Serial.print(outputVoltage); Serial.print(" / UV Intensity (mW/cm^2): "); Serial.print(uvIntensity); lcd.clear(); lcd.print("UV Ray Intensity"); lcd.setCursor(0, 1); lcd.print(uvIntensity); lcd.print(" mW/cm^2"); Serial.println(); delay(200); } //Takes an average of readings on a given pin //Returns the average int averageAnalogRead(int pinToRead) { byte numberOfReadings = 8; unsigned int runningValue = 0; for(int x = 0 ; x < numberOfReadings ; x++) runningValue += analogRead(pinToRead); runningValue /= numberOfReadings; return(runningValue); } float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; }
After Pasting the code do not forget to choose the board as Arduino Uno and choose the correct port and click on upload button. next it takes few seconds to upload the code and after completion of upload restart the Arduino by clicking on reset button on board, to run the program.
In case if get an error compiling the code or no output is displayed or any I2C error use the I2C scanner for this link. And get the I2C value and update it in the above code and upload to work.
Then the LCD display shows the output as below:
Method 2: Interfacing ML8511 UV sensor with ESP32 and OLED display.
In this method, we are going to interface UV sensor ML8511 with ESP 32 WiFi and Bluetooth module and connect it to OLED, You can also connect to any cloud severs to get the UV index over internet like Blynk, Ubidots, Thingspeak, etc.
Required Components:
- UV sensor ML8511
- ESP 32 WiFi and Bluetooth module
- 0.96″ 128×64 I2C OLED display with I2C – SSD1306
- Few connecting wires
Circuit Diagram:
Connect all the required components according to the below schematic diagram
After connecting all the components next step is to upload the code to ESP 32 module.
For code Explanation read the content from Arduino method above.
Source Code:
Copy and paste the below code in Arduino IDE, choose ESP 32 board in the settings and select the port where ESP32 is connected, you can get that in the Device manager of your PC.
To run this program you need to install a library Adafruit_SSD1306, If it not installed on your Arduino IDE download from this Link.
#include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> int UVOUT = 15; //Output from the sensor int REF_3V3 = 4; //3.3V power on the ESP32 board #define OLED_RESET 4 Adafruit_SSD1306 display(OLED_RESET); void setup() { Serial.begin(9600); pinMode(UVOUT, INPUT); pinMode(REF_3V3, INPUT); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //initialize with the I2C addr 0x3C (128x64) display.clearDisplay(); } //Takes an average of readings on a given pin //Returns the average int averageAnalogRead(int pinToRead) { byte numberOfReadings = 8; unsigned int runningValue = 0; for(int x = 0 ; x < numberOfReadings ; x++) runningValue += analogRead(pinToRead); runningValue /= numberOfReadings; return(runningValue); } float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } void loop() { int uvLevel = averageAnalogRead(UVOUT); int refLevel = averageAnalogRead(REF_3V3); //Use the 3.3V power pin as a reference to get a very accurate output value from sensor float outputVoltage = 3.3 / refLevel * uvLevel; float uvIntensity = mapfloat(outputVoltage, 0.99, 2.8, 0.0, 15.0); //Convert the voltage to a UV intensity level Serial.print("output: "); Serial.print(refLevel); Serial.print("ML8511 output: "); Serial.print(uvLevel); Serial.print(" / ML8511 voltage: "); Serial.print(outputVoltage); Serial.print(" / UV Intensity (mW/cm^2): "); Serial.print(uvIntensity); Serial.println(); display.setCursor(20,0); //oled display display.setTextSize(1); display.setTextColor(WHITE); display.println("UV Ray Intensity"); display.setCursor(20,20); //oled display display.setTextSize(3); display.setTextColor(WHITE); display.println(uvIntensity); display.setCursor(20,45); //oled display display.setTextSize(2); display.setTextColor(WHITE); display.println("mW/cm^2"); display.display(); delay(300); display.clearDisplay(); }
After uploading the code press the reset button to display the output on the OLED display as shown in the below image.