Arduino, ШИМ, ПИД и Epson

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

Доброго всем времени суток!

Есть необходимость крутить в Эпсоновской лентопротяжке помпу прокачки чернил. Конструктивно помпа выглядит как пластиковый стакан-статор на стенке которого лежит виток силиконовой трубки внутри которого вращается челнок-ротор с пережимающим трубку валиком. Из-за того, что вход и выход витка в/из стакана имеют 1-2 мм перехлёста (иначе вакуум не создавался бы) каждый оборот валик "наступает" на 2 трубки и нагрузка на вал возрастает аж наблюдается девиация частоты воя шестерёнок (это если питать движок стабилизированными 8..42V - Эпсоновская же плата не иначе как через ПИД-управление на любых, задаваемых прошивкой, оборотах крутит ровно и гладко). Для этого на Али была приобретена китайская Nano и обвязана как-то так:

 

А скетч выглядит так:


#include <PID_v1.h>
#include <TimerOne.h>

#define PIN_encoder 2
#define PIN_MOTOR 9 // PWM
#define Key_Plus 7
#define Key_Minus 12
volatile int encoderCnt = 0;// Счетчик импульсов с энкодера за 1 таймер

//Define Variables we'll be connecting to 
double Setpoint, Input, Output;//volatile

//Define the aggressive and conservative Tuning Parameters
double consKp=0.4, consKi=0, consKd=0;     //подбираем ручками
           //1.3023    
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);

void doEncoder(void)// Обработчик прерывания для энкодера
{
  encoderCnt++;
}

void timerIsr()// “Скорость” – количество импульсов, зарегистрированное за интервал
{              // между вызовами этой процедуры
  Input = double(encoderCnt); // Input = RealSpeed в импульсах с энкодера
//  Serial.println("encoderCnt = " + String(encoderCnt));// строго для отладки
  encoderCnt = 0;
if (Input != Setpoint)
{
    myPID.SetTunings(consKp, consKi, consKd);
  }
  myPID.Compute();
  analogWrite(PIN_MOTOR, byte(Output));
}
}

void setup()
{
  pinMode(Key_Plus, INPUT);// инкремент Setpoint'a
  pinMode(Key_Minus, INPUT);// декремент Setpoint'a
  pinMode(PIN_encoder, INPUT);// Настройка энкодера
  digitalWrite(PIN_encoder, HIGH); // включаем подтяжку входа к «1»
  Serial.begin(9600);// строго для отладки
  Serial.println("Initializing");// строго для отладки
  Setpoint = 196;//128;
  analogWrite(PIN_MOTOR, Setpoint);
  myPID.SetMode(AUTOMATIC);//turn the PID on
  myPID.SetControllerDirection(DIRECT);// REVERSE
  myPID.SetOutputLimits(0, 255);
  // Настройка прерываний для энкодера
  // Энкодер подключен к ноге №2 – прерывание №0
  attachInterrupt(0, doEncoder, RISING);
  // Прерывания от Timer1 будут происходить каждые 6656 микросекунд
  //(длительность импульса с энкодера = 26 мкс * 256 импульсов)
//  Timer1.initialize(6650);//6656
  Timer1.initialize(10000);//6656
  Timer1.attachInterrupt( timerIsr ); // Настройка обработчика
}

void loop()
{
  if (digitalRead(Key_Plus) == HIGH) 
  {
    if (Setpoint < 255){
    Setpoint++; // //250
  }
    delay(200);
    Serial.println("Setpoint = " + String(Setpoint));// строго для отладки
  analogWrite(PIN_MOTOR, Setpoint);
  Serial.println("Output = " + String(byte(Output)));// строго для отладки
  }
  if (digitalRead(Key_Minus) == HIGH) {
    if (Setpoint > 5){
    Setpoint--; // 0
    }
    delay(100);
    Serial.println("Setpoint = " + String(Setpoint));// строго для отладки
  analogWrite(PIN_MOTOR, Setpoint);
  }
}

И никак не могу победить возбуждение/перерегулирование.

З.Ы. Прошу палками и камнями сильно не метать - это 1-й опыт с Ардуиной, а опытный глаз сразу найдёт где собака порылась.

VasiliyV
Offline
Зарегистрирован: 09.07.2018

Первое что бросается в глаза так это насилие над транзисторами:

