Skip to Content

First Measurements

Step-by-step
The guide to obtaining your first accurate measurements. System functionality verification and results interpretation.



Introduction

After successfully compiling and uploading the basic example, you need to verify that the system correctly measures electrical parameters. This guide will help you step-by-step verify all components are working properly and obtain your first reliable measurements.



1. Preparation for First Measurements


Checking Sensor Connections

Before applying power, perform a visual inspection:

  • Zero-Cross Detector:
  • Optocoupler output connected to GPIO18
  • Power isolation properly implemented
ZC detector required
The library RBgrid dosn't init without Zero-Cross sensor
  • ZMPT107-1 Voltage Sensor:
  • AC Line: L (Line) input connected to phase through 0.5A fuse, to terminal L
  • AC Neutral: N (Neutral) input connected to neutral, to terminal N
  • Output connected to GPIO35 (ADC1_CH7)
  • Sensor power: VCC to 3.3V, GND to common ground
Important!!!
AC connection polarity L and N determines correct phase direction. VCC power requires stable power supply - if DC VCC supply is unstable, readings will fluctuate.
  • SCT-013 Current Transformers:
  • Current transformer clamps around phase wire only
  • Note the arrow on the sensor housing - it should point toward the load or away from AC source
  • Signal outputs to corresponding GPIOs (36, 37, 38, 39, 32, 33, 34)
GPIO Usage:
- Library only supports current sensors connected to ADC1, use GPIOs: 36, 37, 38, 39, 32, 33, 34
- Library will not start without ZC detector connected to AC mains


Safety Precautions

Working with mains voltage is life-threatening!
- Use an isolation transformer during debugging
- Check for shorts between power and signal circuits
- Ensure all connections are secure
- Work with a grounded anti-static wrist strap
- Keep a circuit breaker within reach


Preparing Test Load

For initial measurements, we recommend using:
- 60-100W incandescent bulb (pure resistive load)
- Or 1.5-2kW electric kettle
- Avoid switch-mode power supplies and LED lamps for first test




2. Running the Basic Example


Loading the Code

Arduino basic code

c
/**
 * @file basic_app.cpp
 * @brief Basic application example with sensor initialization and terminal output
 */

#include 
#include "rbgrid.h"
#include "rbtelemetry.h"
#include "rbgrid.h"
#include "rbgrid_config_api.h"
#include "esp_timer.h"
#include "driver/gpio.h"

// ====== PINS ======
#define ZC_CROSS_PIN          18    // GPIO18 for Zero Cross

// ====== GLOBAL VARIABLES ======
rbgrid_unit_uid_t voltage_sensor_uid;
rbgrid_unit_uid_t current_sensor_uid;
rbgrid_unit_uid_t alt_sensor_uid;
rbgrid_unit_uid_t heater_sensor_uid;

static rbgrid_extended_config_t* g_extended_config = NULL;

// Forward declaration for access to internal structures
typedef struct rbgrid_config_context_s rbgrid_config_context_t;

