/*Read energy meter IR pulses with an Arduino Nano:
- each pulse triggers an interrupt that increments a counter
- time is determined by the crystal on the uC board
- reports number of pulses, energy per period, average power, cumulated energy
To do:
- save log on SD with number of pulses
*/
//Pulse handling
const byte pulsePin=2;
const float energyPerPulse=12; //energy per 1 pulse, in J = Ws; 1 kWs/(250/3) = 12 Ws
volatile word pulseCount;
//Energy
word pulsesPerPeriod;
unsigned long cumulatedPulses=0;
float energyPerPeriod;
float cumulatedEnergykWh;
float averagePower;
//Timekeeping
const float period=1.0; //period of reporting, in s
const unsigned long ticksPerSec=1000000; //in crystal µs per 1 actual s, nominally 1e6
const unsigned long ticksPerPeriod=round(period*ticksPerSec);
unsigned long tickCount=0; //tick counters, in crystal µs
unsigned long tickCountStep; //tick counters, in crystal µs
unsigned long prevTickCount=0; //in crystal µs
unsigned long periodFraction=0; //period fraction, in crystal µs
void setup() {
Serial.begin(9600); Serial.println();
Serial.print("ticksPerPeriod: "); Serial.println(ticksPerPeriod);
pinMode(pulsePin,INPUT);
attachInterrupt(digitalPinToInterrupt(pulsePin),pulseISR,RISING);
}
void loop() {
//Timekeeping:
do { //keep reading time
tickCount=micros();
tickCountStep=tickCount-prevTickCount; //time step, in μs; no overflow issues
prevTickCount=tickCount; //for the next iteration
//Keep current time from start of period:
periodFraction+=tickCountStep;
} while (periodFraction<ticksPerPeriod); //as long as the period is not full
periodFraction-=ticksPerPeriod; //modulo
//Report/display/record pulses:
pulsesPerPeriod=pulseCount; pulseCount=0; //read pulse counter and reset
unsigned long time=micros();
energyPerPeriod=pulsesPerPeriod*energyPerPulse;
averagePower=energyPerPeriod/period;
cumulatedPulses+=pulsesPerPeriod;
cumulatedEnergykWh=cumulatedPulses*energyPerPulse/3600000;
Serial.print(time); Serial.print(" ticks, ");
Serial.print(pulsesPerPeriod); Serial.print(" p, ");
Serial.print(energyPerPeriod,1); Serial.print(" J, ");
Serial.print(averagePower,1); Serial.print(" W, ");
Serial.print(cumulatedEnergykWh,3); Serial.print(" kWh from start");
Serial.println();
}
void pulseISR() {
pulseCount+=1;
}
nano:12
nano:11
nano:10
nano:9
nano:8
nano:7
nano:6
nano:5
nano:4
nano:3
nano:2
nano:GND.2
nano:RESET.2
nano:0
nano:1
nano:13
nano:3.3V
nano:AREF
nano:A0
nano:A1
nano:A2
nano:A3
nano:A4
nano:A5
nano:A6
nano:A7
nano:5V
nano:RESET
nano:GND.1
nano:VIN
nano:12.2
nano:5V.2
nano:13.2
nano:11.2
nano:RESET.3
nano:GND.3
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r