1. При подаче 1на базу второго С945 5 вольт через КЭ и БЭ радостно сквозит на землю. КЭ - доли вольта, БЭ 0,5 - 0,8 вольт. Не великоват ли ток коллектора?

2. Переходу БЭ КТ846 тоже не позавидуешь....

Посему есть подозрение что какой-то, а может оба транзистора насыщается. А при насыщении управляющего элемента ни о каком регулировании речи быть не может.

И ещё. Нигде не вижу борьбу с дребезгом кнопок. Вы уверены что одно нажатие приводит к одному управляющему импульсу? Я нет.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

А этим мотором точно можно управлять ШИМ?

Pyotr
Offline
Зарегистрирован: 12.03.2014

Вспомните как работал ЛПМ в кассетниках и никакой девиации, Ардуино, ПИД и ШИМ...)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Про транзисторы в правой части схемы Вам уже написали. Я бы ещё добавил, что не вижу диода параллельно двигателю.

Теперь про левую часть схемы :)

1. Пин D2 в программе сконфигурирован, а потом не используется от слова никак. Или я то-то пропустил?
 
2. Кнопка "+" подключена к пину 11, а программа её почему-то читает с пина 7
UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

VasiliyV пишет:

... При подаче 1цы? на базу второго С945 5 вольт через КЭ и БЭ радостно сквозит на землю.

Ну, во-первых: не на землю, а на нагрузку - эм. переход 846-го, во-вторых этот каскад и задумывался как эмиттерный повторитель дабы базовым током 846 не жогнуть выход Ардуинки и в-третьих: когда там стоял делитель - 1Ком на D9 + 1Ком на землю - движок стоя пищал какую-то модуляцию.

И вообще - к чему весь этот разбор полётов (хватит "[/quote]"): я забыл добавить к первому посту, что если заREMировать строки 57 и 58, то, управляемый кнопками, движок крутится очень даже нормально (за исключением подвываний от нагрузки на вал - так что со схемой хоть и "плюс/минус", но вродь как всё норм), а вот процедура обработки прерываний по таймеру через ПИД вносит не детские корректировки в значение Output из-за чего движок разгоняется от минимума до максимума с частотой раза полтора-два в секунду. И как бы я не экпериментировал с П, И и Д коэффициентами - эта частота ("перегазовок") не меняется.

ЕвгенийП пишет:

1. Пин D2 в программе сконфигурирован, а потом не используется от слова никак. Или я то-то пропустил?

2. Кнопка "+" подключена к пину 11, а программа её почему-то читает с пина 7

0 - диод просто забыл нарисовать (иначе транзисторы летели бы как семечми - от первого же фронта);

1 - наверное пропустили: я пометил маркером зуб шестерёнки на которой сидит энкодер и ровно за оборот encoderCnt показал 745 импульсов

2 - аппаратные передвижки в попытке через SPI передать код старта в Эпсоновский драйвер, но...

VasiliyV
Offline
Зарегистрирован: 09.07.2018

Заканчиваем разбор полётов:

UFO 007: И как бы я не экпериментировал с П, И и Д коэффициентами - эта частота ("перегазовок") не меняется.

Значит дело не в программе?

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Про настройку коэффициентов ПИД тут глянте http://lazysmart.ru/osnovy-avtomatiki/nastrojka-pid-regulyatora/

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

mykaida пишет:

А этим мотором точно можно управлять ШИМ?

Я глубоко сумлеваюсь, что теплоотвод под драйвером (QFP48) обеспечивает нормальное функционирование 3-х движков (каретка/бумага/сканер - особенно при копировании документа) в аналоговом режиме.

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

Pyotr пишет:

Вспомните как работал ЛПМ в кассетниках и никакой девиации, Ардуино, ПИД и ШИМ...)

Эт ты щас сострил или сумничал? Хорошо - спешл ту ты: БУМАГОпротяжка

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

VasiliyV пишет:

...

Значит дело не в программе?

А ежелить дело в железе - почему выставленная кнопками скорость, хоть и не идеально ровно, но поддерживается?

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

UFO 007 пишет:

... хоть и не идеально ровно, но поддерживается?

"Ширина" (длительность) импульса, отдаваемой в нагрузку (на ДиСи мотор), мощности не варьируется от нагрузки на вал, хотя энкодер эти отклонения "видит" - наверное именно для такой стабилизации PID и придуман.

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

