Самодельный локомотивный декодер.
- tnt23
- Сообщения: 52
- Зарегистрирован: Вс апр 05, 2020 7:24 am
- Имя: Tim
- Откуда: СПб
- Благодарил (а): 12 раз
- Поблагодарили: 14 раз
Re: Самодельный локомотивный декодер.
И обязательно попробуем. Пока использую мозолистый палец для создания непредвиденных динамических нагрузок, тащит ОК.
- tnt23
- Сообщения: 52
- Зарегистрирован: Вс апр 05, 2020 7:24 am
- Имя: Tim
- Откуда: СПб
- Благодарил (а): 12 раз
- Поблагодарили: 14 раз
Re: Самодельный локомотивный декодер.
У меня не ардуино - другая архитектура (stm32), и скетча как такового нет. Все раскидано по вороху файлов, включая очень недружелюбные низкоуровневые вещи и сомнительного качества комментарии. Когда-нибудь, возможно, причешу и опубликую.
Сам код регулятора прост, как валенок:
Все это крутится в цикле вместе с периодическим замером обратной ЭДС (таймеры, прерывания, DMA - все как у людей). Полученная поправка - fix - подмешивается в PWM мотору.
Сам код регулятора прост, как валенок:
Код: Выделить всё
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;
- tnt23
- Сообщения: 52
- Зарегистрирован: Вс апр 05, 2020 7:24 am
- Имя: Tim
- Откуда: СПб
- Благодарил (а): 12 раз
- Поблагодарили: 14 раз
Re: Самодельный локомотивный декодер.
Сейчас отлаживаюсь с константой, для ушатанного BR 55 это 14..16 единиц. В реале думаю брать как разницу между CV5 и CV2, деленную на количество шагов.
-
- Сообщения: 121
- Зарегистрирован: Пн мар 28, 2016 12:03 pm
- Благодарил (а): 25 раз
- Поблагодарили: 11 раз
- Контактная информация:
Re: Самодельный локомотивный декодер.
Те один и тот же PI алгоритм для малого хода и для нормальной скорости?
Вольтаж референсный лучше снимать до Н моста. Иначе при уходе вольтажа весь алгоритм начнет лажать.
И еще пару вопросов, если можно:
- можно ли финальную схему выложить?
- в какой момент и с какой частотой вы снимаете показания бек емф? Прерывает шим, или просто не доводите скважность до 100% и снимаете в этом промежутке, который гарантированно не заполнен?
Вольтаж референсный лучше снимать до Н моста. Иначе при уходе вольтажа весь алгоритм начнет лажать.
И еще пару вопросов, если можно:
- можно ли финальную схему выложить?
- в какой момент и с какой частотой вы снимаете показания бек емф? Прерывает шим, или просто не доводите скважность до 100% и снимаете в этом промежутке, который гарантированно не заполнен?
- tnt23
- Сообщения: 52
- Зарегистрирован: Вс апр 05, 2020 7:24 am
- Имя: Tim
- Откуда: СПб
- Благодарил (а): 12 раз
- Поблагодарили: 14 раз
Re: Самодельный локомотивный декодер.
Один, меня пока больше заботит тихий ход. Потом можно будет сделать отключение стабилизации, дискретное или плавное, по мере увеличения скорости.
Он не снимается, а задается программно. На АЦП заведено только напряжение с мотора. В принципе можно и напряжение после выпрямителя измерять, только пока не вижу, где его дальше использовать. Регулятор старается поддерживать обороты так, чтобы с мотора приходило более-менее одно и то же. Просядет напряжение на рельсах - чуть упадет BEMF - регулятор поддаст газу - BEMF вырастет - все довольны. Мне так кажется.Вольтаж референсный лучше снимать до Н моста. Иначе при уходе вольтажа весь алгоритм начнет лажать.
Финальная схема будет, когда наступит финал-апофеоз. Пока схема практически как и у топикстартера, только управление мотором сделано на ZXMHC6A да процессор другой. Замер BEMF тоже такой же.
BEMF считывается периодически, по таймеру. Период задается в миллисекундах в CV, минимум 10мс, для отладки довольствуюсь 20мс.- в какой момент и с какой частотой вы снимаете показания бек емф? Прерывает шим, или просто не доводите скважность до 100% и снимаете в этом промежутке, который гарантированно не заполнен?
Когда наступает время замера, ШИМ отключается, выжидаем усыхания тока в обмотке и появления напряжения обратной ЭДС, это примерно 1.5-2 миллисекунды с момента выключения ШИМ. Затем отрабатывает АЦП, и ШИМ включается обратно.
-
- Сообщения: 121
- Зарегистрирован: Пн мар 28, 2016 12:03 pm
- Благодарил (а): 25 раз
- Поблагодарили: 11 раз
- Контактная информация:
Re: Самодельный локомотивный декодер.
А не многовато - 10 миллисекунд?
Народ меряет через микросекунды.
Народ меряет через микросекунды.
- tnt23
- Сообщения: 52
- Зарегистрирован: Вс апр 05, 2020 7:24 am
- Имя: Tim
- Откуда: СПб
- Благодарил (а): 12 раз
- Поблагодарили: 14 раз
Re: Самодельный локомотивный декодер.
Вот прямо через микросекунды? как-то сомнительно. Есть ли в этом практический смысл?
Хотя мне хочется попробовать чаще, но пока не сделать интервал меньше 10мс. Надо плотно переделывать процедуру замера. С другой стороны, и так пауза в подаче ШИМ порядка 1-2мс.
Хотя мне хочется попробовать чаще, но пока не сделать интервал меньше 10мс. Надо плотно переделывать процедуру замера. С другой стороны, и так пауза в подаче ШИМ порядка 1-2мс.
- tnt23
- Сообщения: 52
- Зарегистрирован: Вс апр 05, 2020 7:24 am
- Имя: Tim
- Откуда: СПб
- Благодарил (а): 12 раз
- Поблагодарили: 14 раз
Re: Самодельный локомотивный декодер.
Вот еще отличная лекция про PID доступным языком: http://robofob.ru/materials/articles/pa ... bline1.pdf
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;
}