Adicionar primeiro

This commit is contained in:
2025-06-06 21:17:25 +01:00
parent c188084ba4
commit 282e7f517b
841 changed files with 199592 additions and 1 deletions

View File

@@ -0,0 +1,136 @@
// currentshaper.c
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <sys/param.h>
#include "evse_api.h"
#include "input_filter.h"
static const char *TAG = "currentshaper";
#define EVSE_SHAPER_HYSTERESIS 50 // A*10
#define CHARGING_CURRENT_MIN 60 // A*10
static TaskHandle_t currentshaper_task = NULL;
static uint32_t smoothing_time_ms = 1000;
static uint32_t min_pause_time_ms = 300000;
static uint32_t max_data_interval_ms = 120000;
static int max_grid_current = 300; // A*10
static int live_grid_current = 0; // A*10
static int live_voltage = 230;
static double smoothed_current = 0;
static uint16_t max_current = 0;
static TickType_t timer = 0;
static TickType_t pause_timer = 0;
static bool updated = false;
static bool changed = false;
static portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
void shapeCurrent()
{
taskENTER_CRITICAL(&mux);
updated = true;
smoothed_current = filter(live_grid_current, smoothed_current, smoothing_time_ms);
int diff = max_grid_current - (int)smoothed_current;
int charge_current = evse_get_charging_current();
int new_current = diff + charge_current;
new_current = MIN(new_current, evse_get_max_charging_current() * 10);
new_current = MAX(new_current, CHARGING_CURRENT_MIN);
max_current = new_current;
if (charge_current != max_current)
{
evse_set_charging_current(max_current);
changed = true;
}
taskEXIT_CRITICAL(&mux);
}
void setMaxGridCurrent(int value)
{
taskENTER_CRITICAL(&mux);
max_grid_current = value;
taskEXIT_CRITICAL(&mux);
ESP_LOGI(TAG, "Max grid current: %d A*10", value);
}
void setLiveGridCurrent(int value)
{
taskENTER_CRITICAL(&mux);
live_grid_current = value;
taskEXIT_CRITICAL(&mux);
ESP_LOGI(TAG, "Live grid current: %d A*10", value);
if (evse_state_is_charging(evse_get_state()))
{
shapeCurrent();
}
}
void setLiveVoltage(int value)
{
taskENTER_CRITICAL(&mux);
live_voltage = value;
taskEXIT_CRITICAL(&mux);
ESP_LOGD(TAG, "Live voltage: %d V", value);
}
static void currentshaper_task_func(void *param)
{
while (true)
{
TickType_t now = xTaskGetTickCount();
if (evse_state_is_charging(evse_get_state()))
{
taskENTER_CRITICAL(&mux);
if (changed)
{
if (max_current < CHARGING_CURRENT_MIN)
{
evse_set_charging_current(CHARGING_CURRENT_MIN);
if (pause_timer == 0)
pause_timer = now;
}
else if ((pause_timer != 0) && (now - pause_timer) * portTICK_PERIOD_MS >= min_pause_time_ms &&
(max_current - CHARGING_CURRENT_MIN >= EVSE_SHAPER_HYSTERESIS))
{
pause_timer = 0;
}
timer = now;
changed = false;
}
else if (!updated || (now - timer) * portTICK_PERIOD_MS > max_data_interval_ms)
{
if (updated)
{
pause_timer = now;
updated = false;
smoothed_current = live_grid_current;
}
}
taskEXIT_CRITICAL(&mux);
}
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void currentshaper_start()
{
ESP_LOGI(TAG, "Starting current shaper task");
xTaskCreate(currentshaper_task_func, "currentshaper_task", 4096, NULL, 5, &currentshaper_task);
}
void currentshaper_stop()
{
ESP_LOGI(TAG, "Stopping current shaper task");
if (currentshaper_task != NULL)
{
vTaskDelete(currentshaper_task);
currentshaper_task = NULL;
}
}

View File

@@ -0,0 +1,36 @@
// input_filter.c
#include "input_filter.h"
#include "esp_log.h"
#include <math.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <stdint.h>
static const char *TAG = "inputfilter";
static TickType_t last_data_time = 0;
#define MIN_TAU_MS 100 // Minimum time constant in ms
double getFactor(uint32_t delta_ms, uint32_t tau_ms)
{
if (tau_ms < MIN_TAU_MS)
{
tau_ms = MIN_TAU_MS;
}
double factor = 1.0 - exp(-((double)delta_ms / (double)tau_ms));
ESP_LOGD(TAG, "delta_ms=%" PRIu32 ", tau_ms=%" PRIu32 ", factor=%f", delta_ms, tau_ms, factor);
return factor;
}
double filter(double input, double filtered, uint32_t tau_ms)
{
TickType_t now = xTaskGetTickCount();
uint32_t delta_ms = (now - last_data_time) * portTICK_PERIOD_MS;
last_data_time = now;
double factor = getFactor(delta_ms, tau_ms);
filtered = input * factor + filtered * (1.0 - factor);
ESP_LOGD(TAG, "input=%f, filtered=%f", input, filtered);
return filtered;
}