Overview
The GUVA-S12SD UV Light Intensity Sensor Module is a compact analog ultraviolet sensor built around the Genicom GUVA-S12SD gallium nitride photodiode. The photodiode responds to light in the 240-370 nm band, which covers the UVB range and most of the UVA range — the same wavelengths used to calculate the solar UV Index. The purple CJMCU-style breakout has just three pins (SIG, GND, VCC), making it one of the simplest ways to add sunlight and UV monitoring to an Arduino, ESP32, or Raspberry Pi Pico project.
The photodiode itself produces only a tiny photocurrent — around 113 nA under a 1 mW/cm² UVA source — far too small for a microcontroller to measure directly. The onboard SGM8521 rail-to-rail op-amp amplifies this current into a clean analog voltage on the SIG pin that rises proportionally with UV intensity. A convenient rule of thumb for sunlight is that the UV Index is approximately the output voltage in millivolts divided by 100, so about 0.5 V corresponds to UV Index 5. Because the output tops out around 1 V even in intense sun, it stays comfortably within the safe input range of 3.3V ADCs.
The module runs on anything from 3.3 V to 5 V, so it pairs directly with the ADC pins on an Arduino, ESP32, or Pico with no level shifting. The Raspberry Pi is the one exception: it has no analog inputs, so you read the sensor through an external ADC such as the ADS1115. Typical projects include UV Index weather stations, sun-exposure loggers and wearables, UV lamp monitors, and automatic sunshade or alert systems.
At a Glance
Specifications
| Parameter | Value |
| Sensing Element | GUVA-S12SD gallium nitride Schottky photodiode |
| Spectral Detection Range | 240 - 370 nm (UVB and most UVA) |
| Peak Responsivity | 0.14 A/W at 352 nm |
| Typical Photocurrent | 113 nA at 1 mW/cm² (UVA lamp) |
| Dark Current | 1 nA maximum |
| Onboard Amplifier | SGM8521 rail-to-rail op-amp |
| Operating Voltage | 3.3V - 5V DC |
| Output Signal | Analog voltage, approx. 0.1 V per UV Index point (0 - 1 V in sunlight) |
| UV Index Conversion | UV Index ≈ Vout (mV) / 100 |
| Interface | 3-pin header: SIG, GND, VCC |
| Viewing Angle | Approx. 100 degrees |
| Operating Temperature | -30°C to +85°C |
Pinout Diagram
The module has three pins. SIG is the amplified analog output — connect it to an ADC input on your board (or to an external ADC on Raspberry Pi). GND connects to ground, and VCC accepts any supply from 3.3 V to 5 V. There are no data buses, addresses, or configuration pins to worry about.
Wiring Guide
Arduino Wiring
The GUVA-S12SD connects directly to an Arduino analog pin. Power it from 5V and read SIG on A0 — no level shifting or extra components are needed because the sensor output never exceeds about 1 V.
| GUVA-S12SD Pin | Arduino Pin |
|---|---|
| VCC | 5V |
| GND | GND |
| SIG | A0 |
ESP32 Wiring
The ESP32 reads the sensor directly on one of its ADC pins. Power the module from the 3.3V rail — the output still reaches about 0.1 V per UV Index point, and it stays well below the 3.3V ADC limit.
| GUVA-S12SD Pin | ESP32 Pin | Details |
|---|---|---|
| VCC | 3.3V | |
| GND | GND | |
| SIG | GPIO 34 | ADC1_CH6, input-only pin |
Raspberry Pi Wiring
The Raspberry Pi has no analog-to-digital converter on any of its GPIO pins, so it cannot read the SIG output by itself — a GPIO pin only sees digital highs and lows, and the sensor's 0-1 V output will simply read as "low" forever. The standard solution is an ADS1115 16-bit ADC breakout: the sensor connects to the ADS1115, and the ADS1115 talks to the Pi over I2C.
| Module Pin | Connects To | Details |
|---|---|---|
| GUVA-S12SD VCC | Pin 1 (3.3V) | Shared 3.3V rail |
| GUVA-S12SD GND | Pin 6 (GND) | Shared ground |
| GUVA-S12SD SIG | ADS1115 A0 | Analog input channel 0 |
| ADS1115 VDD | Pin 1 (3.3V) | |
| ADS1115 GND | Pin 6 (GND) | |
| ADS1115 SDA | Pin 3 (GPIO 2) | I2C data |
| ADS1115 SCL | Pin 5 (GPIO 3) | I2C clock |
Raspberry Pi Pico Wiring
Unlike the full-size Raspberry Pi, the Pico has a built-in 12-bit ADC, so the sensor connects directly. Power the module from the 3V3(OUT) pin and read SIG on one of the three ADC-capable GPIOs.
| GUVA-S12SD Pin | Pico Pin | Details |
|---|---|---|
| VCC | 3V3(OUT) (physical pin 36) | |
| GND | GND (physical pin 38) | |
| SIG | GP26 (physical pin 31) | ADC0 input |
Code Examples
Arduino
// GUVA-S12SD UV Sensor - Arduino Example
// SIG Pin: A0, VCC: 5V, GND: GND
// UV Index is approximately the output voltage in mV divided by 100
const int sigPin = A0;
const int numSamples = 16;
void setup() {
Serial.begin(9600);
}
void loop() {
// Average several readings to smooth out ADC noise
long total = 0;
for (int i = 0; i < numSamples; i++) {
total += analogRead(sigPin);
delay(2);
}
float raw = total / (float)numSamples;
// Convert the 10-bit reading (0-1023) to millivolts (5V reference)
float millivolts = raw * (5000.0 / 1023.0);
// Approximate solar UV Index: mV / 100
float uvIndex = millivolts / 100.0;
Serial.print("Voltage: ");
Serial.print(millivolts, 0);
Serial.print(" mV | UV Index: ");
Serial.println(uvIndex, 1);
delay(1000);
}
ESP32 (MicroPython)
# GUVA-S12SD UV Sensor - ESP32 MicroPython Example
# SIG Pin: GPIO 34 (ADC1_CH6), VCC: 3.3V, GND: GND
# UV Index is approximately the output voltage in mV divided by 100
from machine import ADC, Pin
import time
adc = ADC(Pin(34)) # GPIO 34: input-only pin on ADC1
adc.atten(ADC.ATTN_11DB) # Full 0-3.3V input range
while True:
# Average several readings to smooth out ADC noise
total_uv = 0
for _ in range(16):
total_uv += adc.read_uv() # Factory-calibrated reading in microvolts
time.sleep_ms(2)
millivolts = total_uv / 16 / 1000
# Approximate solar UV Index: mV / 100
uv_index = millivolts / 100
print("Voltage: {:.0f} mV | UV Index: {:.1f}".format(millivolts, uv_index))
time.sleep(1)
Raspberry Pi (Python + ADS1115)
#!/usr/bin/env python3
# GUVA-S12SD UV Sensor - Raspberry Pi + ADS1115 Example
# The Pi has no analog inputs, so an ADS1115 reads SIG over I2C.
# SIG -> ADS1115 A0, SDA -> GPIO 2, SCL -> GPIO 3
# Install the library first:
# pip3 install adafruit-circuitpython-ads1x15
import time
import board
import busio
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
# I2C bus on GPIO 2 (SDA) / GPIO 3 (SCL)
i2c = busio.I2C(board.SCL, board.SDA)
# ADS1115 at default address 0x48, sensor SIG on channel A0
ads = ADS.ADS1115(i2c)
ads.gain = 2 # +/-2.048V full scale covers the 0-1V output with headroom
channel = AnalogIn(ads, ADS.P0)
try:
while True:
millivolts = channel.voltage * 1000
# Approximate solar UV Index: mV / 100
uv_index = millivolts / 100
print("Voltage: {:.0f} mV | UV Index: {:.1f}".format(millivolts, uv_index))
time.sleep(1)
except KeyboardInterrupt:
print("Measurement stopped by user")
Raspberry Pi Pico (MicroPython)
# GUVA-S12SD UV Sensor - Pico MicroPython Example
# SIG Pin: GP26 (ADC0, physical pin 31), VCC: 3V3(OUT), GND: GND
# UV Index is approximately the output voltage in mV divided by 100
from machine import ADC
import time
adc = ADC(26) # GP26 = ADC0
CONVERSION = 3.3 / 65535 # read_u16() returns 0-65535 across 0-3.3V
while True:
# Average several readings to smooth out ADC noise
total = 0
for _ in range(16):
total += adc.read_u16()
time.sleep_ms(2)
millivolts = (total / 16) * CONVERSION * 1000
# Approximate solar UV Index: mV / 100
uv_index = millivolts / 100
print("Voltage: {:.0f} mV | UV Index: {:.1f}".format(millivolts, uv_index))
time.sleep(1)