PID регулятор температуры. Климат контроль на Ардуино. Библиотека PID 48

В данной статье мы рассмотрим:

  • регулятор
  • Задачи, решаемые с помощью ПИД регулятора
  • Описание библиотеки PID регулятора
  • Создание климат контроля для автомобиля при помощи Ардуино

Что же такое PID регулятор?

WiKi Пропорционально-интегрально-дифференциальный (ПИД) регулятор — устройство в управляющем контуре с обратной связью. Используется в системах автоматического управления для формирования управляющего сигнала с целью получения необходимых точности и качества переходного процесса.

Не совсем понятная формулировка.

Возьмем некий объем, внутри которого будем изменять температуру воздуха, путем подачи воздуха разной температуры(управление при помощь сервы). Отрегулируем температуру воздуха в объеме до некого значения T и зафиксируем положение сервы — значение S. Теперь подадим в наш объем холодный воздух, в результате которого температура Т уменьшится на значение dT.

Получили исходные данные:

  • Температура Т
  • Положение сервы S
  • Изменение температуры dT

Задача: определить изменение положения сервы dS, для возврата исходной температуры T в объеме

Вот мы и подошли к задаче, которую решает ПИД-регулятор.

В виду того, что наша система инерционная, и возможны колебания температуры, то и положение сервы также должно быть колебательным, причем каждое новое колебание будет зависеть от dT.

ПИД-регулятор позволяет управлять нашей сервой в зависимости от текущей температуры и температуры, которую необходимо установить.

Помимо данной задачи ПИД-регулятор помогает решить такие задачи как:

  • балансировка квадрокоптера
  • ускорение и торможение двух-колесного устройства

Все задачи разные, но решаются при помощи ПИД-регулятора.

Для использования ПИД-регулятора в Ардуино воспользуемся библиотекой PID_v1

Описание функций библиотеки:

PID()
Создает ПИД регулятор

Синтаксис:

1
PID(&Input, &Output, &Setpoint, Kp, Ki, Kd, Direction)
PID(&Input, &Output, &Setpoint, Kp, Ki, Kd, Direction)

Параметры:
&Input(double) — Входящий сигнал, который мы контролируем
&Output(double) — Выходящий сигнал, которым мы управляем
&Setpoint(double) — Заданное значение контролируемого сигнала
Kp(double>=0) — пропорциональная составляющая пид-регулятора
Ki(double>=0) — интегральная составляющая пид-регулятора
Kd(double>=0) — дифференциальная составляющая пид-регулятора
Direction(DIRECT or REVERSE) направление изменения выходного сигнала

Compute()
Расчет выходного сигнала

Синтаксис:

1
Compute()
Compute()

Возвращает функция:
True: когда выходной сигнал рассчитан(расчет ведется с периодичностью заданной SetSampleTime)
False: когда ничего не было сделано

SetMode()
Устанавливает, будет ли ПИД-регулятор включен во время создания.
AUTOMATIC — будет, MANUAL — нет
По умолчанию ПИД-регулятор выключен.

Синтаксис:

1
SetMode(mode)
SetMode(mode)

Параметры:
mode(AUTOMATIC или MANUAL)

SetOutputLimits()
Устанавливает границы выходящего сигнала
по умолчанию это 0-255

Синтаксис:

1
SetOutputLimits(min, max)
SetOutputLimits(min, max)

Параметры:
min — минимальное значение, должно быть меньше max
max — максимальное значение, должно быть больше mix

SetTunings()
позволяет настраивать ПИД-регулятор во время работы

Синтаксис:

1
SetTunings(Kp, Ki, Kd)
SetTunings(Kp, Ki, Kd)

Параметры:
Kp(double>=0) — пропорциональная составляющая пид-регулятора
Ki(double>=0) — интегральная составляющая пид-регулятора
Kd(double>=0) — дифференциальная составляющая пид-регулятора

SetSampleTime()
задает частоту расчета выходного сигнала? по умолчанию 200 мили секунд

Синтаксис:

1
SetSampleTime(SampleTime)
SetSampleTime(SampleTime)

Параметры:
SampleTime — мили секунды >0

SetControllerDirection()
направление изменения выходного сигнала, когда начальный входящий сигнал меньше заданного — DIRECT, когда больше REVERSE

Синтаксис:

