new module
This commit is contained in:
@@ -23,24 +23,20 @@
|
||||
#define MAX_SAMPLE_ATTEMPTS 1000
|
||||
#define PILOT_EXTREME_PERCENT 10 // 10% superior e inferior
|
||||
|
||||
// ADC121S021 setup
|
||||
#define ADC121_VREF_MV 3300 // AJUSTE conforme Vref do seu hardware!
|
||||
#define ADC121_MAX 4095 // 12 bits
|
||||
#define ADC121_VREF_MV 3300
|
||||
#define ADC121_MAX 4095
|
||||
|
||||
static const char *TAG = "evse_pilot";
|
||||
|
||||
// Memoização de estado para evitar comandos/logs desnecessários
|
||||
static int last_pilot_level = -1;
|
||||
static uint32_t last_pwm_duty = 0;
|
||||
|
||||
// Função para converter leitura bruta do ADC para mV
|
||||
static int adc_raw_to_mv(uint16_t raw) {
|
||||
return (raw * ADC121_VREF_MV) / ADC121_MAX;
|
||||
}
|
||||
|
||||
void pilot_init(void)
|
||||
{
|
||||
// PWM (LEDC) configuração
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = PILOT_PWM_SPEED_MODE,
|
||||
.timer_num = PILOT_PWM_TIMER,
|
||||
@@ -61,20 +57,18 @@ void pilot_init(void)
|
||||
};
|
||||
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
|
||||
ESP_ERROR_CHECK(ledc_stop(PILOT_PWM_SPEED_MODE, PILOT_PWM_CHANNEL, 0));
|
||||
//ESP_ERROR_CHECK(ledc_fade_func_install(0));
|
||||
|
||||
// Inicializa ADC121S021 externo
|
||||
adc121s021_dma_init();
|
||||
}
|
||||
|
||||
void pilot_set_level(bool level)
|
||||
{
|
||||
if (last_pilot_level == level) return; // só muda se necessário
|
||||
if (last_pilot_level == level) return;
|
||||
last_pilot_level = level;
|
||||
|
||||
ESP_LOGI(TAG, "Set level %d", level);
|
||||
ledc_stop(PILOT_PWM_SPEED_MODE, PILOT_PWM_CHANNEL, level ? 1 : 0);
|
||||
last_pwm_duty = 0; // PWM parado
|
||||
last_pwm_duty = 0;
|
||||
}
|
||||
|
||||
void pilot_set_amps(uint16_t amps)
|
||||
@@ -85,13 +79,11 @@ void pilot_set_amps(uint16_t amps)
|
||||
}
|
||||
|
||||
uint32_t duty_percent;
|
||||
|
||||
if (amps <= 51) {
|
||||
duty_percent = (amps * 10) / 6; // Duty (%) = Amps / 0.6
|
||||
duty_percent = (amps * 10) / 6;
|
||||
} else {
|
||||
duty_percent = (amps * 10) / 25 + 64; // Duty (%) = (Amps / 2.5) + 64
|
||||
duty_percent = (amps * 10) / 25 + 64;
|
||||
}
|
||||
|
||||
if (duty_percent > 100) duty_percent = 100;
|
||||
|
||||
uint32_t duty = (PILOT_PWM_MAX_DUTY * duty_percent) / 100;
|
||||
@@ -101,40 +93,18 @@ void pilot_set_amps(uint16_t amps)
|
||||
last_pwm_duty = duty;
|
||||
|
||||
ESP_LOGI(TAG, "Pilot set: %d A → %d/%d (≈ %d%% duty)",
|
||||
amps, (int)duty, PILOT_PWM_MAX_DUTY, (int)duty_percent);
|
||||
amps, (int)duty, PILOT_PWM_MAX_DUTY, (int)duty_percent);
|
||||
|
||||
ledc_set_duty(PILOT_PWM_SPEED_MODE, PILOT_PWM_CHANNEL, duty);
|
||||
ledc_update_duty(PILOT_PWM_SPEED_MODE, PILOT_PWM_CHANNEL);
|
||||
}
|
||||
|
||||
bool pilot_get_state(void) {
|
||||
// true se estamos em 12V fixo; false se PWM ou -12V
|
||||
// Se quiser diferenciar PWM, guarde um flag quando chamar set_amps.
|
||||
return (last_pilot_level == 1) && (last_pwm_duty == 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int compare_int(const void *a, const void *b) {
|
||||
return (*(int *)a - *(int *)b);
|
||||
}
|
||||
|
||||
static int select_low_median_qsort(int *src, int n, int percent) {
|
||||
int k = (n * percent) / 100;
|
||||
if (k == 0) k = 1;
|
||||
int *copy = alloca(n * sizeof(int));
|
||||
memcpy(copy, src, n * sizeof(int));
|
||||
qsort(copy, n, sizeof(int), compare_int);
|
||||
return copy[k / 2];
|
||||
}
|
||||
|
||||
static int select_high_median_qsort(int *src, int n, int percent) {
|
||||
int k = (n * percent) / 100;
|
||||
if (k == 0) k = 1;
|
||||
int *copy = alloca(n * sizeof(int));
|
||||
memcpy(copy, src, n * sizeof(int));
|
||||
qsort(copy, n, sizeof(int), compare_int);
|
||||
return copy[n - k + (k / 2)];
|
||||
return (*(const int *)a - *(const int *)b);
|
||||
}
|
||||
|
||||
void pilot_measure(pilot_voltage_t *up_voltage, bool *down_voltage_n12)
|
||||
@@ -145,7 +115,6 @@ void pilot_measure(pilot_voltage_t *up_voltage, bool *down_voltage_n12)
|
||||
int collected = 0, attempts = 0;
|
||||
uint16_t adc_sample = 0;
|
||||
|
||||
// Lê samples usando ADC121S021 externo
|
||||
while (collected < NUM_PILOT_SAMPLES && attempts < MAX_SAMPLE_ATTEMPTS) {
|
||||
adc_sample = 0;
|
||||
if (adc121s021_dma_get_sample(&adc_sample)) {
|
||||
@@ -164,13 +133,21 @@ void pilot_measure(pilot_voltage_t *up_voltage, bool *down_voltage_n12)
|
||||
return;
|
||||
}
|
||||
|
||||
int high_raw = select_high_median_qsort(samples, collected, PILOT_EXTREME_PERCENT);
|
||||
int low_raw = select_low_median_qsort(samples, collected, PILOT_EXTREME_PERCENT);
|
||||
qsort(samples, collected, sizeof(int), compare_int);
|
||||
|
||||
int k = (collected * PILOT_EXTREME_PERCENT) / 100;
|
||||
if (k == 0) k = 1;
|
||||
|
||||
int low_index = k / 2;
|
||||
int high_index = collected - k + (k / 2);
|
||||
if (high_index >= collected) high_index = collected - 1;
|
||||
|
||||
int low_raw = samples[low_index];
|
||||
int high_raw = samples[high_index];
|
||||
|
||||
int high_mv = adc_raw_to_mv(high_raw);
|
||||
int low_mv = adc_raw_to_mv(low_raw);
|
||||
|
||||
// Aplica thresholds definidos em board_config (em mV)
|
||||
if (high_mv >= board_config.pilot_down_threshold_12)
|
||||
*up_voltage = PILOT_VOLTAGE_12;
|
||||
else if (high_mv >= board_config.pilot_down_threshold_9)
|
||||
|
||||
Reference in New Issue
Block a user