【ESP32】實作 Adaptive PID

更新於 發佈於 閱讀時間約 14 分鐘
raw-image


Adaptive PID(比例-積分-微分)自適應 PID,在傳統 PID 控制器在工業與嵌入式領域應用廣泛,但固定參數難以應對動態變化的系統,調參往往耗時又不穩。Adaptive PID 則透過「根據誤差自動調整增益」來彌補這個問題,提供更聰明、更穩定的控制解法。

而更棒的是,我們可以用 ESP32 這顆價格親民、功能強大的微控制器來實現它!這時候,自適應 Adaptive PID 就派上用場了。

■什麼是自適應 Adaptive PID?

傳統 PID 控制器的三個參數:Kp、Ki、Kd 通常是固定的。而「自適應 PID」的核心概念是 「讓 PID 參數隨著系統狀態自動調整」:

1.輕負載時降低增益避免震盪

2.誤差大時增加 Kp 加快響應

3.穩定區自動減少 Ki 以避免超調

這種智慧式調整方式,特別適合控制對象動態變化劇烈的場景。

■Adaptive PID 實作邏輯

1.建立 PID 任務(使用 FreeRTOS Task)

2.讀取實際輸入值(如:溫度、速度)

3.輸出控制訊號(PWM 控制馬達、風扇或加熱器)

4.控制回圈週期(可用 Timer 或 vTaskDelayUntil() 精準控制)

●開發環境

在開始編程之前,請確保已完成以下準備工作:

1.安裝 ESP-IDF 開發環境 (至少版本 v5.x 或更高)。

2.ESP32 開發板。

●專案結構

1.建立一個乾淨的 ESP-IDF PID Control 專案如下:

adaptive_pid_voltage/

├── CMakeLists.txt # Top-level build script

├── sdkconfig # Build-generated config file

├── components/ # Reusable modules

│ └── pid_controller/

│ ├── CMakeLists.txt # PID component build script

│ ├── pid_controller.c # PID algorithm

│ └── pid_controller.h # PID API

├── main/

│ ├── CMakeLists.txt # Main app build script

│ ├── main.c # app_main and task setup

│ └── simulation.c # Controlled system simulation

└── README.md # Project overview


2.為了讓讀者更容易上手,本範例將 PID 演算法、ADC 讀取與 PWM 控制整合於同一個檔案(main.c)中。這樣的寫法更加直觀,方便快速理解與示範,適合初學者快速掌握核心概念。


●Adaptive PID 控制器程式碼

#include <stdio.h>

#include <math.h>

#include "freertos/FreeRTOS.h"

#include "freertos/task.h"

#include "esp_log.h"


static const char *TAG = "VoltagePID";


// PID parameters

float Kp = 1.0f, Ki = 0.5f, Kd = 0.1f;

float setpoint = 100.0f; // Target motor speed (RPM)

float integral = 0.0f;

float last_error = 0.0f;


// Simulated control output voltage (0 ~ 3.3V)

float control_voltage = 0.0f;


// Simulated feedback value (motor speed)

float motor_speed = 0.0f;


void update_pid(float input) {

float error = setpoint - input;

float delta_error = error - last_error;


// Adaptive gain tuning based on error magnitude

if (fabsf(error) > 50) {

Kp = 2.0f; Ki = 0.7f; Kd = 0.2f;

} else if (fabsf(error) > 20) {

Kp = 1.5f; Ki = 0.6f; Kd = 0.15f;

} else {

Kp = 1.0f; Ki = 0.5f; Kd = 0.1f;

}


integral += error;

float derivative = delta_error;


float raw_output = Kp * error + Ki * integral + Kd * derivative;


// Simulate control voltage output: clamp between 0V and 3.3V

control_voltage = raw_output / 100.0f; // Scale the output (depends on application)

if (control_voltage > 3.3f) control_voltage = 3.3f;

if (control_voltage < 0.0f) control_voltage = 0.0f;


last_error = error;


// Log output to monitor behavior

ESP_LOGI(TAG, "[PID] Speed: %.2f RPM | Error: %.2f | Kp: %.2f | Ki: %.2f | Kd: %.2f | Output Voltage: %.2f V",

input, error, Kp, Ki, Kd, control_voltage);

}


// Simulate motor response with inertia based on control voltage

void pid_task(void *arg) {

while (1) {

update_pid(motor_speed);


// Simulate motor acceleration (e.g., proportional to voltage)

float target_speed = control_voltage * 40.0f; // e.g., 3.3V -> ~132 RPM

motor_speed += (target_speed - motor_speed) * 0.05f; // Simulate inertia/delay


// Log the simulated speed for visualization

ESP_LOGI(TAG, "[SIM] Target Speed: %.2f RPM | Current Speed: %.2f RPM",

target_speed, motor_speed);


vTaskDelay(pdMS_TO_TICKS(100)); // Control cycle: 100 ms

}

}


void app_main(void) {

ESP_LOGI(TAG, "Starting Voltage-Controlled PID Simulation...");

xTaskCreate(pid_task, "pid_task", 4096, NULL, 5, NULL);

}

●編譯和燒錄

完成程式碼後,您可以使用 ESP-IDF 提供的命令進行編譯、燒錄和監控。

在 VS Code 的左下角 ESP-IDF 工具列:

1.點選 Build project

2.點選 Flash device

3.點選 Monitor device

●輸出說明

以下是模擬控制過程中的部份 log 輸出:

I (0) VoltagePID: Starting Voltage-Controlled PID Simulation…

I (100) VoltagePID: [PID] Speed: 0.00 RPM | Error: 100.00 | Kp: 2.00 | Ki: 0.70 | Kd: 0.20 | Output Voltage: 3.30 V

I (100) VoltagePID: [SIM] Target Speed: 132.00 RPM | Current Speed: 6.60 RPM

I (200) VoltagePID: [PID] Speed: 6.60 RPM | Error: 93.40 | Kp: 2.00 | Ki: 0.70 | Kd: 0.20 | Output Voltage: 3.30 V

I (1000) VoltagePID: [PID] Speed: 85.60 RPM | Error: 14.40 | Kp: 1.00 | Ki: 0.50 | Kd: 0.10 | Output Voltage: 1.82 V

I (1000) VoltagePID: [SIM] Target Speed: 72.80 RPM | Current Speed: 74.00 RPM

I (2000) VoltagePID: [PID] Speed: 98.20 RPM | Error: 1.80 | Kp: 1.00 | Ki: 0.50 | Kd: 0.10 | Output Voltage: 1.04 V

I (2000) VoltagePID: [SIM] Target Speed: 41.60 RPM | Current Speed: 97.00 RPM


●分析與說明:

1.大誤差時快速響應(起始階段)

一開始馬達尚未轉動,速度為 0 RPM,誤差達 100。此時 Adaptive PID 自動將增益調高(Kp=2.0),使輸出電壓直接飽和到 3.3V,系統加速快速,縮短反應時間。

2.中間誤差階段,控制穩定

當速度進入中間區段,例如誤差約 20~50 時,增益切換為中等(Kp=1.5),電壓輸出也開始降低,系統控制進入「快速收斂、但避免過衝」的平衡狀態。

3.小誤差時精細微調

當誤差小於 20(如 10 以下),控制器自動調整回較小增益(Kp=1.0),避免震盪與過調,讓馬達平穩收斂至設定值附近,控制電壓也相對更平滑。

4.自動增益調整避免手動調參

整個過程中,無需開發者手動調整 PID 參數。Adaptive PID 根據誤差範圍動態調整參數,讓系統既有響應速度,又能避免震盪或不穩。


【視頻】AI Revolution: Design PID Controllers Using DeepSeek-R1 AI Model

and Python Locally



raw-image









