PID-regulering i praksis: Kontroller motorer og temperaturer

MiddelsKode på GitHub6 min lesetid

PID-regulering er kanskje det mest brukte verktøyet i reguleringsteknikk, men mange makere kopierer bare kode uten å forstå hva som egentlig skjer under panseret. La oss se på dette sammen — fra matematikken bak til fungerende Arduino-kode du kan bruke i egne prosjekter.

Hva du trenger

  • Arduino Uno, Nano eller tilsvarende mikrokontroller
  • DC-motor med enkoder (for motoreksempelet)
  • Motordriver (f.eks. L298N eller TB6612FNG)
  • NTC-termistor eller DS18B20 (for temperatureksempelet)
  • Effekttransistor/MOSFET eller SSR til varmeelement
  • Multimeter og eventuelt et seriellt plotteverktøy

Hva er egentlig PID-regulering?

PID står for Proporsjonal, Integral og Derivert — tre bidrag som til sammen beregner hvor mye «innsats» systemet ditt skal gi for å nå et ønsket settpunkt. Enten du styrer motorhastighet, temperatur, eller balansen på en robot, er prinsippet det samme: mål avviket (feilen), og korriger deretter.

Formelen ser slik ut:

output = Kp*e(t) + Ki*∫e(t)dt + Kd*de(t)/dt

P — Proporsjonal

Den proporsjonale leddet gir en respons som er direkte proporsjonal med feilen akkurat nå. Stor feil gir kraftig korrigering, liten feil gir svak korrigering. Problemet med ren P-regulering er at systemet ofte stabiliserer seg med et lite avvik fra settpunktet — kalt steady-state error.

I — Integral

Integralleddet akkumulerer feilen over tid. Dette fjerner steady-state-feilen fordi selv en liten vedvarende feil til slutt bygger seg opp til noe integralleddet reagerer på. Baksiden er at for høy Ki kan gi overshoot og oscillasjon — og her kommer også windup-problemet vi tar for oss senere.

D — Derivert

Deriveringsleddet ser på hvor raskt feilen endrer seg, og bremser responsen før settpunktet nås — som en dempende kraft. Dette reduserer overshoot, men er også svært følsomt for støy i målingen. Mange praktiske implementasjoner filtrerer D-leddet eller utelater det helt for støyfulle sensorer.

Tips: Start alltid med kun P-regulering, legg til I når du ser vedvarende avvik, og legg til D kun hvis du sliter med overshoot. Å tune alle tre samtidig er unødvendig komplisert.

Tuning-metoder som faktisk fungerer

Å finne riktige Kp, Ki og Kd-verdier kalles tuning, og det finnes flere tilnærminger:

1. Manuell tuning (anbefalt for hobbyprosjekter)

  1. Sett Ki og Kd til 0
  2. Øk Kp gradvis til systemet begynner å oscillere jevnt rundt settpunktet
  3. Reduser Kp til ca. 50-60% av denne verdien
  4. Øk Ki forsiktig til steady-state-feilen forsvinner, uten at oscillasjonen kommer tilbake
  5. Legg til Kd om nødvendig for å dempe overshoot

2. Ziegler-Nichols-metoden

En klassisk, mer strukturert metode. Du finner den kritiske forsterkningen (Ku) der systemet oscillerer stabilt uten I og D, og perioden (Tu) på oscillasjonen. Deretter beregnes PID-parametrene ut fra faste forholdstall (Kp = 0.6*Ku, Ki = 2*Kp/Tu, Kd = Kp*Tu/8). Metoden gir ofte et aggressivt utgangspunkt som må finjusteres videre.

3. Autotuning-biblioteker

For Arduino finnes biblioteker som PID_AutoTune_v0 som automatiserer prosessen ved å måle systemets respons. Nyttig når du har mange enheter som skal tunes likt, men gir sjelden perfekte verdier alene.

Tips: Loggfør alltid settpunkt og faktisk verdi over tid i Serial Plotter i Arduino IDE. Å se kurven visuelt gjør tuning enormt mye lettere enn å gjette fra tall alene.

Arduino-implementasjon fra bunnen

