Pulse counter and time measurement

the 0.63 and the 1.88 are correct. I have a little electric heater with two levels for testing purposes.
but if i switch it off and wait a minute (74000ms) then the measurement of the time fails.
here you can see whole scrpt:

const int ldrPin = A0;
boolean timingFlag;
unsigned long timeOff;
unsigned long timingMillis;
float watts;


bool ledDetected = false ;
bool ledDetectedOld = false ;


void setup() {

  Serial.begin(9600);

  pinMode(ledPin, OUTPUT);
  pinMode(ldrPin, INPUT);
  timingMillis = millis();  //set initial timing millis)

}

void loop() {

  if ( analogRead(ldrPin) > 500 )
  {
    ledDetected = true ;
  }
  else ledDetected = false ;

  if ( ledDetected == true && ledDetectedOld == false ) {
    // transition from "No LED detected" to "LED detected"
    Serial.println("Led transition to ON . . . ");

    Serial.print(" elapsed time = ");
    timeOff = millis() - timingMillis;
    Serial.println( timeOff );

    //calculation
    //watts = 0.000625/(timeOff)/1000/3600;
    watts =  (3600 / timeOff) * 0.625 ;  //kw
    Serial.print(watts);
    Serial.println(" kw");

    timingFlag = false;
    timingMillis = millis();
    // do your calculations here . . .
    // . . .
  }
  ledDetectedOld = ledDetected ;

}

That should be watts = (3600.0 / timeOff) * 0.625 ; //kw
Note how 3600 is represented as a float as I tried to make clear in post #16

However, that will not solve the wildly spurious readings.
It looks like the strategy of waiting until the next flash before doing the power calculation for the previous period needs to be revised. It may be better to continually check the interval since the last detected flash and recalculate the power. However this has to be "tuned" to avoid the results visibly changing when the power consumption is actually steady, probably by making it active only if the period since the last flash is longer than a few seconds.

hey,
I made this little change 3600 --> 3600.0 and now it works very well. There were no error anymore during a one hour test with only 40w (0.04 kw).

I think it's ok now.
THank you so much!
The people in this forum are great.
They do not just say "read this wiki" or do a google search and lern programming. Here you can get real help.
Thank you very much!

Well, not always but it is good that you have had some positive experience in this thread.
Anyway, good luck with the project. Maybe you still have some work to do in transmitting the results over WiFi with your ESP8266.

the mqtt part is no problem. I have done this many times. so there should be no issues :slight_smile:

but one more thing. I have tested it now for a longe period of time. it's not often but from time to time there is the issue with the "double reading" of one light up of the LED.

1:16:20.265 -> 0.09 kw
21:16:45.179 -> Led transition to ON . . . 
21:16:45.179 ->  elapsed time = 24941
21:16:45.225 -> 0.09 kw
21:17:10.627 -> Led transition to ON . . . 
21:17:10.627 ->  elapsed time = 25432
21:17:10.627 -> 0.09 kw
21:17:36.317 -> Led transition to ON . . . 
21:17:36.317 ->  elapsed time = 25695
21:17:36.317 -> 0.09 kw
21:17:36.458 -> Led transition to ON . . . 
21:17:36.458 ->  elapsed time = 131
21:17:36.458 -> 17.18 kw
21:18:03.292 -> Led transition to ON . . . 
21:18:03.292 ->  elapsed time = 26852
21:18:03.339 -> 0.08 kw
21:18:31.784 -> Led transition to ON . . . 
21:18:31.784 ->  elapsed time = 28510
21:18:31.833 -> 0.08 kw

the amount of time is always below 200ms and higher than 130ms.
so I think it should be good, if I make a check if the detected blink is at least 300ms in the past or not.
Is it correct if I do it like this?

void loop() {

  if ( analogRead(ldrPin) > 500 )
  {
    ledDetected = true ;
  }
  else ledDetected = false ;

    timeOff = millis() - timingMillis;

  if ( ledDetected == true && ledDetectedOld == false && timeOff>300 ) {
    // transition from "No LED detected" to "LED detected"
    Serial.println("Led transition to ON . . . ");

    Serial.print(" elapsed time = ");
    timeOff = millis() - timingMillis;
    Serial.println( timeOff );

    //calculation
    //watts = 0.000625/(timeOff)/1000/3600;
    watts =  (3600.0 / timeOff) * 0.625 ;  //kw
    Serial.print(watts);
    Serial.println(" kw");

    timingFlag = false;
    timingMillis = millis();
    // do your calculations here . . .
    // . . .
  }
  ledDetectedOld = ledDetected ;

}

Can you tell, say be a slowed video, whether that 131 ms blink is actually generated by the meter or is simply a measurement effect ?

Anyway, I guess that 300ms is about the maximum you can go to, in the course of filtering out spurious readings, without inhibiting the measurement of high loads (> about 6kW). The code looks OK incidentally.

You've also got the "run on" problem. If the load goes from 2kw to zero in the middle of a measurement cycle, it could be left showing 2kw for long after the load had been switched off.

It is the same problem as the speedometer on a bicycle. On the basis of a small number of samples, single revolutions of a wheel, it attempts to give a reasonably smooth average of the speed. If the wheel with the sensor is stopped suddenly, the speed shown ramps down slowly without waiting for the wheel to complete a revolution.

I do not know. maybe the LED is flickering a bit.

300ms are no problem. The power meter is connected to only one phase. So it is not possible to get more power than 3.5kw until the fuse activates/disconnects

indeed. But there is no way to reduce this effect.

You can probably do something to smooth it a bit but it would not be very responsive to disconnecting the load. It would also not be easy. It would need several seconds to ramp down and take increasingly long averages, as the load reduces, to avoid getting visible peaks and troughs in a steady consumption but of a very low load.

For a continuous power measurement, you could also consider one of these current transformers: 30A SCT-013-030 Non-invasive AC current sensor Split Core Current Transformer AL | eBay

image