First Measurements
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
- 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
- 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)
- Library will not start without ZC detector connected to AC mains
Safety Precautions
- 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
/**
* @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
- Open Serial Monitor in Arduino IDE or other terminal
- Set baud rate: 115200 baud
- Settings: 8N1 (8 data bits, no parity, 1 stop bit)
- Enable auto-scroll and timestamps
First Run Without Load: On first power-up without connected load, you should see:
// #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
- Measure voltage with a True RMS multimeter
- Compare readings:
- Acceptable deviation: ±2%
- If greater - calibration required: → Voltage Calibration guide
Voltage Calibration guide
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
- Connect sensor to microcontroller
- If using ACS-712 sensor, use connection diagram on ACS current module documentation
- If using SCT-013 sensor, use JACK adapter
I = P / VExample for 100W bulb at 230V:
I = 100W / 230V = 0.435AInterpreting 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)
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:
// 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:
// 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:
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
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