yul-i-an пишет:
Про настройку коэффициентов ПИД тут глянте http://lazysmart.ru/osnovy-avtomatiki/nastrojka-pid-regulyatora/

Спс, гляну обовъязково.

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

UFO 007 пишет:

Спс, гляну обовъязково.

Сорри - еррор 404

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

VasiliyV пишет:

... И как бы я не экпериментировал с П, И и Д коэффициентами - эта частота ("перегазовок") не меняется.

И = Д = 0 (вродь как с этого советуют начинать), а вот П = 1, 1.1, 1.2, 1.3 = движок "мычит" а при 1.303 перегазовки... Вот, собственно, и дилемма или с майПид что-то не так или, действительно, прав ВасилийВ и транзисторы, получив квадратный импульс, умудряются работать в аналоговом режиме (это там на вход усилка может приходить 0,3 мВ (или 4..20 мА) и соотношение резисторов обратной связи - это есть коэффициент усиления/искажения/шумов и тд и тп - там есть где разгуляться фантазии...). Тут же всё просто: лог "0" - транзистор закрыт, лог "1" - открыт и если грубо утрировать, то угол поворота ротора прямопропорционален длительности "1".

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

А еще пляски возле трения вы забили. Оно как бывает что сдернуть предмет с места тяжелее чем когда это тело скользит. Вот когда движет "мычит", то стоит. А получив заводящий пендаль дергается до следующего мычания, если пендаль слабый.

ПС: А про схему включения некого Дарлингтона слыхали. Нет мы этого чувака в глаза не видели

эмитерный повторитель наше дело.

Pyotr
Offline
Зарегистрирован: 12.03.2014

UFO 007 пишет:

Pyotr пишет:

Вспомните как работал ЛПМ в кассетниках и никакой девиации, Ардуино, ПИД и ШИМ...)

Эт ты щас сострил или сумничал? Хорошо - спешл ту ты: БУМАГОпротяжка

Там ДПТ управлялся регулятором частоты вращения (плата РЧВ), в которой выходной каскад был охвачен ПОС и за счет этого ДПТ имел постоянные обороты при меняющей нагрузке на валу. Скорость выставлялась подстроечником.

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

qwone пишет:

А еще пляски возле трения вы забили. Оно как бывает что сдернуть предмет с места тяжелее чем когда это тело скользит. Вот когда движет "мычит", то стоит. А получив заводящий пендаль дергается до следующего мычания, если пендаль слабый.

ПС: А про схему включения некого Дарлингтона слыхали. Нет мы этого чувака в глаза не видели

и изобрёл этот некий Дарлингтон ни что иное, как КТ827

qwone пишет:

эмитерный повторитель наше дело.

А если вместо R эмиттерный переход КТ846?

qwone пишет:

А еще пляски возле трения вы забили....

Ну, да - если заREMировать 34-ю строку

analogWrite(PIN_MOTOR, byte(Output));

чтобы от PID_v1 в PWM ничего не писалось, то при кнопочном управлении никакого трения... Выходит PID_v1 периодически притирает?

 

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

Pyotr пишет:

Там ДПТ управлялся регулятором частоты вращения (плата РЧВ на К198НТ1+КТ814), в которой выходной каскад был охвачен ПОС и за счет этого ДПТ имел постоянные обороты при меняющей нагрузке на валу. Скорость выставлялась подстроечником.

При соотношении диаметра оси (транспортировавшей МЛ) к диаметру маховика тонвала - коэффициент редукции будь здрав, как следствие: движок потребляет пол-копейки и, соответственно, аналоговый режим возможен даже без радиатора/теплоотвода, а перемотка (нагрузка-то на вал увеличивается, но) длится несколько секунд - особо не перегреешься

З.Ы. "Фамилии" радиоэлементов РЧВ помню неуверенно

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

ЕвгенийП пишет:

 

Или я то-то пропустил?

строку №53 и комментарий над ней. Сейчас (начиная со строки №19) сделал так:

void doEncoder(void)// Обработчик прерывания для энкодера
{
  encoderCnt++;
  Serial.println("encoderCnt = " + String(encoderCnt));// строго для отладки
}

и более точный замер оборота шестерни показал 

encoderCnt = 768

импульсов с энкодера за оборот - т. е. аппаратное прерывание работает тип-топ - не докопаться, а вот програмное...

