Announcements‎ > ‎

Energy consumption and power measurement... from panStamp!

posted Sep 11, 2012, 9:51 AM by Daniel Berenguer   [ updated Sep 11, 2012, 10:17 AM ]

We know many of you were wondering when we'll release a power meter compatible with panStamp. And here we are, sooner as expected, with a first prototype. We at panStamp are passionate about simplicity so you may guess  that either electronics or firmware application have been designed to be as compact and efficient as possible.

panStamp meter board

Figure 1 : panStamp meter board

The hardware

The meter board is "non-AC intrusive", meaning that all voltages handled on the board are low-level, so there is no danger for the user when in direct contact with the on-board circuits. This is achieved thanks to the external transformers (voltage and current), which free the user from having to connect regular AC wires to the meter board.

Meter board in DIN-rail enclosure
Figure 2 : meter board in DIN-rail enclosure

This board with the associated Arduino sketch has an input for an external voltage transformer, which powers the board and provides the voltage information for the internal calculations, six inputs for current transformers (current clamps) and three pulse counting inputs.

The hardware design still needs to be modified with some additions, including a way to store readings for a while after detecting a power outage. A seventh input for current transformer may be added to to the PCB design as well, and finally some additional filtering capacitors.

Working KiCad files can be downloaded from SVN too.

Reading from voltage and current transformers are used to calculate the following data:
  • RMS voltage (VAC)
  • RMS current (AAC)
  • Active (real) power (KW)
  • Apparent power (VA)
  • Power factor
  • Energy consumption (KWh)
On the other hand, pulse inputs are used to count pulses coming from other devices like power meters, water flow meters and gas meters. This gives up to 9 different inputs for measuring energy consumptions from different sources.

 Voltage transformer
Figure 3 : Voltage transformer. 230VAC to 12VAC version

Current transformer

Figure 4: Current transformer. 5A version

SCT-013-005 and SCT-013-030 current clamps from YHDC have been used for the tests. These transformers basically convert AC current to AC voltage (maximum amplitude = 1V) so depending on the current to be measured we may decide to use the 5A version or the 30A one... or even the 50A one. But how does the on-board panStamp calculates power consumption from real-time voltage and currents?

The firmware

Calculations basically rely on the following method:

 * update
 * Update AC channel readings
 * Return:
 *    0 if the function still needs to take additional samples
 *    1 if the function read the necessary amount of samples
 *    2 if the function detected no VAC signal after reading the samples
