add net manager
This commit is contained in:
176
components/meter_manager/driver/meter_ade7758/meter_ade7758.c
Executable file
176
components/meter_manager/driver/meter_ade7758/meter_ade7758.c
Executable file
@@ -0,0 +1,176 @@
|
||||
#include "meter_ade7758.h"
|
||||
#include "ade7758.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
#define TAG "meter_ade7758"
|
||||
|
||||
// === Configurações de hardware ===
|
||||
#define PIN_NUM_CLK 15
|
||||
#define PIN_NUM_MOSI 2
|
||||
#define PIN_NUM_MISO 4
|
||||
#define PIN_NUM_CS 23
|
||||
#define EEPROM_HOST HSPI_HOST
|
||||
|
||||
// === Constantes de calibração ===
|
||||
#define VRMS_CAL 4732.78f
|
||||
#define IRMS_CAL 53416.0f
|
||||
|
||||
#define METER_READ_INTERVAL_MS 5000
|
||||
|
||||
// === Dados internos ===
|
||||
typedef struct {
|
||||
float vrms[3];
|
||||
float irms[3];
|
||||
int watt[3];
|
||||
int var[3]; // reservados
|
||||
int va[3]; // reservados
|
||||
} meter_ade7758_internal_data_t;
|
||||
|
||||
static meter_ade7758_internal_data_t meter_data;
|
||||
static TaskHandle_t meter_task = NULL;
|
||||
static SemaphoreHandle_t meter_mutex = NULL;
|
||||
static uint32_t meter_watchdog_counter = 0;
|
||||
|
||||
// === Utilitários internos ===
|
||||
|
||||
static void meter_ade7758_clear_internal_data(void) {
|
||||
if (meter_mutex && xSemaphoreTake(meter_mutex, pdMS_TO_TICKS(10)) == pdTRUE) {
|
||||
memset(&meter_data, 0, sizeof(meter_data));
|
||||
xSemaphoreGive(meter_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static bool meter_ade7758_read_internal(meter_ade7758_internal_data_t *out) {
|
||||
if (!out) return false;
|
||||
if (xSemaphoreTake(meter_mutex, pdMS_TO_TICKS(10)) == pdTRUE) {
|
||||
*out = meter_data;
|
||||
xSemaphoreGive(meter_mutex);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void meter_ade7758_task_func(void *param) {
|
||||
ESP_LOGI(TAG, "Meter task started");
|
||||
|
||||
meter_ade7758_internal_data_t previous = {0};
|
||||
|
||||
while (true) {
|
||||
meter_ade7758_internal_data_t current = {0};
|
||||
|
||||
current.vrms[0] = avrms() / VRMS_CAL;
|
||||
current.vrms[1] = bvrms() / VRMS_CAL;
|
||||
current.vrms[2] = cvrms() / VRMS_CAL;
|
||||
|
||||
current.irms[0] = airms() / IRMS_CAL;
|
||||
current.irms[1] = birms() / IRMS_CAL;
|
||||
current.irms[2] = cirms() / IRMS_CAL;
|
||||
|
||||
if (setPotLine(PHASE_A, 20)) current.watt[0] = getWatt(PHASE_A);
|
||||
if (setPotLine(PHASE_B, 20)) current.watt[1] = getWatt(PHASE_B);
|
||||
if (setPotLine(PHASE_C, 20)) current.watt[2] = getWatt(PHASE_C);
|
||||
|
||||
if (memcmp(&previous, ¤t, sizeof(current)) != 0) {
|
||||
if (xSemaphoreTake(meter_mutex, pdMS_TO_TICKS(10)) == pdTRUE) {
|
||||
meter_data = current;
|
||||
meter_watchdog_counter++;
|
||||
xSemaphoreGive(meter_mutex);
|
||||
}
|
||||
previous = current;
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(METER_READ_INTERVAL_MS));
|
||||
}
|
||||
}
|
||||
|
||||
// === Interface pública: controle ===
|
||||
|
||||
esp_err_t meter_ade7758_init(void) {
|
||||
ESP_LOGI(TAG, "Inicializando medidor ADE7758...");
|
||||
|
||||
if (!meter_mutex) {
|
||||
meter_mutex = xSemaphoreCreateMutex();
|
||||
if (!meter_mutex) {
|
||||
ESP_LOGE(TAG, "Falha ao criar mutex");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
meter_ade7758_clear_internal_data();
|
||||
|
||||
esp_err_t err = Init(EEPROM_HOST, PIN_NUM_MISO, PIN_NUM_MOSI, PIN_NUM_CLK);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Erro ao inicializar SPI (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
InitSpi(PIN_NUM_CS);
|
||||
gainSetup(INTEGRATOR_OFF, FULLSCALESELECT_0_5V, GAIN_1, GAIN_1);
|
||||
setupDivs(1, 1, 1);
|
||||
setLcycMode(0x00);
|
||||
resetStatus();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t meter_ade7758_start(void) {
|
||||
if (meter_task) return ESP_ERR_INVALID_STATE;
|
||||
|
||||
meter_ade7758_clear_internal_data();
|
||||
BaseType_t result = xTaskCreate(meter_ade7758_task_func, "meter_ade7758_task", 4096, NULL, 5, &meter_task);
|
||||
return result == pdPASS ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
void meter_ade7758_stop(void) {
|
||||
if (meter_task) {
|
||||
vTaskDelete(meter_task);
|
||||
meter_task = NULL;
|
||||
}
|
||||
meter_ade7758_clear_internal_data();
|
||||
}
|
||||
|
||||
bool meter_ade7758_is_running(void) {
|
||||
return meter_task != NULL;
|
||||
}
|
||||
|
||||
void meter_ade7758_clear_data(void) {
|
||||
meter_ade7758_clear_internal_data();
|
||||
}
|
||||
|
||||
// === Interface pública: acesso aos dados ===
|
||||
|
||||
float meter_ade7758_get_vrms_l1(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.vrms[0] : 0; }
|
||||
float meter_ade7758_get_vrms_l2(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.vrms[1] : 0; }
|
||||
float meter_ade7758_get_vrms_l3(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.vrms[2] : 0; }
|
||||
|
||||
float meter_ade7758_get_irms_l1(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.irms[0] : 0; }
|
||||
float meter_ade7758_get_irms_l2(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.irms[1] : 0; }
|
||||
float meter_ade7758_get_irms_l3(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.irms[2] : 0; }
|
||||
|
||||
int meter_ade7758_get_watt_l1(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.watt[0] : 0; }
|
||||
int meter_ade7758_get_watt_l2(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.watt[1] : 0; }
|
||||
int meter_ade7758_get_watt_l3(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.watt[2] : 0; }
|
||||
|
||||
int meter_ade7758_get_var_l1(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.var[0] : 0; }
|
||||
int meter_ade7758_get_var_l2(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.var[1] : 0; }
|
||||
int meter_ade7758_get_var_l3(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.var[2] : 0; }
|
||||
|
||||
int meter_ade7758_get_va_l1(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.va[0] : 0; }
|
||||
int meter_ade7758_get_va_l2(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.va[1] : 0; }
|
||||
int meter_ade7758_get_va_l3(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.va[2] : 0; }
|
||||
|
||||
// === Diagnóstico ===
|
||||
|
||||
uint32_t meter_ade7758_get_watchdog_counter(void) {
|
||||
return meter_watchdog_counter;
|
||||
}
|
||||
Reference in New Issue
Block a user