Light Meter Programming


I'm hoping I can obtain some much needed help with the programming of a circuit. I have never programmed before so this is all new to me. Well I'm designing an ambient light sensor with a digital display showing the amount of lux detected. So pretty much, just a basic light meter with a digital display for the lux. Looking at other light meters on the market I believe I want the lux range to be from 0 to anywhere to 20k, 40k, 50k, or even 100k lux. The max lux range really doesn't matter as long as it's sufficient enough. With the help of a customer service member I have already ordered the main parts I believe I'll need for this circuit. Those parts being a photocell, a LCD screen (HD44780 chipset), and a micro-controller(Arduino Uno). I already have a breadboard, resistors, etc. If someone would be so kind to help me out by telling me how the easiest way to start constructing and programming this circuit I would greatly appreciate it. Diagrams or similar projects with my components would be great too. Thanks again. Here are the web pages to the parts I have ordered so far:


(LCD Screen)


Where “map to 0…5 Volts” is used as comment you need to convert the number to LUX. There may be a formula or you need to create a lookuptable. And you have to print to your display iso to the serial port.

// Cnt is the number of reads that will be averaged
// pin is the analog pinnumber the LDR is connected to.
float ReadLDR(unsigned int cnt, int pin)
  if (cnt > 1000) cnt = 1000;
  else if (cnt == 0) cnt = 1;
  // multiple samples to stabilize
  float v;
  for (int i=0; i<cnt; i++) v += analogRead(pin);
  v = (v * 5.0) / 1023 / cnt;     // map to 0..5 Volts
  return v;

void setup()

void loop() 
  float val = ReadLDR(200, 0);   // read 200 times from Analog 0.
  Serial.print(val, 2);                 // print it with 2 decimals
  Serial.println(" Volt.");
  delay(100);                            // and wait 0.1 second.

Rob thank you so much for replying.

Again this is my first time programming so I'm unfamiliar with a lot of the terms. :o Would you mind explaining more of the basics about how this is all going to work and the 1st steps I have to do get the project started?

Thank you for the help. :)

Connect the LDR to a resistor as show below. As the resistance of the LDR will vary with the amount of light the voltage at point X will vary. To gain better understanding I suggest to try different values for the resistor R, to get a feeling how this sketch works. E.g. try the following 5 values for R : 1K 10K 100K 1M 10M. You will see that depending on the value of R the range of voltages (no light, max light) will change.

5V >-- [ LDR ] ---+--- [ R ] ---<  GND
           Arduino pin A0

Now to the software: The Arduino globally works as follows, when started it first will call the Setup() routine. In my example code it initializes the speed of the serial port to match the default value of the PC. Then a string is printed to see it works.

After calling Setup the arduino will call the Loop() routine over and over again. In my example a value from the LDR is read by calling ReadLDR(with some parameters), then this value which is a floating point var is printed to the serial port with 2 decimal places, and because it represents a voltage the code prints that too . Notice the difference between print en println. The latter adds a newline. Then the loop waits for 200 milliseconds and starts over again.

Then there is float ReadLDR(unsigned int cnt, int pin).
The signature states this function needs two variables, a counter and a pinnumber (abbreviated by lazy programmer) The pinnumber refers to the Analog0 pin where the hardware is connected to. The count is added to stabilize the reading by averaging multiple readings.

if (cnt > 1000) cnt = 1000;
  else if (cnt == 0) cnt = 1;

takes care that count will allways stay between 1 and 1000 as we must have at least 1 reading and not to much.

  float v;
  for (int i=0; i<cnt; i++) v += analogRead(pin);

we must declare a float for the value to return, here named v. Then we enter a for loop in which the analogRead(pin) reads a binary representation of the voltage at pin . This is a 0 for 0 volt and 1023 for 5.0 volt, 2Volt will return ~410 etc.
The construction v+= analogRead(pin) is equal to v = v + analogRead(pin). So in short the for loop adds up multiple readings.

v = (v * 5.0) / 1023 / cnt; does several things. The / cnt takes care that the reading is averaged, the *5.0 / 1023 maps the value 0…1023 to a floating point value of 0…5.0 volt. This value is returned.

So this is about how the posted code works.

Rob might also worth reading

Rob once again THANK YOU SO MUCH for the great feedback. I appreciate it a lot. ;D

I have a few questions. Well I have 3 main parts to this circuit; the LCD screen, the Arduino Uno, and the LDR. On your sketch I do not see the LCD screen. Where does this come into play?

Now for your code that you posted, what originally did that do or control?

You talk about converting the number to LUX. Could you please tell me more about what you mean by that. Also when I do that will it really be that easy just to put in the code and it should work in displaying the LUX on the screen after the circuit is built.

Thanks again. I look forward to your response.

On your sketch I do not see the LCD screen. Where does this come into play?

I use mostly a serial LCD from parallax #27979 [4x20] as it is very easy to use and it uses only pin 1 (TX) Only when uploading a new sketch you witness the Arduino version of the matrix :)

Now for your code that you posted, what originally did that do or control?

It is a testapp to see how many readings I had to do, to get a stabilized reading from the LDR.

You talk about converting the number to LUX. Could you please tell me more about what you mean by that

IN my code I convert the readings to Volts. You don't want volts, you wanted lux

Well I'm designing an ambient light sensor with a digital display showing the amount of lux detected.

So you need another formula: When you cover the LDR with black velvet == "absolute dark" , you will have found the zero point. A simple google said for the rest.


Thanks Rob.

Now I read about how I will have to calibrate to show the proper lux detected. Is there a way I don't have to do this? Like maybe a light to frequency converter found here;


Thanks always!

Very interesting sensor, I would try the first one as this has less lines :)