byte CHANNEL::update(void) 
  unsigned long adcV1, adcV2, adcI;
  float voltage, current;
  static double accumulated;
  static int i = 0;
  const float peakToRMS = 0.707106781;       // Peak to RMS conversion factor
  unsigned long currentTime, elapsedTime;
  double energy;
  bool getEnergy = false;
  const float scale = ACVOLT_SCALE;
  static bool noVac = true;
  //Read voltage and current
  adcV1 = analogRead(voltagePin);    // First AC voltage reading
  adcI = analogRead(currentPin);     // AC current reading
  adcV2 = analogRead(voltagePin);    // Second AC current reading
  adcV1 += adcV2;
  adcV1 /= 2;                        // Average between both voltage readings. This should give us
                                     // an approximate value of the voltage at the moment of reading
                                     // the current value

  // Discard 0 and negative voltages since we are working with a rectified voltage signal
  if (adcV1 > 0)
    if (noVac)
      noVac = false;                   // VAC signal detected
    // Process AC voltage
    adcV1 = adcV1 * voltageSupply;
    adcV1 *= scale;
    voltage = adcV1 / 1023;
    voltage += ACVOLT_OFFSET_DIODE;    // Apply offset
    voltage *= voltageScale;
    voltage /= 1000;                   // convert to volts
    //Process AC current
    adcI = adcI * voltageSupply;
    current = adcI / 1023;
    current -= voltageSupply/2;        // Apply offset
    current *= currentScale;
    current /= 1000;                   // Convert to amps
    // Update peak current
    if (current > peakCurrent)
      peakCurrent = current;

    // Update peak voltage
    if (voltage > peakVoltage)
      peakVoltage = voltage;

    // Prepare for active power calculation
    accumulated += voltage * current;
    // When a given amount of samples is read
    if (i == NB_OF_SAMPLES)
      // No VAC signal detected?
      if (noVac)
        return CHANNEL_NO_VAC_SIGNAL;
      // Read current time
      currentTime = millis();
      if (lastTime > 0)
        // Elapsed time between readings
        elapsedTime = currentTime - lastTime;  
        // Calculate KWh this time
        getEnergy = true;
      // Update last time
      lastTime = currentTime;
      // Active power (W)
      if (accumulated < 0)
        accumulated = 0;
      actPower = accumulated / (NB_OF_SAMPLES/2);
      accumulated = 0;
      // RMS voltage (V)
      rmsVoltage = peakVoltage * peakToRMS;
      peakVoltage = 0;
      // RMS current (A)
      rmsCurrent = peakCurrent * peakToRMS;
      peakCurrent = 0;
      // Apparent power (VA)
      appPower = rmsVoltage * rmsCurrent;
      // Power factor
      powerFactor = actPower / appPower;
      // Can't be greater than 1
      if (powerFactor > 1.0)
        powerFactor = 1;
        actPower = appPower;
      i = 0;

      // Power factor offset to be applied?
      if (pfOffset > 0 && powerFactor < 1)
        // Correct power factor
        powerFactor += pfOffset;
        if (powerFactor > 1)
          powerFactor = 1;
        // Back calculate active power
        actPower = appPower * powerFactor;

      if (getEnergy)
        energy = actPower * elapsedTime;
        energy /= 3600000;        
        kwh += energy;


(The complete "meter" sketch can be downloaded from SVN too)

The above method is called in a loop until it gets the necessary amount of voltage and current samples to calculate RMS values, active power, apparent power, power factor and energy consumption. Then the function is able to calculate power data as follows:

The maths

Active power:

P = (V0 x I0 + V1 x I1 + V2 x I2 + ... + VN x IN) / N

being N the amount of samples read. At the moment of writing this review, 80 samples are read before doing any calculation. Around 40 of those 80 samples are discarded since the board is really measuring a half-wave version of the original low-level AC voltage.

RMS values:

VRMS = VMAX / √2
IRMS = IMAX / √2

Apparent power:


Power factor:

PF = S / P

Energy consumed:

Energy = P x time

Power factor is the cosine of the phase difference between the voltage and the current waves:

AC signals and phases

Figure 5 : AC voltage and current signals

It gives an idea about the effectiveness of the energy being consumed and it basically depends on the type of load being powered.Thus, for pure resistive loads, the phase difference is 0 (voltage and current signals in phase) so power factor equals 1. The more reactive the load is the bigger the phase difference is and the lower the power factor is. The problem about transformers is that they tend to shift the signal a bit on the secondary so we need a way to calibrate this when this additional phase shift affects readings significantly.

Wireless capabilities

In order to provide support for calibration, the on-board panStamp application provides some SWAP configuration registers, letting the user enter the following settings wirelessly:

For current transformer inputs:
  • Voltage transformer scaling factor
  • Current transformer scaling factor
  • Power factor offset
  • Channel enable

For counter inputs:
  • Initial KWh reading
  • Amount of pulses per unit step
This device is already defined in the current Device Definition Files database so SWAPdmt is able to detect it and understand the contents of each register.

Automatic detection of the meter device from SWAPdmt

Figure 6 : Automatic detection of the meter device from SWAPdmt

Readings from one of the channels

Figure 7 : Readings from one of the channels

The community

As you can see, a lot of work has been done over the last weeks to get a first working version. However, we still need to run many additional tests, answer some questions... and even ask new ones before going to production. A new thread has been created in the forum in order to address questions and responses from/to our community. Feel free to drop your ideas and suggestions from there!

Energy meter board

Figure 8 : Energy meter board with external transformers