Source: https://mokxi.com/libraries/pid
Updated: 2026-11-02

Libraries / Data and time
Arduino library · Data and time

# The Arduino PID library: hold a temperature, speed or position

PID_v1, by Brett Beauregard, is the PID controller behind most Arduino temperature, motor speed and self-balancing tutorials. You give it three variables by address (the measured input, the output it should drive, and the setpoint you want) and three gains, Kp, Ki and Kd. Every time Compute() runs it reads the input, works out the error from the setpoint, and writes a new output.

Open the example in the editor See the calls

Built in on Mokxi: #include <PID_v1.h> and it builds, with nothing to install. Free, and no account needed.

## What PID does

It was written to avoid the classic beginner mistakes. Compute() only acts once per sample time (100 ms by default) so the gains mean the same thing however fast loop() runs. The integral is clamped to the output limits, 0 to 255 unless you change them, so it cannot wind up while an output is saturated. The derivative uses the change in the input rather than the error, so moving the setpoint does not kick the output.

The controller starts in MANUAL and does nothing until SetMode(AUTOMATIC). Use DIRECT when a bigger output raises the input (a heater) and REVERSE when it lowers it (a cooling fan).

Library Manager name | PID

Author | Brett Beauregard

Include | #include <PID_v1.h>

Boards | every board Mokxi compiles for but ATtiny85

In the simulator | Simulated: it runs against the part the way it does on the bench.

## Install it

It builds on every board Mokxi compiles for but ATtiny85.

In Mokxi it is built in: #include <PID_v1.h> and the sketch compiles, with no download, no zip and no Library Manager.

On a real board, install "PID" by Brett Beauregard from the Arduino IDE’s Library Manager (Sketch, Include Library, Manage Libraries), or add PID to lib_deps in PlatformIO. Mokxi follows the calls of release 1.2.1, so a sketch written here builds there too.

ESP32-C3 · Arduino Uno · Arduino Nano · Arduino Mega 2560 · Arduino Leonardo · SparkFun Pro Micro · Arduino Micro · ESP32-C6 · Raspberry Pi Pico · Raspberry Pi Pico W · Seeed XIAO SAMD21 · STM32 · STM32 Nucleo-F411RE · STM32 Blue Pill · micro:bit V2 · Arduino Uno R4 · ESP32 DevKit · ESP32-S3-DevKitC-1 · ESP8266 NodeMCU · Arduino Pro Mini 3.3 V · Seeed XIAO ESP32-C3 · ESP32-C3 SuperMini · Seeed XIAO ESP32-C6 · ESP32-DevKitC V4 · LOLIN32 Lite · Wemos D1 R32 · Cheap Yellow Display · TTGO T-Display · Seeed XIAO ESP32-S3 · Arduino Nano ESP32 · Arduino Nano RP2040 Connect · Seeed XIAO RP2040 · Waveshare RP2040-Zero · Arduino Uno R4 WiFi

## The calls you will use

In the order a sketch meets them.

### PID myPID(&Input, &Output, &Setpoint, 2, 5, 1, DIRECT);

A controller on three double variables, with Kp 2, Ki 5 and Kd 1. The variables are passed by address, so the library reads and writes them directly.

### myPID.SetMode(AUTOMATIC)

Turns the controller on. MANUAL turns it off and leaves Output to the sketch; switching back is bumpless.

### myPID.Compute()

Call it on every pass of loop(). It returns true when it recalculated the output and false when the sample time has not passed yet.

### myPID.SetTunings(Kp, Ki, Kd)

Changes the gains while running, for tuning from Serial or a pot.

### myPID.SetOutputLimits(0, 255)

The range Output is held to. Use -255 to 255 for a motor that can reverse, or 0 to 1 for a time-proportioned relay.

### myPID.SetSampleTime(50)

How often Compute() acts, in milliseconds.

### myPID.SetControllerDirection(REVERSE)

Flips the action, for a process where more output lowers the input.

### myPID.GetKp()

Reads back a gain; GetKi(), GetKd() and GetMode() do the same for the others.

## Example: A PID controller holds a simulated heater at 100

On the Arduino Uno R3. It runs in the browser exactly as printed.

sketch.ino · Arduino Uno R3

Open it in the editor, wired and ready to run

## Common errors and how to fix them

### Output stays at 0 and never changes

The controller is still in MANUAL, or Compute() is not called in loop(). Call SetMode(AUTOMATIC) in setup() after giving Input and Setpoint their first values, and call Compute() every loop.

### The output swings from one limit to the other and never settles

The gains are too high for the process. Start with Ki and Kd at 0, raise Kp until it just begins to oscillate, halve it, then add a little Ki to remove the offset and Kd only if it overshoots.

### The output goes the wrong way, heating harder as it gets hotter

The controller direction does not match the process. Use REVERSE when increasing the output decreases the input, such as a fan cooling a sensor.

### no matching function for call to 'PID::PID(int*, int*, int*, ...)'

The library works on doubles. Declare Input, Output and Setpoint as double, convert sensor readings into them, and pass their addresses with &.

## Keep going

### Learn

- Arduino millis(): Timers and Multiple Tasks

### More data and time libraries

- QRCode
- Madgwick
- TimerOne
- MsTimer2
- Low-Power
- RTClib
- DS1307RTC
- DS3231 (NorthernWidget) and DS3231 (Rinky-Dink Electronics)

Every built-in library · Open the editor

## Try PID without installing anything

Open the example, change the sketch, and keep your version in a free account.

Start building free

Open the editor
