new meter

This commit is contained in:
2025-06-14 10:27:29 +01:00
parent 4892718736
commit 6f95c7ba59
228 changed files with 3178 additions and 3115 deletions

View File

@@ -4,7 +4,6 @@ set(srcs
"src/peripherals.c"
"src/led.c"
"src/buzzer.c"
"src/pilot.c"
"src/proximity.c"
"src/ac_relay.c"
"src/socket_lock.c"

View File

@@ -1,69 +0,0 @@
#ifndef PILOT_H_
#define PILOT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
/**
* @brief Níveis categóricos de tensão no sinal CP (Control Pilot)
*/
typedef enum
{
PILOT_VOLTAGE_12, ///< Estado A: +12V
PILOT_VOLTAGE_9, ///< Estado B: +9V
PILOT_VOLTAGE_6, ///< Estado C: +6V
PILOT_VOLTAGE_3, ///< Estado D: +3V
PILOT_VOLTAGE_1 ///< Estado E/F: abaixo de 3V
} pilot_voltage_t;
/**
* @brief Inicializa o driver do sinal Pilot
*/
void pilot_init(void);
/**
* @brief Define o nível do Pilot: +12V ou -12V
*
* @param level true = +12V, false = -12V
*/
void pilot_set_level(bool level);
/**
* @brief Ativa o PWM do Pilot com corrente limitada
*
* @param amps Corrente em décimos de ampère (ex: 160 = 16A)
*/
void pilot_set_amps(uint16_t amps);
/**
* @brief Mede o nível de tensão do Pilot e detecta -12V
*
* @param up_voltage Valor categórico da tensão positiva
* @param down_voltage_n12 true se o nível negativo atingir -12V
*/
void pilot_measure(pilot_voltage_t *up_voltage, bool *down_voltage_n12);
/**
* @brief Retorna o estado lógico atual do Pilot (nível alto = +12V)
*
* @return true se nível atual for +12V, false se for -12V
*/
bool pilot_get_state(void);
/**
* @brief Cache interno opcional dos níveis de tensão reais do Pilot
*/
typedef struct {
uint16_t high_mv; ///< Pico positivo medido (mV)
uint16_t low_mv; ///< Pico negativo medido (mV)
} pilot_voltage_cache_t;
#ifdef __cplusplus
}
#endif
#endif /* PILOT_H_ */

View File

@@ -91,7 +91,7 @@ static void buzzer_worker_task(void *arg) {
while (true) {
if (xQueueReceive(buzzer_queue, &pattern_id, portMAX_DELAY)) {
buzzer_execute_pattern(pattern_id);
//buzzer_execute_pattern(pattern_id);
}
}
}
@@ -158,6 +158,6 @@ void buzzer_init(void) {
buzzer_queue = xQueueCreate(4, sizeof(buzzer_pattern_id_t));
xTaskCreate(buzzer_monitor_task, "buzzer_monitor", 2048, NULL, 5, NULL);
xTaskCreate(buzzer_worker_task, "buzzer_worker", 2048, NULL, 5, NULL);
xTaskCreate(buzzer_monitor_task, "buzzer_monitor", 2048, NULL, 3, NULL);
xTaskCreate(buzzer_worker_task, "buzzer_worker", 2048, NULL, 3, NULL);
}

View File

@@ -59,5 +59,5 @@ void ntc_sensor_init(void)
ESP_ERROR_CHECK(ntc_dev_create(&ntc_config, &ntc, &adc_handle));
ESP_ERROR_CHECK(ntc_dev_get_adc_handle(ntc, &adc_handle));
xTaskCreate(ntc_sensor_task_func, "ntc_sensor_task", 5 * 1024, NULL, 5, NULL);
xTaskCreate(ntc_sensor_task_func, "ntc_sensor_task", 5 * 1024, NULL, 3, NULL);
}

View File

@@ -2,7 +2,6 @@
#include "adc.h"
#include "led.h"
#include "buzzer.h"
#include "pilot.h"
#include "proximity.h"
#include "ac_relay.h"
#include "socket_lock.h"
@@ -16,7 +15,6 @@ void peripherals_init(void)
led_init();
buzzer_init();
adc_init();
pilot_init();
proximity_init();
// socket_lock_init();
// rcm_init();

View File

