Ir al contenido

rbgrid

Coffee
PayPal
ESP32
License
Version
Platform

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 (v2.1)

  • 🌐 Web Application: Modern interface for visualization and configuration
  • 📡 Extended Telemetry: MQTT, HTTP API, WebSocket streaming
  • 📱 Mobile App: iOS/Android clients


Planned (v2.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 (v3.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-C3/C6: Not supported (single-core)
  • ESP8266: Not supported


Software Platforms

  • ESP-IDF: v5.0+ (recommended for maximum performance)
  • Arduino Core: v3.0+ (use VS code IDE, not Arduino IDE)
  • PlatformIO: Not support 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

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

#include "Arduino.h"
#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
struct rbgrid_config_context_s {
    rbgrid_extended_config_t* extended_config;
    rbgrid_hardware_config_t* hardware_config;
    rbgrid_electrical_network_t* network;
    rbgrid_unit_definition_t* units_array;
    uint16_t units_allocated;
    uint16_t units_count;
    struct {
        int next_sensor_id;
        int next_unit_id;
        uint8_t adc_channels_used;
        bool has_zc_sensor;
        bool has_voltage_bus;
        bool has_main_supply;
        bool has_alternative_supply;
    } builder;
    struct {
        bool base_initialized;
        bool network_configured;
        bool sensors_configured;
        bool units_configured;
    } status;
    bool is_initialized;
    bool is_applied;
};
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");
    }

    // Additional settings
    extended_config->rbhome_settings.logging_level = RBGRID_LOG_LEVEL_DEBUG;
    extended_config->enable_time_synchronization = false;
    extended_config->auto_start_measurements = true;

    // Pass units array
    extended_config->units_config.predefined_units = config_ctx->units_array;
    extended_config->units_config.predefined_units_count = config_ctx->units_count;
    extended_config->units_config.use_predefined_only = true;

    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);
}



🔌 DIY Maker'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.


  • 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



📚 Documentation



🤝 Community & Support



🏆 Showcase

Check out amazing projects built with rbgrid:
- 🏠 Smart Home Energy Dashboard
- ☀️ DIY Solar Tracker with MPPT
- 🔌 Industrial Power Quality Monitor
- 🚗 EV Charging Station Controller



📄 License

This project is released under the MIT License. See LICENSE file for details.



🙏 Acknowledgments


Standing on the Shoulders of Giants

  • EmonLib: Inspiration for energy monitoring algorithms
  • ESP32 Arduino Core: Making ESP32 accessible to makers
  • OpenEnergyMonitor: Pioneering open-source energy monitoring

Made with ❤️ for the Maker Community and Energy Enthusiasts

[!WARNING] If you find this project useful, please give it

Coffee
PayPal