/*
Emon.cpp - Library for openenergymonitor
Created by Trystan Lea, April 27 2010
GNU GPL
*/
//#include “WProgram.h” un-comment for use on older versions of Arduino IDE
#include “EmonLib.h”
#if defined(ARDUINO) && ARDUINO >= 100
#include “Arduino.h”
#else
#include “WProgram.h”
#endif
//--------------------------------------------------------------------------------------
// Sets the pins to be used for voltage and current sensors
//--------------------------------------------------------------------------------------
void EnergyMonitor::voltage(int _inPinV, double _VCAL, double _PHASECAL)
{
inPinV = _inPinV;
VCAL = _VCAL;
PHASECAL = _PHASECAL;
}
void EnergyMonitor::current(int _inPinI, double _ICAL)
{
inPinI = _inPinI;
ICAL = _ICAL;
}
//--------------------------------------------------------------------------------------
// Sets the pins to be used for voltage and current sensors based on emontx pin map
//--------------------------------------------------------------------------------------
void EnergyMonitor::voltageTX(double _VCAL, double _PHASECAL)
{
inPinV = 2;
VCAL = _VCAL;
PHASECAL = _PHASECAL;
}
void EnergyMonitor::currentTX(int _channel, double _ICAL)
{
if (_channel == 1) inPinI = 3;
if (_channel == 2) inPinI = 0;
if (_channel == 3) inPinI = 1;
ICAL = _ICAL;
}
//--------------------------------------------------------------------------------------
// emon_calc procedure
// Calculates realPower,apparentPower,powerFactor,Vrms,Irms,kwh increment
// From a sample window of the mains AC voltage and current.
// The Sample window length is defined by the number of half wavelengths or crossings we choose to measure.
//--------------------------------------------------------------------------------------
void EnergyMonitor::calcVI(int crossings, int timeout)
{
int SUPPLYVOLTAGE = readVcc();
int crossCount = 0; //Used to measure number of times threshold is crossed.
int numberOfSamples = 0; //This is now incremented
//-------------------------------------------------------------------------------------------------------------------------
// 1) Waits for the waveform to be close to ‘zero’ (500 adc) part in sin curve.
//-------------------------------------------------------------------------------------------------------------------------
boolean st=false; //an indicator to exit the while loop
unsigned long start = millis(); //millis()-start makes sure it doesnt get stuck in the loop if there is an error.
while(st==false) //the while loop…
{
startV = analogRead(inPinV); //using the voltage waveform
if ((startV < 550) && (startV > 440)) st=true; //check its within range
if ((millis()-start)>timeout) st = true;
}
//-------------------------------------------------------------------------------------------------------------------------
// 2) Main measurment loop
//-------------------------------------------------------------------------------------------------------------------------
start = millis();
while ((crossCount < crossings) && ((millis()-start)<timeout))
{
numberOfSamples++; //Count number of times looped.
lastSampleV=sampleV; //Used for digital high pass filter
lastSampleI=sampleI; //Used for digital high pass filter
lastFilteredV = filteredV; //Used for offset removal
lastFilteredI = filteredI; //Used for offset removal
//-----------------------------------------------------------------------------
// A) Read in raw voltage and current samples
//-----------------------------------------------------------------------------
sampleV = analogRead(inPinV); //Read in raw voltage signal
sampleI = analogRead(inPinI); //Read in raw current signal
//-----------------------------------------------------------------------------
// B) Apply digital high pass filters to remove 2.5V DC offset (centered on 0V).
//-----------------------------------------------------------------------------
filteredV = 0.996*(lastFilteredV+sampleV-lastSampleV);
filteredI = 0.996*(lastFilteredI+sampleI-lastSampleI);
//-----------------------------------------------------------------------------
// C) Root-mean-square method voltage
//-----------------------------------------------------------------------------
sqV= filteredV * filteredV; //1) square voltage values
sumV += sqV; //2) sum
//-----------------------------------------------------------------------------
// D) Root-mean-square method current
//-----------------------------------------------------------------------------
sqI = filteredI * filteredI; //1) square current values
sumI += sqI; //2) sum