first commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"potentiometer_manager.c"
|
||||
INCLUDE_DIRS
|
||||
"include"
|
||||
REQUIRES
|
||||
driver
|
||||
st7789
|
||||
)
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @file potentiometer_manager.h
|
||||
* @brief Potentiometer Manager for Volume & Brightness Control
|
||||
*
|
||||
* Features:
|
||||
* - Volume control (0-100%)
|
||||
* - Brightness control (10-100%)
|
||||
* - ADC reading with smoothing
|
||||
* - Automatic updates
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Potentiometer change callback
|
||||
* @param volume Current volume (0-100%)
|
||||
* @param brightness Current brightness (10-100%)
|
||||
*/
|
||||
typedef void (*poti_change_callback_t)(uint8_t volume, uint8_t brightness);
|
||||
|
||||
/**
|
||||
* @brief Initialize potentiometer manager
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t poti_manager_init(void);
|
||||
|
||||
/**
|
||||
* @brief Start potentiometer monitoring task
|
||||
* @param callback Callback function for changes (can be NULL)
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t poti_manager_start(poti_change_callback_t callback);
|
||||
|
||||
/**
|
||||
* @brief Stop potentiometer monitoring task
|
||||
*/
|
||||
void poti_manager_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Get current volume (0-100%)
|
||||
* @return Volume percentage
|
||||
*/
|
||||
uint8_t poti_get_volume(void);
|
||||
|
||||
/**
|
||||
* @brief Get current brightness (10-100%)
|
||||
* @return Brightness percentage
|
||||
*/
|
||||
uint8_t poti_get_brightness(void);
|
||||
|
||||
/**
|
||||
* @brief Manual update (read ADC values)
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t poti_update(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,256 @@
|
||||
/**
|
||||
* @file potentiometer_manager.c
|
||||
* @brief Potentiometer Manager Implementation - COMPLETE!
|
||||
*
|
||||
* Features:
|
||||
* - Dual ADC reading (Volume + Brightness)
|
||||
* - Moving average filter (smoothing)
|
||||
* - Automatic monitoring task
|
||||
* - Callback on changes
|
||||
* - Direct ST7789 brightness control
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "esp_log.h"
|
||||
#include "driver/adc.h"
|
||||
#include "esp_adc_cal.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "potentiometer_manager.h"
|
||||
#include "st7789.h"
|
||||
#include "hardware_config.h"
|
||||
|
||||
static const char *TAG = "POTI";
|
||||
|
||||
// ADC Configuration
|
||||
#define ADC_SAMPLES 8 // Samples for averaging
|
||||
#define POTI_THRESHOLD 5 // Change threshold (%)
|
||||
#define POTI_UPDATE_MS 100 // Update interval
|
||||
|
||||
// Current values
|
||||
static uint8_t current_volume = 50;
|
||||
static uint8_t current_brightness = 80;
|
||||
|
||||
// Monitoring task
|
||||
static TaskHandle_t poti_task_handle = NULL;
|
||||
static bool poti_task_running = false;
|
||||
static poti_change_callback_t change_callback = NULL;
|
||||
|
||||
// ADC calibration
|
||||
static esp_adc_cal_characteristics_t adc1_chars;
|
||||
static esp_adc_cal_characteristics_t adc2_chars;
|
||||
|
||||
/**
|
||||
* @brief Initialize ADC for potentiometers
|
||||
*/
|
||||
static esp_err_t poti_adc_init(void)
|
||||
{
|
||||
// Configure ADC1 (Volume - GPIO 3)
|
||||
adc1_config_width(POTI_ADC_WIDTH);
|
||||
adc1_config_channel_atten(ADC1_CHANNEL_2, POTI_ADC_ATTEN); // GPIO 3 = ADC1_CH2
|
||||
|
||||
// Configure ADC2 (Brightness - GPIO 46)
|
||||
adc2_config_channel_atten(ADC2_CHANNEL_5, POTI_ADC_ATTEN); // GPIO 46 = ADC2_CH5
|
||||
|
||||
// Characterize ADC
|
||||
esp_adc_cal_characterize(ADC_UNIT_1, POTI_ADC_ATTEN, POTI_ADC_WIDTH,
|
||||
1100, &adc1_chars);
|
||||
esp_adc_cal_characterize(ADC_UNIT_2, POTI_ADC_ATTEN, POTI_ADC_WIDTH,
|
||||
1100, &adc2_chars);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read ADC with averaging
|
||||
*/
|
||||
static uint32_t poti_read_adc1_averaged(void)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
|
||||
for (int i = 0; i < ADC_SAMPLES; i++) {
|
||||
uint32_t voltage;
|
||||
int raw = adc1_get_raw(ADC1_CHANNEL_2);
|
||||
voltage = esp_adc_cal_raw_to_voltage(raw, &adc1_chars);
|
||||
sum += voltage;
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
}
|
||||
|
||||
return sum / ADC_SAMPLES;
|
||||
}
|
||||
|
||||
static uint32_t poti_read_adc2_averaged(void)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
|
||||
for (int i = 0; i < ADC_SAMPLES; i++) {
|
||||
int raw;
|
||||
uint32_t voltage;
|
||||
|
||||
// ADC2 read (can fail if WiFi is active!)
|
||||
esp_err_t ret = adc2_get_raw(ADC2_CHANNEL_5, POTI_ADC_WIDTH, &raw);
|
||||
if (ret == ESP_OK) {
|
||||
voltage = esp_adc_cal_raw_to_voltage(raw, &adc2_chars);
|
||||
sum += voltage;
|
||||
} else {
|
||||
ESP_LOGW(TAG, "ADC2 read failed (WiFi active?)");
|
||||
return sum / (i > 0 ? i : 1); // Return partial average
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
}
|
||||
|
||||
return sum / ADC_SAMPLES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert voltage to percentage (0-100%)
|
||||
*/
|
||||
static uint8_t voltage_to_percent(uint32_t voltage_mv, uint32_t max_mv)
|
||||
{
|
||||
if (voltage_mv >= max_mv) return 100;
|
||||
return (voltage_mv * 100) / max_mv;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Potentiometer monitoring task
|
||||
*/
|
||||
static void poti_monitor_task(void *arg)
|
||||
{
|
||||
ESP_LOGI(TAG, "Potentiometer monitoring task started");
|
||||
|
||||
while (poti_task_running) {
|
||||
// Read potentiometers
|
||||
uint32_t volume_mv = poti_read_adc1_averaged();
|
||||
uint32_t brightness_mv = poti_read_adc2_averaged();
|
||||
|
||||
// Convert to percentage
|
||||
uint8_t new_volume = voltage_to_percent(volume_mv, 3300);
|
||||
uint8_t new_brightness = voltage_to_percent(brightness_mv, 3300);
|
||||
|
||||
// Clamp brightness to minimum (display shouldn't be completely off)
|
||||
if (new_brightness < LCD_BCKL_MIN) {
|
||||
new_brightness = LCD_BCKL_MIN;
|
||||
}
|
||||
|
||||
// Check if changed significantly
|
||||
bool volume_changed = abs(new_volume - current_volume) >= POTI_THRESHOLD;
|
||||
bool brightness_changed = abs(new_brightness - current_brightness) >= POTI_THRESHOLD;
|
||||
|
||||
if (volume_changed || brightness_changed) {
|
||||
current_volume = new_volume;
|
||||
current_brightness = new_brightness;
|
||||
|
||||
ESP_LOGD(TAG, "Volume: %d%%, Brightness: %d%%",
|
||||
current_volume, current_brightness);
|
||||
|
||||
// Update display brightness immediately
|
||||
st7789_set_backlight(current_brightness);
|
||||
|
||||
// Call callback if registered
|
||||
if (change_callback != NULL) {
|
||||
change_callback(current_volume, current_brightness);
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(POTI_UPDATE_MS));
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Potentiometer monitoring task stopped");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
// ===========================================
|
||||
// Public API
|
||||
// ===========================================
|
||||
|
||||
esp_err_t poti_manager_init(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Initializing Potentiometer Manager...");
|
||||
|
||||
// Initialize ADC
|
||||
ESP_ERROR_CHECK(poti_adc_init());
|
||||
|
||||
// Read initial values
|
||||
poti_update();
|
||||
|
||||
ESP_LOGI(TAG, "✓ Potentiometer Manager initialized");
|
||||
ESP_LOGI(TAG, " Volume: %d%%, Brightness: %d%%",
|
||||
current_volume, current_brightness);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t poti_manager_start(poti_change_callback_t callback)
|
||||
{
|
||||
if (poti_task_running) {
|
||||
ESP_LOGW(TAG, "Potentiometer task already running");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
change_callback = callback;
|
||||
poti_task_running = true;
|
||||
|
||||
BaseType_t ret = xTaskCreate(
|
||||
poti_monitor_task,
|
||||
"poti_monitor",
|
||||
4096,
|
||||
NULL,
|
||||
5, // Priority
|
||||
&poti_task_handle
|
||||
);
|
||||
|
||||
if (ret != pdPASS) {
|
||||
ESP_LOGE(TAG, "Failed to create potentiometer task!");
|
||||
poti_task_running = false;
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "✓ Potentiometer monitoring started");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void poti_manager_stop(void)
|
||||
{
|
||||
if (!poti_task_running) {
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Stopping potentiometer monitoring...");
|
||||
poti_task_running = false;
|
||||
|
||||
// Task will delete itself
|
||||
}
|
||||
|
||||
uint8_t poti_get_volume(void)
|
||||
{
|
||||
return current_volume;
|
||||
}
|
||||
|
||||
uint8_t poti_get_brightness(void)
|
||||
{
|
||||
return current_brightness;
|
||||
}
|
||||
|
||||
esp_err_t poti_update(void)
|
||||
{
|
||||
// Manual single update (without task)
|
||||
uint32_t volume_mv = poti_read_adc1_averaged();
|
||||
uint32_t brightness_mv = poti_read_adc2_averaged();
|
||||
|
||||
current_volume = voltage_to_percent(volume_mv, 3300);
|
||||
current_brightness = voltage_to_percent(brightness_mv, 3300);
|
||||
|
||||
if (current_brightness < LCD_BCKL_MIN) {
|
||||
current_brightness = LCD_BCKL_MIN;
|
||||
}
|
||||
|
||||
// Update display brightness
|
||||
st7789_set_backlight(current_brightness);
|
||||
|
||||
ESP_LOGD(TAG, "Manual update: Volume %d%%, Brightness %d%%",
|
||||
current_volume, current_brightness);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user