175 lines
4.4 KiB
C
175 lines
4.4 KiB
C
#include "meter.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <inttypes.h>
|
|
|
|
#include "esp_log.h"
|
|
#include "esp_system.h"
|
|
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/semphr.h"
|
|
|
|
#include "driver/spi_master.h"
|
|
#include "driver/gpio.h"
|
|
|
|
#include "ade7758.h"
|
|
#include "evse_api.h"
|
|
|
|
#define TAG "meter"
|
|
|
|
// SPI Config
|
|
#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
|
|
|
|
// Calibration constants
|
|
#define VRMS_CAL 4732.78f
|
|
#define IRMS_CAL 53416.0f
|
|
|
|
#define METER_READ_INTERVAL_MS 5000
|
|
|
|
static TaskHandle_t meter_task = NULL;
|
|
static MeterData metervalue;
|
|
static SemaphoreHandle_t meter_mutex = NULL;
|
|
|
|
static uint32_t meter_watchdog_counter = 0;
|
|
|
|
void meter_initData(void) {
|
|
if (xSemaphoreTake(meter_mutex, pdMS_TO_TICKS(10)) == pdTRUE) {
|
|
memset(&metervalue, 0, sizeof(metervalue));
|
|
xSemaphoreGive(meter_mutex);
|
|
} else {
|
|
ESP_LOGE(TAG, "Falha ao adquirir semáforo para zerar dados.");
|
|
}
|
|
}
|
|
|
|
MeterData meter_getData(void) {
|
|
MeterData copy;
|
|
if (xSemaphoreTake(meter_mutex, pdMS_TO_TICKS(10)) == pdTRUE) {
|
|
copy = metervalue;
|
|
xSemaphoreGive(meter_mutex);
|
|
} else {
|
|
ESP_LOGE(TAG, "Falha ao adquirir semáforo para leitura de dados.");
|
|
memset(©, 0, sizeof(copy));
|
|
}
|
|
return copy;
|
|
}
|
|
|
|
bool meter_is_running(void) {
|
|
return meter_task != NULL;
|
|
}
|
|
|
|
uint32_t meter_get_watchdog_counter(void) {
|
|
return meter_watchdog_counter;
|
|
}
|
|
|
|
static void meter_task_func(void *param) {
|
|
ESP_LOGI(TAG, "Meter task started");
|
|
|
|
MeterData previousData = {0};
|
|
bool dataChanged = false;
|
|
|
|
while (true) {
|
|
if (evse_state_is_charging(evse_get_state())) {
|
|
MeterData local = {0};
|
|
|
|
local.vrmsA = avrms() / VRMS_CAL;
|
|
local.vrmsB = bvrms() / VRMS_CAL;
|
|
local.vrmsC = cvrms() / VRMS_CAL;
|
|
|
|
local.irmsA = airms() / IRMS_CAL;
|
|
local.irmsB = birms() / IRMS_CAL;
|
|
local.irmsC = cirms() / IRMS_CAL;
|
|
|
|
ESP_LOGD(TAG, "VRMS: A=%.2f, B=%.2f, C=%.2f", local.vrmsA, local.vrmsB, local.vrmsC);
|
|
ESP_LOGD(TAG, "IRMS: A=%.2f, B=%.2f, C=%.2f", local.irmsA, local.irmsB, local.irmsC);
|
|
|
|
if (setPotLine(PHASE_A, 20)) {
|
|
local.wattA = getWatt(PHASE_A);
|
|
ESP_LOGD(TAG, "Watt A: %" PRIi32, local.wattA);
|
|
}
|
|
|
|
if (setPotLine(PHASE_B, 20)) {
|
|
local.wattB = getWatt(PHASE_B);
|
|
ESP_LOGD(TAG, "Watt B: %" PRIi32, local.wattB);
|
|
}
|
|
|
|
if (setPotLine(PHASE_C, 20)) {
|
|
local.wattC = getWatt(PHASE_C);
|
|
ESP_LOGI(TAG, "Watt C: %" PRIi32, local.wattC);
|
|
}
|
|
|
|
// Verifique se os dados mudaram antes de atualizar
|
|
if (memcmp(&local, &previousData, sizeof(MeterData)) != 0) {
|
|
dataChanged = true;
|
|
previousData = local;
|
|
} else {
|
|
dataChanged = false;
|
|
}
|
|
|
|
if (dataChanged && xSemaphoreTake(meter_mutex, pdMS_TO_TICKS(10)) == pdTRUE) {
|
|
metervalue = local;
|
|
meter_watchdog_counter++;
|
|
xSemaphoreGive(meter_mutex);
|
|
}
|
|
}
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(METER_READ_INTERVAL_MS));
|
|
}
|
|
}
|
|
|
|
void Calibrate_ADE7758(void) {
|
|
gainSetup(INTEGRATOR_OFF, FULLSCALESELECT_0_5V, GAIN_1, GAIN_1);
|
|
setupDivs(1, 1, 1);
|
|
setLcycMode(0x00);
|
|
resetStatus();
|
|
}
|
|
|
|
void meter_init(void) {
|
|
ESP_LOGI(TAG, "Initializing meter");
|
|
|
|
if (!meter_mutex) {
|
|
meter_mutex = xSemaphoreCreateMutex();
|
|
if (!meter_mutex) {
|
|
ESP_LOGE(TAG, "Erro ao criar semáforo de mutex");
|
|
return; // Pode parar a inicialização caso não consiga criar o mutex
|
|
}
|
|
}
|
|
|
|
meter_initData();
|
|
esp_err_t err = Init(EEPROM_HOST, PIN_NUM_MISO, PIN_NUM_MOSI, PIN_NUM_CLK);
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Erro na inicialização do hardware SPI: %d", err);
|
|
return;
|
|
}
|
|
|
|
InitSpi(PIN_NUM_CS);
|
|
}
|
|
|
|
void meter_start(void) {
|
|
ESP_LOGI(TAG, "Starting meter");
|
|
|
|
Calibrate_ADE7758();
|
|
meter_initData();
|
|
|
|
if (!meter_task) {
|
|
xTaskCreate(meter_task_func, "meter_task", 5 * 1024, NULL, 5, &meter_task);
|
|
}
|
|
}
|
|
|
|
void meter_stop(void) {
|
|
ESP_LOGI(TAG, "Stopping meter");
|
|
|
|
if (meter_task) {
|
|
vTaskDelete(meter_task);
|
|
meter_task = NULL;
|
|
}
|
|
|
|
meter_initData();
|
|
}
|