Управление скоростью вентилятора с помощью библиотеки 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);
}
Какие изменения нужно внести в код, чтобы мы могли устанавливать точки из входных значений? И Пожалуйста, помогите мне, чтобы этот код работал для меня.
@ANKIT JAIN, 👍4
Обсуждение5 ответов
Сначала попробуйте использовать внешний источник питания для питания мотора, так как к источнику питания Arduino можно подключить только очень маленькие моторы. питание для правильной работы Arduino)
Если это не поможет, измените код (к завтрашнему дню я дам пример кода, если вы не сможете найти его сами) — возможно, используйте ШИМ-сигнал вместо того, чтобы пытаться использовать ПИД-регулятор, так как это намного проще и дает очень мало места для ошибки.
А также не забудьте про обратный диод, упомянутый Гербеном.
Вы не прочитали вопрос полностью, я знаю, что выход двигателя постоянного тока всегда представляет собой ШИМ-сигнал для управления скоростью. Я хочу использовать библиотеку PID для обнаружения ошибки между заданным значением и текущим значением температуры и изменения скорости двигателя в соответствии с этим значением., @ANKIT JAIN
Я знал, что вы, очевидно, знаете, что выход на двигатель постоянного тока всегда является ШИМ-сигналом, я хотел сказать вам, чтобы вы оставили библиотеку ПИД и написали свой собственный код, чтобы он действовал как ПИД., @Mathsman 100
Я пробовал это, и это работает достаточно легко., @Mathsman 100
[ссылка](http://www.homofaciens.de/technics-computer-arduino-uno_en_navion.htm), @Mathsman 100
Две вещи, которые могут быть полезны. Сначала убедитесь, что у вас есть общий язык. Например, для вашего транзистора вы используете отдельное питание от arduino и источника 12 вольт. Подключение двух заземлений Arduino и источника питания может решить эту проблему. Во-вторых, часто бывает полезно подключить конденсатор к двигателю постоянного тока, чтобы уменьшить колебания напряжения.
Но основания *соединены* на схеме..., @CharlieHanson
Возможно, лучше не использовать map()
, так как это вызовет проблемы между использованием переменных float
и int
— сделайте это вручную в коде.
Это и комментарий, а не ответ, и тоже ошибочный. Карта Arduino() в целочисленной функции. Совершенно законно инициализировать переменную с плавающей запятой целым значением., @Chris Stratton
Есть некоторые проблемы с вашей командой карты.
Например, вы считываете значение термистора с помощью analogRead(A0)
, который имеет диапазон возврата от 0 до 1023. После этого вы пытаетесь использовать map()
изменить это значение на 0–255, но использовать неправильный синтаксис. Правильный синтаксис этой команды: Input = map(analogRead(0), 0, 1023, 0, 255);
. Однако я не вижу причины этого, потому что вы читаете значения 0-1023, измените их на 0-255, но заданное значение равно 650. Таким образом, вы никогда не получите заданное значение, потому что максимальное значение равно 255.
Попробуйте использовать в качестве входных данных только analogread(0)
. Нет необходимости изменять входной сигнал в диапазоне ШИМ, а вывод по умолчанию предназначен для библиотеки ПИД в диапазоне ШИМ, поэтому вы можете отправлять выходные данные непосредственно на вывод двигателя. Конечно, используйте какой-нибудь H-мост или что-то в этом роде.
//Теперь все будет работать
// 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);
}
- Попытка контролировать скорость двигателя постоянного тока с помощью ПИД
- Как устранить шум от вентилятора 12 В с ШИМ-управлением на низкой скорости
- ПИД-регулятор для управления скоростью двигателя
- Как управлять 6 шаговыми двигателями с помощью Arduino?
- Не могу контролировать скорость двигателей постоянного тока с помощью analogWrite()
- Можно ли использовать цифровые контакты в качестве выхода ШИМ?
- Как Arduino Uno может поддерживать до 12 сервоприводов, если у него всего 6 цифровых выводов ШИМ?
- L298N издает звуковые сигналы и дает сбой при получении определенных значений AnalogWrite
Вы не можете подключить двигатель напрямую к выходному контакту (если только это не очень маленький двигатель). Вам также необходимо обратноходовой диод к двигателю. Я предполагаю, что двигатель создает много «шума» на шине питания, что приводит к странным значениям AnalogRead., @Gerben