Может не правильно выбран тайминг для Timer1? В исходнике было 20000 мкс = 50 Гц, но сколько тысяч импульсов за это время насчитает encoderCnt? А в PWM "помещается" значение только #00...#FF. Так вот чтобы не вводить дополнительные коэффициенты пересчёта (а как я соображаю - чем больше этот коэффициент, тем меньше точность регулирования) была замерена осциллоскопом длительность импульса с энкодера на максимальных оборотах (когда вал подаёт бумагу на печать помпа отключается и подвывания пропадают) и умножена на 256: т. е. какое значение в PWM записали - столько импульсов encoderCnt между проверками по таймеру должен накопить. Иначе говоря PID_v1 должна варьировать значение Output, запысываемое в PWM  так, чтобы encoderCnt постоянно совпадал с Setpoint. Или я совсем неправильно всё понимаю?

 

 

 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Да, нет, я пропустил attachInterrupt. Комментарии меня не особо волнуют :)))

VasiliyV
Offline
Зарегистрирован: 09.07.2018

UFO 007. Вам бы книжечку  почитать: Пол Хоровиц и Уильям Хилл. Искусство схемотехники. Том первый. Читать пару раз в год в течении 2х лет. Потом с интервалом  раз в 3 года. И разобрать там примеры. Тогда поймете что переход база - эмиттер не самая тривиальная нагрузка. Далеко не сопротивление. 

По теме. Замените выходной транзистор на n-канальный мосфет. С материнской платы с цепи питания процессора, неважно верхнее плечо или нижнее. Затвор притяните к земле сопротивлением 1к.

 

По моему место теме в аппаратной ветке.

Pyotr
Offline
Зарегистрирован: 12.03.2014

VasiliyV пишет:

UFO 007. Вам бы книжечку  почитать: Пол Хоровиц и Уильям Хилл. Искусство схемотехники. Том первый. Читать пару раз в год в течении 2х лет. Потом с интервалом  раз в 3 года. И разобрать там примеры. Тогда поймете что переход база - эмиттер не самая тривиальная нагрузка. Далеко не сопротивление. 

По теме. Замените выходной транзистор на n-канальный мосфет. С материнской платы с цепи питания процессора, неважно верхнее плечо или нижнее. Затвор притяните к земле сопротивлением 1к.

 

По моему место теме в аппаратной ветке.

В той книжице есть раздел неправильные схемы (или что-то похожее). Схеме ТС там место.

UFO 007, какой макс. ток перистальтика потребляет при 42 В?

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

Э-э-эх, жестянщики... Вам бы только (хоть и схемотехническим, но) молотком (точнее - паяльником) размахивать...

А ларчик открывался просто (собака порылась всё-таки в коде):

  myPID.SetSampleTime(1);//SampleTime — по умолчанию 200 мили секунд

и диагноз "перегазовки" - искоренён: смысл пытаться чё-то вычислять каждые 6,6 мС если ждём целых 200.

З.Ы. По поводу перистальтики в ветку про хирургию - однозначно, т. к. согласно ГОСТ - это недопустимое название шлангового насоса. А помпа потребляет динамически изменяющийся ток - иначе PID было бы не нужно.

Pyotr
Offline
Зарегистрирован: 12.03.2014

UFO 007 пишет:

З.Ы. По поводу перистальтики в ветку про хирургию - однозначно, т. к. согласно ГОСТ - это недопустимое название шлангового насоса. А помпа потребляет динамически изменяющийся ток - иначе PID было бы не нужно.

Я заметил, что поисковиком можешь пользоваться. Даже в вики заглянул...

Перистальтика и шланговый насос - синонимы.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

UFO 007 пишет:

Э-э-эх, жестянщики... Вам бы только (хоть и схемотехническим, но) молотком (точнее - паяльником) размахивать...

А ларчик открывался просто (собака порылась всё-таки в коде):

Штирлиц осторожно вошел в кабинет Бормана и, убедившись, что никого нет, подошел к несгараемому шкафу, где Борман хранил секретные документы. 
Штирлиц ударил шкаф слева. Тот не открылся. Тогда Штирлиц ударил его справа. Шкаф не открылся. Штирлиц поднял его и с размаху бросил на пол. Шкаф не открылся. 
"Наверное, он закрыт, - подумал Штирлиц и полез в карман за ключом.

Вот за чем вы тему на форуме открыли, а потом туману напускали. Ясно же Вам надо поднять навык Программирования, который разумеется подымается индивидуально.

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