// ====== SETUP ======
void setup() {
    Serial.begin(115200);
    Serial.println("\n=== Basic rbgrid example ===");

    // Reset ADC pins
    gpio_reset_pin(GPIO_NUM_33);
    gpio_reset_pin(GPIO_NUM_34);
    gpio_set_direction(GPIO_NUM_33, GPIO_MODE_INPUT);
    gpio_set_direction(GPIO_NUM_34, GPIO_MODE_INPUT);
    gpio_set_pull_mode(GPIO_NUM_33, GPIO_FLOATING);
    gpio_set_pull_mode(GPIO_NUM_34, GPIO_FLOATING);

    // Create configuration via API
    rbgrid_config_handle_t config_handle = rbgrid_config_create("Test House", "HongKong");
    if (!config_handle) {
        Serial.println("ERROR: Failed to create configuration");
        return;
    }

    // Configure network
    int config_err = rbgrid_config_set_configuration(config_handle);
    if (config_err != RBGRID_CONFIG_OK) {
        Serial.print("ERROR: Failed to configure network: ");
        Serial.println(config_err);
        rbgrid_config_destroy(config_handle);
        return;
    }

    // Get pointers to internal structures
    rbgrid_config_context_t* config_ctx = (rbgrid_config_context_t*)config_handle;
    rbgrid_extended_config_t* extended_config = config_ctx->extended_config;
    rbgrid_hardware_config_t* base_hardware_config = config_ctx->hardware_config;

    // Network frequency configuration
    base_hardware_config->network.nominal_frequency = 50;

    // Add voltage sensor ZMPT107-1 on GPIO35
    voltage_sensor_uid = rbgrid_config_add_adc_sensor(config_handle, GPIO_NUM_35, RBSENSOR_TYPE_VOLTAGE_ZMPT107_1);
    if (voltage_sensor_uid == RBGRID_INVALID_UNIT_UID) {
        Serial.println("ERROR: Failed to add voltage sensor");
    } else {
        Serial.print("Voltage sensor added, UID: 0x");
        Serial.println(voltage_sensor_uid, HEX);
    }

    // Add current sensor SCT013-10A on GPIO34
    current_sensor_uid = rbgrid_config_add_adc_sensor(config_handle, GPIO_NUM_34, RBSENSOR_TYPE_CURRENT_SCT013_10A);
    if (current_sensor_uid == RBGRID_INVALID_UNIT_UID) {
        Serial.println("ERROR: Failed to add main current sensor");
    } else {
        Serial.print("Main current sensor added, UID: 0x");
        Serial.println(current_sensor_uid, HEX);
    }

    // Add current sensor SCT013-50A on GPIO33
    alt_sensor_uid = rbgrid_config_add_adc_sensor(config_handle, GPIO_NUM_33, RBSENSOR_TYPE_CURRENT_SCT013_50A);
    if (alt_sensor_uid == RBGRID_INVALID_UNIT_UID) {
        Serial.println("ERROR: Failed to add alternative current sensor");
    } else {
        Serial.print("Alternative current sensor added, UID: 0x");
        Serial.println(alt_sensor_uid, HEX);
    }

    // Add current sensor for heater on GPIO32
    heater_sensor_uid = rbgrid_config_add_adc_sensor(config_handle, GPIO_NUM_32, RBSENSOR_TYPE_CURRENT_SCT013_10A);
    if (heater_sensor_uid == RBGRID_INVALID_UNIT_UID) {
        Serial.println("ERROR: Failed to add heater sensor");
    } else {
        Serial.print("Heater sensor added, UID: 0x");
        Serial.println(heater_sensor_uid, HEX);
    }

    // Add Zero-Cross sensor on GPIO18
    config_err = rbgrid_config_add_zc_sensor(config_handle, (gpio_num_t)ZC_CROSS_PIN);
    if (config_err != RBGRID_CONFIG_OK) {
        Serial.print("ERROR: Failed to add ZC sensor: ");
        Serial.println(config_err);
    } else {
        Serial.print("Zero-Cross sensor configured on GPIO");
        Serial.println(ZC_CROSS_PIN);

        // Initialize ZC
        rbgrid_zc_config_t zc_config = RBPOWER_ZC_DEFAULT_CONFIG((rbgrid_gpio_t)ZC_CROSS_PIN);
        rbgrid_err_t zc_err = rbgrid_init_zc(&zc_config);
        if (zc_err != RBPOWER_OK) {
            Serial.print("ERROR: ZC init failed: ");
            Serial.println((int)zc_err);
        } else {
            delay(200);
            uint16_t measured_freq = rbgrid_get_network_frequency();
            Serial.print("ZC initialized, measured frequency: ");
            Serial.print((int)measured_freq);
            Serial.println("Hz");
            base_hardware_config->network.nominal_frequency = measured_freq;
        }
    }

    // Create Voltage Bus
    if (voltage_sensor_uid != RBGRID_INVALID_UNIT_UID) {
        config_err = rbgrid_config_set_voltage_bus(config_handle, voltage_sensor_uid, "Main Voltage Bus");
        if (config_err != RBGRID_CONFIG_OK) {
            Serial.print("ERROR: Failed to configure voltage bus: ");
            Serial.println(config_err);
        } else {
            Serial.print("Voltage bus configured with UID: 0x");
            Serial.println(voltage_sensor_uid, HEX);
        }
    }

    // Create Main Supply
    if (current_sensor_uid != RBGRID_INVALID_UNIT_UID) {
        config_err = rbgrid_config_set_main_supply(config_handle, current_sensor_uid, "Main Supply", RBPOWER_STAT_PERIOD_1HOUR);
        if (config_err != RBGRID_CONFIG_OK) {
            Serial.print("ERROR: Failed to configure main supply: ");
            Serial.println(config_err);
        } else {
            Serial.print("Main supply configured with UID: 0x");
            Serial.println(current_sensor_uid, HEX);
        }
    }

    // Configure Alternative Supply
    config_err = rbgrid_config_set_alternative_supply(config_handle, alt_sensor_uid, "Alternative Supply", RBPOWER_STAT_PERIOD_1HOUR);
    if (config_err != RBGRID_CONFIG_OK) {
        Serial.print("ERROR: Failed to configure alternative supply: ");
        Serial.println(config_err);
    } else {
        Serial.println("Alternative supply configured");
    }

    // Configure heater
    config_err = rbgrid_config_add_unit(config_handle, heater_sensor_uid, "Heater 10A", RBPOWER_STAT_PERIOD_1HOUR);
    if (config_err != RBGRID_CONFIG_OK) {
        Serial.print("ERROR: Failed to configure heater: ");
        Serial.println(config_err);
    } else {
        Serial.println("Heater configured");
    }

    g_extended_config = extended_config;

    // Initialize rbgrid system
    Serial.println("Initializing rbgrid system...");
    rbgrid_err_t rbgrid_err = rbgrid_init_hardware();
    if (rbgrid_err != RBGRID_OK) {
        Serial.print("ERROR: rbgrid init failed: ");
        Serial.println(rbgrid_err);
        Serial.println("WARNING: Unit UID mapping features may be limited");
    } else {
        Serial.println("rbgrid system initialized");
    }

    // Initialize rbgrid
    rbgrid_err_t power_err = rbgrid_init_extended(extended_config);
    if (power_err != RBPOWER_OK) {
        Serial.print("ERROR: rbgrid init failed: ");
        Serial.println(power_err);
        Serial.println("WARNING: Continuing with limited functionality");
    }

    Serial.println("\n===== Initialization completed =====");
}