1
SetControllerDirection(Direction);
SetControllerDirection(Direction);

Параметры:
Direction(DIRECT или REVERSE)

Пример использования:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <PID_v1.h>
 
double Setpoint, Input, Output;
 
PID myPID(&Input, &Output, &Setpoint,1,4,3, DIRECT);
 
void setup()
{
Input = analogRead(0);
Setpoint = 27;
myPID.SetMode(AUTOMATIC);
}
 
void loop()
{
Input = analogRead(0);
myPID.Compute();
analogWrite(3,Output);
}
#include <PID_v1.h>

double Setpoint, Input, Output;

PID myPID(&Input, &Output, &Setpoint,1,4,3, DIRECT);

void setup()
{
Input = analogRead(0);
Setpoint = 27;
myPID.SetMode(AUTOMATIC);
}

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

Автомобильный на ардуино с использованием ПИД-регулятора

  1. Исходные данные
  2. Схема подключения
  3. Настройка ПИД-регулятора

Исходные данные для проектирования:

  • Автомобиль с кондиционером и тросиковым управлением заслонкой печки
  • Сервопривод
  • Ардуино
  • Датчик температуры

Схема подключения:
pid.png Сервопривод управляет заслонкой печки.

Скетч:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <PID_v1.h>//библиотека ПИД-ругулятора
#include //библиотека серво привода
 
double Setpoint, Input, Output;
 
 myservo;//серво привод
 
PID myPID(&Input, &Output, &Setpoint,8.6,0.5,1, DIRECT);//создаем ПИД-регулятор
 
boolean revers;
 
void setup()
{
Setpoint = 20;//заданная температура в салоне автомобиля
Input = analogRead(0)/9.31;//читаем показания с датчика температуры LM35
myPID.SetOutputLimits(0, 180);//устанавливаем границы выходного сигнала для ПИД-регулятора
if (Setpoint<Input){//если начальная температура больше заданной
revers=true;
myPID.SetControllerDirection(REVERSE);//ПИД-регулятор используем обратный
}
myPID.SetMode(AUTOMATIC);//включаем ПИД-регулятор
}
 
void loop()
{
Input = analogRead(0)/9.31;//анализируем температуру салона
myPID.Compute();//считаем выходной сигнал ПИД-регулятора
myservo.attach(3,630,2540);//включаем серву на 3 цифровом пине, с длинной импульса от 630 до 2540(указываем границы поворота сервы)
if (revers)//если пид регулятор обратный, то сервой управляем также относительно противоположной крайней точки
myservo.write(180-Output);
else
myservo.write(Output);
delay(1000);//ждем серву
myservo.detach();//отключаемся от сервы
}
#include <PID_v1.h>//библиотека ПИД-ругулятора
#include //библиотека серво привода

double Setpoint, Input, Output;

Servo myservo;//серво привод

PID myPID(&Input, &Output, &Setpoint,8.6,0.5,1, DIRECT);//создаем ПИД-регулятор

boolean revers;

void setup()
{
Setpoint = 20;//заданная температура в салоне автомобиля
Input = analogRead(0)/9.31;//читаем показания с датчика температуры LM35
myPID.SetOutputLimits(0, 180);//устанавливаем границы выходного сигнала для ПИД-регулятора
if (Setpoint<Input){//если начальная температура больше заданной
revers=true;
myPID.SetControllerDirection(REVERSE);//ПИД-регулятор используем обратный
}
myPID.SetMode(AUTOMATIC);//включаем ПИД-регулятор
}

void loop()
{
Input = analogRead(0)/9.31;//анализируем температуру салона
myPID.Compute();//считаем выходной сигнал ПИД-регулятора
myservo.attach(3,630,2540);//включаем серву на 3 цифровом пине, с длинной импульса от 630 до 2540(указываем границы поворота сервы)
if (revers)//если пид регулятор обратный, то сервой управляем также относительно противоположной крайней точки
myservo.write(180-Output);
else
myservo.write(Output);
delay(1000);//ждем серву
myservo.detach();//отключаемся от сервы
}

Настройка ПИД-регулятора:
Вот мы и подошли к последнему, самому сложному этапу проектирования — Настройка ПИД-регулятора.
Останавливаться на этой теме не будем, в сети есть множество способов. От себя скажу, что настраивал методом подбора и измерений, в результате чего подобрал оптимальные параметры ПИД-регулятора указанные в скетче.

