chore: snapshot before shared RS485 bus integration
This commit is contained in:
109
components/evse/evse_pilot.c
Executable file → Normal file
109
components/evse/evse_pilot.c
Executable file → Normal file
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "evse_pilot.h"
|
||||
#include "adc121s021_dma.h"
|
||||
#include "adc.h"
|
||||
#include "board_config.h"
|
||||
|
||||
#define PILOT_PWM_TIMER LEDC_TIMER_0
|
||||
@@ -27,7 +28,8 @@
|
||||
// Percentagem para descartar extremos superior/inferior (ruído)
|
||||
#define PILOT_EXTREME_PERCENT 10 // 10% superior e inferior
|
||||
|
||||
// ADC referência
|
||||
// Referência usada pelo ADC121S021 externo.
|
||||
// No ADC interno, o valor já é convertido para mV por adc_cali_raw_to_voltage().
|
||||
#define ADC121_VREF_MV 3300
|
||||
#define ADC121_MAX 4095
|
||||
|
||||
@@ -41,24 +43,100 @@ typedef enum {
|
||||
|
||||
static pilot_mode_t s_mode = PILOT_MODE_DC_LOW;
|
||||
static uint32_t last_pwm_duty = 0;
|
||||
static bool s_internal_adc_configured = false;
|
||||
|
||||
// ---------------------
|
||||
// Helpers internos
|
||||
// ---------------------
|
||||
static int adc_raw_to_mv(uint16_t raw)
|
||||
static int adc121_raw_to_mv(uint16_t raw)
|
||||
{
|
||||
return (int)((raw * ADC121_VREF_MV) / ADC121_MAX);
|
||||
}
|
||||
|
||||
static int compare_uint16(const void *a, const void *b)
|
||||
static int compare_int(const void *a, const void *b)
|
||||
{
|
||||
uint16_t va = *(const uint16_t *)a;
|
||||
uint16_t vb = *(const uint16_t *)b;
|
||||
int va = *(const int *)a;
|
||||
int vb = *(const int *)b;
|
||||
if (va < vb) return -1;
|
||||
if (va > vb) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool pilot_adc_read_mv(int *mv)
|
||||
{
|
||||
if (!mv)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (board_config.pilot_adc_source == BOARD_CONFIG_PILOT_ADC_INTERNAL_ESP32)
|
||||
{
|
||||
if (!adc_handle || !adc_cali_handle)
|
||||
{
|
||||
ESP_LOGE(TAG, "ADC interno não inicializado/calibrado");
|
||||
return false;
|
||||
}
|
||||
|
||||
int raw = 0;
|
||||
esp_err_t err;
|
||||
|
||||
adc_lock();
|
||||
err = adc_oneshot_read(adc_handle, board_config.pilot_adc_channel, &raw);
|
||||
if (err == ESP_OK)
|
||||
{
|
||||
err = adc_cali_raw_to_voltage(adc_cali_handle, raw, mv);
|
||||
}
|
||||
adc_unlock();
|
||||
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "Erro ao ler/converter ADC interno do pilot: %s", esp_err_to_name(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t raw = 0;
|
||||
if (!adc121s021_dma_get_sample(&raw))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*mv = adc121_raw_to_mv(raw);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void pilot_adc_init(void)
|
||||
{
|
||||
if (board_config.pilot_adc_source == BOARD_CONFIG_PILOT_ADC_INTERNAL_ESP32)
|
||||
{
|
||||
if (!adc_handle)
|
||||
{
|
||||
adc_init();
|
||||
}
|
||||
|
||||
if (!s_internal_adc_configured)
|
||||
{
|
||||
adc_oneshot_chan_cfg_t config = {
|
||||
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||||
.atten = ADC_ATTEN_DB_12
|
||||
};
|
||||
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc_handle,
|
||||
board_config.pilot_adc_channel,
|
||||
&config));
|
||||
s_internal_adc_configured = true;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Pilot ADC: interno ESP32 ADC1_CH%d",
|
||||
(int)board_config.pilot_adc_channel);
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Pilot ADC: ADC121S021 externo via SPI");
|
||||
adc121s021_dma_init();
|
||||
}
|
||||
|
||||
// ---------------------
|
||||
// Inicialização PWM + ADC
|
||||
// ---------------------
|
||||
@@ -91,8 +169,8 @@ void pilot_init(void)
|
||||
s_mode = PILOT_MODE_DC_LOW;
|
||||
last_pwm_duty = 0;
|
||||
|
||||
// Inicializa driver do ADC121S021
|
||||
adc121s021_dma_init();
|
||||
// Inicializa o backend de leitura do pilot configurado na board.
|
||||
pilot_adc_init();
|
||||
}
|
||||
|
||||
// ---------------------
|
||||
@@ -165,17 +243,17 @@ void pilot_measure(pilot_voltage_t *up_voltage, bool *down_voltage_n12)
|
||||
{
|
||||
ESP_LOGD(TAG, "pilot_measure");
|
||||
|
||||
uint16_t samples[NUM_PILOT_SAMPLES];
|
||||
int samples_mv[NUM_PILOT_SAMPLES];
|
||||
int collected = 0;
|
||||
int attempts = 0;
|
||||
|
||||
while (collected < NUM_PILOT_SAMPLES && attempts < MAX_SAMPLE_ATTEMPTS)
|
||||
{
|
||||
uint16_t adc_sample;
|
||||
int sample_mv = 0;
|
||||
|
||||
if (adc121s021_dma_get_sample(&adc_sample))
|
||||
if (pilot_adc_read_mv(&sample_mv))
|
||||
{
|
||||
samples[collected++] = adc_sample;
|
||||
samples_mv[collected++] = sample_mv;
|
||||
esp_rom_delay_us(PILOT_SAMPLE_DELAY_US);
|
||||
}
|
||||
else
|
||||
@@ -194,7 +272,7 @@ void pilot_measure(pilot_voltage_t *up_voltage, bool *down_voltage_n12)
|
||||
}
|
||||
|
||||
// Ordena as amostras para eliminar extremos (ruído/espúrios)
|
||||
qsort(samples, collected, sizeof(uint16_t), compare_uint16);
|
||||
qsort(samples_mv, collected, sizeof(int), compare_int);
|
||||
|
||||
int k = (collected * PILOT_EXTREME_PERCENT) / 100;
|
||||
if (k < 2) k = 2; // garante margem mínima
|
||||
@@ -207,11 +285,8 @@ void pilot_measure(pilot_voltage_t *up_voltage, bool *down_voltage_n12)
|
||||
if (high_index >= collected) high_index = collected - 1;
|
||||
if (high_index <= low_index) high_index = low_index;
|
||||
|
||||
uint16_t low_raw = samples[low_index];
|
||||
uint16_t high_raw = samples[high_index];
|
||||
|
||||
int high_mv = adc_raw_to_mv(high_raw);
|
||||
int low_mv = adc_raw_to_mv(low_raw);
|
||||
int low_mv = samples_mv[low_index];
|
||||
int high_mv = samples_mv[high_index];
|
||||
|
||||
// Determina o nível positivo (+12, +9, +6, +3 ou <3 V)
|
||||
if (high_mv >= board_config.pilot_down_threshold_12)
|
||||
|
||||
Reference in New Issue
Block a user