LDR Counting

I am doing a project using a LDR sensor . I have to count the number of LED blinks using the sensor. I have to call an interrupt when the LED glows and increase the count. The LDR sensor is connected to digital pin 2. Now the count is far more than the led blinks the counter counts more than the actuall led blinks............. how could i solve this issue?

Show us your code.

Please, you must show us your complete sketch. Attach your code using the </> icon on the left side of the posting menu.
.

const int pin_LDR = 2; // the number of the pin_LDR
void setup() {
pinMode(pin_LDR, INPUT);
pinMode(pin_chg, INPUT);
chg_st = digitalRead(pin_chg);
// Attach an interrupt to the ISR vector
attachInterrupt(0, LDR, RISING);
if(count==0)
{
count=EEPROM.read(0);
}
addr=addr+1;
Serial.begin(9600);
while (!Serial) ; // wait for serial
delay(200);
Serial.println(“DS1307RTC Read Test”);
Serial.println("-------------------");
}

void LDR() {
count=count+1;
if(count==200)
{
c = EEPROM.read(1022);
c = c+1;
count = 0;
if(c == 16)
{
perday=EEPROM.read(1023);
perday=perday+1;
EEPROM.write(1023,perday);
c = 0;
}
EEPROM.write(1022,c);
}
EEPROM.write(0, count);

}</>

Roy, you need to post your code in code tags, not inline, as Larry said:- “Attach your code using the </> icon on the left side of the posting menu.
It’s not too late to edit your post and do this. :wink:

(Paste your code after the “code” between square brackets and before the “/code” between square brackets.)
Or you can paste the code, then select it and press the </> button.

Edit: The first thing I see is that you haven’t declared ‘pin_chg’, so your code won’t compile.
You also haven’t declared ‘chg_st’ or ‘count’ or ‘addr’ or ‘c’ or ‘perday’.
You haven’t included the “EEPROM” library either.
You also don’t have a ‘loop()’ function.

How about you post all of your code, not just a bit? It needs to be compileable.

On top of this, any variables modified in the ISR must be declared as ‘volatile’.

Where is loop() ?

Writing to EEPROM too much makes it unusable
You have about ~100,000 Writes

<

#include <DS1307RTC.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include <Time.h>
#include <EEPROM.h>
LiquidCrystal lcd(12,11,10,7,6,5,4);
const int pin_LDR = 2; // the number of the pin_LDR
const int pin_chg = 8;
volatile int count=0,perday=0,c=0;
volatile int d=0,m=0,addr=0,sd=0,sm=0,i=0,j=0,k=0,rd=0,rm=0,chg_st=0;

void setup() {
pinMode(pin_LDR, INPUT);
pinMode(pin_chg, INPUT);
chg_st = digitalRead(pin_chg);
// Attach an interrupt to the ISR vector
attachInterrupt(0, LDR, RISING);
if(count==0)
{
count=EEPROM.read(0);
}
addr=addr+1;
Serial.begin(9600);
while (!Serial) ; // wait for serial
delay(200);
Serial.println(“DS1307RTC Read Test”);
Serial.println("-------------------");
}