qwone пишет:

Вот за чем вы тему на форуме открыли...

Я же думал - помогут, а тут: умничают... А вместо того, чтобы пальцы гнуть - взяли бы да и привели идеально работающую схему коммутации/управления движком

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

UFO 007 пишет:
Я же думал - помогут, а тут: умничают... А вместо того, чтобы пальцы гнуть - взяли бы да и привели идеально работающую схему коммутации/управления движком
Так вот и помогают, но у пациентов видно свое мнение. Но самолечением они себя точно быстрее в могилу сведут.

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

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

qwone пишет:

Так вот и помогают...

точнее - ахинею несут... И вообще: слыш ты, великий теоретик, или нарисуй схему, или не разводи грязь в теме

Pyotr
Offline
Зарегистрирован: 12.03.2014

UFO 007 пишет:

точнее - ахинею несут... И вообще: слыш ты, великий теоретик, или нарисуй схему, или не разводи грязь в теме

Волшебное слово забыл добавить...

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

Э-э-эх... Господа Великие Семотехники... вам из-за паяльника не видно, что переменная Input, "уходящая в прерывание" имеет НЕволатильную ипостась (на её волатильность ругается компилятор) и возвращается из прерывания некий "мусор", в соответсвии с которым, движок и рычал пока я не избавился от прерывания - теперь програмным таймером жду 6,6 мс... но библиотеке PID_v1 из-за работы с дублёвым типом данных не хватило быстродействия, а вот FastPID (что на интах работает) передвигает пузырёк воздуха внутри трубки от капельницы так гладко, как будто движок (ну и помпу) вращает сам Эпсоновский Realoid. А то: "... нетривиальная нагрузка ...", "... МОСфеты ...", ... - прерывания удобней феном припаивать.

mykaida пишет:

А этим мотором точно можно управлять ШИМ?

я поначалу тоже колебался в сторону аналога (у эпсона движки работают "молча" - не пищат, не зудят) но бациллоскоп показал - ШИМ только с часототой за звуковым диапазоном.

Pyotr пишет:

Волшебное слово забыл добавить...

а нежные слова пусть ему Shtirlic с Bormanом шепчут

sadman41
Offline
Зарегистрирован: 19.10.2016

Да всем просто пофиг на вашу неволатильнось, бессмысленное использование глобалов и счетчик в типе int.

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

sadman41 пишет:

счетчик в типе int.

а зачем ему быть дублём (или ещё кем нить) если он должен насчитывать как максимум то, что можно записать в ШИМ (нога 9)? А про волатильность: собери схему, зашей туда скетч (из 1-го поста) и увидишь: по фигу или нет...

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

UFO 007 пишет:

 движки работают "молча" - не пищат, не зудят

а "зуд" с "писком" убираются в TCCR1B, и какую ногу к какой припаять - схемотехникам виднее

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

UFO 007 пишет:

sadman41 пишет:

счетчик в типе int.

а зачем ему быть дублём (или ещё кем нить) если он должен насчитывать как максимум то, что можно записать в ШИМ (нога 9)?

И зачем ему тогда быть int, если максимальное значение ШИМ 255?

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

Jeka_M пишет:

И зачем ему тогда быть int, если максимальное значение ШИМ 255?

ну, да - можно было и byte впердолить, но первое, что на ум пришло: ширпотребовский int

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

P.S. А вообще лучше пользоваться типами данных с точной шириной. Например вместо byte использовать uint8_t

b707
Offline
Зарегистрирован: 26.05.2017

UFO 007 - зачем вы эту тему снова подняли? - чтобы доказать. что форум вам не помог, а сами вы справились? - довольно смешно выглядите, с учетом того, что реванш занял у вас полгода...

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

Jeka_M пишет:

...uint8_t

пардон - в Delphi таких штук не было

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

b707 пишет:

... полгода...

ну, да - с такой-то помощью: всё сам, всё сам...

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

b707 пишет:

UFO 007 - зачем вы эту тему снова подняли? 

чтобы поблагодарить "помощников"

UFO 007
UFO 007 аватар
Offline
Зарегистрирован: 11.01.2018

а ещё в СИ меня прикалывает unsignet char - если он просто char (сигнет), то может быть и "-А"?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

UFO 007 пишет:

то может быть и "-А"?

А то!