rbgrid
Professional Power Measurement Library for ESP32
Real-time Monitoring • High Precision • Smart Energy Management
About the Library
rbgrid is a high-performance library for ESP32, designed for professional measurement and analysis of electrical parameters in real-time. Leveraging the full potential of ESP32's dual-core architecture and high-speed ADC with DMA, the library delivers unprecedented measurement accuracy and response speed for energy management systems.
Key Advantages
- Ultra-Fast Response: Real-time control with response times down to 10ms (1/100 second) — 100-300x faster than typical smart home solutions
- High Accuracy: ADC sampling rates up to 10kHz per channel provide detailed waveform analysis
- Bidirectional Measurements: Automatic current direction detection for systems with generation and energy storage
- Intelligent Billing: Flexible cost calculation system with multi-zone tariffs and net-metering support
- IoT Ready: Built-in support for web interface, MQTT, WebSocket for smart home integration
Applications
Home Energy Systems
- Solar Power: Monitor generation, consumption, and balance with accurate energy direction tracking
- Smart Home: Integration with Home Assistant, ESPHome for automation and energy optimization
- Protection & Safety: Instant disconnection on overloads, power quality monitoring
Commercial Solutions
- EV Charging Stations: Charging process control with dynamic load balancing
- Industrial Monitoring: Predictive maintenance based on power consumption analysis
- Metering & Billing: Multi-point metering with various tariff plan support
Energy Management
- Load Balancing: Automatic priority management of consumers with limited power capacity
- Peak Shaving: Reduce peak loads through intelligent control
- Generation Optimization: Maximize self-consumption before grid import
Technical Features
Measurements & Analysis
- True RMS voltage and current measurements
- Power Calculations: Active (P), Reactive (Q), Apparent (S) power
- Power Factor (cos φ) and phase shift analysis
- THD Analysis and harmonic spectrum up to 25th harmonic
- Grid Frequency with ±0.01 Hz accuracy
- Energy Accumulation with separate consumption and generation tracking
Supported Sensors
- Voltage: ZMPT101B, ZMPT107-1, resistive voltage dividers
- Current: SCT-013 (all variants), ACS712, shunt resistors
- Calibration: Automatic and manual with NVS storage
Architecture & Performance
- Dual-Core Processing: Core 0 for API and peripherals, Core 1 for calculations
- ADC DMA: Hardware data acquisition without CPU load
- Linear Processing: Optimized algorithms for embedded systems
- Zero-Cross Synchronization: Precise grid phase locking
Economic Features
Billing & Metering
- Multi-Zone Tariffs: Peak/off-peak, weekends, holidays
- Net-Metering: Separate tracking of import and export
- Forecasting: Expected cost calculations based on history
- Optimization: Load shifting recommendations for favorable tariff zones
Generation Monitoring
- Solar Panels: MPPT tracking, yield forecasting
- Wind Turbines: Efficiency analysis
- Batteries: Charge/discharge control, ROI calculations
- Hybrid Systems: Source optimization
Development Roadmap
In Development (v1.1)
- Web Application: Modern interface for visualization and configuration
- Extended Telemetry: MQTT, HTTP API, WebSocket streaming
- Mobile App: iOS/Android clients
Planned (v1.2)
- Wireless Sensors: BLE and ESP-NOW for remote measurement points
- Load Control: Integration with relays and AC dimmers
- Automation: Energy management scenarios and rules
- ESPHome/HA: Native integration via YAML configuration
Future (v2.0)
- 3-Phase Systems: Full industrial grid support
- ML Optimization: Predictive consumption algorithms
- Blockchain: Decentralized metering for P2P energy trading
- Cloud Platform: SaaS solution for fleet management
Compatibility
Supported Hardware
- ✅ ESP32: Original series (recommended)
- ✅ ESP32-H: Dual-core architecture with improved ADC
- ❌ ESP32-C/S: Not supported (single-core)
- ❌ ESP8266: Not supported
Software Platforms
- ESP-IDF: v5.0+ (recommended for maximum performance)
- Arduino Core: v3.0+ (ease of use)
- PlatformIO: Full support
Comparison with Alternatives
| Feature | rbgrid | PZEM-004T | EmonLib | IotaWatt |
|---|---|---|---|---|
| Sample Rate | 10 kHz | 1 Hz | 2 kHz | 2 kHz |
| Response Time | 10 ms | 1000 ms | 100 ms | 1000 ms |
| Current Direction | ✅ | ❌ | ❌ | ✅ |
| THD Analysis | ✅ | ❌ | Basic | ✅ |
| Web Interface | ✅ | ❌ | ❌ | ✅ |
| Solution Cost | free | $$ | $ | $$$ |
🚀 Quick Start. Arduino example
/**
* @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);
}
Developers's Corner
Perfect for Hobbyists
Whether you're building your first energy monitor or designing a sophisticated home energy management system, rbgrid provides professional-grade measurements with maker-friendly simplicity.
Popular DIY Projects
- Solar MPPT Controller: Track your panels' performance and optimize energy harvest
- Smart Power Strip: Build an intelligent PDU with individual outlet monitoring
- Whole House Monitor: Non-invasive energy monitoring with split-core CTs
- Battery Bank Manager: Monitor charge/discharge cycles and calculate efficiency
- Workshop Power Analyzer: Check your tools' power quality and consumption
Maker-Friendly Features
- Breadboard Compatible: Works with common breakout boards
- No Complex Math: Library handles all calculations internally
- Auto-Calibration: Self-calibrating routines for easy setup
- Extensive Examples: From basic to advanced projects
- Active Community: Get help from fellow makers
Hardware Tips for DIYers
Current Transformers (CTs)
- SCT-013-030: 30A non-invasive, perfect for home circuits
- SCT-013-100: 100A for main panel monitoring
- Burden Resistor: Library auto-calculates optimal values
Voltage Sensing
- ZMPT101B Module: Ready-to-use, isolated measurement
- Voltage Divider: Simple resistor network for direct sensing
- Safety First: Always use proper isolation for mains voltage!
Wiring Best Practices
- Keep sensor wires short and twisted
- Use shielded cable for noisy environments
- Add 100nF capacitors close to ADC pins
- Separate analog and digital grounds properly
Open Source License
RBgrid is freely available on GitHub. Most SDK components are distributed under Apache 2.0 license. Performance-critical hardware-level components are provided as optimized binary modules.