fbpx
Light Intensity Meter
Arduino Project

Light Intensity Meter

Measure the Light Intensity using an LDR

Components Required

Introduction

A light meter is a device used to measure the amount of light. The aim of this project is to build a light intensity meter. Light intensity is measured in Lux. We will use the magicbit onboard Photoresistor (LDR) to measure the Lux. We will have to calibrate our light intensity meter, which is a bit of mathematical work. But for this project, we will be using the simplest possible method.

What is LUX?

The word LUX is derived from the Latin word for light.

Lux is SI units of illuminance, measuring luminous flux per unit area.

Instructions

  1. First, we will be needing an already available lux meter. We can use the Magicblocks app on the play store (For iOS users, any app that can measure lux will be fine).

  1. Then we have to get some data sets to calibrate our sensor with the app. We have to note down analog output values from the photoresistor and lux meter app for the same lighting conditions.

You can make a table like this below and fill it.

  1. Then adjust the light level and get the Lux value and LDR values. You can choose LDR values to be the independent variables (choose LDR values as you wish and find the lux value corresponding to it). Get many data sets as you can (>20).
  1. After filling the table, copy the given code.
// Light intensity meter
// Magicbit
// Project by Pandula and Chathumal

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Adafruit_SSD1306 display(128, 64);
 
void setup(){
  pinMode(36,INPUT);
  Serial.begin(115200);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.drawRect(0, 0, 128, 15, 1);
  display.setTextSize(1.5);
  display.setTextColor(WHITE);
  display.setCursor(19,4);
  display.print("Light Intensity");
  display.setTextSize(1);
  display.setCursor(0,18);
  display.print(" Move the LDR toward\n  the light source");
  
 
}
void loop(){

  // Array that stores LDR values
  float in[] = {0,200,400,600,800,1000,1200,1400,1600,1800,2000,2200,2400,2600,2800,3000,3200,3400,3600,3800,4000};

  // Array that stores LUX values
  float out[] = {0,6,9,13,18,24,31,39,49,64,80,105,139,184,257,366,626,896,1532,3000,6400}; 
  
  float val1 = analogRead(36); // LDR pin
  float val = FmultiMap(val1, in, out,21);
  Serial.println(val);
  delay(100);
  int prevVal = 0;

  // Displaying the value
  if(val != prevVal){
    prevVal = val;
    display.fillRect(0, 42, 120, 20, 0);
    display.setTextSize(2);
    display.setCursor(0,48);
    display.print(val);
    display.print("LUX");
    display.display();
}
}


float FmultiMap(float val, float * _in, float * _out, uint8_t size)
{
  // take care the value is within range
  // val = constrain(val, _in[0], _in[size-1]);
  if (val <= _in[0]) return _out[0];
  if (val >= _in[size - 1]) return _out[size - 1];

  // search right interval
  uint8_t pos = 1;  // _in[0] allready tested
  while (val > _in[pos]) pos++;

  // this will handle all exact "points" in the _in array
  if (val == _in[pos]) return _out[pos];

  // interpolate in the right segment for the rest
  return (val - _in[pos - 1]) * (_out[pos] - _out[pos - 1]) / (_in[pos] - _in[pos - 1]) + _out[pos - 1];
}
  
  

  1. Edit the in array with LDR values and OUT array with Lux values.

  1. Upload the code.

Note:

  • Note that The accuracy of this meter will be low if you have a smaller number of data sets. This is because we have used linear interpolation techniques in our code.
  • Using better mathematical tools, we can get a better result (curve fitting).
Related Posts
Leave a Reply