// ====== LOOP ======
void loop() {
    // Print data every 5 seconds
    static unsigned long last_print = millis();

    if (millis() - last_print >= 5000) {
        last_print = millis();

        Serial.println("\n========== Sensor Data ==========");

        // Get voltage statistics
        statistics_3sec_final_t voltage_stats;
        rbgrid_err_t result = rbgrid_realtime_get_voltage(&voltage_stats);

        if (result == RBGRID_OK) {
            Serial.print("Voltage: ");
            Serial.print(voltage_stats.voltage_rms_final, 2);
            Serial.print(" V, Frequency: ");
            Serial.print(voltage_stats.frequency_avg_final, 2);
            Serial.print(" Hz, THD: ");
            Serial.print(voltage_stats.thd_voltage_avg_final, 2);
            Serial.println("%");
        } else {
            Serial.print("ERROR: Failed to get voltage data: ");
            Serial.println(result);
        }

        // Get Main Supply data
        float current_rms, power_active, power_reactive, power_apparent, power_factor, energy_increment;
        uint32_t samples_count;
        rbgrid_current_direction_t direction;

        result = rbgrid_realtime_get_main_supply(¤t_rms, &power_active, &direction,
                                                  &power_reactive, &power_apparent, &power_factor,
                                                  &samples_count, &energy_increment);

        if (result == RBGRID_OK) {
            Serial.print("Main Supply: I=");
            Serial.print(current_rms, 3);
            Serial.print(" A, P=");
            Serial.print(power_active, 1);
            Serial.print(" W, PF=");
            Serial.println(power_factor, 3);
        } else {
            Serial.print("ERROR: Failed to get main supply data: ");
            Serial.println(result);
        }

        // Get Alternative Supply data
        float alt_current_rms, alt_power_active, alt_efficiency, alt_dc_power;
        result = rbgrid_realtime_get_alt_supply(&alt_current_rms, &alt_power_active, &direction,
                                                 &power_reactive, &power_apparent, &power_factor,
                                                 &samples_count, &energy_increment,
                                                 &alt_efficiency, &alt_dc_power);

        if (result == RBGRID_OK) {
            Serial.print("Alt Supply: I=");
            Serial.print(alt_current_rms, 3);
            Serial.print(" A, P=");
            Serial.print(alt_power_active, 1);
            Serial.print(" W, Efficiency=");
            Serial.print(alt_efficiency, 1);
            Serial.println("%");
        } else {
            Serial.print("ERROR: Failed to get alt supply data: ");
            Serial.println(result);
        }

        // Get heater data
        float unit_current, unit_power_active;
        result = rbgrid_realtime_get_unit(heater_sensor_uid, &unit_current, 
                                          &unit_power_active, &power_reactive, 
                                          &power_apparent, &power_factor, 
                                          &samples_count);

        if (result == RBGRID_OK) {
            Serial.print("Heater: I=");
            Serial.print(unit_current, 3);
            Serial.print(" A, P=");
            Serial.print(unit_power_active, 1);
            Serial.print(" W, PF=");
            Serial.println(power_factor, 3);
        } else {
            Serial.print("ERROR: Failed to get heater data: ");
            Serial.println(result);
        }

        Serial.println("=====================================");
    }

    delay(100);
}