@@ -1,186 +0,0 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "driver/ledc.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_rom_sys.h"
#include "pilot.h"
#include "adc.h"
#include "board_config.h"
#define PILOT_PWM_TIMER LEDC_TIMER_0
#define PILOT_PWM_CHANNEL LEDC_CHANNEL_0
#define PILOT_PWM_SPEED_MODE LEDC_LOW_SPEED_MODE
#define PILOT_PWM_DUTY_RES LEDC_TIMER_10_BIT
#define PILOT_PWM_MAX_DUTY 1023
#define NUM_PILOT_SAMPLES 100
#define MAX_SAMPLE_ATTEMPTS 1000
#define PILOT_EXTREME_PERCENT 10 // 15% superior e inferior
static const char *TAG = "pilot";
static pilot_voltage_cache_t last_voltage = {0, 0};
static inline uint16_t adc_to_mv(uint16_t x) {
return (uint16_t)(((uint32_t)(x) * 3300U) / 4095U);
}
void pilot_init(void)
{
ledc_timer_config_t ledc_timer = {
.speed_mode = PILOT_PWM_SPEED_MODE,
.timer_num = PILOT_PWM_TIMER,
.duty_resolution = PILOT_PWM_DUTY_RES,
.freq_hz = 1000,
.clk_cfg = LEDC_AUTO_CLK
};
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
ledc_channel_config_t ledc_channel = {
.speed_mode = PILOT_PWM_SPEED_MODE,
.channel = PILOT_PWM_CHANNEL,
.timer_sel = PILOT_PWM_TIMER,
.intr_type = LEDC_INTR_DISABLE,
.gpio_num = board_config.pilot_pwm_gpio,
.duty = 0,
.hpoint = 0
};
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));
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));
}
void pilot_set_level(bool level)
{
ESP_LOGI(TAG, "Set level %d", level);
ledc_stop(PILOT_PWM_SPEED_MODE, PILOT_PWM_CHANNEL, level ? 1 : 0);
}
void pilot_set_amps(uint16_t amps)
{
ESP_LOGI(TAG, "Set amps %d", amps);
if (amps < 60 || amps > 800) {
ESP_LOGE(TAG, "Invalid ampere value: %d A*10", amps);
return;
}
uint32_t duty;
if (amps <= 510) {
duty = (PILOT_PWM_MAX_DUTY * amps) / 600;
} else {
duty = ((PILOT_PWM_MAX_DUTY * amps) / 2500) + (64 * (PILOT_PWM_MAX_DUTY / 100));
}
if (duty > PILOT_PWM_MAX_DUTY)
duty = PILOT_PWM_MAX_DUTY;
ESP_LOGI(TAG, "Set amp %dA*10 -> duty %lu/%d", amps, duty, PILOT_PWM_MAX_DUTY);
ledc_set_duty(PILOT_PWM_SPEED_MODE, PILOT_PWM_CHANNEL, duty);
ledc_update_duty(PILOT_PWM_SPEED_MODE, PILOT_PWM_CHANNEL);
}
static int compare_u16(const void *a, const void *b) {
return (*(uint16_t *)a - *(uint16_t *)b);
}
static uint16_t select_low_median_qsort(uint16_t *src, int n, int percent) {
int k = (n * percent) / 100;
if (k == 0) k = 1;
uint16_t *copy = alloca(n * sizeof(uint16_t));
memcpy(copy, src, n * sizeof(uint16_t));
qsort(copy, n, sizeof(uint16_t), compare_u16);
return copy[k / 2];
}
static uint16_t select_high_median_qsort(uint16_t *src, int n, int percent) {
int k = (n * percent) / 100;
if (k == 0) k = 1;
uint16_t *copy = alloca(n * sizeof(uint16_t));
memcpy(copy, src, n * sizeof(uint16_t));
qsort(copy, n, sizeof(uint16_t), compare_u16);
return copy[n - k + (k / 2)];
}
void pilot_measure(pilot_voltage_t *up_voltage, bool *down_voltage_n12)
{
ESP_LOGD(TAG, "pilot_measure");
uint16_t samples[NUM_PILOT_SAMPLES];
int collected = 0, attempts = 0;
uint16_t sample;
while (collected < NUM_PILOT_SAMPLES && attempts < MAX_SAMPLE_ATTEMPTS) {
if (adc_oneshot_read(adc_handle, board_config.pilot_adc_channel, &sample) == ESP_OK) {
samples[collected++] = sample;
esp_rom_delay_us(10);
} else {
esp_rom_delay_us(100);
attempts++;
}
}
if (collected < NUM_PILOT_SAMPLES) {
ESP_LOGW(TAG, "Timeout on sample read (%d/%d)", collected, NUM_PILOT_SAMPLES);
*up_voltage = PILOT_VOLTAGE_1;
*down_voltage_n12 = false;
return;
}
uint16_t high_raw = select_high_median_qsort(samples, collected, PILOT_EXTREME_PERCENT);
uint16_t low_raw = select_low_median_qsort(samples, collected, PILOT_EXTREME_PERCENT);
int high_mv = 0;
int low_mv = 0;
if (adc_cali_raw_to_voltage(adc_cali_handle, high_raw, &high_mv) != ESP_OK ||
adc_cali_raw_to_voltage(adc_cali_handle, low_raw, &low_mv) != ESP_OK) {
ESP_LOGW(TAG, "ADC calibration failed");
*up_voltage = PILOT_VOLTAGE_1;
*down_voltage_n12 = false;
return;
}
if (high_mv >= board_config.pilot_down_threshold_12)
*up_voltage = PILOT_VOLTAGE_12;
else if (high_mv >= board_config.pilot_down_threshold_9)
*up_voltage = PILOT_VOLTAGE_9;
else if (high_mv >= board_config.pilot_down_threshold_6)
*up_voltage = PILOT_VOLTAGE_6;
else if (high_mv >= board_config.pilot_down_threshold_3)
*up_voltage = PILOT_VOLTAGE_3;
else
*up_voltage = PILOT_VOLTAGE_1;
*down_voltage_n12 = (low_mv <= board_config.pilot_down_threshold_n12);
ESP_LOGD(TAG, "Final: up_voltage=%d, down_voltage_n12=%d", *up_voltage, *down_voltage_n12);
}
bool pilot_get_state(void)
{
pilot_voltage_t voltage;
bool is_n12v;
pilot_measure(&voltage, &is_n12v);
// Considera que "estado alto" significa pelo menos 12V (standby ou pronto)
return voltage == PILOT_VOLTAGE_12;
}