void LDR() {
count=count+1;
if(count==200)
{
c = EEPROM.read(1022);
c = c+1;
count = 0;
if(c == 16)
{
perday=EEPROM.read(1023);
perday=perday+1;
EEPROM.write(1023,perday);
c = 0;
}
EEPROM.write(1022,c);
}
EEPROM.write(0, count);

}
void btn()
{
chg_st = 0;
lcd.begin(8,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.clear(); // start with a blank screen
lcd.setCursor(0,0);
lcd.print(“Enter date & month”);
lcd.setCursor(0,1);
while(chg_st != HIGH)
{
delay(200);
}
if (chg_st == HIGH)
{
chg_st = 0;
chg();
if(chg_st == 0)
goto l3;
}
i = 2;
l1:
{
rd = EEPROM.read(i);
j=i+1;
rm = EEPROM.read(j);
i=j+2;
if(rd == sd && rm == sm)
{
lcd.begin(8,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.clear(); // start with a blank screen
lcd.setCursor(0,0);
lcd.print(rd);
lcd.print("/");
lcd.print(rm);
lcd.setCursor(0,1);
lcd.print(“Usage :”);
lcd.print(EEPROM.read(j+1));
delay(5000);
}
else if(i == 1022)
{
lcd.begin(8,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.clear(); // start with a blank screen
lcd.setCursor(0,0);
lcd.print(“Not found !”);
delay(3000);
}
else
goto l1;
}
l3:{
chg_st = 0;
}
}

void chg()
{
lcd.clear();
lcd.begin(8,2);
lcd.setCursor(0,0);
lcd.print(“Day : “);
while(chg_st != HIGH)
{
delay(200);
}
if(chg_st == HIGH)
{
chg_st = 0;
for(k=1;k<32;k++)
{
sd=k;
lcd.clear();
lcd.begin(8,2);
lcd.setCursor(0,0);
lcd.print(“Day : “);
lcd.print(k);
delay(3000);
if(chg_st == HIGH)
break;
}
chg_st = 0;
for(k=1;k<13;k++)
{
sm=k;
lcd.clear();
lcd.begin(8,2);
lcd.setCursor(0,0);
lcd.print(“Month : “);
lcd.print(k);
delay(3000);
if(chg_st == HIGH)
{
break;
}
}
}
}
void loop() {
tmElements_t tm;
if (RTC.read™) {
Serial.print(“Ok, Time = “);
print2digits(tm.Hour);
Serial.write(’:’);
print2digits(tm.Minute);
Serial.write(’:’);
print2digits(tm.Second);
Serial.print(”, Date (D/M/Y) = “);
Serial.print(tm.Day);
Serial.write(’/’);
Serial.print(tm.Month);
Serial.write(’/’);
Serial.print(tmYearToCalendar(tm.Year));
Serial.println();
lcd.begin(8,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.clear(); // start with a blank screen
lcd.setCursor(0,0);
lcd.print(tm.Hour);
lcd.print(”:”);
lcd.print(tm.Minute);
lcd.print(”:”);
lcd.print(tm.Second); // change this text to whatever you like. keep it clean.
lcd.setCursor(0,1); // set cursor to column 0, row 1
lcd.print(tm.Day);
lcd.print(”/”);
lcd.print(tm.Month);
lcd.print(”/”);
lcd.print(tmYearToCalendar(tm.Year));

} else {
if (RTC.chipPresent()) {
lcd.println(“The DS1307 is stopped. Please run the SetTime”);
lcd.println(“example to initialize the time and begin running.”);
Serial.println();
} else {
lcd.clear();
lcd.setCursor(0,0);
lcd.println(“DS1307 read error! Please check the circuitry.”);
Serial.println();
}

delay(9000);
}
delay(1000);
if(chg_st == HIGH)
{
btn();
}

if(tm.Hour==23 && tm.Day>d){
d = tm.Day;
m = tm.Month;
save();
}
lcd.clear(); // start with a blank screen
lcd.begin(8,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.setCursor(0,0);
lcd.print("Count : ");
lcd.print(count);
lcd.setCursor(0,1);
lcd.print("D Usage : ");
lcd.print(perday);

delay(1000);
if(chg_st == HIGH)
{
btn();
}
}
void print2digits(int number) {
if (number >= 0 && number < 10) {
Serial.write(‘0’);
}
Serial.print(number);
}

void save(){
addr = EEPROM.read(1);
EEPROM.write(addr,d);
addr = addr + 1;
EEPROM.write(addr,m);
addr = addr + 1;
EEPROM.write(addr,perday);
addr = addr + 1;
if (addr == 1021) {
addr = 1;
EEPROM.write(addr,2);
}
else
EEPROM.write(1,addr);
}
/>

Sorry, I didn’t describe how to post code properly. That was a silly description. I meant post it after the first tag and before the second. (Not < and /> exactly.) I can’t type them here.

Just edit, select your code, then press </>.
(If you’d read the “How to use this forum” posts, you’d have no problem.)
How to use this forum - please read
How to use this forum

Edit: Or, if you must type the code tags manually, you want square brackets around “code” immediately before your code, then square brackets around “/code” immediately after your code.

Also, before posting code, it’s always a good idea to correctly format it first. (You can do that using “Auto Format” in the IDE.)
Make it as easy as possible for people to help you, not hard.

[code]Write your code here[/code]
So it looks like this

MorganS:

[code]Write your code here[/code]
So it looks like this

Thanks Morgan. I didn't know how to create visible code tags.

Edit: I've made a note of your method for future reference.

#include <DS1307RTC.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include <Time.h>
#include <EEPROM.h>
LiquidCrystal lcd(12,11,10,7,6,5,4);
const int pin_LDR = 2;     // the number of the pin_LDR
const int pin_chg = 8;
volatile int count=0,perday=0,c=0;
volatile int d=0,m=0,addr=0,sd=0,sm=0,i=0,j=0,k=0,rd=0,rm=0,chg_st=0;

void setup() {
  pinMode(pin_LDR, INPUT); 
  pinMode(pin_chg, INPUT);
  chg_st = digitalRead(pin_chg);
  // Attach an interrupt to the ISR vector
  attachInterrupt(0, LDR,  RISING);
    if(count==0)
{
  count=EEPROM.read(0);
}
  addr=addr+1;
  Serial.begin(9600);
  while (!Serial) ; // wait for serial
  delay(200);
  Serial.println("DS1307RTC Read Test");
  Serial.println("-------------------");
}

void LDR() {
  count=count+1;
  if(count==200)
  {
   c = EEPROM.read(1022);
   c = c+1;
   count = 0;
   if(c == 16) 
   {
     perday=EEPROM.read(1023);
     perday=perday+1;
     EEPROM.write(1023,perday);
     c = 0;
    }
  EEPROM.write(1022,c);
  }    
  EEPROM.write(0, count);
    
}
void btn()
{ 
 chg_st = 0; 
 lcd.begin(8,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
 lcd.clear(); // start with a blank screen
 lcd.setCursor(0,0); 
 lcd.print("Enter date & month");
 lcd.setCursor(0,1); 
 while(chg_st != HIGH)
 {
  delay(200);
 }
 if (chg_st == HIGH)
 {
   chg_st = 0;
   chg();
   if(chg_st == 0)
    goto l3;
 }
 i = 2;
 l1:
 {
 rd = EEPROM.read(i);
 j=i+1;
 rm = EEPROM.read(j);
 i=j+2;
 if(rd == sd && rm == sm)
 {
  lcd.begin(8,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
  lcd.clear(); // start with a blank screen
  lcd.setCursor(0,0); 
  lcd.print(rd);
  lcd.print("/");
  lcd.print(rm);
  lcd.setCursor(0,1);
  lcd.print("Usage :");
  lcd.print(EEPROM.read(j+1));
  delay(5000);
 }
 else if(i == 1022)
  {
  lcd.begin(8,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
  lcd.clear(); // start with a blank screen
  lcd.setCursor(0,0);
  lcd.print("Not found !");
  delay(3000);
  } 
 else
  goto l1;
 }
 l3:{
  chg_st = 0;
  }
}

void chg()
{
  lcd.clear();
  lcd.begin(8,2);
  lcd.setCursor(0,0);
  lcd.print("Day : ");
  while(chg_st != HIGH)
  {
    delay(200);
  }
  if(chg_st == HIGH)
  {
  chg_st = 0;
  for(k=1;k<32;k++)
   {
    sd=k;
    lcd.clear();
    lcd.begin(8,2);
    lcd.setCursor(0,0);
    lcd.print("Day : ");   
    lcd.print(k);
    delay(3000);
    if(chg_st == HIGH)  
     break;
   }
  chg_st = 0;
  for(k=1;k<13;k++)
   {
    sm=k;
    lcd.clear();
    lcd.begin(8,2);   
    lcd.setCursor(0,0);   
    lcd.print("Month : ");    
    lcd.print(k);
    delay(3000);
    if(chg_st == HIGH)
    {
      break;
    }
   }
  }   
}
void loop() {
tmElements_t tm;
if (RTC.read(tm)) {
Serial.print("Ok, Time = ");
print2digits(tm.Hour);
Serial.write(':');
print2digits(tm.Minute);
Serial.write(':');
print2digits(tm.Second);
Serial.print(", Date (D/M/Y) = ");
Serial.print(tm.Day);
Serial.write('/');
Serial.print(tm.Month);
Serial.write('/');
Serial.print(tmYearToCalendar(tm.Year));
Serial.println();
lcd.begin(8,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.clear(); // start with a blank screen
lcd.setCursor(0,0);
lcd.print(tm.Hour);
lcd.print(":");
lcd.print(tm.Minute);
lcd.print(":");
lcd.print(tm.Second); // change this text to whatever you like. keep it clean.
lcd.setCursor(0,1); // set cursor to column 0, row 1
lcd.print(tm.Day);
lcd.print("/");
lcd.print(tm.Month);
lcd.print("/");
lcd.print(tmYearToCalendar(tm.Year));

} else {
if (RTC.chipPresent()) {
lcd.println("The DS1307 is stopped. Please run the SetTime");
lcd.println("example to initialize the time and begin running.");
Serial.println();
} else {
  lcd.clear();
  lcd.setCursor(0,0);
lcd.println("DS1307 read error! Please check the circuitry.");
Serial.println();
}


delay(9000);
}
delay(1000);
if(chg_st == HIGH)
{
  btn();
}

if(tm.Hour==23 && tm.Day>d){
d = tm.Day;
m = tm.Month;
save();
}
lcd.clear(); // start with a blank screen
lcd.begin(8,2); // columns, rows. use 16,2 for a 16x2 LCD, etc.
lcd.setCursor(0,0);
lcd.print("Count : ");
lcd.print(count);
lcd.setCursor(0,1);
lcd.print("D Usage : ");
lcd.print(perday);

delay(1000);
if(chg_st == HIGH)
{
  btn();
}
}
void print2digits(int number) {
if (number >= 0 && number < 10) {
Serial.write('0');
}
Serial.print(number);
}

void save(){
  addr = EEPROM.read(1);
  EEPROM.write(addr,d);
 addr = addr + 1;
  EEPROM.write(addr,m);
 addr = addr + 1; 
  EEPROM.write(addr,perday);
 addr = addr + 1;
  if (addr == 1021) {
    addr = 1;
    EEPROM.write(addr,2);
  }
  else
   EEPROM.write(1,addr); 
}

The single-letter variable names and lack of decent comments make your code extremely hard to follow.

Using "goto" is a very bad idea.

'lcd.begin()' should be in setup, not in the 'loop()' function, and repeated many times.

In this, nothing can ever change 'chg_st', so it's a perpetual loop and will stop program execution altogether. Is this what you intended? :-

chg_st = 0;
.
.
.
    while (chg_st != HIGH)
    {
        delay(200);
    }

I can't see why you made these 'volatile':-

volatile int d = 0, m = 0, addr = 0, sd = 0, sm = 0, i = 0, j = 0, k = 0, rd = 0, rm = 0, chg_st = 0;

You need to rethink things, correct the obvious errors, give your variables meaningful names and add descriptive comments throughout the code if you really want much help.

Is there any other solution to count the led blinking other than LDR the count has to be accurate?

You could use an IR LED and an IR photodiode.

Part 2 and Part 2 Revisited of my article here might help.

The photodiode conducts or doesn't, depending on the state of the LED. That in turn causes a 0V or 5V to appear on a digital pin, and we count the pulses using the standard State Change Detection example.

Is it an already-existing LED, or can an IR LED be used as JimboZA suggests?
Either way, I think a phototransistor might be a better option than a photodiode.

Does it really need to keep track of the previous count each time it starts up? Writing to the EEPROM as often as you do is not a good idea. As Larry said, the EEPROM has a limited life of about 100,000 writes per address.

What's the actual purpose of this project? We might be able to suggest a better approach if we know a little more about it.

Also, if you attempting a wear leveling scheme for the EEPROM, it is a failure because it keeps using addresses 1 and 2 on each write.

Hi,
Did you write all this code at once, trying to get it all to work, or did you write

  • code for counting the LDR input,
  • separate code for LCD
  • separate code for EPROM write and read