Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
PowerMeasurement.h
00001 /// 00002 /// 00003 /// 00004 00005 #ifndef POWERMEASUREMENT_H 00006 #define POWERMEASUREMENT_H 00007 00008 #include "mbed.h" 00009 00010 00011 /// The PowerMeasurement class is used to take voltage and current measurements and compute power consumption. 00012 /// 00013 /// This is done as a process that takes some amount of time, as it will sample two inputs over a number of 00014 /// cycles of the AC line input (typically 60 Hz). In order to avoid blocking the CPU any more than necessary 00015 /// it will be processed with a ticker. So, there will be functions to start an acquisition, monitor the 00016 /// acquisition, and extract the results when it is done. 00017 /// 00018 /// The power measurement is performed on virtual channels, which map to real analog inputs. The virtual 00019 /// channels may be direct-wired to the processor analog inputs, or it may be esternally multiplexed. 00020 /// 00021 /// Electrically, the voltage measurements are normalized so the A/C swing is biased to mid-range on the 00022 /// A/D and then peak-to-peak is measured from 0 to FFFF. 00023 /// 00024 /// @code 00025 /// NumMuxes 00026 /// +----------+ MuxChannels 00027 /// Input 1 ---|0 a|--------------------------------------+ 00028 /// Input 2 ---|1 b|--------------------------------------+ 00029 /// Input 3 ---|2 c|--------------------------------------+ 00030 /// ... ---| | | 00031 /// ... ---| inh|------------------------------------+ | 00032 /// ... ---| | AinCount | | 00033 /// ... ---| | +--------------+ | | 00034 /// Input 8 ---|7 Y|--------|p15 | | | 00035 /// +----------+ | | Select | | 00036 /// | pxx|------------+ | 00037 /// - - -|p16 | | 00038 /// | | | 00039 /// | | | 00040 /// | | MusBus | 00041 /// | pcc|--------------+ 00042 /// | pbb|--------------+ 00043 /// | paa|--------------+ 00044 /// GetVoltage() -------> | | 00045 /// +--------------+ 00046 /// 00047 /// @endcode 00048 /// 00049 class PowerMeasurement { 00050 public: 00051 /// The callback to get the instantaneous value of the voltage time-synchronous with the current measurement. 00052 /// 00053 /// The called function should return the instantaneous voltage measurement. The value is an unsigned value 00054 /// normalized to the range of 0 to FFFF, with a zero-offset of 32768. 00055 /// 00056 /// If not voltage measurement system is in place, the user may choose not to define this function, in 00057 /// which case the power measurements cannot be made. The current measurements are still valid, and power 00058 /// can be computed by the users program. 00059 /// 00060 /// @returns a value in the range of 0 to FFFF, biased to the mid-point of 32768 which represents 0.0v. 00061 /// 00062 typedef uint16_t (* GetVoltage_T)(void); 00063 00064 /// Each raw sample consists of 2 values - the voltage and the current at that moment. The labels 'voltage' 00065 /// and 'current' are somewhat artificial. The 'current' values are gathers from the analog inputs and 00066 /// multiplexers. The 'voltage' is from an external callback, which in turn might be using one of the 00067 /// analog inputs, or it might be from an external measurement source. 00068 typedef struct { 00069 uint16_t voltage; ///< The voltage, in A/D units, which are scaled 0 to FFFF 00070 uint16_t current; ///< The current, in A/D units, which are scaled 0 to FFFF 00071 } RawPowerData_T; 00072 00073 #define SAMPLES_PER_CYCLE 100 ///< The number of samples in each cycle 00074 #define CYCLES_PER_SAMPLE 2 ///< The number of cycles in the sample 00075 #define PM_ZERO_OFFSET 32767 ///< Zero-Offset applied to A/D values 00076 #define PM_FULL_SCALE 32767 ///< The full-scale value against the calibration 00077 00078 /// The constructor for the PowerMeasurement class is used to create various hardware assignments. 00079 /// 00080 /// @param[in] AinList is a pointer to an array of AnalogIn classes 00081 /// @param[in] MuxBus is a pointer to a BusOut that is used to select the external multiplexer channel. 00082 /// @param[in] Select is a pointer to a DigitalOut that is used to enable the external multplexer. 00083 /// @param[in] v_get is the callback used to get the voltage time synchronous with the current measurement. 00084 /// @param[in] AinCount is the count of Analog Inputs to use, from 1 to 6, which maps to p15 thru p20. Default: 6. 00085 /// @param[in] MuxChannels is the count of channels on each external multiplexer. Default: 8. 00086 /// 00087 PowerMeasurement(AnalogIn * AinList, BusOut * MuxBus = NULL, DigitalOut * Select = NULL, 00088 GetVoltage_T callback = NULL, int AinCount = 6, int MuxChannels = 8); 00089 00090 /// The destructor. 00091 ~PowerMeasurement(); 00092 00093 /// Define the frequency of the line voltage, which in turn defines the sample-rate. 00094 /// 00095 /// Based on this line frequency, the sample-rate for the measurement is set to achieve 00096 /// 'SAMPLES_PER_CYCLE' samples per cycle, and 'CYCLES_PER_SAMPLE' cycles. 00097 /// 00098 /// @param[in] Hz sets the line frequency. 00099 /// 00100 void frequency(float _Hz); 00101 00102 /// Define the measuremenbt interval, as an alternative to setting the frequency. 00103 /// 00104 /// Instead of defining the measurement interval by specifying the line frequency, the period 00105 /// can be directly set. 00106 /// 00107 /// @param uSec is the number of microseconds between samples. 00108 /// 00109 void period_us(uint32_t uSec); 00110 00111 /// Set the analog input to current calibration value for a channel. 00112 /// 00113 /// Each analog input channel can be configured for the current sensor used on that channel. 00114 /// If the channel has a 30 A current sensor, that channel should be set to 30.0f. 00115 /// If the user calibrates the sensor more precisely, an improved calibration factor (e.g. 31.1) 00116 /// can be defined. 00117 /// 00118 /// The calibration is based on the full-scale reading from the A/D. As the A/D is a normalized 00119 /// uint16_t value, and biased to approximately mid-supply, the full scale range is then 00120 /// 1/2 of the total range, or approximately 32767. Component tolerances, of the voltage 00121 /// reference, the mid-supply divider, and the current sensing component can affect this. 00122 /// 00123 /// @param[in] channel defines the channel to calibrate. 00124 /// @param[in] fullScaleCurrentCalibration is the calibration factor representing the full-scale current. 00125 /// @returns true if the value is accepted. 00126 /// @returns false if the channel was incorrect. 00127 /// 00128 bool SetFullScaleCurrent(int channel, float fullScaleCurrentCalibration); 00129 00130 /// Set the voltage value representing the full scale measurement. 00131 /// 00132 /// The GetVoltage callback is expecting a uint16_t as the return value. When configured for a 00133 /// 120V circuit, which measures approximately 170v peak, the fullScaleVoltageCalibration value 00134 /// would be 170.0f. 00135 /// 00136 /// The calibration is based on the full-scale reading from the A/D. As the A/D is a normalized 00137 /// uint16_t value, and biased to approximately mid-supply, the full scale range is then 00138 /// 1/2 of the total range, or approximately 32767. Component tolerances, of the voltage 00139 /// reference, the mid-supply divider, and the current sensing component can affect this. 00140 /// 00141 /// @param[in] fullScaleVoltageCalibration is the full-scale voltage value. 00142 /// @returns true if the value is accepted, which it will be. 00143 /// 00144 bool SetFullScaleVoltage(float fullScaleVoltageCalibration); 00145 00146 /// Starts a measurement on the specified channel. 00147 /// 00148 /// This starts the measurement on a specified channel. The subsystem will then configure 00149 /// the external multiplexer and a/d sampling to gather the the samples. 00150 /// 00151 /// The actual sampling of the data can be either synchronous, or asynchonous, based on a 00152 /// #define value. 00153 /// 00154 /// @param[in] channel defines the channel to measure. This is in the range of 0 to N-1, where N is 00155 /// AinCount * MuxChannels. 00156 /// @returns true if the measurement can be started (in async mode), or if the measurement is complete 00157 /// when operating in synchonous mode. 00158 /// @returns false if the measurement cannot be started - likely because of an incorrect channel 00159 /// selection. 00160 /// 00161 bool StartMeasurement(int channel); 00162 00163 /// Determines if the conversion is complete and the results are readable. 00164 /// 00165 /// When operating in the asynchronous mode, this API can be used to detect when the conversion 00166 /// is complete. 00167 /// 00168 /// @returns true if the measurement is complete (or if no measurement is in process). 00169 /// @returns false if the measurement is in process. 00170 /// 00171 bool readable(); 00172 00173 /// Get the rms current measurement. 00174 /// 00175 /// This retrieves the rms current measurement for the channel which just completed measurement. 00176 /// 00177 /// @returns the rm current measurement. 00178 /// 00179 float GetRMSCurrent(); 00180 00181 /// Get the rms voltage measurement. 00182 /// 00183 /// This retrieves the rms voltage measurement for the channel which just completed measurement. 00184 /// 00185 /// @note This is only valid if the user supplied GetVoltage() function was provided. 00186 /// 00187 /// @returns the rms voltage measurement. 00188 /// 00189 float GetRMSVoltage(); 00190 00191 /// Get the real power measurement. 00192 /// 00193 /// This retrieves the real power measurement for the channel which just completed measurement. 00194 /// This is the average of the instantaneous power. 00195 /// 00196 /// @note This is only valid if the user supplied GetVoltage() function was provided. 00197 /// 00198 /// @returns the real power measurement. 00199 /// 00200 float GetRealPower(); 00201 00202 /// Get the apparent power measurement. 00203 /// 00204 /// This retrieves the apparent power measurement for the channel which just completed measurement. 00205 /// 00206 /// @note This is only valid if the user supplied GetVoltage() function was provided. 00207 /// 00208 /// @returns the apparent power measurement. 00209 /// 00210 float GetApparentPower(); 00211 00212 /// Get the power factor 00213 /// 00214 /// @note This is only valid if the user supplied GetVoltage() function was provided. 00215 /// 00216 /// @returns the power factor measurement. 00217 /// 00218 float GetPowerFactor(); 00219 00220 /// Get the peak current measurement values from the recent sample. 00221 /// 00222 /// @note if either parameter is null, that data will not be provided. 00223 /// 00224 /// @param[inout] negPeak is a pointer to the negative going peak current measured. 00225 /// @param[inout] posPeak is a pointer to the positive going peak current measured. 00226 /// @returns true if a measurement was completed and the data was updated. 00227 /// @returns false if a measurement has not started or is in process. 00228 /// 00229 bool GetPeakCurrent(float * negPeak, float * posPeak); 00230 00231 /// Get the raw sample data for a given sample number. 00232 /// 00233 /// If a measurement is complete, or has at least proceeded beyond the desired 00234 /// sample, then pass that raw data to the calling function. 00235 /// 00236 /// @param[in] sample is the sample number of interest, ranging from 0 to N-1. 00237 /// @param[inout] rawsample is a pointer to where the specified sample will be written. 00238 /// @returns true if the sample was available for the calling function. 00239 /// @returns false if the same was not available. 00240 /// 00241 bool GetRawSample(int sample, RawPowerData_T * rawsample); 00242 00243 /// Get the count of raw samples that are being taken, 00244 /// 00245 /// @returns count of samples that are taken. 00246 /// 00247 int GetRawSampleCount(void); 00248 00249 private: 00250 00251 void TakeSample(void); ///< Ticker callback to take a sample 00252 BusOut * MuxBus; ///< pointer to the bus used to modify the multiplexer. 00253 DigitalOut * Select; ///< pointer to the pin used to enable the multiplexer. 00254 GetVoltage_T * GetVoltage; ///< pointer to the GetVoltage callback. 00255 int AinCount; ///< count of direct A/D channels. 00256 int NumMuxes; ///< count of the number of multiplexers. 00257 int MuxChannels; ///< count of the number of channels per multiplexer. 00258 00259 AnalogIn * AinList; ///< This defines the list of AnalogInputs 00260 int a2dChannel; ///< the AnalogIn channel number to sample 00261 uint32_t uSecInterval; ///< time in uSec between each sample 00262 int totalChannels; ///< total number of input channels 00263 Ticker sampleTimer; ///< Timer to schedule the a/d sample. 00264 volatile bool inProcess; ///< indicates when a sample is in process. 00265 volatile bool isComplete; ///< indicates when conversion is complete. 00266 RawPowerData_T * rawSamples; ///< points to an array of raw a/d value samples. 00267 volatile int sampleNum; ///< keeps track of the current sample in process. 00268 float * fullScaleCurrent; ///< pointer to an array sized based on total number of channels. 00269 float fullScaleVoltage; ///< the full scale voltage calibration setting. 00270 }; 00271 00272 00273 00274 00275 #endif // POWERMEASUREMENT_H
Generated on Sun Aug 21 2022 08:48:13 by
1.7.2