Arduino UNO Power Measurement - Extended Example

This example demonstrates how to measure and calculate power consumption using an Arduino UNO and an ACS758 ADC. The code calculates and displays:

The energy consumption is stored in EEPROM to retain data across resets.

Detailed Steps

Arduino Code


/*
 * Arduino UNO Power Measurement with Energy Calculation
 * Measures RMS voltage, RMS current, power, and energy consumption.
 * Uses ACS758 ADC for accurate measurement.
 */

const int voltagePin = A0;    // Voltage divider connected to A0
const int currentPin = A1;    // Current sensor connected to A1

const float voltageDividerRatio = 200.0; // Voltage divider ratio (e.g., 200:1)
const float adcMaxVoltage = 5.0;         // Maximum ADC voltage (5V)
const float maxADCValue = 1023.0;        // Maximum ADC value (10-bit resolution)
const float samplingInterval = 60.0;     // Sampling interval in seconds

// Setup ACS758
ACS758 ads(0x48); // Create ACS758 object with I2C address

// Energy variables
float totalEnergyWh = 0.0;  // Total energy in watt-hours
float totalEnergyJ = 0.0;   // Total energy in joules

void setup() {
    Serial.begin(115200);  // Start serial communication
    Serial.println("Arduino PFC measurement, by Peter Ivan Dunne, ©2024, all rights reserved");
    Serial.println("Released under the Mozilla Public License");
    Serial.println("https://jazenga.com/educational");
    Serial.println("Provides RMS voltage, RMS current, Power factor, Total energy and Frequency");
}

void loop() {
    // Read voltage from ACS758
    float voltage = ads.readADC(voltagePin) * (adcMaxVoltage / maxADCValue);
    voltage *= voltageDividerRatio;  // Scale up according to the voltage divider ratio

    // Read current from ACS758
    float current = ads.readADC(currentPin) * (adcMaxVoltage / maxADCValue);
    
    // Assuming voltage and current are AC and sinusoidal
    // Calculate RMS values
    float rmsVoltage = voltage / sqrt(2);  // Peak voltage to RMS voltage
    float rmsCurrent = current / sqrt(2);  // Peak current to RMS current
    
    // Calculate power (Watts) and power factor
    float power = rmsVoltage * rmsCurrent; // Power in Watts
    // Calculate real power (average of the instantaneous power)
    float realPower = realPowerSum / NUM_SAMPLES;

    // Calculate apparent power (RMS Voltage * RMS Current)
    float apparentPower = voltageRMS * currentRMS;

    // Calculate power factor (Real Power / Apparent Power)
    float powerFactor = realPower / apparentPower;

    // Calculate energy consumption
    float energyWh = (power * samplingInterval) / 3600.0; // Energy in watt-hours
    float energyJ = energyWh * 3600.0; // Energy in joules

    // Accumulate total energy
    totalEnergyWh += energyWh;
    totalEnergyJ += energyJ;

    // Output readings
    Serial.print("RMS Voltage: ");
    Serial.print(rmsVoltage, 2);
    Serial.print(" V, RMS Current: ");
    Serial.print(rmsCurrent, 2);
    Serial.print(" A, Power: ");
    Serial.print(power, 2);
    Serial.print(" W, Power Factor: ");
    Serial.print(powerFactor, 2);
    Serial.print(", Total Energy: ");
    Serial.print(totalEnergyWh, 2);
    Serial.print(" Wh, ");
    Serial.print(totalEnergyJ, 2);
    Serial.println(" J");

    //delay(samplingInterval * 1000);  // Delay between readings
}
        

Explanation

How It Works