И обязательно попробуем. Пока использую мозолистый палец для создания непредвиденных динамических нагрузок, тащит ОК.Дык она то поди на ходу по другому совсем будет работать. Надоть на ходу пробовать.
Код: Выделить всё
err = TARGET_BEMF_VOLTAGE - bemf;
// P-term
proportional = (err * ReadCV (CV56_KP)) / KPDIV;
if (proportional > MAXKP) proportional = MAXKP;
if (proportional < -MAXKP) proportional = -MAXKP;
// I-term
integral += err;
if (integral > MAXINTEGRAL) integral = MAXINTEGRAL;
if (integral < -MAXINTEGRAL) integral = -MAXINTEGRAL;
ki = (integral * ReadCV (CV57_KI)) / KIDIV;
if (ki > MAXKI) ki = MAXKI;
if (ki < -MAXKI) ki = -MAXKI;
fix = proportional + ki;
Сейчас отлаживаюсь с константой, для ушатанного BR 55 это 14..16 единиц. В реале думаю брать как разницу между CV5 и CV2, деленную на количество шагов.А TARGET_BEMF_VOLTAGE как определяется?
Один, меня пока больше заботит тихий ход. Потом можно будет сделать отключение стабилизации, дискретное или плавное, по мере увеличения скорости.Те один и тот же PI алгоритм для малого хода и для нормальной скорости?
Он не снимается, а задается программно. На АЦП заведено только напряжение с мотора. В принципе можно и напряжение после выпрямителя измерять, только пока не вижу, где его дальше использовать. Регулятор старается поддерживать обороты так, чтобы с мотора приходило более-менее одно и то же. Просядет напряжение на рельсах - чуть упадет BEMF - регулятор поддаст газу - BEMF вырастет - все довольны. Мне так кажется.Вольтаж референсный лучше снимать до Н моста. Иначе при уходе вольтажа весь алгоритм начнет лажать.
BEMF считывается периодически, по таймеру. Период задается в миллисекундах в CV, минимум 10мс, для отладки довольствуюсь 20мс.- в какой момент и с какой частотой вы снимаете показания бек емф? Прерывает шим, или просто не доводите скважность до 100% и снимаете в этом промежутке, который гарантированно не заполнен?
PS и еще нашелся скетч PID для ардуино на пол-странички, буквально: https://alexgyver.ru/gyverpid/ПИД-управление в нестрогом изложении
Настоящая работа представляет собой очередную попытку неформального, популярного описания основ построения ПИД-регулятора, причем с уклоном в робототехнику, если под этим уклоном понимать иллюстрацию теории на примере движения мобильного робота.
Код: Выделить всё
// ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
// величины регулятора
int setpoint = 0; // заданная величина, которую должен поддерживать регулятор
int input = 0; // сигнал с датчика (например температура, которую мы регулируем)
int output = 0; // выход с регулятора на управляющее устройство (например величина ШИМ или угол поворота серво)
int pidMin = 0; // минимальный выход с регулятора
int pidMax = 255; // максимальный выход с регулятора
// коэффициенты
float Kp = 1.0;
float Ki = 1.0;
float Kd = 1.0;
float _dt_s = 0.1; // время итерации в секундах
// вспомогательные переменные
int prevInput = 0;
float integral = 0.0;
// ПИД
// функция расчёта выходного сигнала
int computePID() {
float error = setpoint - input; // ошибка регулирования
float delta_input = prevInput - input; // изменение входного сигнала
prevInput = input;
output = 0;
output += (float)error * Kp; // пропорционально ошибке регулирования
output += (float)delta_input * Kd / _dt_s; // дифференциальная составляющая
integral += (float)error * Ki * _dt_s; // расчёт интегральной составляющей
// тут можно ограничить интегральную составляющую!
output += integral; // прибавляем интегральную составляющую
output = constrain(output, pidMin, pidMax); // ограничиваем выход
return output;
}