Управление скоростью вентилятора с помощью библиотеки Arduino PID

Я хочу создать схему, которая регулирует скорость вращения вентилятора постоянного тока, используя библиотеку PID Arduino, чтобы получить вещь при определенной температуре.

Схема выглядит так, но ее можно изменить: двигатель вентилятора постоянного тока подключен к ШИМ 3, а термистор подключен к контакту A0.

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

Случай 1

Когда нагреватель не работает, значение термистора в последовательном мониторе составляет 0-1023, когда вентилятор не работает, он показывает 1023, а когда вентилятор работает на полной скорости, он дает около 0.

Случай 2

Но когда нагреватель работает, значения термистора изменились, и когда вентилятор не работает, он дает 1023, а когда вентилятор работает на полной скорости, он дает около 500.

Я хочу установить точку 650 по значению термистора (входное значение), а скорость вентилятора должна регулироваться с помощью pid, чтобы температура регулировалась, а термистор выдавал значение 650.

Пример кода PID

 #include <PID_v1.h>
// Определяем переменные, которые мы будем подключать к double Setpoint, Input, Output;
//Определяем агрессивные и консервативные параметры настройки
double aggKp=4, aggKi=0.2, aggKd=1;
double consKp=1, consKi=0.05, consKd=0.25;
//Указываем ссылки и параметры начальной настройки
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);
void setup()
{
  Serial.begin(115200);
  // инициализируем переменные, с которыми мы связаны
  Input = map(analogRead(0), 0, 1023, 255, 0);
  Setpoint = 650;
  myPID.SetOutputLimits(0, 255);
  // включаем PID
  myPID.SetMode(AUTOMATIC);
}
void loop()
{
  int sensorValue = analogRead(0);
  Input = map(analogRead(0), 0, 1023, 255, 0);
    double gap = abs(Setpoint-Input); //расстояние от заданного значения
  if(gap<10)
  {  //мы близки к заданному значению, используйте консервативные параметры настройки
    myPID.SetTunings(consKp, consKi, consKd);
  }
  else
  {
     //мы далеки от уставки, используйте агрессивные параметры настройки
     myPID.SetTunings(aggKp, aggKi, aggKd);
  }
  myPID.Compute();
  analogWrite(3,Output);
  Serial.println(sensorValue);
}

Какие изменения нужно внести в код, чтобы мы могли устанавливать точки из входных значений? И Пожалуйста, помогите мне, чтобы этот код работал для меня.

, 👍4

Обсуждение

Вы не можете подключить двигатель напрямую к выходному контакту (если только это не очень маленький двигатель). Вам также необходимо обратноходовой диод к двигателю. Я предполагаю, что двигатель создает много «шума» на шине питания, что приводит к странным значениям AnalogRead., @Gerben


5 ответов


1

Сначала попробуйте использовать внешний источник питания для питания мотора, так как к источнику питания Arduino можно подключить только очень маленькие моторы. питание для правильной работы Arduino)
Если это не поможет, измените код (к завтрашнему дню я дам пример кода, если вы не сможете найти его сами) — возможно, используйте ШИМ-сигнал вместо того, чтобы пытаться использовать ПИД-регулятор, так как это намного проще и дает очень мало места для ошибки. А также не забудьте про обратный диод, упомянутый Гербеном.

,

Вы не прочитали вопрос полностью, я знаю, что выход двигателя постоянного тока всегда представляет собой ШИМ-сигнал для управления скоростью. Я хочу использовать библиотеку PID для обнаружения ошибки между заданным значением и текущим значением температуры и изменения скорости двигателя в соответствии с этим значением., @ANKIT JAIN

Я знал, что вы, очевидно, знаете, что выход на двигатель постоянного тока всегда является ШИМ-сигналом, я хотел сказать вам, чтобы вы оставили библиотеку ПИД и написали свой собственный код, чтобы он действовал как ПИД., @Mathsman 100

Я пробовал это, и это работает достаточно легко., @Mathsman 100

[ссылка](http://www.homofaciens.de/technics-computer-arduino-uno_en_navion.htm), @Mathsman 100


2

Две вещи, которые могут быть полезны. Сначала убедитесь, что у вас есть общий язык. Например, для вашего транзистора вы используете отдельное питание от arduino и источника 12 вольт. Подключение двух заземлений Arduino и источника питания может решить эту проблему. Во-вторых, часто бывает полезно подключить конденсатор к двигателю постоянного тока, чтобы уменьшить колебания напряжения.

,

Но основания *соединены* на схеме..., @CharlieHanson


-1

Возможно, лучше не использовать map(), так как это вызовет проблемы между использованием переменных float и int — сделайте это вручную в коде.

,

Это и комментарий, а не ответ, и тоже ошибочный. Карта Arduino() в целочисленной функции. Совершенно законно инициализировать переменную с плавающей запятой целым значением., @Chris Stratton


0

Есть некоторые проблемы с вашей командой карты.

Например, вы считываете значение термистора с помощью analogRead(A0), который имеет диапазон возврата от 0 до 1023. После этого вы пытаетесь использовать map() изменить это значение на 0–255, но использовать неправильный синтаксис. Правильный синтаксис этой команды: Input = map(analogRead(0), 0, 1023, 0, 255);. Однако я не вижу причины этого, потому что вы читаете значения 0-1023, измените их на 0-255, но заданное значение равно 650. Таким образом, вы никогда не получите заданное значение, потому что максимальное значение равно 255.

Попробуйте использовать в качестве входных данных только analogread(0). Нет необходимости изменять входной сигнал в диапазоне ШИМ, а вывод по умолчанию предназначен для библиотеки ПИД в диапазоне ШИМ, поэтому вы можете отправлять выходные данные непосредственно на вывод двигателя. Конечно, используйте какой-нибудь H-мост или что-то в этом роде.

,

0
//Теперь все будет работать
// https://arduino.stackexchange.com/questions/9731/control-speed-of-dc-fan-using-arduino-pid-library

#include <PID_v1.h>
double Setpoint, Input, Output;  //нет в исходном скетче
// Определяем переменные, которые мы будем подключать к double Setpoint, Input , Output;
//Определяем агрессивные и консервативные параметры настройки
double aggKp = 4, aggKi = 0.2, aggKd = 1;
double consKp = 1, consKi = 0.05, consKd = 0.25;
//двойной consKp=2, consKi=5, consKd=1;

//Указываем ссылки и параметры начальной настройки
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, REVERSE);
void setup()
{
  Serial.begin(9600);
  // инициализируем переменные, с которыми мы связаны
  // Ввод = карта (аналоговое чтение (0), 0, 1023, 255, 0);

  //целое значение = AnalogRead(0);
  //val = map(val, 0, 1023, 0, 255);
  // аналогЗапись(9, значение);

  Setpoint = 100;
  myPID.SetOutputLimits(0, 255); //МИН МАКС
  // включаем PID
  myPID.SetMode(AUTOMATIC);  // РУКОВОДСТВО
  myPID.SetControllerDirection(REVERSE);  // ПРЯМОЙ
}
void loop()
{
  int sensorValue = analogRead(0);
  Input = map(sensorValue, 0, 1023, 0, 255);

  double gap = abs(Setpoint - Input); //расстояние от заданного значения
  if (gap < 10)
  { //мы близки к заданному значению, используйте консервативные параметры настройки
    myPID.SetTunings(consKp, consKi, consKd);
  }
  else
  {
    //мы далеки от уставки, используйте агрессивные параметры настройки
    myPID.SetTunings(aggKp, aggKi, aggKd);
  }

  myPID.Compute();
  analogWrite(3, Output);
  Serial.print(" PWM = ");
  Serial.print(Output,0);
  Serial.print("       sensor value =  ");
  Serial.print(sensorValue);
  Serial.print("       Input =");
  Serial.println(Input,0);
}
,