Arduino Nano 33 IoT - GUVA-S12SD UV Sensor

This tutorial instructs you how to use Arduino Nano 33 IoT to measure ultraviolet light with a GUVA-S12SD UV sensor module. Because the board already has Wi-Fi, it is a natural base for a sun monitor on a balcony that later sends the UV index to your phone or to a cloud dashboard. In detail, we will learn:

Arduino Nano 33 IoT GUVA-S12SD UV Sensor

We suggest:

Hardware Preparation

1×Arduino Nano 33 IoT
1×Micro USB Cable
1×GUVA-S12SD UV Sensor Module
1×Breadboard
1×Jumper Wires
1×Recommended: Screw Terminal Expansion Board for Arduino Nano
1×Recommended: Breakout Expansion Board for Arduino Nano
1×Recommended: Power Splitter for Arduino Nano

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Overview of GUVA-S12SD UV Sensor and Its Pinout

GUVA-S12SD UV Sensor Pinout
image source: diyables.io

The GUVA-S12SD module is a small purple board, about 11mm x 27mm, with two holes for screws. Two parts do the work. The small white square is the GUVA-S12SD photodiode. When UV light falls on it, it lets a very tiny current flow. That current is too small to read, so a VLM358 op-amp next to it changes it into a voltage on the SIG pin. The Arduino Nano 33 IoT then reads that voltage with analogRead(). More UV means a higher voltage. The DIYables module comes presoldered, in a pack of two.

GUVA-S12SD UV Sensor Module
Sensing element GUVA-S12SD UV photodiode
Amplifier VLM358 op-amp
Light it detects UV-A and UV-B, 240nm to 370nm
Viewing angle 130 degrees
Supply voltage 2.5V to 5V DC
Output analog voltage, about 0V (no UV) to about 1V or a bit more (strong sun)
Board size about 11mm x 27mm, two mounting holes

Three pins are printed on the board, in this order:

  • SIG pin: must be connected to an analog input pin of the Arduino Nano 33 IoT. Its voltage goes up as the UV light gets stronger
  • GND pin: must be connected to GND (0V)
  • VCC pin: must be connected to the 3.3V pin of the Arduino Nano 33 IoT

※ NOTE THAT:

The arrangement of pins on a module may differ from one manufacturer to another. It is essential to always refer to the labels printed on the module when using it. Take a close look!

From Voltage to UV Index

Most makers use a simple rule with this module: the UV index is roughly the SIG voltage divided by 0.1V. So 0.1V is about UV index 1, and 0.6V is about UV index 6. This is a good guess for a hobby project, but the module is not a calibrated UV meter. The World Health Organization groups the UV index into five levels:

UV Index Level What it means
0 - 2 Low little danger for most people
3 - 5 Moderate use sunscreen and a hat around noon
6 - 7 High cover up and look for shade
8 - 10 Very High skin can burn quickly
11+ Extreme avoid the midday sun

A key point before testing: window glass, indoor lamps and normal LEDs give almost no UV, so inside a room the reading stays near 0. Take the sensor outside into sunlight, or shine a UV flashlight on it, to see the numbers move.

Wiring Diagram

Feed the module from the 3.3V pin, which is the logic level of the Arduino Nano 33 IoT, join the grounds, and route SIG to analog pin A0.

The wiring diagram between Arduino Nano and 33 IoT GUVA-S12SD UV Sensor

This image is created using Fritzing. Click to enlarge image

GUVA-S12SD UV Sensor Arduino Nano 33 IoT
SIG A0
GND GND
VCC 3.3V

How To Program For GUVA-S12SD UV Sensor

The sensor needs no library. Everything is done with analogRead() and a little math.

  • The first step is to name the Arduino Nano 33 IoT pin that receives the SIG signal:
#define UV_SIG_PIN A0
  • Raise the ADC resolution in setup(). Out of the box, analogRead() on the Arduino Nano 33 IoT returns 0 to 1023 (10-bit). With 12-bit it returns 0 to 4095, which gives steps of about 0.8mV - useful, because the SIG signal rarely goes above 1V:
analogReadResolution(12);
  • Read the pin and turn the number into volts. The ADC measures from 0V to 3.3V:
int adc_value = analogRead(UV_SIG_PIN); float sig_voltage = adc_value * 3.3 / 4095.0;
  • Divide by 0.1 to get an approximate UV index:
float uv_index = sig_voltage / 0.1;

Arduino Nano 33 IoT Code for GUVA-S12SD UV Sensor - ADC Value and Voltage

Start with the bare numbers. Once a second, this sketch prints the 12-bit ADC value from pin A0 and the matching SIG voltage with three decimals. It is the best way to check the wiring and to get a feeling for how the sensor reacts.

/* * This Arduino Nano 33 IoT code was developed by newbiely.com * * This Arduino Nano 33 IoT code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano-iot/arduino-nano-33-iot-guva-s12sd-uv-sensor */ #define UV_SIG_PIN A0 // The Arduino Nano 33 IoT pin A0 connected to the SIG pin of the GUVA-S12SD module #define ADC_MAX 4095.0 // 12-bit ADC: values from 0 to 4095 #define VREF 3.3 // the ADC of the Arduino Nano 33 IoT measures from 0V to 3.3V void setup() { Serial.begin(9600); analogReadResolution(12); // the default is 10-bit (0 to 1023); 12-bit gives finer steps for the small UV signal } void loop() { int adc_value = analogRead(UV_SIG_PIN); // raw number from 0 to 4095 float sig_voltage = adc_value * VREF / ADC_MAX; // convert it to the voltage on the SIG pin Serial.print("ADC: "); Serial.print(adc_value); Serial.print(" | SIG: "); Serial.print(sig_voltage, 3); // three decimals, because the signal is small Serial.println(" V"); delay(1000); }

