2025年12月6日 星期六

ESP32 Control LED Brightness (PWM) with ESP-IDF

ESP32 Control LED Brightness (PWM) with ESP-IDF








main.c

#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

// *** 修正: 替換為新的 ADC 驅動 API ***
#include "esp_adc/adc_oneshot.h"
// **********************************

#include "driver/ledc.h"

#define SAMPLE_CNT 32
// 注意:GPIO32 是 ESP32 ADC1 的 Channel 4
static const adc_channel_t adc_channel = ADC_CHANNEL_4;
#define LEDC_GPIO 27
static ledc_channel_config_t ledc_channel;

// *** 修正: 使用新的 ADC oneshot 句柄 ***
static adc_oneshot_unit_handle_t adc1_handle;

static void init_hw(void)
{
    // 1. 配置並校準 ADC
    adc_oneshot_unit_init_cfg_t init_config = {
        .unit_id = ADC_UNIT_1, // 使用 ADC1
    };
    // 初始化 ADC 模組
    ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config, &adc1_handle));

    adc_oneshot_chan_cfg_t config = {
        .bitwidth = ADC_BITWIDTH_DEFAULT, // 默認為 10 bit
        // *** 修正: 使用新的衰減常數 ADC_ATTEN_DB_12 (取代已棄用的 DB_11) ***
        .atten = ADC_ATTEN_DB_12,
    };
    // 配置 ADC 通道
    ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, adc_channel, &config));
   
    // 2. 配置 LEDC (PWM)
    ledc_timer_config_t ledc_timer = {
        .duty_resolution = LEDC_TIMER_10_BIT,
        .freq_hz = 1000,
        .speed_mode = LEDC_LOW_SPEED_MODE, // 建議使用 LOW_SPEED_MODE
        .timer_num = LEDC_TIMER_0,
        .clk_cfg = LEDC_AUTO_CLK,
    };

    ledc_timer_config(&ledc_timer);
   
    ledc_channel.channel = LEDC_CHANNEL_0;
    ledc_channel.duty = 0;
    ledc_channel.gpio_num = LEDC_GPIO;
    ledc_channel.speed_mode = LEDC_LOW_SPEED_MODE;
    ledc_channel.hpoint = 0;
    ledc_channel.timer_sel = LEDC_TIMER_0;
    ledc_channel_config(&ledc_channel);
}

void app_main()
{
    init_hw();
    while (1)
    {
        int adc_raw = 0;
        int adc_val = 0;
       
        // 讀取多次取樣並平均
        for (int i = 0; i < SAMPLE_CNT; ++i)
        {
            // *** 修正: 使用新的 ADC oneshot 讀取 API ***
            adc_oneshot_read(adc1_handle, adc_channel, &adc_raw);
            adc_val += adc_raw;
            // *****************************************
        }
        adc_val /= SAMPLE_CNT;

        // 將 ADC 值 (0-1023) 作為 PWM 的 Duty (0-1023)
        ledc_set_duty(ledc_channel.speed_mode, ledc_channel.channel, adc_val);
        ledc_update_duty(ledc_channel.speed_mode, ledc_channel.channel);
       
        // *** 修正: 替換為正確的 FreeRTOS 宏 ***
        vTaskDelay(pdMS_TO_TICKS(500));
        // 替代方法: vTaskDelay(500 / portTICK_PERIOD_MS);
        // 推薦使用 pdMS_TO_TICKS() 宏,因為它更簡潔且安全。
    }
}

沒有留言:

張貼留言

8-QAM Signal 4 Phases 2 Amplitudes + 8PSK

 8-QAM Signal 4 Phases 2 Amplitudes + 8PSK import tkinter as tk from tkinter import messagebox import math import cmath # --- 8-QAM 參數設定 ---...