TrifasicEthernetEthercard: diferència entre les revisions
Salta a la navegació
Salta a la cerca
Cap resum de modificació |
Cap resum de modificació |
||
| Línia 1: | Línia 1: | ||
#include <EtherCard.h> | #include <EtherCard.h> | ||
// ethernet interface mac address, must be unique on the LAN | // ethernet interface mac address, must be unique on the LAN | ||
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x06 }; | static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x06 }; | ||
static byte myip[] = { 192,168,130,6 }; | static byte myip[] = { 192,168,130,6 }; | ||
static byte gwip[] = { 192,168,130,1 }; | static byte gwip[] = { 192,168,130,1 }; | ||
byte Ethernet::buffer[500]; | byte Ethernet::buffer[500]; | ||
BufferFiller bfill; | BufferFiller bfill; | ||
// The Animation loop is to provide some bling to the LCD diaplay | // The Animation loop is to provide some bling to the LCD diaplay | ||
#define FILTERSETTLETIME 5000 // Time (ms) to allow the filters to settle before sending data | #define FILTERSETTLETIME 5000 // Time (ms) to allow the filters to settle before sending data | ||
#define SERIALPRINT // include print statement for commissioning - comment this line to exclude | #define SERIALPRINT // include print statement for commissioning - comment this line to exclude | ||
#define PHASE2 8 // Number of samples delay for L2 | #define PHASE2 8 // Number of samples delay for L2 | ||
#define PHASE3 17 // Number of samples delay for L3, also size of array | #define PHASE3 17 // Number of samples delay for L3, also size of array | ||
#define RF69_COMPAT 0 // set to 1 to use RFM69CW | #define RF69_COMPAT 0 // set to 1 to use RFM69CW | ||
const int UNO = 0; | const int UNO = 0; | ||
int inPinV = 6; | int inPinV = 6; | ||
int inPinI1 = 1; | int inPinI1 = 1; | ||
int inPinI2 = 4; | int inPinI2 = 4; | ||
int inPinI3 = 7; | int inPinI3 = 7; | ||
//Calibration coefficients - see http://openenergymonitor.org/emon/modules/emontx/firmware/calibration%20 | //Calibration coefficients - see http://openenergymonitor.org/emon/modules/emontx/firmware/calibration%20 | ||
//These need to be set in order to obtain accurate results | //These need to be set in order to obtain accurate results | ||
double Vcal = 163.8; // Calibration - constant for voltage input - for ideal power voltage adapter | double Vcal = 163.8; // Calibration - constant for voltage input - for ideal power voltage adapter | ||
double Ical1 = 60.6; // Calibration constant for current transformer 1 | double Ical1 = 60.6; // Calibration constant for current transformer 1 | ||
double Ical2 = 60.6; // Calibration constant for current transformer 2 | double Ical2 = 60.6; // Calibration constant for current transformer 2 | ||
double Ical3 = 60.6; // Calibration constant for current transformer 3 | double Ical3 = 60.6; // Calibration constant for current transformer 3 | ||
double Phasecal1 = 1.0; // Calibration constant for phase shift L1 | double Phasecal1 = 1.0; // Calibration constant for phase shift L1 | ||
double Phasecal2 = 1.6; // Calibration constant for phase shift L2 | double Phasecal2 = 1.6; // Calibration constant for phase shift L2 | ||
double Phasecal3 = 1.0; // Calibration constant for phase shift L3 | double Phasecal3 = 1.0; // Calibration constant for phase shift L3 | ||
//-------------------------------------------------------------------------------------- | //-------------------------------------------------------------------------------------- | ||
// Variable declaration for filters, phase shift, voltages, currents & powers | // Variable declaration for filters, phase shift, voltages, currents & powers | ||
//-------------------------------------------------------------------------------------- | //-------------------------------------------------------------------------------------- | ||
int lastSampleV,sampleV; //sample_ holds the raw analog read value, lastSample_ holds the last sample | int lastSampleV,sampleV; //sample_ holds the raw analog read value, lastSample_ holds the last sample | ||
int lastSampleI1,sampleI1; | int lastSampleI1,sampleI1; | ||
int lastSampleI2,sampleI2; | int lastSampleI2,sampleI2; | ||
int lastSampleI3,sampleI3; | int lastSampleI3,sampleI3; | ||
double lastFilteredV,filteredV; //Filtered_ is the raw analog value minus the DC offset | double lastFilteredV,filteredV; //Filtered_ is the raw analog value minus the DC offset | ||
double lastFilteredI1, filteredI1; | double lastFilteredI1, filteredI1; | ||
double lastFilteredI2, filteredI2; | double lastFilteredI2, filteredI2; | ||
double lastFilteredI3, filteredI3; | double lastFilteredI3, filteredI3; | ||
double phaseShiftedV1; //Holds the calibrated delayed & phase shifted voltage. | double phaseShiftedV1; //Holds the calibrated delayed & phase shifted voltage. | ||
double phaseShiftedV2; | double phaseShiftedV2; | ||
double phaseShiftedV3; | double phaseShiftedV3; | ||
double sqV,sumV,sqI1,sumI1,sqI2,sumI2,sqI3,sumI3; | double sqV,sumV,sqI1,sumI1,sqI2,sumI2,sqI3,sumI3; | ||
double instP1,sumP1,instP2,sumP2,instP3,sumP3; //sq = squared, sum = Sum, inst = instantaneous | double instP1,sumP1,instP2,sumP2,instP3,sumP3; //sq = squared, sum = Sum, inst = instantaneous | ||
int startV; //Instantaneous voltage at start of sample window. | int startV; //Instantaneous voltage at start of sample window. | ||
int Vrms2; | int Vrms2; | ||
double realPower1, // The final data | double realPower1, // The final data | ||
apparentPower1, | |||
powerFactor1, | |||
Irms1, | |||
realPower2, | |||
apparentPower2, | |||
powerFactor2, | |||
Irms2, | |||
realPower3, | |||
apparentPower3, | |||
powerFactor3, | |||
Irms3, | |||
Vrms; | |||
typedef struct { int power1, power2, power3, Vrms; } PayloadTX; // neat way of packaging data for RF comms | typedef struct { int power1, power2, power3, Vrms; } PayloadTX; // neat way of packaging data for RF comms | ||
// (Include all the variables that are desired, | |||
// ensure the same struct is used to receive) | |||
PayloadTX emontx; // create an instance | PayloadTX emontx; // create an instance | ||
const int LEDpin = 9; // On-board emonTx LED | const int LEDpin = 9; // On-board emonTx LED | ||
boolean settled = false; | boolean settled = false; | ||
void calcVI3Ph(int cycles, int timeout) | void calcVI3Ph(int cycles, int timeout) | ||
{ | { | ||
int SupplyVoltage = readVcc(); | |||
int crossCount = 0; // Used to measure number of times threshold is crossed. | |||
int numberOfSamples = 0; // This is now incremented | |||
int numberOfPowerSamples = 0; // Needed because 1 cycle of voltages needs to be stored before use | |||
boolean lastVCross, checkVCross; // Used to measure number of times threshold is crossed. | |||
double storedV[PHASE3]; // Array to store >120 degrees of voltage samples | |||
//------------------------------------------------------------------------------------------------------------------------- | |||
// 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) // Wait for first zero crossing... | |||
{ | |||
startV = analogRead(inPinV); // using the voltage waveform | |||
if ((startV < 550) && (startV > 440)) st=true; // check it's within range | |||
if ((millis()-start)>timeout) st = true; | |||
} | |||
//------------------------------------------------------------------------------------------------------------------------- | |||
// 2) Main measurment loop | |||
//------------------------------------------------------------------------------------------------------------------------- | |||
start = millis(); | |||
while ((crossCount < cycles * 2) && ((millis()-start)<timeout)) | |||
{ | |||
lastSampleV=sampleV; // Used for digital high pass filter - offset removal | |||
lastSampleI1=sampleI1; | |||
lastSampleI2=sampleI2; | |||
lastSampleI3=sampleI3; | |||
lastFilteredV = filteredV; | |||
lastFilteredI1 = filteredI1; | |||
lastFilteredI2 = filteredI2; | |||
lastFilteredI3 = filteredI3; | |||
//----------------------------------------------------------------------------- | |||
// A) Read in raw voltage and current samples | |||
//----------------------------------------------------------------------------- | |||
sampleV = analogRead(inPinV); // Read in raw voltage signal | |||
sampleI1 = analogRead(inPinI1); // Read in raw current signal | |||
sampleI2 = analogRead(inPinI2); // Read in raw current signal | |||
sampleI3 = analogRead(inPinI3); // Read in raw current signal | |||
//----------------------------------------------------------------------------- | |||
// B) Apply digital high pass filters to remove 2.5V DC offset (to centre wave on 0). | |||
//----------------------------------------------------------------------------- | |||
filteredV = 0.996*(lastFilteredV+sampleV-lastSampleV); | |||
filteredI1 = 0.996*(lastFilteredI1+sampleI1-lastSampleI1); | |||
filteredI2 = 0.996*(lastFilteredI2+sampleI2-lastSampleI2); | |||
filteredI3 = 0.996*(lastFilteredI3+sampleI3-lastSampleI3); | |||
storedV[numberOfSamples%PHASE3] = filteredV; // store this voltage sample in circular buffer | |||
if (crossCount > 2) // one complete cycle has been stored, so can use delayed | |||
{ // voltage samples to calculate instantaneous powers | |||
//----------------------------------------------------------------------------- | |||
// C) Root-mean-square method voltage | |||
//----------------------------------------------------------------------------- | |||
sqV= filteredV * filteredV; //1) square voltage values | |||
sumV += sqV; //2) sum | |||
//----------------------------------------------------------------------------- | |||
// D) Root-mean-square method current | |||
//----------------------------------------------------------------------------- | |||
sqI1 = filteredI1 * filteredI1; //1) square current values | |||
sumI1 += sqI1; //2) sum | |||
sqI2 = filteredI2 * filteredI2; | |||
sumI2 += sqI2; | |||
sqI3 = filteredI3 * filteredI3; | |||
sumI3 += sqI3; | |||
//----------------------------------------------------------------------------- | |||
// E) Phase calibration - for Phase 1: shifts V1 to correct transformer errors | |||
// for phases 2 & 3 delays V1 by 120 degrees & 240 degrees respectively | |||
// and shifts for fine adjustment and to correct transformer errors. | |||
//----------------------------------------------------------------------------- | |||
phaseShiftedV1 = lastFilteredV + Phasecal1 * (filteredV - lastFilteredV); | |||
phaseShiftedV2 = storedV[(numberOfSamples-PHASE2-1)%PHASE3] | |||
+ Phasecal2 * (storedV[(numberOfSamples-PHASE2)%PHASE3] | |||
- storedV[(numberOfSamples-PHASE2-1)%PHASE3]); | |||
phaseShiftedV3 = storedV[(numberOfSamples+1)%PHASE3] | |||
+ Phasecal3 * (storedV[(numberOfSamples+2)%PHASE3] | |||
- storedV[(numberOfSamples+1)%PHASE3]); | |||
//----------------------------------------------------------------------------- | |||
// F) Instantaneous power calc | |||
//----------------------------------------------------------------------------- | |||
instP1 = phaseShiftedV1 * filteredI1; //Instantaneous Power | |||
sumP1 +=instP1; //Sum | |||
instP2 = phaseShiftedV2 * filteredI2; | |||
sumP2 +=instP2; | |||
instP3 = phaseShiftedV3 * filteredI3; | |||
sumP3 +=instP3; | |||
numberOfPowerSamples++; //Count number of times looped for Power averages. | |||
} | |||
//----------------------------------------------------------------------------- | |||
// G) Find the number of times the voltage has crossed the initial voltage | |||
// - every 2 crosses we will have sampled 1 wavelength | |||
// - so this method allows us to sample an integer number of half wavelengths which increases accuracy | |||
//----------------------------------------------------------------------------- | |||
lastVCross = checkVCross; | |||
if (sampleV > startV) | |||
checkVCross = true; | |||
else | |||
checkVCross = false; | |||
if (numberOfSamples==1) | |||
lastVCross = checkVCross; | |||
if (lastVCross != checkVCross) | |||
crossCount++; | |||
numberOfSamples++; //Count number of times looped. | |||
} | |||
//------------------------------------------------------------------------------------------------------------------------- | |||
// 3) Post loop calculations | |||
//------------------------------------------------------------------------------------------------------------------------- | |||
//Calculation of the root of the mean of the voltage and current squared (rms) | |||
//Calibration coefficients applied. | |||
double V_Ratio = Vcal *((SupplyVoltage/1000.0) / 1023.0); | |||
Vrms = V_Ratio * sqrt(sumV / numberOfPowerSamples); | |||
double I_Ratio1 = Ical1 *((SupplyVoltage/1000.0) / 1023.0); | |||
Irms1 = I_Ratio1 * sqrt(sumI1 / numberOfPowerSamples); | |||
double I_Ratio2 = Ical2 *((SupplyVoltage/1000.0) / 1023.0); | |||
Irms2 = I_Ratio2 * sqrt(sumI2 / numberOfPowerSamples); | |||
double I_Ratio3 = Ical3 *((SupplyVoltage/1000.0) / 1023.0); | |||
Irms3 = I_Ratio3 * sqrt(sumI3 / numberOfPowerSamples); | |||
//Calculation power values | |||
realPower1 = V_Ratio * I_Ratio1 * sumP1 / numberOfPowerSamples; | |||
apparentPower1 = Vrms * Irms1; | |||
powerFactor1 = realPower1 / apparentPower1; | |||
realPower2 = V_Ratio * I_Ratio2 * sumP2 / numberOfPowerSamples; | |||
apparentPower2 = Vrms * Irms2; | |||
powerFactor2 = realPower2 / apparentPower2; | |||
realPower3 = V_Ratio * I_Ratio3 * sumP3 / numberOfPowerSamples; | |||
apparentPower3 = Vrms * Irms3; | |||
powerFactor3 = realPower3 / apparentPower3; | |||
//Reset accumulators | |||
sumV = 0; | |||
sumI1 = 0; | |||
sumI2 = 0; | |||
sumI3 = 0; | |||
sumP1 = 0; | |||
sumP2 = 0; | |||
sumP3 = 0; | |||
//-------------------------------------------------------------------------------------- | |||
// Include these statements for development/debugging only. Not used Gerard | |||
/*#ifdef DEBUGGING | |||
Serial.print("Total Samples: "); Serial.print(numberOfSamples); | |||
Serial.print(" Power Samples: "); Serial.print(numberOfPowerSamples); | |||
Serial.print(" Time: "); Serial.print(millis() - start); | |||
Serial.print(" Crossings: "); Serial.println(crossCount); | |||
for (int j=0; j<PHASE3; j++) | |||
{ | |||
Serial.print(storedV[j]); Serial.print(" "); | |||
Serial.println(); | |||
} | |||
#endif*/ | |||
} | |||
//********************************************************************************************************************* | |||
long readVcc() | |||
{ | |||
long result; | |||
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); | |||
delay(2); | |||
ADCSRA |= _BV(ADSC); | |||
while (bit_is_set(ADCSRA,ADSC)); | |||
result = ADCL; | |||
result |= ADCH<<8; | |||
result = 1126400L / result; | |||
return result; | |||
} | |||
// Setup - bring Ethernet, LCD and DHT11 live | |||
void setup () { | |||
Serial.begin(9600); | |||
if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0) | |||
Serial.println( "Failed to access Ethernet controller"); | |||
ether.staticSetup(myip, gwip); | |||
} | |||
// Here we build a web page and pass the t and h values into it | |||
static word homePage() { | |||
//ReadDHT11(); | |||
bfill = ether.tcpOffset(); | |||
bfill.emit_p(PSTR( | |||
"HTTP/1.0 200 OK\r\n" | |||
"Content-Type: text/html\r\n" | |||
"\r\n" | |||
"$T L1 $T $T $T $T L2 $T $T $T $T L3 $T $T $T $T"), | |||
Vrms, Irms1, realPower1, apparentPower1, powerFactor1, realPower2, apparentPower2, powerFactor2, Irms2, realPower3, apparentPower3, powerFactor3, Irms3); | |||
return bfill.position(); | |||
} | |||
} | |||
Revisió de 20:13, 27 oct 2015
#include <EtherCard.h>
// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x06 };
static byte myip[] = { 192,168,130,6 };
static byte gwip[] = { 192,168,130,1 };
byte Ethernet::buffer[500];
BufferFiller bfill;
// The Animation loop is to provide some bling to the LCD diaplay
#define FILTERSETTLETIME 5000 // Time (ms) to allow the filters to settle before sending data
#define SERIALPRINT // include print statement for commissioning - comment this line to exclude
#define PHASE2 8 // Number of samples delay for L2
#define PHASE3 17 // Number of samples delay for L3, also size of array
#define RF69_COMPAT 0 // set to 1 to use RFM69CW
const int UNO = 0;
int inPinV = 6;
int inPinI1 = 1;
int inPinI2 = 4;
int inPinI3 = 7;
//Calibration coefficients - see http://openenergymonitor.org/emon/modules/emontx/firmware/calibration%20
//These need to be set in order to obtain accurate results
double Vcal = 163.8; // Calibration - constant for voltage input - for ideal power voltage adapter
double Ical1 = 60.6; // Calibration constant for current transformer 1
double Ical2 = 60.6; // Calibration constant for current transformer 2
double Ical3 = 60.6; // Calibration constant for current transformer 3
double Phasecal1 = 1.0; // Calibration constant for phase shift L1
double Phasecal2 = 1.6; // Calibration constant for phase shift L2
double Phasecal3 = 1.0; // Calibration constant for phase shift L3
//--------------------------------------------------------------------------------------
// Variable declaration for filters, phase shift, voltages, currents & powers
//--------------------------------------------------------------------------------------
int lastSampleV,sampleV; //sample_ holds the raw analog read value, lastSample_ holds the last sample
int lastSampleI1,sampleI1;
int lastSampleI2,sampleI2;
int lastSampleI3,sampleI3;
double lastFilteredV,filteredV; //Filtered_ is the raw analog value minus the DC offset
double lastFilteredI1, filteredI1;
double lastFilteredI2, filteredI2;
double lastFilteredI3, filteredI3;
double phaseShiftedV1; //Holds the calibrated delayed & phase shifted voltage.
double phaseShiftedV2;
double phaseShiftedV3;
double sqV,sumV,sqI1,sumI1,sqI2,sumI2,sqI3,sumI3;
double instP1,sumP1,instP2,sumP2,instP3,sumP3; //sq = squared, sum = Sum, inst = instantaneous
int startV; //Instantaneous voltage at start of sample window.
int Vrms2;
double realPower1, // The final data
apparentPower1,
powerFactor1,
Irms1,
realPower2,
apparentPower2,
powerFactor2,
Irms2,
realPower3,
apparentPower3,
powerFactor3,
Irms3,
Vrms;
typedef struct { int power1, power2, power3, Vrms; } PayloadTX; // neat way of packaging data for RF comms
// (Include all the variables that are desired,
// ensure the same struct is used to receive)
PayloadTX emontx; // create an instance
const int LEDpin = 9; // On-board emonTx LED
boolean settled = false;
void calcVI3Ph(int cycles, int timeout)
{
int SupplyVoltage = readVcc();
int crossCount = 0; // Used to measure number of times threshold is crossed.
int numberOfSamples = 0; // This is now incremented
int numberOfPowerSamples = 0; // Needed because 1 cycle of voltages needs to be stored before use
boolean lastVCross, checkVCross; // Used to measure number of times threshold is crossed.
double storedV[PHASE3]; // Array to store >120 degrees of voltage samples
//-------------------------------------------------------------------------------------------------------------------------
// 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) // Wait for first zero crossing...
{
startV = analogRead(inPinV); // using the voltage waveform
if ((startV < 550) && (startV > 440)) st=true; // check it's within range
if ((millis()-start)>timeout) st = true;
}
//-------------------------------------------------------------------------------------------------------------------------
// 2) Main measurment loop
//-------------------------------------------------------------------------------------------------------------------------
start = millis();
while ((crossCount < cycles * 2) && ((millis()-start)<timeout))
{
lastSampleV=sampleV; // Used for digital high pass filter - offset removal
lastSampleI1=sampleI1;
lastSampleI2=sampleI2;
lastSampleI3=sampleI3;
lastFilteredV = filteredV;
lastFilteredI1 = filteredI1;
lastFilteredI2 = filteredI2;
lastFilteredI3 = filteredI3;
//-----------------------------------------------------------------------------
// A) Read in raw voltage and current samples
//-----------------------------------------------------------------------------
sampleV = analogRead(inPinV); // Read in raw voltage signal
sampleI1 = analogRead(inPinI1); // Read in raw current signal
sampleI2 = analogRead(inPinI2); // Read in raw current signal
sampleI3 = analogRead(inPinI3); // Read in raw current signal
//-----------------------------------------------------------------------------
// B) Apply digital high pass filters to remove 2.5V DC offset (to centre wave on 0).
//-----------------------------------------------------------------------------
filteredV = 0.996*(lastFilteredV+sampleV-lastSampleV);
filteredI1 = 0.996*(lastFilteredI1+sampleI1-lastSampleI1);
filteredI2 = 0.996*(lastFilteredI2+sampleI2-lastSampleI2);
filteredI3 = 0.996*(lastFilteredI3+sampleI3-lastSampleI3);
storedV[numberOfSamples%PHASE3] = filteredV; // store this voltage sample in circular buffer
if (crossCount > 2) // one complete cycle has been stored, so can use delayed
{ // voltage samples to calculate instantaneous powers
//-----------------------------------------------------------------------------
// C) Root-mean-square method voltage
//-----------------------------------------------------------------------------
sqV= filteredV * filteredV; //1) square voltage values
sumV += sqV; //2) sum
//-----------------------------------------------------------------------------
// D) Root-mean-square method current
//-----------------------------------------------------------------------------
sqI1 = filteredI1 * filteredI1; //1) square current values
sumI1 += sqI1; //2) sum
sqI2 = filteredI2 * filteredI2;
sumI2 += sqI2;
sqI3 = filteredI3 * filteredI3;
sumI3 += sqI3;
//-----------------------------------------------------------------------------
// E) Phase calibration - for Phase 1: shifts V1 to correct transformer errors
// for phases 2 & 3 delays V1 by 120 degrees & 240 degrees respectively
// and shifts for fine adjustment and to correct transformer errors.
//-----------------------------------------------------------------------------
phaseShiftedV1 = lastFilteredV + Phasecal1 * (filteredV - lastFilteredV);
phaseShiftedV2 = storedV[(numberOfSamples-PHASE2-1)%PHASE3]
+ Phasecal2 * (storedV[(numberOfSamples-PHASE2)%PHASE3]
- storedV[(numberOfSamples-PHASE2-1)%PHASE3]);
phaseShiftedV3 = storedV[(numberOfSamples+1)%PHASE3]
+ Phasecal3 * (storedV[(numberOfSamples+2)%PHASE3]
- storedV[(numberOfSamples+1)%PHASE3]);
//-----------------------------------------------------------------------------
// F) Instantaneous power calc
//-----------------------------------------------------------------------------
instP1 = phaseShiftedV1 * filteredI1; //Instantaneous Power
sumP1 +=instP1; //Sum
instP2 = phaseShiftedV2 * filteredI2;
sumP2 +=instP2;
instP3 = phaseShiftedV3 * filteredI3;
sumP3 +=instP3;
numberOfPowerSamples++; //Count number of times looped for Power averages.
}
//-----------------------------------------------------------------------------
// G) Find the number of times the voltage has crossed the initial voltage
// - every 2 crosses we will have sampled 1 wavelength
// - so this method allows us to sample an integer number of half wavelengths which increases accuracy
//-----------------------------------------------------------------------------
lastVCross = checkVCross;
if (sampleV > startV)
checkVCross = true;
else
checkVCross = false;
if (numberOfSamples==1)
lastVCross = checkVCross;
if (lastVCross != checkVCross)
crossCount++;
numberOfSamples++; //Count number of times looped.
}
//-------------------------------------------------------------------------------------------------------------------------
// 3) Post loop calculations
//-------------------------------------------------------------------------------------------------------------------------
//Calculation of the root of the mean of the voltage and current squared (rms)
//Calibration coefficients applied.
double V_Ratio = Vcal *((SupplyVoltage/1000.0) / 1023.0);
Vrms = V_Ratio * sqrt(sumV / numberOfPowerSamples);
double I_Ratio1 = Ical1 *((SupplyVoltage/1000.0) / 1023.0);
Irms1 = I_Ratio1 * sqrt(sumI1 / numberOfPowerSamples);
double I_Ratio2 = Ical2 *((SupplyVoltage/1000.0) / 1023.0);
Irms2 = I_Ratio2 * sqrt(sumI2 / numberOfPowerSamples);
double I_Ratio3 = Ical3 *((SupplyVoltage/1000.0) / 1023.0);
Irms3 = I_Ratio3 * sqrt(sumI3 / numberOfPowerSamples);
//Calculation power values
realPower1 = V_Ratio * I_Ratio1 * sumP1 / numberOfPowerSamples;
apparentPower1 = Vrms * Irms1;
powerFactor1 = realPower1 / apparentPower1;
realPower2 = V_Ratio * I_Ratio2 * sumP2 / numberOfPowerSamples;
apparentPower2 = Vrms * Irms2;
powerFactor2 = realPower2 / apparentPower2;
realPower3 = V_Ratio * I_Ratio3 * sumP3 / numberOfPowerSamples;
apparentPower3 = Vrms * Irms3;
powerFactor3 = realPower3 / apparentPower3;
//Reset accumulators
sumV = 0;
sumI1 = 0;
sumI2 = 0;
sumI3 = 0;
sumP1 = 0;
sumP2 = 0;
sumP3 = 0;
//--------------------------------------------------------------------------------------
// Include these statements for development/debugging only. Not used Gerard
/*#ifdef DEBUGGING
Serial.print("Total Samples: "); Serial.print(numberOfSamples);
Serial.print(" Power Samples: "); Serial.print(numberOfPowerSamples);
Serial.print(" Time: "); Serial.print(millis() - start);
Serial.print(" Crossings: "); Serial.println(crossCount);
for (int j=0; j<PHASE3; j++)
{
Serial.print(storedV[j]); Serial.print(" ");
Serial.println();
}
#endif*/
}
//*********************************************************************************************************************
long readVcc()
{
long result;
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2);
ADCSRA |= _BV(ADSC);
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result;
return result;
}
// Setup - bring Ethernet, LCD and DHT11 live
void setup () {
Serial.begin(9600);
if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0)
Serial.println( "Failed to access Ethernet controller");
ether.staticSetup(myip, gwip);
}
// Here we build a web page and pass the t and h values into it
static word homePage() {
//ReadDHT11();
bfill = ether.tcpOffset();
bfill.emit_p(PSTR(
"HTTP/1.0 200 OK\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"$T L1 $T $T $T $T L2 $T $T $T $T L3 $T $T $T $T"),
Vrms, Irms1, realPower1, apparentPower1, powerFactor1, realPower2, apparentPower2, powerFactor2, Irms2, realPower3, apparentPower3, powerFactor3, Irms3);
return bfill.position();
}