Не могу заставить GyverPID запустить ШИМ

Yuriy-Shved

✩✩✩✩✩✩✩
24 Мар 2024
10
0
Добрый день.
Не удается завести PID обработку поступающих сигналов с библиотекой. Вне зависимости от величины Kp на выходе 0. Не могу понять - в чем ошибка?
 

Вложения

viktor1703

★★★✩✩✩✩
9 Дек 2021
633
150
А сколько вы ожидаете? В каком месте вы прописали, что на выходе (кстати не известном) что-то должно быть?
C++:
void loop() {

if (micros() - timing_dt >= dt_delay){
regulator_L.setpoint = float(SET);
regulator_L.input = float(cur_pos_L);
GyverPID_L = long(regulator_L.getResult());
regulator_R.setpoint = float(SET);
regulator_R.input = float(cur_pos_R);
GyverPID_R = long(regulator_L.getResult());
timing_dt = micros();
}
 

Yuriy-Shved

✩✩✩✩✩✩✩
24 Мар 2024
10
0
@viktor1703,
GyverPID_L = long(regulator_L.getResult());
GyverPID_R = long(regulator_R.getResult());
Согласно документации и примерам, метод getResult() объектов regulator_L и regulator_R должен передать значения, вычисленные PID алгоритмом.
Эти значения записываются в переменных GyverPID_L и GyverPID_L и выводятся на печать.
Выходом при отладке алгоритма пока служит print(). Пины и AnalogWrite() будут, когда PID заработает корректно.
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
499
146
@Yuriy-Shved,
Такой короткий код лучше вставлять прямо в сообщение. Кнопка в панели </>
У вас канал R перепутан.

GyverPID_R = long(regulator_L.getResult());
 

viktor1703

★★★✩✩✩✩
9 Дек 2021
633
150
C++:
regulator_R.setLimits(0,  (pow(2, 10) - 1));
regulator_L.setLimits(0,  (pow(2, 10) - 1));
Месье знает толк в извращениях. Ну да ладно,это ваши тараканы так захотели.
А вот буквы правильно расставить не пожелали
C++:
regulator_R.setpoint = float(SET);
regulator_R.input = float(cur_pos_R);
GyverPID_R = long(regulator_L.getResult());
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,975
634
45
Если что то не работает - возьмите рабочий пример, если он работает - доработайте его под себя.
 

Yuriy-Shved

✩✩✩✩✩✩✩
24 Мар 2024
10
0
@Геннадий П,
Увы, пример тоже показывает нули:
#include "GyverPID.h"
GyverPID regulator(0.1, 0.00, 0.01, 10); // коэф. П, коэф. И, коэф. Д, период дискретизации dt (мс)
void setup() {
Serial.begin(9600);
regulator.setDirection(NORMAL); // направление регулирования (NORMAL/REVERSE). ПО УМОЛЧАНИЮ СТОИТ NORMAL
regulator.setLimits(0, 255); // пределы (ставим для 8 битного ШИМ). ПО УМОЛЧАНИЮ СТОЯТ 0 И 255
regulator.setpoint = 50; // сообщаем регулятору температуру, которую он должен поддерживать
// в процессе работы можно менять коэффициенты
regulator.Kp = 150.2;
regulator.Ki += 0.0;
regulator.Kd = 0;
}
void loop() {
int temp = 100; // читаем с датчика температуру
regulator.input = temp; // сообщаем регулятору текущую температуру
Serial.println(regulator.getResultTimer());
delay(1000);
}
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,975
634
45
Зачем вы задержку ставите?
Смысл этой библиотеки в том, что вы должны вызывать getResultTimer чаще (желательно в несколько раз, чем чаще тем лучше), чем задан период дискретизации, т.к. в нем и происходит вся обработка.
 

Yuriy-Shved

✩✩✩✩✩✩✩
24 Мар 2024
10
0
@Геннадий П, здесь только для печати, мне надо увидеть вычисленное значение без мерцания. В работе с драйвером
конечно delay() использоваться не будет.
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
499
146
@Yuriy-Shved,
А без программы, если на бумажке считать
Если у вас в данный момент температура 100, а вы хотите получить 50 , то какой должна быть мощность нагревателя в данный момент?
 
  • Лойс +1
Реакции: Геннадий П

Yuriy-Shved

✩✩✩✩✩✩✩
24 Мар 2024
10
0
@Bruzzer,
Поднял уставку до 150, пошел результат (255). То есть задание диапазона значений от нуля в положительную область (setLimits(0, 255) ) включает ШИМ только при превышении уставки над показанием датчика, как нужно для нагревателя.
Но в моем случае надо заставить ШИМ управлять серводвигателем, то есть отрабатывать и в обратном направлении. Поставил диапазон от -255 до 255, заработало и при уставке, меньшей показания датчика - показывает теперь отрицательное значение.
То есть для управления серводвигателем ОБЯЗАТЕЛЬНО надо задавать диапазон с отрицательной областью!
Придется преобразовывать его в отдельный сигнал направления, нужный драйверу, но это решаемо. Главное - заработало! Спасибо, помогли.
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
499
146
@Yuriy-Shved,

Не знаю, надо вам это или нет, но в вашем первом сообщении
#define PID_INTEGRAL_WINDOW 50
объявлен после
#include <GyverPID.h>
и не влияет на поведение GyverPID
Если надо чтобы влиял, то надо объявлять перед #include <GyverPID.h>
т.е.
#define PID_INTEGRAL_WINDOW 50
#include <GyverPID.h>
 
Изменено: