{"id":23220791,"url":"https://github.com/lily-osp/autotunepid","last_synced_at":"2025-08-04T16:33:26.412Z","repository":{"id":267752002,"uuid":"902239291","full_name":"lily-osp/AutoTunePID","owner":"lily-osp","description":"The AutoTunePID library is an easy-to-use library for Arduino IDE that provides a powerful PID (Proportional, Integral, Derivative) controller with built-in auto-tuning capabilities.","archived":false,"fork":false,"pushed_at":"2025-05-10T10:54:45.000Z","size":155,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-05-10T11:30:37.558Z","etag":null,"topics":["arduino-library","automation","control-systems","pid-control","pid-tuning"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lily-osp.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-12-12T07:20:35.000Z","updated_at":"2025-05-10T05:15:01.000Z","dependencies_parsed_at":"2024-12-12T08:25:25.987Z","dependency_job_id":"cfd7c43a-7ccc-402f-836f-9d703803c72f","html_url":"https://github.com/lily-osp/AutoTunePID","commit_stats":null,"previous_names":["lily-osp/autotunepid"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/lily-osp/AutoTunePID","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lily-osp%2FAutoTunePID","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lily-osp%2FAutoTunePID/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lily-osp%2FAutoTunePID/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lily-osp%2FAutoTunePID/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lily-osp","download_url":"https://codeload.github.com/lily-osp/AutoTunePID/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lily-osp%2FAutoTunePID/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268723073,"owners_count":24296544,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-04T02:00:09.867Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino-library","automation","control-systems","pid-control","pid-tuning"],"created_at":"2024-12-18T22:14:03.358Z","updated_at":"2025-08-04T16:33:26.382Z","avatar_url":"https://github.com/lily-osp.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AutoTunePID Library\n\nA robust, feature-rich PID control library for Arduino that implements advanced auto-tuning algorithms, signal filtering, anti-windup, and operational modes for flexible control.\n\n---\n\n## Features\n\n- **Comprehensive PID Control**\n  \n  - Real-time PID calculations with configurable update intervals.\n  - Constrained output range to ensure system safety.\n  - Support for both auto-tuning and manual parameter configuration.\n\n- **Multiple Auto-Tuning Methods**:\n  \n  - **Ziegler-Nichols**: Determines ultimate gain (Ku) and oscillation period (Tu) using observed output extremes.\n  - **Cohen-Coon**: Fine-tunes Ku and Tu with alternative multipliers for better initial performance.\n  - **IMC (Internal Model Control)**: Balances system robustness and responsiveness using a lambda tuning parameter.\n  - **Tyreus-Luyben**: Provides robust tuning with minimal overshoot, ideal for systems requiring stability.\n  - **Lambda Tuning (CLD)**: Optimizes systems with significant dead time using process time constant (T) and dead time (L).\n\n- **Operational Modes**:\n  \n  - **Normal**: Standard PID operation.\n  - **Reverse**: Reverses the error calculation for cooling systems.\n  - **Hold**: Stops all calculations to save resources.\n  - **Preserve**: Minimal calculations to keep the system responsive.\n  - **Tune**: Performs auto-tuning to determine `Tu` and `Ku`.\n  - **Auto**: Automatically selects the best operational mode based on system behavior.\n\n- **Oscillation Modes**:\n  \n  - **Normal**: Full oscillation (`MaxOutput - MinOutput`).\n  - **Half**: Half oscillation (`1/2 MaxOutput - 1/2 MinOutput`).\n  - **Mild**: Mild oscillation (`1/4 MaxOutput - 1/4 MinOutput`).\n\n- **Signal Filtering**:\n  \n  - Configurable input and output signal filters using exponential moving averages.\n  - Adjustable alpha values for filter responsiveness (range: 0.01–1.0).\n\n- **Anti-Windup**:\n  \n  - Prevents integral windup by constraining the integral term when the output is saturated.\n  - Configurable threshold for anti-windup behavior.\n\n- **Safety and Reliability**:\n  \n  - Output values are constrained within specified bounds.\n  - Fixed interval updates ensure stability.\n  - Protected filter parameters to prevent invalid configurations.\n\n---\n\n## Installation\n\n1. Download the library as a ZIP file.\n2. In the Arduino IDE, go to **Sketch \u003e Include Library \u003e Add .ZIP Library**.\n3. Select the downloaded ZIP file.\n4. Restart the Arduino IDE.\n\n---\n\n## Quick Start\n\n```cpp\n#include \u003cAutoTunePID.h\u003e\n\n// Initialize PID controller with output range and tuning method\nAutoTunePID pid(0, 255, TuningMethod::ZieglerNichols);\n\nvoid setup() {\n  pid.setSetpoint(100.0); // Target setpoint\n  pid.enableInputFilter(0.1); // Optional input filtering\n  pid.enableAntiWindup(true, 0.8); // Enable anti-windup with 80% threshold\n  pid.setOscillationMode(OscillationMode::Normal); // Set oscillation mode to Normal\n  pid.setOperationalMode(OperationalMode::Tune); // Set operational mode to Tune\n}\n\nvoid loop() {\n  float input = analogRead(A0); // Read input\n  pid.update(input); // Update the PID controller\n  analogWrite(PWM_PIN, pid.getOutput()); // Write output\n}\n```\n\n---\n\n## API Reference\n\n### Core Functions\n\n#### Initialization\n\n```cpp\nAutoTunePID(float minOutput, float maxOutput, TuningMethod method = TuningMethod::ZieglerNichols);\n```\n\n- `minOutput`: Lower bound for controller output.\n- `maxOutput`: Upper bound for controller output.\n- `method`: Auto-tuning method selection (default: Ziegler-Nichols).\n\n#### Control Configuration\n\n```cpp\nvoid setSetpoint(float setpoint); // Set the desired setpoint\nvoid setTuningMethod(TuningMethod method); // Change the tuning method\nvoid setManualGains(float kp, float ki, float kd); // Set manual PID gains\n```\n\n#### Signal Filtering\n\n```cpp\nvoid enableInputFilter(float alpha);  // Enable input filtering (alpha range: 0.01-1.0)\nvoid enableOutputFilter(float alpha); // Enable output filtering (alpha range: 0.01-1.0)\n```\n\n#### Anti-Windup\n\n```cpp\nvoid enableAntiWindup(bool enable, float threshold = 0.8f); // Enable/disable anti-windup with optional threshold\n```\n\n#### Operational Modes\n\n```cpp\nvoid setOperationalMode(OperationalMode mode); // Set the operational mode\n```\n\n#### Oscillation Modes\n\n```cpp\nvoid setOscillationMode(OscillationMode mode); // Set the oscillation mode for auto-tuning\nvoid setOscillationSteps(int steps); // Set the number of oscillation steps for auto-tuning\n```\n\n#### Runtime Operations\n\n```cpp\nvoid update(float currentInput); // Update at minimum 100ms intervals\nfloat getOutput(); // Get the current output value\n```\n\n#### Parameter Access\n\n```cpp\nfloat getKp(); // Get the proportional gain (Kp)\nfloat getKi(); // Get the integral gain (Ki)\nfloat getKd(); // Get the derivative gain (Kd)\nfloat getKu(); // Get the ultimate gain (Ku)\nfloat getTu(); // Get the oscillation period (Tu)\nfloat getSetpoint(); // Get the current setpoint\n```\n\n---\n\n## Advanced Auto-Tuning Methods\n\nThe library implements five distinct auto-tuning algorithms:\n\n1. **Ziegler-Nichols**:\n   \n   - Oscillates the system to determine Ku and Tu based on output extremes.\n   - Calculates PID gains:\n     - $ K_p = 0.6 \\cdot Ku $\n     - $ K_i = \\frac{1.2 \\cdot K_p}{Tu} $\n     - $ K_d = 0.075 \\cdot K_p \\cdot Tu $\n\n2. **Cohen-Coon**:\n   \n   - Alternative multipliers provide better transient response.\n   - Gains are calculated as:\n     - $ K_p = 0.8 \\cdot Ku $\n     - $ K_i = \\frac{K_p}{0.8 \\cdot Tu} $\n     - $ K_d = 0.194 \\cdot K_p \\cdot Tu $\n\n3. **IMC (Internal Model Control)**:\n   \n   - Incorporates a smoothing factor ('λ') to adjust response speed:\n     - $ K_p = 0.4 \\cdot Ku $\n     - $ K_i = \\frac{K_p}{2 \\cdot \\lambda} $\n     - $ K_d = 0.5 \\cdot K_p \\cdot \\lambda $\n\n4. **Tyreus-Luyben**:\n   \n   - Provides robust tuning with minimal overshoot:\n     - $ K_p = 0.45 \\cdot Ku $\n     - $ K_i = \\frac{K_p}{2.2 \\cdot Tu} $\n     - $ K_d = 0.0 $ (No derivative term)\n\n5. **Lambda Tuning (CLD)**:\n   \n   - Optimizes systems with significant dead time:\n     - $ K_p = \\frac{T}{K(\\lambda + L)} $\n     - $ K_i = \\frac{K_p}{T} = \\frac{1}{K(\\lambda + L)} $\n     - $ K_d = K_p \\cdot 0.5L = \\frac{0.5L \\cdot T}{K(\\lambda + L)} $\n\n---\n\n## Signal Filtering\n\nFilters smooth inputs and outputs using an exponential moving average:\n\n- $\\text{filteredValue} = (\\alpha \\cdot \\text{input}) + ((1 - \\alpha) \\cdot \\text{filteredValue})$\n- $ \\alpha $: Responsiveness of the filter (range: 0.01–1.0).\n\n---\n\n## Example Applications\n\n### 1. Ziegler-Nichols Example: Temperature Control\n\n```cpp\n#include \u003cAutoTunePID.h\u003e\nAutoTunePID tempController(0, 255, TuningMethod::ZieglerNichols);\n\nvoid setup() {\n  tempController.setSetpoint(75.0); // Target temperature\n  tempController.enableInputFilter(0.1); // Enable input filtering\n  tempController.enableAntiWindup(true, 0.8); // Enable anti-windup\n  tempController.setOscillationMode(OscillationMode::Normal); // Set oscillation mode to Normal\n  tempController.setOperationalMode(OperationalMode::Tune); // Set operational mode to Tune\n}\n\nvoid loop() {\n  float temp = readTemperature(); // Read temperature sensor\n  tempController.update(temp); // Update PID controller\n  analogWrite(HEATER_PIN, tempController.getOutput()); // Control heater\n  delay(100);\n}\n```\n\n### 2. Cohen-Coon Example: Motor Speed Control\n\n```cpp\n#include \u003cAutoTunePID.h\u003e\nAutoTunePID motorController(0, 255, TuningMethod::CohenCoon);\n\nvoid setup() {\n  motorController.setSetpoint(1500); // Target RPM\n  motorController.enableInputFilter(0.2); // Enable input filtering\n  motorController.enableAntiWindup(true, 0.7); // Enable anti-windup\n  motorController.setOscillationMode(OscillationMode::Half); // Set oscillation mode to Half\n  motorController.setOperationalMode(OperationalMode::Tune); // Set operational mode to Tune\n}\n\nvoid loop() {\n  float rpm = readEncoderSpeed(); // Read motor speed\n  motorController.update(rpm); // Update PID controller\n  analogWrite(MOTOR_PIN, motorController.getOutput()); // Control motor\n  delay(100);\n}\n```\n\n### 3. IMC Example: Pressure Control\n\n```cpp\n#include \u003cAutoTunePID.h\u003e\nAutoTunePID pressureController(0, 255, TuningMethod::IMC);\n\nvoid setup() {\n  pressureController.setSetpoint(100.0); // Target pressure\n  pressureController.enableInputFilter(0.1); // Enable input filtering\n  pressureController.enableAntiWindup(true, 0.8); // Enable anti-windup\n  pressureController.setOscillationMode(OscillationMode::Normal); // Set oscillation mode to Normal\n  pressureController.setOperationalMode(OperationalMode::Tune); // Set operational mode to Tune\n}\n\nvoid loop() {\n  float pressure = readPressureSensor(); // Read pressure sensor\n  pressureController.update(pressure); // Update PID controller\n  analogWrite(PUMP_PIN, pressureController.getOutput()); // Control pump\n  delay(100);\n}\n```\n\n### 4. Tyreus-Luyben Example: Chemical Reactor Temperature Control\n\n```cpp\n#include \u003cAutoTunePID.h\u003e\nAutoTunePID reactorController(0, 255, TuningMethod::TyreusLuyben);\n\nvoid setup() {\n  reactorController.setSetpoint(80.0); // Target reactor temperature\n  reactorController.enableInputFilter(0.1); // Enable input filtering\n  reactorController.enableAntiWindup(true, 0.8); // Enable anti-windup\n  reactorController.setOscillationMode(OscillationMode::Half); // Set oscillation mode to Half\n  reactorController.setOperationalMode(OperationalMode::Tune); // Set operational mode to Tune\n}\n\nvoid loop() {\n  float temp = readReactorTemperature(); // Read reactor temperature\n  reactorController.update(temp); // Update PID controller\n  analogWrite(HEATER_PIN, reactorController.getOutput()); // Control heater\n  delay(100);\n}\n```\n\n### 5. Lambda Tuning Example: Flow Control\n\n```cpp\n#include \u003cAutoTunePID.h\u003e\nAutoTunePID flowController(0, 255, TuningMethod::LambdaTuning);\n\nvoid setup() {\n  flowController.setSetpoint(50.0); // Target flow rate\n  flowController.enableInputFilter(0.15); // Enable input filtering\n  flowController.enableAntiWindup(true, 0.9); // Enable anti-windup\n  flowController.setOscillationMode(OscillationMode::Mild); // Set oscillation mode to Mild\n  flowController.setOperationalMode(OperationalMode::Tune); // Set operational mode to Tune\n}\n\nvoid loop() {\n  float flowRate = readFlowSensor(); // Read flow sensor\n  flowController.update(flowRate); // Update PID controller\n  analogWrite(VALVE_PIN, flowController.getOutput()); // Control valve\n  delay(100);\n}\n```\n\n---\n\n## Performance Considerations\n\n- Update interval fixed at 100ms for stability.\n- Filter alpha values impact system responsiveness.\n- Auto-tuning duration configurable (default: 5 seconds).\n- Memory footprint optimized (~40 bytes per instance).\n\n---\n\n## Detailed Explanation\n\n- For more details about the algorithms used in the library, read [here](docs/explanation.md).\n- For more details about the library usage, read [here](docs/usage.md).\n- For more details about manual tuning, read [here](docs/manual.md).\n- And For those who seek the Flowchart and the state diagram of the library u can see here:\n  - [Flowchart](docs/flowchart.mermaid)\n  - [State diagram](docs/state-diagram.mermaid)\n\n---\n\n## Contributing\n\nContributions are welcome! Please follow these steps:\n\n1. Fork the repository.\n2. Create a feature branch.\n3. Submit a pull request.\n\n---\n\n## License\n\nThis project is licensed under the MIT License. See [LICENSE](LICENSE) file for details.\n\n---\n\n## Support\n\nFor bug reports and feature requests, please use the [GitHub issue tracker](https://github.com/lily-osp/AutoTunePID/issues).\n\nFor technical questions, contact: azzar.mr.zs@gmail.com\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flily-osp%2Fautotunepid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flily-osp%2Fautotunepid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flily-osp%2Fautotunepid/lists"}