Commit Iniziale, progetto funzionante caricato su box ETcontroller in

cantina
This commit is contained in:
2019-10-09 23:25:44 +02:00
commit c6e4e461ca
555 changed files with 118433 additions and 0 deletions

View File

@@ -0,0 +1,213 @@
/*
* TEnergyMonitor.cpp
*
* Created on: 07 apr 2018
* Author: Emanuele
*/
#include "TEnergyMonitor.h"
TEnergyMonitor::TEnergyMonitor(Serial* _pc){
pc=_pc;
}
//--------------------------------------------------------------------------------------
// Sets the pins to be used for voltage and current sensors
//--------------------------------------------------------------------------------------
void TEnergyMonitor::voltage(PinName _inPinV, double _VCAL, double _PHASECAL)
{
inPinV = _inPinV;
VCAL = _VCAL;
PHASECAL = _PHASECAL;
offsetV = ADC_COUNTS>>1;
adcV = new AnalogIn(inPinV);
}
void TEnergyMonitor::current(PinName _inPinI, double _ICAL)
{
inPinI = _inPinI;
ICAL = _ICAL;
offsetI = ADC_COUNTS>>1;
adcI = new AnalogIn(inPinI);
}
//--------------------------------------------------------------------------------------
// Sets the pins to be used for voltage and current sensors based on emontx pin map
//--------------------------------------------------------------------------------------
//void TEnergyMonitor::voltageTX(double _VCAL, double _PHASECAL)
//{
// inPinV = 2;
// VCAL = _VCAL;
// PHASECAL = _PHASECAL;
// offsetV = ADC_COUNTS>>1;
//}
//
//void TEnergyMonitor::currentTX(unsigned int _channel, double _ICAL)
//{
// if (_channel == 1) inPinI = 3;
// if (_channel == 2) inPinI = 0;
// if (_channel == 3) inPinI = 1;
// ICAL = _ICAL;
// offsetI = ADC_COUNTS>>1;
//}
//--------------------------------------------------------------------------------------
// 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 TEnergyMonitor::calcVI(unsigned int crossings, unsigned int timeout)
{
#if defined emonTxV3
int SupplyVoltage=3300;
#else
int SupplyVoltage = readVcc();
#endif
unsigned int crossCount = 0; //Used to measure number of times threshold is crossed.
unsigned int numberOfSamples = 0; //This is now incremented
//-------------------------------------------------------------------------------------------------------------------------
// 1) Waits for the waveform to be close to 'zero' (mid-scale adc) part in sin curve.
//-------------------------------------------------------------------------------------------------------------------------
bool 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 = adcV->read_u16(); //using the voltage waveform
if ((startV < (ADC_COUNTS*0.55)) && (startV > (ADC_COUNTS*0.45))) st=true; //check its within range
if ((millis()-start)>timeout) st = true;
}
//-------------------------------------------------------------------------------------------------------------------------
// 2) Main measurement loop
//-------------------------------------------------------------------------------------------------------------------------
start = millis();
while ((crossCount < crossings) && ((millis()-start)<timeout))
{
numberOfSamples++; //Count number of times looped.
lastFilteredV = filteredV; //Used for delay/phase compensation
//-----------------------------------------------------------------------------
// A) Read in raw voltage and current samples
//-----------------------------------------------------------------------------
sampleV = adcV->read_u16(); //Read in raw voltage signal
sampleI = adcI->read_u16(); //Read in raw current signal
//-----------------------------------------------------------------------------
// B) Apply digital low pass filters to extract the 2.5 V or 1.65 V dc offset,
// then subtract this - signal is now centred on 0 counts.
//-----------------------------------------------------------------------------
offsetV = offsetV + ((sampleV-offsetV)/1024);
filteredV = sampleV - offsetV;
offsetI = offsetI + ((sampleI-offsetI)/1024);
filteredI = sampleI - offsetI;
//-----------------------------------------------------------------------------
// 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
//-----------------------------------------------------------------------------
// E) Phase calibration
//-----------------------------------------------------------------------------
phaseShiftedV = lastFilteredV + PHASECAL * (filteredV - lastFilteredV);
//-----------------------------------------------------------------------------
// F) Instantaneous power calc
//-----------------------------------------------------------------------------
instP = phaseShiftedV * filteredI; //Instantaneous Power
sumP +=instP; //Sum
//-----------------------------------------------------------------------------
// 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++;
}
//-------------------------------------------------------------------------------------------------------------------------
// 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) / (ADC_COUNTS));
Vrms = V_RATIO * sqrt(sumV / numberOfSamples);
double I_RATIO = ICAL *((SupplyVoltage/1000.0) / (ADC_COUNTS));
Irms = I_RATIO * sqrt(sumI / numberOfSamples);
//Calculation power values
realPower = V_RATIO * I_RATIO * sumP / numberOfSamples;
apparentPower = Vrms * Irms;
powerFactor=realPower / apparentPower;
//Reset accumulators
sumV = 0;
sumI = 0;
sumP = 0;
//--------------------------------------------------------------------------------------
}
//--------------------------------------------------------------------------------------
double TEnergyMonitor::calcIrms(unsigned int timeout)
{
#if defined emonTxV3
int SupplyVoltage=3300;
#else
int SupplyVoltage = readVcc();
#endif
//Reset accumulators
sumI = 0;
unsigned long NumberOfSamples=0;
unsigned long start=millis();
while ((millis()-start)<timeout*1000)
{
sampleI = adcI->read_u16();
// Digital low pass filter extracts the 2.5 V or 1.65 V dc offset,
// then subtract this - signal is now centered on 0 counts.
offsetI = (offsetI + (sampleI-offsetI)/1024);
filteredI = sampleI - offsetI;
// Root-mean-square method current
// 1) square current values
sqI = filteredI * filteredI;
// 2) sum
sumI += sqI;
NumberOfSamples++;
}
double I_RATIO = ICAL *((SupplyVoltage/1000.0) / (ADC_COUNTS));
Irms = I_RATIO * sqrt(sumI / NumberOfSamples);
return Irms;
}
long TEnergyMonitor::readVcc(){
return 3340;
}

