Simple loop giving longer delay than expected ?

Ok, I'm trying to work on a simple project to show my gas used of my gas meter - rate of use and cubic meters, using a infra-red reflective sensor counting a shiny 'zero' of the meters 10's of litres dial. All works ok apart from the reading seems higher than expected ? what I'm thinking is the dial takes about ~15 seconds to rotate and the 'zero' takes about a second to pass the sensor. So (I think)my code subtracts the passing time of the 'zero' hence giving a patently shorter delay ? - I've checked the everything against a wall clocks second hand (using the reflective IR sensor) and everything is spot on, as expected, the second hand on the clock moves in steps so went past the sensor very fast so maybe not affecting the result ?

To summarize, I'm trying to measure the delay between two falling edges - and not the delay between a rising edge and the next falling edge which would subtract the 'off' pulse bit ?

The sensor goes LOW when the 'zero' passes btw

#define  DELAY_START   HIGH         // or low depending on your blink detection logic
#define  DELAY_END   !DELAY_START   // this is the inverse of the above 
#include <LiquidCrystal.h>

// LiquidCrystal display with:
// RS on pin 12
// RW on pin 11
// E  on pin 10
// d0, d1, d2, d3 on pins 5, 4, 3, 2         d4 ,d5 ,d6, d7 on pins 10,9,8,7 
LiquidCrystal lcd(12, 11, 2, 10, 9, 8, 7);

long start, duration, watt, lit, kwh;
int scale = 112;                       // calorific value for m3  = 39.4MJ * 1.02264 / 3.6 * 10
int ledPin = 13;                       //  pin for the LED
int inputPin = 3;                      // IR input pin

void setup() {
  lcd.clear();
  lcd.print("Gasmeter Kwh display");
  pinMode(ledPin, OUTPUT);      // declare LED as output
  pinMode(inputPin, INPUT);     // declare IR for input
  Serial.begin(9600);
  Serial.println(" Gas Meter reading display");
  delay(100); }
  
void loop(){
  while( digitalRead(inputPin) != DELAY_START   ); // wait for falling edge 
  start = millis();
  digitalWrite(ledPin,0);
  while( digitalRead(inputPin) != DELAY_END   );
  duration = millis() - start;
  digitalWrite(ledPin,1);
  
  
// display results on LCD and serial port  
lit++;
watt = lit * scale;
kwh =  36000000/duration * scale ;
   Serial.print( lit*10);Serial.println(" Liters used");
   Serial.print(  watt );Serial.println(" watts used");
   Serial.print(  kwh/10 );Serial.println(" Watts Rate");
   Serial.print( duration);Serial.println("   Duration Ms"); // ** seems to be higher than expected ??
   Serial.println("        ");  
   lcd.clear();
   lcd.print(kwh/10);
   lcd.print(" wh"); // ** seems to be higher than expected ??
   lcd.setCursor(12,0);
   lcd.print(watt);
   //lcd.setCursor(19,0);
   lcd.print(" W");
   }

If you want to measure the time between successive falling edges, then assuming digitalRead returns DELAY_START at the falling edge (as per yr comment) then you want to wait for the next transition to DELAY_START.

i.e.
wait for falling edge – save start time
wait for rising edge
wait for falling edge – save end time and calculate duration
end time becomes the next start time if you want continuous calculations

Ah, that makes sense more a three step process than two. It doesn't matter if it's a rising or falling edge just so it counts a full rev of the dial - 10 litres or ~112 watts gas, not just the 'off' bit if you see what I mean :slight_smile:

Thanks !

It doesn't matter if it's a rising or falling edge

My approach would be to choose start and end measurements on the edge that has the longer period. That way any code you may add in future to calculate or display results is less likely to overrun the start of the next transition. Although in the code you have posted , it probably doesn't matter.