Minor update to improve documentation and add missing functions.
PowerMeasurement.h
- Committer:
- WiredHome
- Date:
- 2016-10-17
- Revision:
- 2:7f6a39ec5c01
- Parent:
- 1:d99a72afec32
File content as of revision 2:7f6a39ec5c01:
/// /// /// #ifndef POWERMEASUREMENT_H #define POWERMEASUREMENT_H #include "mbed.h" /// The PowerMeasurement class is used to take voltage and current measurements and compute power consumption. /// /// This is done as a process that takes some amount of time, as it will sample two inputs over a number of /// cycles of the AC line input (typically 60 Hz). In order to avoid blocking the CPU any more than necessary /// it will be processed with a ticker. So, there will be functions to start an acquisition, monitor the /// acquisition, and extract the results when it is done. /// /// The power measurement is performed on virtual channels, which map to real analog inputs. The virtual /// channels may be direct-wired to the processor analog inputs, or it may be esternally multiplexed. /// /// Electrically, the voltage measurements are normalized so the A/C swing is biased to mid-range on the /// A/D and then peak-to-peak is measured from 0 to FFFF. /// /// @code /// NumMuxes /// +----------+ MuxChannels /// Input 1 ---|0 a|--------------------------------------+ /// Input 2 ---|1 b|--------------------------------------+ /// Input 3 ---|2 c|--------------------------------------+ /// ... ---| | | /// ... ---| inh|------------------------------------+ | /// ... ---| | AinCount | | /// ... ---| | +--------------+ | | /// Input 8 ---|7 Y|--------|p15 | | | /// +----------+ | | Select | | /// | pxx|------------+ | /// - - -|p16 | | /// | | | /// | | | /// | | MusBus | /// | pcc|--------------+ /// | pbb|--------------+ /// | paa|--------------+ /// GetVoltage() -------> | | /// +--------------+ /// /// @endcode /// class PowerMeasurement { public: /// The callback to get the instantaneous value of the voltage time-synchronous with the current measurement. /// /// The called function should return the instantaneous voltage measurement. The value is an unsigned value /// normalized to the range of 0 to FFFF, with a zero-offset of 32768. /// /// If not voltage measurement system is in place, the user may choose not to define this function, in /// which case the power measurements cannot be made. The current measurements are still valid, and power /// can be computed by the users program. /// /// @returns a value in the range of 0 to FFFF, biased to the mid-point of 32768 which represents 0.0v. /// typedef uint16_t (* GetVoltage_T)(void); /// Each raw sample consists of 2 values - the voltage and the current at that moment. The labels 'voltage' /// and 'current' are somewhat artificial. The 'current' values are gathers from the analog inputs and /// multiplexers. The 'voltage' is from an external callback, which in turn might be using one of the /// analog inputs, or it might be from an external measurement source. typedef struct { uint16_t voltage; ///< The voltage, in A/D units, which are scaled 0 to FFFF uint16_t current; ///< The current, in A/D units, which are scaled 0 to FFFF } RawPowerData_T; #define SAMPLES_PER_CYCLE 100 ///< The number of samples in each cycle #define CYCLES_PER_SAMPLE 2 ///< The number of cycles in the sample #define PM_ZERO_OFFSET 32767 ///< Zero-Offset applied to A/D values #define PM_FULL_SCALE 32767 ///< The full-scale value against the calibration /// The constructor for the PowerMeasurement class is used to create various hardware assignments. /// /// @param[in] AinList is a pointer to an array of AnalogIn classes /// @param[in] MuxBus is a pointer to a BusOut that is used to select the external multiplexer channel. /// @param[in] Select is a pointer to a DigitalOut that is used to enable the external multplexer. /// @param[in] v_get is the callback used to get the voltage time synchronous with the current measurement. /// @param[in] AinCount is the count of Analog Inputs to use, from 1 to 6, which maps to p15 thru p20. Default: 6. /// @param[in] MuxChannels is the count of channels on each external multiplexer. Default: 8. /// PowerMeasurement(AnalogIn * AinList, BusOut * MuxBus = NULL, DigitalOut * Select = NULL, GetVoltage_T callback = NULL, int AinCount = 6, int MuxChannels = 8); /// The destructor. ~PowerMeasurement(); /// Define the frequency of the line voltage, which in turn defines the sample-rate. /// /// Based on this line frequency, the sample-rate for the measurement is set to achieve /// 'SAMPLES_PER_CYCLE' samples per cycle, and 'CYCLES_PER_SAMPLE' cycles. /// /// @param[in] Hz sets the line frequency. /// void frequency(float _Hz); /// Define the measuremenbt interval, as an alternative to setting the frequency. /// /// Instead of defining the measurement interval by specifying the line frequency, the period /// can be directly set. /// /// @param uSec is the number of microseconds between samples. /// void period_us(uint32_t uSec); /// Set the analog input to current calibration value for a channel. /// /// Each analog input channel can be configured for the current sensor used on that channel. /// If the channel has a 30 A current sensor, that channel should be set to 30.0f. /// If the user calibrates the sensor more precisely, an improved calibration factor (e.g. 31.1) /// can be defined. /// /// The calibration is based on the full-scale reading from the A/D. As the A/D is a normalized /// uint16_t value, and biased to approximately mid-supply, the full scale range is then /// 1/2 of the total range, or approximately 32767. Component tolerances, of the voltage /// reference, the mid-supply divider, and the current sensing component can affect this. /// /// @param[in] channel defines the channel to calibrate. /// @param[in] fullScaleCurrentCalibration is the calibration factor representing the full-scale current. /// @returns true if the value is accepted. /// @returns false if the channel was incorrect. /// bool SetFullScaleCurrent(int channel, float fullScaleCurrentCalibration); /// Set the voltage value representing the full scale measurement. /// /// The GetVoltage callback is expecting a uint16_t as the return value. When configured for a /// 120V circuit, which measures approximately 170v peak, the fullScaleVoltageCalibration value /// would be 170.0f. /// /// The calibration is based on the full-scale reading from the A/D. As the A/D is a normalized /// uint16_t value, and biased to approximately mid-supply, the full scale range is then /// 1/2 of the total range, or approximately 32767. Component tolerances, of the voltage /// reference, the mid-supply divider, and the current sensing component can affect this. /// /// @param[in] fullScaleVoltageCalibration is the full-scale voltage value. /// @returns true if the value is accepted, which it will be. /// bool SetFullScaleVoltage(float fullScaleVoltageCalibration); /// Starts a measurement on the specified channel. /// /// This starts the measurement on a specified channel. The subsystem will then configure /// the external multiplexer and a/d sampling to gather the the samples. /// /// The actual sampling of the data can be either synchronous, or asynchonous, based on a /// #define value. /// /// @param[in] channel defines the channel to measure. This is in the range of 0 to N-1, where N is /// AinCount * MuxChannels. /// @returns true if the measurement can be started (in async mode), or if the measurement is complete /// when operating in synchonous mode. /// @returns false if the measurement cannot be started - likely because of an incorrect channel /// selection. /// bool StartMeasurement(int channel); /// Determines if the conversion is complete and the results are readable. /// /// When operating in the asynchronous mode, this API can be used to detect when the conversion /// is complete. /// /// @returns true if the measurement is complete (or if no measurement is in process). /// @returns false if the measurement is in process. /// bool readable(); /// Get the rms current measurement. /// /// This retrieves the rms current measurement for the channel which just completed measurement. /// /// @returns the rm current measurement. /// float GetRMSCurrent(); /// Get the rms voltage measurement. /// /// This retrieves the rms voltage measurement for the channel which just completed measurement. /// /// @note This is only valid if the user supplied GetVoltage() function was provided. /// /// @returns the rms voltage measurement. /// float GetRMSVoltage(); /// Get the real power measurement. /// /// This retrieves the real power measurement for the channel which just completed measurement. /// This is the average of the instantaneous power. /// /// @note This is only valid if the user supplied GetVoltage() function was provided. /// /// @returns the real power measurement. /// float GetRealPower(); /// Get the apparent power measurement. /// /// This retrieves the apparent power measurement for the channel which just completed measurement. /// /// @note This is only valid if the user supplied GetVoltage() function was provided. /// /// @returns the apparent power measurement. /// float GetApparentPower(); /// Get the power factor /// /// @note This is only valid if the user supplied GetVoltage() function was provided. /// /// @returns the power factor measurement. /// float GetPowerFactor(); /// Get the peak current measurement values from the recent sample. /// /// @note if either parameter is null, that data will not be provided. /// /// @param[inout] negPeak is a pointer to the negative going peak current measured. /// @param[inout] posPeak is a pointer to the positive going peak current measured. /// @returns true if a measurement was completed and the data was updated. /// @returns false if a measurement has not started or is in process. /// bool GetPeakCurrent(float * negPeak, float * posPeak); /// Get the raw sample data for a given sample number. /// /// If a measurement is complete, or has at least proceeded beyond the desired /// sample, then pass that raw data to the calling function. /// /// @param[in] sample is the sample number of interest, ranging from 0 to N-1. /// @param[inout] rawsample is a pointer to where the specified sample will be written. /// @returns true if the sample was available for the calling function. /// @returns false if the same was not available. /// bool GetRawSample(int sample, RawPowerData_T * rawsample); /// Get the count of raw samples that are being taken, /// /// @returns count of samples that are taken. /// int GetRawSampleCount(void); private: void TakeSample(void); ///< Ticker callback to take a sample BusOut * MuxBus; ///< pointer to the bus used to modify the multiplexer. DigitalOut * Select; ///< pointer to the pin used to enable the multiplexer. GetVoltage_T * GetVoltage; ///< pointer to the GetVoltage callback. int AinCount; ///< count of direct A/D channels. int NumMuxes; ///< count of the number of multiplexers. int MuxChannels; ///< count of the number of channels per multiplexer. AnalogIn * AinList; ///< This defines the list of AnalogInputs int a2dChannel; ///< the AnalogIn channel number to sample uint32_t uSecInterval; ///< time in uSec between each sample int totalChannels; ///< total number of input channels Ticker sampleTimer; ///< Timer to schedule the a/d sample. volatile bool inProcess; ///< indicates when a sample is in process. volatile bool isComplete; ///< indicates when conversion is complete. RawPowerData_T * rawSamples; ///< points to an array of raw a/d value samples. volatile int sampleNum; ///< keeps track of the current sample in process. float * fullScaleCurrent; ///< pointer to an array sized based on total number of channels. float fullScaleVoltage; ///< the full scale voltage calibration setting. }; #endif // POWERMEASUREMENT_H