留言
avatar-img
留言分享你的想法!
avatar-img
跨元探索的沙龍
84會員
103內容數
跨領域探索分享
跨元探索的沙龍的其他內容
2025/07/08
●Ziegier-Nichois調整法 在1940年代, Ziegier 及Nichois 兩位工程師,基於控制系統在穩定性為臨界狀態時之行 為,提出增益參數之最佳化調整法。當PID 控制器被描述為下列形式 : 其中 三個參數增益值,可以下列程序決定 :
Thumbnail
2025/07/08
●Ziegier-Nichois調整法 在1940年代, Ziegier 及Nichois 兩位工程師,基於控制系統在穩定性為臨界狀態時之行 為,提出增益參數之最佳化調整法。當PID 控制器被描述為下列形式 : 其中 三個參數增益值,可以下列程序決定 :
Thumbnail
2025/07/02
●Google AI Studio到底是什麼?         AI Studio 是Google推出的人工智慧開發平臺,可自訂AI測試環境,供開發者試驗 AI 模型。目前,該測試平台可運行 13 種獨特的模型。這款工具可以根據您的需求調整複雜 程度或簡單程度。而且它完全免費! Goo
Thumbnail
2025/07/02
●Google AI Studio到底是什麼?         AI Studio 是Google推出的人工智慧開發平臺,可自訂AI測試環境,供開發者試驗 AI 模型。目前,該測試平台可運行 13 種獨特的模型。這款工具可以根據您的需求調整複雜 程度或簡單程度。而且它完全免費! Goo
Thumbnail
2025/06/22
Docker  與  n8n    簡介 ; █什麼是 n8n
Thumbnail
2025/06/22
Docker  與  n8n    簡介 ; █什麼是 n8n
Thumbnail
看更多
你可能也想看
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
就簡單介紹一下static
Thumbnail
就簡單介紹一下static
Thumbnail
本文介紹了Power Automate Desktop的變數型態轉換,解釋了什麼時候需要進行變數型態的轉換,並提供了文字轉換為數字、數字轉換為文字、文字轉換為日期、日期轉換為文字的功能與操作方式。
Thumbnail
本文介紹了Power Automate Desktop的變數型態轉換,解釋了什麼時候需要進行變數型態的轉換,並提供了文字轉換為數字、數字轉換為文字、文字轉換為日期、日期轉換為文字的功能與操作方式。
Thumbnail
本文介紹了在網站開發中如何運用狀態機的原則和設計方法。通過具體案例分析,以及狀態和數據的區分,詳細介紹了狀態機的設計原則和應用。讀者可以通過本文瞭解如何將狀態機應用於實際的網站開發中。
Thumbnail
本文介紹了在網站開發中如何運用狀態機的原則和設計方法。通過具體案例分析,以及狀態和數據的區分,詳細介紹了狀態機的設計原則和應用。讀者可以通過本文瞭解如何將狀態機應用於實際的網站開發中。
Thumbnail
隨著企業數位轉型的步伐加快,提升工作效率和降低成本成為了重要目標。 在這個過程中,RPA與API結合使用,為企業帶來了更高效、更智能的自動化解決方案。 RPAI 數位優化器將和大家一起探討RPA與API串接的應用,並分析其在不同領域中的實際效益。
Thumbnail
隨著企業數位轉型的步伐加快,提升工作效率和降低成本成為了重要目標。 在這個過程中,RPA與API結合使用,為企業帶來了更高效、更智能的自動化解決方案。 RPAI 數位優化器將和大家一起探討RPA與API串接的應用,並分析其在不同領域中的實際效益。
Thumbnail
本文介紹了Power Automate Desktop中的變數資料類型,包括簡單資料類型和進階資料類型,並提供了常見變數的用途和實際應用案例。這將有助於初學者更好地理解Power Automate Desktop的變數基本觀念,並期待下一篇文章將繼續介紹更多功能。
Thumbnail
本文介紹了Power Automate Desktop中的變數資料類型,包括簡單資料類型和進階資料類型,並提供了常見變數的用途和實際應用案例。這將有助於初學者更好地理解Power Automate Desktop的變數基本觀念,並期待下一篇文章將繼續介紹更多功能。
Thumbnail
Ae 小技巧:Adjustment Layer 調整圖層 動態後記系列會記錄一些我在製作中的記錄,可能是分解動畫、小技巧、發想、腳本......等等。 每篇都是小短篇,就是補充用的小筆記,沒有前後順序,可跳著閱讀。
Thumbnail
Ae 小技巧:Adjustment Layer 調整圖層 動態後記系列會記錄一些我在製作中的記錄,可能是分解動畫、小技巧、發想、腳本......等等。 每篇都是小短篇,就是補充用的小筆記,沒有前後順序,可跳著閱讀。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News