Sunburn warning indicator

As someone with fair skin who is prone to sunburns, I would benefit from an early warning system which reminded me when I had spent too much time in the sun. This prototype simply increments a counter at a rate proportional to the light level reported by the photo sensor, then triggers a warning when the counter exceeds a preset level. A two-color LED is used to display the current light level as a range of blue (low light) to red (bright light).

Planned improvements include:

  • light level floor (no exposure is registered when you are inside)
  • UV-only filter (more accurate measurement of sunlight)
  • adjustable sensitivity (for different skin types)
  • multi-level warning indicator (green/yellow/red)
  • sunscreen mode: sensitivity is divided by the SPF for a few hours
  • decrement the counter when user is out of the sun for a while
  • embed it in a wearable object, such as a pendant

The wiring schematic is quite simple: the analog input is driven by a voltage divider using a 1kOhm resistor to +5V and a photo sensor to ground. Two PWM “analog” outputs power the 2-color LED (blue/red in this case). The red warning LED is powered by a digital output.


One red LED and one bi-color LED are used as indicators, while a photo-sensitive resistor is the input.

One red LED and one bi-color LED are used as indicators, while a photo-sensitive resistor provides input.

Arduino Code

The code is fairly straightforward: calculate the resistance of the photo resistor using the voltage measurement at the voltage divider, use that to scale the red/blue LED. Add the light level to the exposure counter and set off the warning light if exposure exceeds the threshold.


sunburn warning
A photo-resistor is used to detect bright-light situations,
and a bi-color LED indicates the level of light detected.
Once the cumulative light exposure passes a set threshold,
a red warning LED is lit.


int photoPin = 5; // the photo resistor
int ledPinRed = 5; // the red half of the LED
int ledPinBlue = 6; // the blue half of the LED
int ledPinWarn = 7; // the red warning LED
int lightLevel; // used to store the current level of light sensed
int lightAccum = 0; // the accumulated light counter
int maxLightAccum = 20000; // the warning threshold for the accumulated light counter
// note that to convert this number to a useful unit like lumen-seconds it is necessary to consider the delay (currently 0.01 sec)
int ledLevelRed; // level to set the red portion of the bi-color LED
int ledLevelBlue; // level to set the blue portion of the bi-color LED
int blinkRate; // not used; early concept was to communicate warning through speed of blinking
int vIn = 5; // voltage on V+ rail; used to scale the photo resistor reading
int rBridge = 10000; // rating of the voltage bridge resistor in Ohms
int rPhoto; // calculated resistance of the photo resistor at each cycle

void setup(){
pinMode(ledPinWarn, OUTPUT);

void loop(){
measure light level
lightLevel = analogRead(photoPin); // get the current voltage at the voltage divider, over a range of 0-1023
rPhoto = rBridge * ((vIn / lightLevel) - 1); // calculated resistance of photo resistor
Serial.print("light level: ");
// Serial.print(" = r of ");
// Serial.println(rPhoto);
set bi-color LED levels
ledLevelRed = map(lightLevel, 1023, 0, 0, 254); // red gets brighter as light level increases; note that resistance decreases as light level increases
ledLevelBlue = map(lightLevel, 1023, 0, 254, 0); // blue gets dimmer as light level increases; note that resistance decreases as light level increases
Serial.print(" led level Red: ");
Serial.print(" led level Blue: ");
analogWrite(ledPinRed, ledLevelRed);
analogWrite(ledPinBlue, ledLevelBlue);
update accumlated light exposure
lightAccum = lightAccum + (ledLevelRed);
Serial.print(" light accum: ");
set off warning light if exposure level is exceeded
if (lightAccum > maxLightAccum){
digitalWrite(ledPinWarn, HIGH);