View File

@@ -0,0 +1,78 @@
/*
* TEnergyMonitor.h
*
* Created on: 07 apr 2018
* Author: Emanuele
*/
#ifndef TENERGYMONITOR_H_
#define TENERGYMONITOR_H_
#define ADC_BITS 16
#define ADC_COUNTS (1<<ADC_BITS)
#define VSUPPLY 3300
#include "mbed.h"
#include "millis.h"
class TEnergyMonitor {
public:
TEnergyMonitor(Serial* _pc);
void voltage(PinName _inPinV, double _VCAL, double _PHASECAL);
void current(PinName _inPinI, double _ICAL);
void voltageTX(double _VCAL, double _PHASECAL);
void currentTX(unsigned int _channel, double _ICAL);
void calcVI(unsigned int crossings, unsigned int timeout);
double calcIrms(unsigned int NUMBER_OF_SAMPLES);
void serialprint();
long readVcc();
//Useful value variables
double realPower,
apparentPower,
powerFactor,
Vrms,
Irms;
private:
Serial* pc;
//Set Voltage and current input pins
PinName inPinV;
PinName inPinI;
AnalogIn *adcV;
AnalogIn *adcI;
//Calibration coefficients
//These need to be set in order to obtain accurate results
double VCAL;
double ICAL;
double PHASECAL;
//--------------------------------------------------------------------------------------
// Variable declaration for emon_calc procedure
//--------------------------------------------------------------------------------------
unsigned int sampleV; //sample_ holds the raw analog read value
unsigned int sampleI;
double lastFilteredV,filteredV; //Filtered_ is the raw analog value minus the DC offset
double filteredI;
double offsetV; //Low-pass filter output
double offsetI; //Low-pass filter output
double phaseShiftedV; //Holds the calibrated phase shifted voltage.
double sqV,sumV,sqI,sumI,instP,sumP; //sq = squared, sum = Sum, inst = instantaneous
int startV; //Instantaneous voltage at start of sample window.
bool lastVCross, checkVCross; //Used to measure number of times threshold is crossed.
};
#endif /* TENERGYMONITOR_H_ */