Serial Monitor Setup

  1. Open Serial Monitor in Arduino IDE or other terminal
  2. Set baud rate: 115200 baud
  3. Settings: 8N1 (8 data bits, no parity, 1 stop bit)
  4. Enable auto-scroll and timestamps

First Run Without Load: On first power-up without connected load, you should see:

c
// #Add terminal log output



3. Verifying Voltage Readings


Interpreting Voltage Bus Data

The system should display:
- RMS Voltage: Root Mean Square voltage value
- Frequency: Mains frequency (50Hz for EU/Asia, 60Hz for US)
- THD: Total Harmonic Distortion (normal < 5%)


Comparison with Reference Meter

The voltage sensor is pre-calibrated for maximum RMS voltage of 250V

  1. Measure voltage with a True RMS multimeter
  2. Compare readings:
  3. Acceptable deviation: ±2%
  4. If greater - calibration required: → Voltage Calibration guide

Voltage Calibration guide

Modify code to output to terminal at 2-3 messages per second. Connect a voltmeter to mains. Using the trim potentiometer, adjust until terminal readings match voltmeter readings.

Typical Voltage Values

Region Nominal Acceptable Range Frequency
Europe 230V 207-253V 50Hz
USA 120V 108-132V 60Hz
Japan 100V 90-110V 50/60Hz
China 220V 198-242V 50Hz



4. Verifying Current Measurements


Connecting Test Load

  1. Connect sensor to microcontroller
  2. If using ACS-712 sensor, use connection diagram on ACS current module documentation
  3. If using SCT-013 sensor, use JACK adapter
Calculating Expected Current
For resistive load: I = P / V
Example for 100W bulb at 230V: I = 100W / 230V = 0.435A


Interpreting LOAD Data

After switching on the load, readings should appear: LOAD: I=0.434 A, P=99.8 W, PF=0.998

  • I (Current): RMS current value
  • P (Power): Active power
  • PF (Power Factor): Power factor


Checking Current Direction

