Overview
In this project we are interfacing UV Sensor ML8511 with ESP32 for measuring Ultra Violet Light Intensity in mW/cm^2. UV Radiation or Ultraviolet light radiation occurs from 10nm to 400nm wavelength in the electromagnetic spectrum. So in order to get effective output in accordance with UV light the GY/ML8511 sensor from lapis semiconductor helps a lot. The ML8511 UV sensor detects 280nm – 390nm light in a better way, this wavelength is categorized as part of the UVB-burning rays spectrum and most of the UVA-tanning rays spectrum.
The ML8511 sensor is very easy to use. It outputs an analogue voltage that is linearly related to the measured UV intensity (mW/cm2). If your microcontroller can do an analogue to voltage conversion, then you can detect the level of UV. It has Low supply current of 300uA and low standby current of 0.1A. It comes with Small and thin surface-mount package (4.0mm x 3.7mm x 0.73mm(0.16″ x 0.15″ x 0.03″), 12-pin ceramic QFN).
You can see check this sensor interfacing with Arduino here:
1. UV Index Meter with UV Sensor ML8511 & Arduino
Bill of Materials
Following are the components that can be used for this project. All these components can be purchased from the Amazon.
| S.N. | Components Name | Quantity | Purchase Links |
|---|---|---|---|
| 1 | ESP32 Board | 1 | Amazon | AliExpress |
| 2 | UV Sensor ML8511 | 1 | Amazon | AliExpress |
| 4 | 16X2 LCD Display | 1 | Amazon | AliExpress |
| 5 | Connecting Wires | 10 | Amazon | AliExpress |
| 6 | Breadboard | 1 | Amazon | AliExpress |
UV Sensor ML8511
Introduction:
The ML8511 UV sensor is easy to use the ultraviolet light sensor. The MP8511 UV (ultraviolet) Sensor works by outputting an analog signal in relation to the amount of UV light that’s detected. This breakout can be very handy in creating devices that warn the user of sunburn or detect the UV index as it relates to weather conditions.
This sensor detects 280-390nm light most effectively. This is categorized as part of the UVB (burning rays) spectrum and most of the UVA (tanning rays) spectrum. It outputs an analogue voltage that is linearly related to the measured UV intensity (mW/cm2). If your microcontroller can do an analogue to digital signal conversion then you can detect the level of UV!
Block Diagram
The UV Sensor ML8511 has Photodiode sensitive to UV-A and UV-B. Then it has internal Embedded operational amplifier which will convert photocurrent to voltage output depending on the UV light intensity.
The output is always in the form of Analog voltage. Through the voltage output, it is easy to interface with external microcontrollers and ADC.
UV Characteristics
The characteristics are drawn between output Voltage from the sensor with respect to UV intensity (mW/cm²) at constant VDD supply. The curves in different colors represent sensor operation in the different temperatures range.
UV Index Meter with ESP32 & UV Sensor ML8511
The circuit diagram for interfacing UV sensor ML8511 with ESP32 and I2C LCD Display is given below. LCD is supplied with 5V & its GND is connected to GND of ESP32. The SCL & SDA pin of I2C LCD is connected to GPIO22 & GPIO21 of ESP32.
The UV Sensor has 5 pins Vin, 3V3, GND, OUT, EN. Some of the modules don’t have Vin pin which is not used too. The EN pin and 3V3 pin are connected to the 3.3V pin of ESP32. The same 3V3 Pin is connected to Analog pin GPIO4 which is used as a reference voltage. The out pin is connected to GPIO of ESP32 and GND to GND.
This connection for ML8511 is somewhat tricky. Analog to digital conversions rely completely on VCC. We assume this is 5.0V, but if the board is powered from USB this may be as high as 5.25V or as low as 4.75V. Because of this unknown window, it makes the ADC on the ESP32 fairly inaccurate. To fix this, we use the very accurate onboard 3.3V reference (accurate within 1%). So by doing an analog to digital conversion on the 3.3V pin (by connecting it to GPIO4) and then comparing this reading against the reading from the sensor, we can extrapolate a true-to-life reading, no matter what VIN is (as long as it’s above 3.4V).
Program/Source Code
The source code for UV Sensor ML8511 & ESP32 Interfacing is given below. Copy the source code and upload it to the ESP32 Board.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
#include <Wire.h> #include <LiquidCrystal_I2C.h> // Set the LCD address to 0x27 for a 16 chars and 2 line display LiquidCrystal_I2C lcd(0x27, 16, 2); int UVOUT = 15; //Output from the sensor int REF_3V3 = 4; //3.3V power on the ESP32 board void setup() { // initialize the LCD lcd.begin(21,22); // sda=21, scl=22 lcd.backlight(); pinMode(UVOUT, INPUT); pinMode(REF_3V3, INPUT); } //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); lcd.clear(); lcd.print("UV Ray Intensity"); lcd.setCursor(0, 1); lcd.print(uvIntensity); lcd.print(" mW/cm^2"); Serial.println(); delay(200); } |
Once the code is uploaded, you can now see the UV Index when placed in sunlight.
Code Explanation
|
1 |
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.
|
1 2 3 4 |
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; } |
Mapping the UV_Voltage to intensity is straight forward. No UV light starts at 1V with a maximum of 15mW/cm2 at around 2.8V. ESP32 has a built-in map() function, but map() does not work for floats, so we have a simple mapFloat() function.
|
1 |
float uvIntensity = mapfloat(outputVoltage, 0.99, 2.8, 0.0, 15.0); |
The following line converts the voltage read from the sensor to mW/cm2 intensity.












3 Comments
How are you using not analog pins to read analog values?
Looks like he is:
int uvLevel = averageAnalogRead(UVOUT);
int refLevel = averageAnalogRead(REF_3V3);
That’s in the loop()
how was ur experience with the sensor.. kindly suggest me