I have done a lot more research about programming and feel more comfortable with the terms now. I have my arduino board and my computer up and now communicating. Anyways, I was wondering if someone could send me or create a similar code for my design (light meter displaying the amount of lux on a lcd screen) that I could edit to my needs. I haven't been able to find a good code to start with yet, so I'm hoping someone can help me out with that. I appreciate your help so much. THANKS!!!


I was hoping you could help me out. I have a question about the coding. I've attached a video and code for a light meter below. I was wondering if you could tell me for that code that someone has posted if that's all the code you need for it to work. I was talking to someone at school today about it and he wasn't sure but he was telling me about how that's not an entire code. (Even though the person who posted it said it was.) He talked about the beginning of the code and how it starts with "Serial.begin (9600) " He was telling me there is a code for that alone and I would need it along with the code that got posted. Something about a library code. I was confused with what he was saying. To me it looks like an entire code but then again I don't really know nothing about coding. Can you clear anything up for me? Thanks!!!

The code you refer to is a good starting point. Learning to program is do it, try, fail , retry, fail, retry again, fail, think, think deeper ..... aha!! , try, succes, lookback, understanding :)

If you don't understand how coding the Arduino works there is an excellent PDF to get started see might takes sometime to download as it is over 100 pages.

So is that the entire code or do I have to look up some code for serial.begin in a library somewhere? Thanks!

No it is not the entire code, if you don't understand "Serial.begin(9600)" please [u]study[/u] the reference section . You can google "Arduino Serial reference".

As said in my previous mail , the code is a starting point that looks a bit like the code you have to develop for your need. So you could changing it a little bit to understand in detail how it works.

I understand that you are not familiar with arduino so please download the PDF mentioned earlier to [u]learn[/u] about how to work with an Arduino.

This forum helps people with questions about Arduino, hardware and software. However we never do projects for people as most of us have their own projects to take care of.

Okay so I’ve made some great progress on my light meter since I last posted. I have successfully completed the “Hello World” project from the Arduino website ( I’ve got the Arduino board communicating with the computer and now the LCD screen is correctly displaying the information. I have attached a picture of my project so you can see it. I feel like I’m almost there which feels great!
My last 2 parts I need to complete is hooking up the photocell that I have ( to the Arduino board and obtaining the right code so the LCD will display the amount of lux. Well I was able to find a few codes online and try them out but they did not work. Here is one of them I tried:

The two links go together. The video is of that particular code working. I know this code does not display the amount of lux but it does display 4 different light conditions (pretty dark, dark, bright, pretty bright). I just wanted to see my photocell in action displaying the light conditions on my lcd screen. When I hooked up the photocell and uploaded the code my lcd screen just went blank for some reason. This is how I hooked up the photocell which I found on a different webpage:

5V >–[ Photocell ]—±–[ 10k Ohm ]—< GND
Arduino pin A0

I tried resetting the board and uploading the code many times. I also uploaded the “Hello World” code in between testing and that would work perfectly every time. So the possible 2 issues I think I’m having are that I do not know the type of photocell the person used or how exactly he hooked up the photocell. Even if I didn’t know his exact photocell he used I’m thinking I should still be able to see a light condition being displayed on my lcd even if it’s a wrong light condition.
I also found this code ( which looks to be the best and the exact code I would need for my application but it also just makes the LCD screen go blank for some reason. Can anyone please help me out? I would so greatly appreciate it. THANK YOU SO MUCH! [/img]

I also found this code ( which looks to be the best and the exact code I would need for my application but it also just makes the LCD screen go blank for some reason. Can anyone please help me out?

That code has nothing in it that knows anything about your LCD, so it's not surprising that your LCD show nothing.

Thanks for responding. I appreciate it a lot. Now how would I get that code to go with my lcd screen? Is it just a simple edit somewhere in the code and it should work? This is the LCD screen I have:


I have successfully completed the “Hello World” project from the Arduino website (

Well, then, you know how to write to the LCD.
The LiquidCrystal class derives from the Print class. So does Serial.

Everywhere that you do a Serial.print(), you can do a lcd.print(), instead, after declaring an instance of LiquidCrystal.

Hi Guys,
Sorry I haven’t been back in over a week. I was having some trouble with the lcd screen but it’s all set now. Also I have been editing the code to my needs. I have the code working to the best of my knowledge. I was able to compare my light meter design to an actual light meter and the lux readings were close to one another. I do have 1 issue though with my code that I’m hoping I could get some help with. My lux readings display on the lcd screen continually scroll and I would like it to be still but do not know how to edit the code correctly for that. Can anyone help me with that? THANKS! (If someone does respond I won’t be able to test it out until Monday.)
Here is the current code that I’m using which scrolls the results:

int photocellPin0 = 0; // the cell and 10K pulldown are connected to a0
int photocellReading0; // the analog reading from the analog resistor divider
float Res0=10.0; // Resistance in the circuit of sensor 0 (KOhms)
// depending of the Resistance used, you could measure better at dark or at bright conditions.
// you could use a double circuit (using other LDR connected to analog pin 1) to have fun testing the sensors.
// Change the value of Res0 depending of what you use in the circuit
// include the library code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int val = 0;
void setup()
// set up the LCD’s number of columns and rows:
void loop(void) {
photocellReading0 = analogRead(photocellPin0); // Read the analogue pin
float Vout0=photocellReading00.0048828125; // calculate the voltage
int lux0=104.1
Vout0; // calculate the Lux
// Print the measurement (in Lux units) in the screen
lcd.print(" Lux\t");
lcd.print(lux0); // Print the measured level at pin 0
// turn off automatic scrolling

There is a lcd.setCursor() command that you can use to position the cursor before you write the text. If you add that to loop, the text will always be printed in the same place, so it won't scroll away.