/*
Forum: https://forum.arduino.cc/t/falling-interrupt-triggers-many-times-per-event/1356817/4
Wokwi: https://wokwi.com/projects/423601736139637761
Original: bmoerdyk2
Modified: DaveX -> Implemented Limited StromZaehler()
Modified: ec2021 -> Re-Implemented Original StromZaehler()
*/
//#define LIMITED
#define pinInputZaehler 27 //verified, has internal pull-up
volatile uint32_t zaehler = 0; //volatile - can be changed in the interrupt
volatile unsigned long zaehlerMillis = 0; //volatile - can be changed in the interrupt
uint32_t zaehlerLast = 0; //only changed in function
unsigned zaehlerMillisLast = 0; //only changed in function
double zaehlerPower_W;
char a2dstr[128];
void setup() {
//in void setup():
Serial.begin(115200);
#ifdef LIMITED
Serial.println("Limited");
#else
Serial.println("Original");
#endif
pinMode(pinInputZaehler, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(pinInputZaehler), StromZaehler, FALLING);
}
void loop() {
// in void loop():
ZaehlerStatus();
}
#ifdef LIMITED
// interrupt function Limited:
void StromZaehler() {
uint32_t now = millis();
static uint32_t lastInt = 0;
if (now - lastInt < 10) return;
lastInt = now;
zaehler = zaehler + 1;
zaehlerMillis = now;
}
#else
// interrupt function Original:
void StromZaehler() {
zaehler = zaehler + 1;
zaehlerMillis = millis();
}
#endif
//calculation function
void ZaehlerStatus() {
if (zaehler != zaehlerLast) { // pulse = 0.5kWh. 1p/h = 0.5kW
if (zaehlerMillisLast != 0) { //avoid calculation when there haven't been two good pulses.
zaehlerPower_W = 3600.0 * 0.5 * float(zaehler - zaehlerLast) / float((zaehlerMillis - zaehlerMillisLast) / 1000.0);
sprintf(a2dstr, "Z:%i/%i T:%i/%i", zaehler, zaehlerLast, zaehlerMillis, zaehlerMillisLast);
Serial.println(a2dstr);
}
zaehlerMillisLast = zaehlerMillis;
zaehlerLast = zaehler;
}
}