Du kan bruke det etablerte biblioteket PID_v1 av Brett Beauregard, som er godt dokumentert og mye brukt i industrien. Her er en enkel implementasjon:

#include <PID_v1.h>

double Setpoint, Input, Output;
double Kp = 2.0, Ki = 5.0, Kd = 1.0;

PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

void setup() {
  Setpoint = 100;
  myPID.SetMode(AUTOMATIC);
  myPID.SetOutputLimits(0, 255);
}

void loop() {
  Input = analogRead(A0);
  myPID.Compute();
  analogWrite(9, Output);
}

Biblioteket håndterer sampling-tid, output-begrensning og til og med anti-windup internt, men det er verdifullt å forstå hva som skjer under panseret.

Praktisk eksempel: Motorhastighetskontroll

La oss anta du har en DC-motor med enkoder koblet til motordriveren din. Målet er konstant turtall uavhengig av last.

  1. Les enkoderpulser og beregn RPM over et fast tidsintervall (f.eks. 50 ms)
  2. Sett dette som Input i PID-koden
  3. Setpoint er ønsket RPM
  4. Output styrer PWM-signalet til motordriveren (0–255)

Med kun P-regulering vil motoren typisk stabilisere seg litt under ønsket hastighet ved belastning. Legg til I-leddet, og den kryper opp til korrekt verdi over noen hundre millisekunder.

Trenger du komponenter til dette oppsettet, finner du både motorer og motordrivere i RoboNordic sin nettbutikk under kategoriene motorer og elektronikk.

Anti-windup — et must for I-leddet

Integral windup oppstår når systemet ikke klarer å nå settpunktet raskt nok (f.eks. motoren er fysisk blokkert, eller varmeelementet har begrenset effekt), og integralleddet fortsetter å akkumulere feil i det uendelige. Når feilen til slutt reverseres, tar det unødvendig lang tid før output faller tilbake — resultatet er kraftig overshoot.

De vanligste løsningene er:

  • Clamping: Begrens den akkumulerte integralsummen til et fornuftig maksimum/minimum
  • Back-calculation: Reduser integralsummen aktivt når output er mettet (saturert)
  • Conditional integration: Stopp akkumulering av I-leddet helt når output ligger på grensen

PID_v1-biblioteket håndterer dette automatisk via SetOutputLimits(), men skriver du egen kode, må du implementere dette manuelt — ellers får du store problemer spesielt i temperaturregulering der oppvarming er treg.

Tips: Test alltid systemet ditt med en kraftig, brå forstyrrelse (blokker motoren et sekund, eller åpne et vindu ved temperaturregulering) for å se hvordan anti-windup-logikken oppfører seg i praksis.

Settpunkt (ønsket verdi) Feil e(t) = mål − verdi PID-regulator P-ledd I-ledd D-ledd Sum + Anti-windup Aktuator (motor/varme) Sensor (enkoder/temp)

Vanlige feil

  • For høy Kp uten filter: Gir aggressiv, hakkete respons og kan skade mekaniske komponenter over tid
  • Ignorerer sampling-tid: PID-beregninger må skje med konsistent tidsintervall, ellers blir spesielt D-leddet upålitelig
  • Glemmer anti-windup: Fører til kraftig overshoot etter at systemet har vært mettet en stund
  • Bruker rå, ufiltrert sensordata til D-leddet: Støy blir forsterket og gir uforutsigbar output
  • Tuner i simulert miljø uten å teste under reell last: En motor uten belastning oppfører seg helt annerledes enn en som driver et hjul med friksjon

Avsluttende tanker

PID-regulering er enkel i teorien, men krever praktisk erfaring å mestre. Start smått — bygg motorhastighetsregulatoren først, forstå hvordan de tre leddene påvirker responsen din, og bygg deretter videre til mer komplekse systemer som temperaturkontroll med treg respons. Dokumentasjonen til PID_v1-biblioteket på GitHub, samt Ziegler-Nichols’ originale artikkel fra 1942, er gode referanser å lene seg på når du vil gå dypere.

Koden på GitHub
All kode fra denne guiden – kompilert og klar til bruk – ligger i det åpne repoet vårt: robonordic-prosjekter/regulering/pid-regulering

Mer om robotikk og styring

Se alle →