Detailed Instructions

If this is the first time you use the Arduino Nano 33 IoT, see the Getting Started with Arduino Nano 33 IoT tutorial before going further.

  • Wire the components as shown in the diagram, with VCC on the 3.3V pin.
  • Connect the Arduino Nano 33 IoT board to your computer using a USB cable.
  • Open Arduino IDE on your computer.
  • Select the Arduino Nano 33 IoT board and the right COM port.
  • Copy the code above and paste it into the Arduino IDE.
  • Click the Upload button to compile the code and send it to the board.
  • Open the Serial Monitor at 9600 baud.
  • Read a few lines indoors, then carry the board (on a laptop or a power bank) to a sunny spot and point the white sensor at the sky.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Nano 33 IoT
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Nano 33 IoT' on 'COM15')
New Line
9600 baud
ADC: 6 | SIG: 0.005 V ADC: 9 | SIG: 0.007 V ADC: 14 | SIG: 0.011 V ADC: 412 | SIG: 0.332 V ADC: 587 | SIG: 0.473 V ADC: 731 | SIG: 0.589 V ADC: 748 | SIG: 0.603 V ADC: 702 | SIG: 0.566 V
Ln 11, Col 1
Arduino Nano 33 IoT on COM15
2

The first three lines come from a desk next to a window: almost nothing, as expected. The jump starts the moment the sensor sees open sky. If the value stays at 0 even in bright sun, check the SIG wire on A0.

Arduino Nano 33 IoT Code for GUVA-S12SD UV Sensor - UV Index and Risk Level

A raw voltage does not tell you whether you need sunscreen. This sketch reads A0 sixteen times, takes the average so the result does not jump around, converts it to volts, then to a UV index with one decimal. Finally it picks the WHO level name from the table above.

/* * This Arduino Nano 33 IoT code was developed by newbiely.com * * This Arduino Nano 33 IoT code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/arduino-nano-iot/arduino-nano-33-iot-guva-s12sd-uv-sensor */ #define UV_SIG_PIN A0 // The Arduino Nano 33 IoT pin A0 connected to the SIG pin of the GUVA-S12SD module #define ADC_MAX 4095.0 // 12-bit ADC: values from 0 to 4095 #define VREF 3.3 // ADC reference voltage of the Arduino Nano 33 IoT #define SAMPLE_COUNT 16 // number of readings averaged together for one result void setup() { Serial.begin(9600); analogReadResolution(12); // read the analog pin as 12-bit (0 to 4095) } void loop() { // take several readings and average them to calm down small jumps long sum = 0; for (int i = 0; i < SAMPLE_COUNT; i++) { sum += analogRead(UV_SIG_PIN); delay(5); } float adc_average = sum / (float)SAMPLE_COUNT; float sig_voltage = adc_average * VREF / ADC_MAX; // approximate rule for this module: every 0.1V on SIG is about 1 UV index point float uv_index = sig_voltage / 0.1; Serial.print("SIG: "); Serial.print(sig_voltage, 2); Serial.print(" V -> UV index: "); Serial.print(uv_index, 1); Serial.print(" ("); Serial.print(uvLevel(uv_index)); Serial.println(")"); delay(1000); } // return the WHO risk level name for a UV index value const char* uvLevel(float uv) { if (uv < 3) return "Low"; if (uv < 6) return "Moderate"; if (uv < 8) return "High"; if (uv < 11) return "Very High"; return "Extreme"; }

Detailed Instructions

  • Keep the same wiring.
  • Paste the code above into the Arduino IDE and click Upload.
  • Take the sensor outdoors and open the Serial Monitor.
  • Try full sun, then light shade under a tree, and compare the levels.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Nano 33 IoT
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Nano 33 IoT' on 'COM15')
New Line
9600 baud
SIG: 0.71 V -> UV index: 7.1 (High) SIG: 0.73 V -> UV index: 7.3 (High) SIG: 0.74 V -> UV index: 7.4 (High) SIG: 0.46 V -> UV index: 4.6 (Moderate) SIG: 0.39 V -> UV index: 3.9 (Moderate) SIG: 0.42 V -> UV index: 4.2 (Moderate) SIG: 0.82 V -> UV index: 8.2 (Very High)
Ln 11, Col 1
Arduino Nano 33 IoT on COM15
2

Shade cuts the UV a lot but not to zero, which the middle lines show. If your numbers look much higher or lower than the UV index in your local weather app, you can adjust the 0.1 divisor a little to match.

Additional Knowledge

Can a normal light sensor do the job of the GUVA-S12SD on the Arduino Nano 33 IoT?

Light Sensor (LDR) GUVA-S12SD UV Sensor
What it reacts to visible light, the light our eyes see UV-A and UV-B only, 240nm to 370nm
Indoor lamp big change in the reading almost no change, stays near 0
Output a resistance that changes, used with a resistor a ready-made voltage from the op-amp on the board
Typical use day/night switch, room brightness sunburn alerts, UV index station, UV lamp check

It is evident that only the GUVA-S12SD tells you about the part of sunlight that burns the skin. A cloudy day can feel dark but still carry a lot of UV, and an LDR would miss that.

Some project ideas for this sensor on the Arduino Nano 33 IoT:

  • A sunscreen reminder that sends a message when the UV index passes 6
  • A small UV index station that posts readings to a cloud dashboard over Wi-Fi
  • A tester that checks whether a UV lamp or UV LED is still strong
  • A smart window blind that closes when the sun gets too strong

Video Tutorial

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!