48 комментс для “PID регулятор температуры. Климат контроль на Ардуино. Библиотека PID

  1. Ответить Дмитрий Май 24, 2015 16:01

    Пробую пример на Ардуино мега 2560, сменил только ноги

    #include

    double Setpoint, Input, Output;

    PID myPID(&Input, &Output, &Setpoint,1,4,3, DIRECT);

    void setup()
    {
    pinMode(A0, INPUT);
    pinMode(7, OUTPUT);
    Input = analogRead(0);
    Setpoint = 27;
    myPID.SetMode(AUTOMATIC);
    }

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

    на выходе 7 всегда 0. Где что почитать чтобы разобраться

    • Ответить Slava Май 26, 2015 09:15

      Дело в том, что должна быть реакция системы, если вы изменяете выходной сигнал, значит должен ОБЯЗАТЕЛЬНО измениться входной

      У Вас задано значение 27, текущее, к примеру, > 27, следовательно выходной сигнал будет стремиться к нулю, до тех пор пока значение на входе не начнет приближаться к заданному.

      Т.е. без реально работающей системы протестировать нельзя…

      Выведете в сериал input и output + добавьте задержку

    • Ответить Василий Авг 29, 2017 12:58

      Это надо убрать:
      pinMode(A0, INPUT);
      pinMode(7, OUTPUT);

  2. Ответить Дмитрий Май 26, 2015 12:34

    На в вводе стоит термосопротивление (с +5в 9к и подгружено на ноль 10к). Напряжение на А0 меняется от 2.7 до 3.2. После команды map input меняется от 20 до 30, Мне кажется input меняется в достаточном диапазоне для отладки и понимания работы программы. Спасибо.

    • Ответить Slava Май 27, 2015 19:59

      возможно коэффициенты выбраны не правильно…
      еще попробуйте отфильтровать значения равные нулю… т.е. выводит если не ноль
      if (!Output==0.00) Serial.write(Output, DEC);

  3. Ответить Тимур Июл 2, 2015 18:56

    Делаю ИК паялку, все почти собрал, и дошло дело до ПИД. Библиотека возвращает значение от 0 до 255, а если у меня реле? И мне нужно знать включать его или выкючать. Как перейти в релейный режим? Как в пидах овен например

  4. Ответить Тимур Дек 23, 2015 01:43

    Ну и что я выставляю там 1 и все равно она как то тупо работает
    http://vk.com/omicoms
    напишите кто шарит мне

  5. Ответить serg Дек 27, 2015 15:33

    немного изменил скетч. Slava подправил.

    #include //библиотека ПИД-ругулятора
    #include //библиотека серво привода
    #include
    #include
    #define ONE_WIRE_BUS 8
    OneWire oneWire (ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);
    double Setpoint, Input, Output;

    Servo myservo;//серво привод

    PID myPID(&Input, &Output, &Setpoint,15,1,3, DIRECT);//создаем ПИД-регулятор

    boolean revers;

    int valrez;//slava
    int output_old;
    void setup()
    {
    Serial.begin (9600);
    sensors.begin();

    Input = digitalRead(8);//читаем показания с датчика температуры ds18b20
    myPID.SetOutputLimits(0, 60);//устанавливаем границы выходного сигнала для ПИД-регулятора
    myPID.SetMode(AUTOMATIC);//включаем ПИД-регулятор

    if (Setpoint<Input)

    if (Setpoint<Input){//если начальная температура больше заданной
    revers=true;
    }
    myPID.SetControllerDirection(REVERSE);//ПИД-регулятор используем обратный
    }

    void loop()
    {
    valrez=analogRead(A0);//потенцеометр для уставки желаемой температуры в салоне
    Setpoint= map(valrez,0,1023,18,30);//читаем положение регулятора температуры(потенциометр)

    sensors.requestTemperatures();
    Input =(sensors.getTempCByIndex(0));//анализируем температуру салона,заданная температура в салоне автомобиля
    myPID.Compute();//считаем выходной сигнал ПИД-регулятора
    if (Output!=output_old){//если нужно управлять сервой
    myservo.attach(9,2540,640);//включаем серву на 9 цифровом пине.
    if (revers)//если пид регулятор обратный, то сервой управляем также относительно противоположной крайней точки
    myservo.write(60-Output);
    else
    myservo.write(Output);
    delay(1000);//ждем серву
    myservo.detach();//отключаемся от сервы.

    output_old=Output;
    }
    Serial.print("Output: ");
    Serial.print(Output);
    Serial.print(" Actual Temp: ");
    Serial.println(Input);
    Serial.print(" ystanovka t : ");
    Serial.println (Setpoint);
    }

  6. Ответить Алексей Фев 21, 2016 14:42

    А возможно с помощью этой библиотеки сделать ПИД регулятор на два канала, то есть например регулировать одновременно сразу две разные температуры?

    • Ответить Slava Фев 21, 2016 15:03

      Да. В скетче создаете 2 пид регулятора

      • Ответить Алексей Фев 22, 2016 13:19

        А можно пример, а то я пробовал и второй просто повторяет первый.

        • Ответить Slava Мар 17, 2016 15:35

          double Setpoint2, Input2, Output2;
          double Setpoint3, Input3, Output3;
          double Setpoint4, Input4, Output4;

          PID myPID2(&Input, &Output, &Setpoint,15,1,3, DIRECT);//создаем ПИД-регулятор
          PID myPID3(&Input2, &Output2, &Setpoint2,15,1,3, DIRECT);//создаем ПИД-регулятор
          PID myPID4(&Input3, &Output3, &Setpoint3,15,1,3, DIRECT);//создаем ПИД-регулятор

          и далее по аналогии

  7. Ответить Виктор Мар 11, 2016 18:26

    Что нада поменять если поставить датчик TMP36

    • Ответить Slava Мар 17, 2016 15:32

      Вместо
      Input = analogRead(0)/9.31;//анализируем температуру салона

      Input = Данные с вашего датчика

  8. Ответить Алексей Июн 9, 2016 09:44

    Много читал,собрал из кусков скетч пид регулятора температуры газовой колонки (задолбали скачки давления).Регулирует хорошо.Помогите,нужно,чтоб регулирование включалось при подаче 3-х вольт на пин (в программировании-0)

    #include
    #include //пид регулятор
    double Setpoint, Input, Output;

    Servo myservo;//серво привод

    PID myPID(&Input, &Output, &Setpoint,1.8,3,0.1, DIRECT);//создаем ПИД-регулятор

    boolean revers;

    int output_old;
    int termalPin=A5;

    void setup()
    {
    Serial.begin (9600);

    Input = map(analogRead(termalPin),800,635,31,51);
    myPID.SetOutputLimits(0, 40);//устанавливаем границы выходного сигнала для ПИД-регулятора
    myPID.SetMode(AUTOMATIC);//включаем ПИД-регулятор

    if (Setpoint<Input)

    if (Setpoint<Input){//если начальная температура больше заданной
    revers=true;
    }
    myPID.SetControllerDirection(DIRECT);//ПИД-регулятор используем
    }

    void loop()
    {
    Setpoint= 41;

    Input =map(analogRead(termalPin),800,635,31,51);//анализируем температуру
    myPID.Compute();//считаем выходной сигнал ПИД-регулятора
    if (Output!=output_old){//если нужно управлять сервой
    myservo.attach(9,1500,640);//включаем серву на 9 цифровом пине.
    if (revers)//если пид регулятор обратный, то сервой управляем также относительно противоположной крайней точки
    myservo.write(40-Output);
    else
    myservo.write(Output);
    delay(1000);//ждем серву
    myservo.detach();//отключаемся от сервы.

    output_old=Output;
    }
    Serial.print("Output: ");
    Serial.print(Output);
    Serial.print(" Actual Temp: ");
    Serial.println(Input);
    Serial.print(" ystanovka t : ");
    Serial.println (Setpoint);
    }

  9. Ответить Алексей Июн 9, 2016 14:21

    подать на 8 пин

    • Ответить Slava Июн 9, 2016 14:27

      Чтобы померить напряжение, нужно подавать сигнал на один из Аналоговых входов
      А0-А6

      тогда все что у вас помещено в блок void loop{}

      нужно поместить во внутрь if

      void loop()
      {
      if (map(analogRead(номер аналогового пина),1024,0,5,0)>=3)
      {
      //текущее содержимое void loop
      }
      }

  10. Ответить Алексей Июн 9, 2016 14:33

    Мне не нужно мерить, нужно при подаче запустить регулирование, а при сня тии остановить. Как я понял ,типа этого «if (digitalRead(1)==HIGH){«

  11. Ответить Алексей Июн 9, 2016 14:42

    вставлял — не работает, наверное не в то место….
    …………..
    void loop()
    {
    if (digitalRead(1)==HIGH){
    Setpoint= 41;

    Input =map(analogRead(termalPin),800,635,31,51);//анализируем температуру
    …………….

  12. Ответить Slava Июн 9, 2016 15:00

    1. проверить номер пина if (digitalRead(номер пина)==HIGH){
    2. проверить сигнал который вы пытаетесь проверить, действительно ли там постоянные 3v
    3. проверить питание контроллера, если оно отличное от 5v возможно не правильно срабатывает digitalRead

  13. Ответить Алексей Июн 9, 2016 15:29

    Огрмное спасибо. Нужно было пин на землю подтянуть. Все заработало)))))

  14. Ответить void Авг 29, 2016 20:03

    добрый день

    было бы правильнее в описаниях функций указывать параметры «по умолчанию»
    как то:

    SetMode(mode=MANUAL)
    SetOutputLimits(min=0, max=255)
    SetSampleTime(SampleTime=200)

  15. Ответить Сергей Дек 15, 2016 16:29

    Ищу простое и дешевое решение для контроля температуры в рефрежераторной камере
    так что бы схема+скетч
    подскажите МК+ацп+датчик температуры еще что то нужно?

  16. Ответить Денис Янв 31, 2017 17:01

    Доброго времени.
    Запустил этот скетч

    #include
    #include //пид регулятор
    #include
    #include
    #define ONE_WIRE_BUS 8
    OneWire oneWire (ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);
    double Setpoint, Input, Output;

    Servo myservo;//серво привод

    PID myPID(&Input, &Output, &Setpoint,15,1,3, DIRECT);//создаем ПИД-регулятор

    boolean revers;

    int valrez;//slava
    int output_old;
    void setup()
    {
    Serial.begin (9600);
    sensors.begin();

    Input = digitalRead(8);//читаем показания с датчика температуры ds18b20
    myPID.SetOutputLimits(0,60);//устанавливаем границы выходного сигнала для ПИД-регулятора
    myPID.SetMode(AUTOMATIC);//включаем ПИД-регулятор

    if (Setpoint<Input)

    if (Setpoint<Input){//если начальная температура больше заданной
    revers=true;
    }
    myPID.SetControllerDirection(REVERSE);//ПИД-регулятор используем обратный
    }

    void loop()
    {
    valrez=analogRead(A0);//потенцеометр для уставки желаемой температуры в салоне
    Setpoint= map(valrez,0,1023,25,80);//читаем положение регулятора температуры(потенциометр)

    sensors.requestTemperatures();
    Input =(sensors.getTempCByIndex(0));//анализируем температуру салона,заданная температура в салоне автомобиля
    myPID.Compute();//считаем выходной сигнал ПИД-регулятора
    if (Output!=output_old){//если нужно управлять сервой
    myservo.attach(9,2540,640);//включаем серву на 9 цифровом пине.
    if (revers)//если пид регулятор обратный, то сервой управляем также относительно противоположной крайней точки
    myservo.write(60-Output);
    else
    myservo.write(Output);
    delay(1000);//ждем серву
    myservo.detach();//отключаемся от сервы.

    output_old=Output;
    }
    Serial.print("Output: ");
    Serial.print(Output);
    Serial.print(" Actual Temp: ");
    Serial.println(Input);
    Serial.print(" ystanovka t : ");
    Serial.println (Setpoint);

    Вопрос как вместо монитора последовательного порта, подключить LiquidCrystal_I2C
    Зарастание благодарен.

  17. Ответить валерий Фев 7, 2017 17:03

    Здравствуйте может кто поможет мне надо реализовать так называемый погодный компенсатор на ардуино
    цель два датчика температуры один на отоплении а второй на улице .
    уличный датчик должен изменять уставку в пид регуляторе для отопления

    • Ответить Slava Фев 9, 2017 09:59

      Воспользуйтесь функцией

      SetTunings()
      позволяет настраивать ПИД-регулятор во время работы

      Синтаксис:

      SetTunings(Kp, Ki, Kd)
      Параметры:
      Kp(double>=0) — пропорциональная составляющая пид-регулятора
      Ki(double>=0) — интегральная составляющая пид-регулятора
      Kd(double>=0) — дифференциальная составляющая пид-регулятора

  18. Ответить Денис Мар 7, 2017 19:24

    Можно ли уйти от
    delay(1000);//ждем серву
    на Millis, при простое не реагирует на кнопки и т.д.

  19. Ответить Денис Мар 7, 2017 20:37

    можно ли
    delay(1000);//ждем серву
    заменить на millis?

    • Ответить Slava Мар 8, 2017 10:31

      millis — Получение времени работы контроллера в миллисекундах от его включения.

      Придется часть программы переписывать

  20. Ответить Денис Мар 9, 2017 08:55

    Прям так координально)

  21. Ответить Денис Мар 11, 2017 20:03

    unsigned long time;
    void setup()
    {
    time = millis();
    }

    void loop()
    {

    myPID.Compute();
    myservo.attach(9,250,750);
    if (revers)
    myservo.write(90-Output);
    else
    myservo.write(Output);

    if (millis() — time >= 3000) {
    myservo.detach();
    time = millis();
    }
    Все не касающееся millis опустил, вроде залил работает, примерно так будет?

  22. Ответить Дмитрий Сен 20, 2017 08:30

    Здравствуйте.
    Подскажите пожалуйста, что я не правильно понимаю в работе PID-регулятора.
    При значениях Pk = 1, Ik = 0, Dk = 0 — выход разве ни должен всегда оставаться равный разности установленной и действительным значением на входе PID-регулятора.

  23. Ответить Дмитрий Сен 20, 2017 09:05

    /********************************************************** * Arduino PID Library — Version 1.1.1
    * by Brett Beauregard brettbeauregard.com
    *
    * This Library is licensed under a GPLv3 License
    *********************************************************/
    Вот и я думал должен, а не дает. Второй день бьюсь, ни чего не получается.

  24. Ответить Дмитрий Сен 20, 2017 09:37

    Это нужно?

    bool PID::Compute()
    {
    if(!inAuto) return false;
    unsigned long now = millis();
    unsigned long timeChange = (now — lastTime);
    if(timeChange>=SampleTime)
    {
    /*Compute all the working error variables*/
    double input = *myInput;
    double error = *mySetpoint — input;
    double dInput = (input — lastInput);
    outputSum+= (ki * error);

    /*Add Proportional on Measurement, if P_ON_M is specified*/
    if(!pOnE) outputSum-= kp * dInput;

    if(outputSum > outMax) outputSum= outMax;
    else if(outputSum outMax) output = outMax;
    else if(output < outMin) output = outMin;
    *myOutput = output;

    /*Remember some variables for next time*/
    lastInput = input;
    lastTime = now;
    return true;
    }
    else return false;
    }

  25. Ответить Дмитрий Сен 20, 2017 12:55

    По факту, постоянно растет, начинает от 0 и до максимума со скоростью в зависимости от разности уставки и темп-ры.

  26. Ответить Дмитрий Сен 20, 2017 13:05

    bool PID::Compute()
    {
    if(!inAuto) return false;
    unsigned long now = millis();
    unsigned long timeChange = (now — lastTime);
    if(timeChange>=SampleTime)
    {
    /*Compute all the working error variables*/
    double input = *myInput;
    double error = *mySetpoint — input;
    double dInput = (input — lastInput);
    outputSum+= (ki * error);

    /*Add Proportional on Measurement, if P_ON_M is specified*/
    if(!pOnE) outputSum-= kp * dInput;

    if(outputSum > outMax) outputSum= outMax;
    else if(outputSum outMax) output = outMax;
    else if(output < outMin) output = outMin;
    *myOutput = output;

    /*Remember some variables for next time*/
    lastInput = input;
    lastTime = now;
    return true;
    }
    else return false;
    }

    выход вычесляется где-то сдесь:

    /*Add Proportional on Error, if P_ON_E is specified*/
    double output;
    if(pOnE) output = kp * error;
    else output = 0;

    /*Compute Rest of PID Output*/
    output += outputSum — kd * dInput;

    и пока грешу все на outputSum

Добавить комментарий