Климат контроль на Arduino. Пид регулятор.Скетч. 40

Исходные данные:

  • автомобиль
  • заслонка управляющая температурой обдуваемого воздуха
  • сервопривод с углом поворота не менее 180 градусов 
  • температурный датчик Dallas DS18B20
  • потенциометр для задания нужной температуры

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//Автомобильный , по принципу управления заслонкой
//www.bigbarrel.ru
// разработан для контроллера Attiny85 или 
#include <.h>
#include <_v1.h>//пид регулятор
#include <OneWire.h>
#include <.h>
 
#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float tempC;//текущая температура
float temp_old = 0;//старое значение текущей температуры
int val; //угол поворота мотора
int val_old;//старый угол поворота мотора
Servo myservo;//серво привод
double Setpoint, Input, Output;//переменные для пид регулятора
PID myPID(&Input, &Output, &Setpoint,1,0.4,90, DIRECT);//пид регулятор. Очень важно правильно подобрать коэффициенты пид регулятора
 
void setup() {
    sensors.begin();
    myPID.SetOutputLimits(1, 255);//устанавливаем пределы для выходного сигнала пид регулятора
    myservo.attach(3,2540,640);//устанавливаем пин управления servo/устанавливаем границы поворота сервы
    val_old=-100;
}
int sp(){
    return map(analogRead(1),255,1023,15,27);//читаем положение регулятора температуры(потенциометр)
}
void loop() {
    if (digitalRead(1)==HIGH){
        sensors.requestTemperatures();
        tempC =sensors.getTempCByIndex(0); //получаем температуру с датчика
        if (abs(tempC-temp_old)>0.1){
            Input = tempC;
            temp_old=tempC;
        } else {
            Input=temp_old;
        }
        if (Setpoint!=sp()){
            Setpoint=sp();
        }
        myPID.Compute();
        delay(20);
        if (!Output==0.00){
            val=map(Output, 1, 255, 0, 180);
            if (abs(val-val_old)>4){
                val_old=val;
                myservo.write(val);//управляем мотором
                delay(200);
            }
        }else{
            val=val_old;
        }
    } else {
    delay(10000);
    }
}
//Автомобильный климат контроль, по принципу управления заслонкой
//www.bigbarrel.ru
//скетч разработан для контроллера Attiny85 или Arduino
#include <Servo.h>
#include <PID_v1.h>//пид регулятор
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float tempC;//текущая температура
float temp_old = 0;//старое значение текущей температуры
int val; //угол поворота мотора
int val_old;//старый угол поворота мотора
Servo myservo;//серво привод
double Setpoint, Input, Output;//переменные для пид регулятора
PID myPID(&Input, &Output, &Setpoint,1,0.4,90, DIRECT);//пид регулятор. Очень важно правильно подобрать коэффициенты пид регулятора

void setup() {
	sensors.begin();
	myPID.SetOutputLimits(1, 255);//устанавливаем пределы для выходного сигнала пид регулятора
	myservo.attach(3,2540,640);//устанавливаем пин управления servo/устанавливаем границы поворота сервы
	val_old=-100;
}
int sp(){
	return map(analogRead(1),255,1023,15,27);//читаем положение регулятора температуры(потенциометр)
}
void loop() {
	if (digitalRead(1)==HIGH){
		sensors.requestTemperatures();
		tempC =sensors.getTempCByIndex(0); //получаем температуру с датчика
		if (abs(tempC-temp_old)>0.1){
			Input = tempC;
			temp_old=tempC;
		} else {
			Input=temp_old;
		}
		if (Setpoint!=sp()){
			Setpoint=sp();
		}
		myPID.Compute();
		delay(20);
		if (!Output==0.00){
			val=map(Output, 1, 255, 0, 180);
			if (abs(val-val_old)>4){
				val_old=val;
				myservo.write(val);//управляем мотором
				delay(200);
			}
		}else{
			val=val_old;
		}
	} else {
	delay(10000);
	}
}

Кривая изменения температуры:

Безымянный.png

Более подробно о сервоприводах и пид регуляторах поговорим в следующих статьях.

40 комментс для “Климат контроль на Arduino. Пид регулятор.Скетч.

  1. Ответить Vladimir Окт 30, 2014 16:22

    Приветствую. Я начинающий ардуинщик. Поясните, как работает это условие: if (!Output==0.00) ?
    Т.е. что означает Не перед Output?

    • Ответить Slava Окт 31, 2014 00:47

      это означает отрицание условия, т.е. не выполнение условия

      Output==0.00 — условие выполняется (true)
      !Output==0.00(или Output!=0.00) — условие не выполняется (false)

  2. Ответить seriy Июн 9, 2015 22:19

    пишет ошибка компиляции

  3. Ответить seriy Июн 11, 2015 18:04

    sketch_jun11a.ino:3:35: fatal error: PID_v1.h: No such file or directory
    compilation terminated.
    Ошибка компиляции.

  4. Ответить seriy Июн 12, 2015 17:09

    Установил библиотеку и вот PID_AdaptiveTunings.ino:7:31: fatal error: DallasTemperature.h: No such file or directory
    compilation terminated.
    Ошибка компиляции.

  5. Ответить seriy Июн 12, 2015 17:34

    sketch_jun12a.ino:7:31: fatal error: DallasTemperature.h: No such file or directory
    compilation terminated.
    Ошибка компиляции.

  6. Ответить seriy Июн 14, 2015 15:12

    Slava спасибо большое

  7. Ответить seriy Июн 14, 2015 15:13

    но всеравно не работает

  8. Ответить seriy Июн 17, 2015 20:37

    C:\Users\1\Desktop\arduino-nightly-windows\arduino-nightly\libraries\PID_v1\PID_v1.cpp:8:22: fatal error: WProgram.h: No such file or directory
    #include
    ^
    compilation terminated.
    Ошибка компиляции.

    • Ответить Slava Июн 18, 2015 09:21

      замените WProgram.h на Arduino.h в файле PID_v1.cpp

      или так

      #if ARDUINO >= 100
      #include «Arduino.h»
      #else
      #include «WProgram.h»
      #endif

  9. Ответить Serg Дек 6, 2015 22:21

    Всем е! Я начинающий ардуиншик. У меня такая проблема,серва не реагирует на изменение температуры.В этом коде ничего не изменял. Что мне нужно настроить?

    • Ответить Slava Дек 6, 2015 22:39

      В каком положении стоит мотор? Что показывает датчик температуры? На цифровом входе 1есть логическая единица?
      Проверка входа номер один
      if (digitalRead(1)==HIGH){

      Потенциометр правильно подключен?

      • Ответить Алексей Дек 19, 2015 05:17

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

        • Ответить Slava Дек 19, 2015 11:43

          Прошу прощения. Статья писалась на скорую руку для drive2.

          На первый цифровой вход подайте +5 — это включить управление. Когда на нем 0, управление отключено.

      • Ответить serg Дек 20, 2015 19:25

        //ВОТ ЧТО Я ИЗМЕНИЛ.НА ЦИФРОВОМ ВХОДЕ ЕСТЬ ЛОГ 1.
        //Автомобильный климат контроль, по принципу управления заслонкой
        //www.bigbarrel.ru
        //скетч разработан для контроллера Attiny85 или Arduino
        #include
        #include //пид регулятор
        #include
        #include

        #define ONE_WIRE_BUS 8
        OneWire oneWire(ONE_WIRE_BUS);
        DallasTemperature sensors(&oneWire);
        LiquidCrystalRus lcd (12, 11, 5, 4, 3, 2);
        float tempC;//текущая температура
        float temp_old = 0;//старое значение текущей температуры
        int val; //угол поворота мотора
        int val_old;//старый угол поворота мотора
        Servo myservo;//серво привод
        double Setpoint, Input, Output;//переменные для пид регулятора
        PID myPID(&Input, &Output, &Setpoint,1,0.4,90, DIRECT);//пид регулятор. Очень важно правильно подобрать коэффициенты пид регулятора

        void setup() {
        lcd.begin(16,4);
        sensors.begin();
        myPID.SetOutputLimits(1, 255);//устанавливаем пределы для выходного сигнала пид регулятора
        myservo.attach(9,2540,640);//устанавливаем пин управления servo/устанавливаем границы поворота сервы
        val_old=-100;
        }
        int sp(){
        return map(analogRead(0),255,1023,15,27);//читаем положение регулятора температуры(потенциометр)
        }
        void loop() {
        if (digitalRead(1)==HIGH){
        sensors.requestTemperatures();
        tempC =sensors.getTempCByIndex(0);//получаем температуру с датчика
        lcd.setCursor(0, 1); // Устанавливаем курсор в начало 1 строки
        lcd.print(«CLIMAT «);
        lcd.print(Setpoint);

        lcd.print(«SALON TEM «);
        lcd.print(tempC,0);
        lcd.setCursor(30,0);

        if (abs(tempC-temp_old)>0.1){
        Input = tempC;
        temp_old=tempC;
        } else {
        Input=temp_old;
        }
        if (Setpoint!=sp()){
        Setpoint=sp();
        }
        myPID.Compute();
        delay(20);
        if (!Output==0.00)
        {
        val=map(Output, 1, 255, 0, 180);
        if (abs(val-val_old)>4)
        {
        val_old=val;
        myservo.write(val);//управляем мотором
        delay(200);
        }
        }else{
        val=val_old;
        }
        } else {
        delay(10000);
        }
        }

        • Ответить serg Дек 20, 2015 19:30

          всё равно не работает.

          • Ответить Slava Дек 20, 2015 22:49

            В момент изменения температуры какое значение Output?
            Есть возможность в Serial вывести значения температуры и Output?

            • Ответить Serg Дек 21, 2015 07:20

              Значение output выводили.оно не меняется.это меня тоже удивило. Показывает 0.00

            • Ответить serg Дек 21, 2015 19:15

              где мне копать?

            • Ответить Slava Дек 21, 2015 21:29

              1 можно убрать delay(10000);
              или изменить на 1000 это задержка опроса и управления.
              2 проверить какое значение возвращает sp();
              3 внутри if (!Output==0.00){ сделать вывод Output и проверить чему оно равно, когда не ноль
              4 проверить работу серво с настройками myservo.attach(3,2540,640);
              myservo.write(val); val от 0 до 180
              5 Серво подключен на 3й пин
              6 Поставить заданную температуру больше фактической
              7 Изменить коэффициенты пид регулятора PID myPID(&Input, &Output, &Setpoint,1,0.4,90, DIRECT)
              например 2,5,1

            • Ответить serg Дек 23, 2015 19:14

              Слав! Скинь пожалуйста код который показываешь в видео! можно на почту cgserg@mail.ru. я уже всё перепробывал ни чего не работает.

  10. Ответить Алексей Дек 19, 2015 11:05

    Слава вы еще здесь?
    А как сделать стабилизатор оборотов бензогенератора? Суть та-же только вместо датчика температуры- датчик холла. Требуется 3000 об.мин стабилизация. Управление дроссельной заслонкой с сервомашинки. Так-же резистором выставил нужное количество оборотов.

    • Ответить Slava Дек 19, 2015 11:40

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

      Советую опробовать пид регулятор на светодиоде и фоторезисторе, а уже потом переходить на серво привод.

      Постараюсь в скором времени написать еще статью по пид регулированию с простыми примерами.

  11. Ответить Slava Дек 19, 2015 11:27

    Посмотрите более простой пример со схемой http://bigbarrel.ru/arduino_pid/

  12. Ответить Андрей Апр 15, 2016 07:46

    Скажите, заморочено ли использование шаговика вместо сервы В программном решении?

  13. Ответить Александр Янв 6, 2017 10:27

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

    ИМХО, без энкодера — чушь.

    • Ответить Slava Янв 15, 2017 20:01

      Все зависит от того, какая будет дискретность устанавливаться.

      Проблем с регулировкой у меня нет.

  14. Ответить сергей Фев 6, 2017 18:34

    хочу собрать климатконтроль на авто,но схемы нет(где взять?

  15. Ответить NLObP Мар 18, 2017 20:53

    На счет шагового мотора, вместо сервы. Это возможно?

    • Ответить Slava Мар 20, 2017 12:58

      Возможно.

      Просто напишите функцию позиционирования шагового двигателя и передавайте ей положение

  16. Ответить NLObP Мар 18, 2017 21:53

    Поддерживаю функцию, добавить шаговый мотор вместо сервы.

  17. Ответить Евгений Мар 28, 2017 16:31

    Это как сделать?

  18. Ответить mihey1n1 Апр 10, 2017 21:16

    Не хватает в Setup строки myPID.SetMode(AUTOMATIC);
    Вот и не работает.

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