The system determines energy direction:
- CONSUMING: Drawing from grid (normal mode)
- SUPPLYING: Feeding to grid (generation)




5. Verifying Power Calculations


Power Parameters

The system calculates four types of power:

Parameter Symbol Unit Description
Active P Watt (W) Real consumed power
Reactive Q VAr (VAR) Electromagnetic field power
Apparent S VA (VA) Geometric sum of P and Q
Factor PF - Ratio P/S (0..1)


Verification for Resistive Load

For incandescent bulb (pure resistive load):
- P ≈ bulb's rated power (±5%)
- Q ≈ 0 VAR (close to zero)
- PF ≈ 1.0 (0.98-1.00)
- S ≈ P (since Q ≈ 0)

Verification Formulas
S = V × I // Apparent power
P = V × I × cos(φ) // Active power
Q = V × I × sin(φ) // Reactive power
S² = P² + Q² // Power relationship
PF = P / S = cos(φ) // Power factor



6. Troubleshooting Common Issues


Zero or Near-Zero Readings

Symptoms: All values show 0 or very small numbers

Possible causes:
- Incorrect GPIO connections
- No VCC power to sensors, or wrong voltage VCC
- Wrong initial configuration
- Current sensor installed on neutral wire

Solution:

cpp
// Check pin definitions
// Add current sensor SCT013-10A on GPIO34
current_sensor_uid = rbgrid_config_add_adc_sensor(config_handle, GPIO_NUM_34, RBSENSOR_TYPE_CURRENT_SCT013_10A);


Unstable Readings (Noise)

Symptoms:
- Values constantly "jumping"
- Low-level values unstable for SCT-013. These sensors have unstable readings below 1%.

Possible causes:
- Poor grounding
- Interference from power cables
- Poor quality ESP32 power supply

Solution:
- Add electrolytic capacitors to power supply
- Use shielded cables
- Separate power and signal circuits
- For low values under 1%, set low cutoff threshold in library



Incorrect Measurement Scale

Symptoms: Readings off by orders of magnitude

Possible causes:
- Wrong sensor selected in code
- Error in sensor profile

Solution:

cpp
// Check sensor type in configuration
RBSENSOR_TYPE_CURRENT_SCT013_10A  // For 10A version
RBSENSOR_TYPE_CURRENT_SCT013_30A  // For 30A version
RBSENSOR_TYPE_CURRENT_SCT013_50A  // For 50A version


Missing Zero-Cross Events

Symptoms: Frequency shows 0Hz or incorrect value

Possible causes:
- No connection to mains
- Incorrect connection to GPIO18

Solution:
- Check connection quality




7. System Validation


Verification Checklist

Check completed items:

  • ☐ System successfully initialized
  • ☐ Voltage shows correct values (±2%)
  • ☐ Frequency matches mains (50Hz or 60Hz)
  • ☐ Voltage THD < 5%
  • ☐ Current without load < 0.01A
  • ☐ Current with load matches calculated (±2%)
  • ☐ Active power matches load rating (±2%)
  • ☐ Power factor for resistive load > 0.95
  • ☐ Current direction shows CONSUMING
  • ☐ Readings are stable (not "jumping")



  • 8. Next Steps

    After successful validation of basic measurements, you can proceed to:


    Extended Monitoring

    • Configure statistic logging
    • Add statistics periods


    Adding Functionality

    • Connect additional sensors
    • Configure multi-unit system


    Tariff Configuration

    • Configure tariff zones
    • Calculate consumption costs
    • Configure net metering


    Integration

    • Connect to WiFi
    • Configure web interface
    • Send data to cloud (MQTT, HTTP)



    Conclusion

    Congratulations!
    If all checklist items are completed, your power measurement system is working correctly. Save the reference readings and configuration for future use.

    If problems arise:
    1. Double-check connections against schematic
    2. Use debug mode for detailed diagnostics
    3. Refer to "Diagnostics and Debugging" section
    4. Ask questions in the developer community