How to Make a UV Sensor With OLED Screen Display
by lobster_enthusiast in Circuits > Arduino
48 Views, 0 Favorites, 0 Comments
How to Make a UV Sensor With OLED Screen Display
This project will detect the UV level and display it on a little OLED display screen. the circuit is small, and perfect to adapt into a little keychain to take around (which i'm working on). i made this because i rarely put on sunscreen despite the high UV levels around, especially during summer, so i'm hoping that this device will help me put on sunscreen more often
Supplies
electronics needed:
- Arduino nano (another microcontroller could work too, like Uno)
- button (optional just to turn on and off)
- I2C OLED display screen, 0.96'' by 0.96''
- UV sensor GUVA-S12SD
- breadboard
- jumpers
Electronics Wiring
Both the UV sensor and the oled display are powered by the 5V pin on the Nano, and have shared ground. Connect the signal (SIG) pin on the UV sensor to A0, SCL to A5 and SDA to A4 (A4 and A5 pins on the nano are capable of I2C, so can control the oled display).
optionally you could add a button to turn the display and sensor on and off, which you would connect it across gnd and a digital pin (i.e. D2)
Upload Arduino Code + Drawing Bitmaps
below is the code i used (no button logic), which includes the cloudy and sunny drawings i drew as bitmaps.
if you want to use your own drawings, you can draw them in this website which will generate a bitmap of the drawing, which you can just replace in the code: https://oled-pixel-editor.netlify.app/
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define UV_PIN A0 //uv sensor pin
const float VREF = 5.0;
#define ICON_WIDTH 32
#define ICON_HEIGHT 32
// sun 32x32 bits
const unsigned char sunBitmap[] PROGMEM = {
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x40,
0x10, 0x00, 0x03, 0x80,
0x00, 0x00, 0x81, 0x00,
0x00, 0x00, 0x80, 0x02,
0x02, 0x00, 0x80, 0x20,
0x01, 0x00, 0x80, 0x40,
0x00, 0x80, 0x00, 0x80,
0x00, 0x43, 0xE1, 0x00,
0x00, 0x0F, 0xF8, 0x00,
0x00, 0x1F, 0xFC, 0x00,
0x00, 0x3F, 0xFE, 0x00,
0x00, 0x3F, 0xFE, 0x00,
0x00, 0x7F, 0xFF, 0x00,
0x00, 0x7F, 0xFF, 0x00,
0x0F, 0x7F, 0xFF, 0x78,
0x00, 0x7F, 0xFF, 0x00,
0x00, 0x7F, 0xFF, 0x00,
0x00, 0x3F, 0xFE, 0x00,
0x40, 0x3F, 0xFE, 0x00,
0x00, 0x1F, 0xFC, 0x00,
0x00, 0x4F, 0xF9, 0x00,
0x00, 0x83, 0xE0, 0x80,
0x01, 0x00, 0x00, 0x40,
0x02, 0x00, 0x80, 0x20,
0x00, 0x00, 0x80, 0x00,
0x00, 0x00, 0x80, 0x00,
0x00, 0x00, 0x80, 0x00,
0x01, 0x00, 0x80, 0x00,
0x03, 0x80, 0x00, 0x08,
0x09, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
// cloud 32x32 bits
const unsigned char cloudBitmap[] PROGMEM = {
0x00, 0x00, 0x00, 0x07,
0x0E, 0x08, 0x00, 0x0F,
0x1F, 0x80, 0x00, 0x1F,
0x7F, 0xF0, 0x02, 0x3F,
0x7F, 0xF8, 0x00, 0x3F,
0xFF, 0xFC, 0x00, 0x7F,
0xFF, 0xFC, 0x00, 0x7F,
0x7F, 0xF8, 0x0F, 0xFF,
0x3F, 0xC0, 0x3F, 0xFF,
0x00, 0x00, 0x7F, 0xFF,
0x00, 0x00, 0x7F, 0xFF,
0x00, 0x40, 0xFF, 0xFF,
0x00, 0x21, 0xFF, 0xFF,
0x00, 0x71, 0xFF, 0xFF,
0x00, 0x21, 0xFF, 0xFF,
0x20, 0x01, 0xFF, 0xFF,
0x00, 0x01, 0xFF, 0xFF,
0x00, 0x00, 0xFF, 0xFF,
0x00, 0x00, 0x7F, 0xFF,
0x00, 0x00, 0x00, 0xFF,
0x00, 0x78, 0x00, 0x00,
0x01, 0xFC, 0x04, 0x00,
0x0F, 0xFF, 0x00, 0x00,
0x0F, 0xFF, 0x80, 0x08,
0x8F, 0xFF, 0x80, 0x1C,
0x07, 0xFF, 0x00, 0x08,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x20
};
void setup() {
Serial.begin(9600);
Wire.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
display.display();
}
void loop() {
// sensor & disp
int rawValue = analogRead(UV_PIN);
float voltage = rawValue * (VREF / 1023.0);
float uvIndex = voltage / 0.1;
if (uvIndex < 0) uvIndex = 0;
if (uvIndex > 11) uvIndex = 11;
bool isHighUV = (uvIndex >= 3.0); //adjust threshold if needed..
display.clearDisplay();
// cloud or sun bitmap
int iconX = 95;
int iconY = 0;
if (isHighUV) {
display.drawBitmap(iconX, iconY, sunBitmap, ICON_WIDTH, ICON_HEIGHT, SSD1306_WHITE);
} else {
display.drawBitmap(iconX, iconY, cloudBitmap, ICON_WIDTH, ICON_HEIGHT, SSD1306_WHITE);
}
// disp uv reading
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(4, 6);
display.print("UV:");
display.setCursor(16, 22);
display.print(uvIndex, 1);
//message
display.setTextSize(1);
display.setCursor(0, 50);
if (isHighUV) {
display.println("Wear your sunscreen!");
} else {
display.println("No sunscreen needed!");
}
display.display();
delay(200);
}
Test
Try testing it out in the sun or nearby a window to see if the UV changes, and cover the uv photodiode (the small square on the side) to see if it senses uv properly. Now it's done! :))