Дата: Воскресенье, 15.04.2018, 19:53 | Сообщение # 76
Подполковник
Группа: Модераторы
Сообщений: 191
Статус: Offline
snmar4enko, Мне не совсем понятна логика применения moc3063 который и так имеет контроль ноля,вот если поставить из серии без этого контроля ноля,тогда да,вы развязываете себе руки можете запилить фазовое или сигма-дельта с выкусыванием фаз или полуфаз, легко переключаясь в настройках между всеми вариантами. У атмела есть аппноут AVR221_PID,там есть пример для понимания
Цитатаsnmar4enko ()
когда опрос ПИД приближается к 100 разам в секунду
В вашей программе я не увидел регулировку времени опроса ПИД,Функция внутри if (reflowStatus == REFLOW_STATUS_ON) и проверяется лишь станус как я понял включения работы и функция ПИД крутится внутри loop на частоте осциллятора.
Дата: Воскресенье, 15.04.2018, 20:38 | Сообщение # 78
Лейтенант
Группа: Пользователи
Сообщений: 68
Статус: Offline
Цитатаmon ()
Мне не совсем понятна логика применения moc3063 который и так имеет контроль ноля
- Как оказалось я не совсем понимал как работает контроль нуля, хотя и читал даташиты до того как купить moc3063. Оказывается она работает так же как и SSR реле с контролем нуля. А именно если если подан сигнал включения то со следующего перехода через ноль включается и остается включенным до следующего перехода через ноль. Для этого пришлось почти пол дня просидеть с осциллографом тестирую работу версии 2.0.0
Посему переписал регулировки под SSR или moc3063, может даже для эксперимента и назвал 1.4.0 Убрал прерывания и освободил 2 вывод детектор нуля. Поменял PID коэффициенты.
В плане программы - она не моя - а общая. И время опроса PID расчетно-теоретическое.
Дата: Воскресенье, 15.04.2018, 21:17 | Сообщение # 79
Подполковник
Группа: Модераторы
Сообщений: 191
Статус: Offline
Цитатаsnmar4enko ()
И время опроса PID расчетно-теоретическое
Заведите таймер ,а в нем выставляйте флаг события опроса самой функции ПИД,в реальности нужно опрашивать от 100 -2000ms,не зачем так быстро молотить ее в цикле. И ещё чтобы была возможностью задавать этот параметр из меню,тогда можно избавится от деления переменной c плавающей запятой (kp1/100...) для слабых МК без аппаратного деления отнимает много процессорного времени.Так же можно избавится в функции ПИД от float и привести к u16 ну или u32 ,расширить диапазон регулировки воздействия на нагреватель с шагом от 0-1000,если сделайте фазовую регулировку,тогда избавитесь от мерцания касательно галагенок, да и вообще предпочтительно именно сигма-дельта, чем просто шимом как попало рубить фазы в узком диапазоне.
Дата: Понедельник, 16.04.2018, 10:47 | Сообщение # 80
Лейтенант
Группа: Пользователи
Сообщений: 68
Статус: Offline
Цитатаmon ()
И время опроса PID расчетно-теоретическоеЗаведите таймер ,а в нем выставляйте флаг события опроса самой функции ПИД,в реальности нужно опрашивать от 100 -2000ms,не зачем так быстро молотить ее в цикле.
Зачем еще таймеры - их и так достаточно для ШИМ и прочего (скорость роста температуры, задержки кнопок, звуков, пауз перед переходим на следующий шаг .....
Время опроса задается самоходом в loop цикле.
Цитатаmon ()
Так же можно избавится в функции ПИД от float
На самом деле 4 байта одна переменная .... и это обусловлено точностью расчета выходного значения PID и чтобы поменять нужно переписывать библиотеку.
Код
double Setpoint1, Input1; double Output1=0;
Цитатаmon ()
расширить диапазон регулировки воздействия на нагреватель с шагом от 0-1000
Для экспериментальной версии 1.4.0 где используется встроенный в ключ детектор нуля это не к чему, так как ШИМ работает с периодом 1 секунда а изменения параметра увеличит скорость опроса PID. А от для новой ветки 2.0.0 - хорошая идея.
Тестил версию 1.4.0 : общим петля PID регулирования не разрывается даже при Kp=25.5 Ki=2.5 Kd=0.4 Температура измеренная немного отстает от заданной
Добавлено (16.04.2018, 10:47) --------------------------------------------- На Ардуино ИДЕ программирую только пару месяцев, вопрос к более опытным :
Как переназначить Byte массив десятичными значениями от 0 до 255 ? Возможно ли такое?
Сообщение отредактировал snmar4enko - Понедельник, 16.04.2018, 07:20
Пользователи поблагодарившие snmar4enko за этот пост:
Дата: Понедельник, 16.04.2018, 19:48 | Сообщение # 81
Лейтенант
Группа: Пользователи
Сообщений: 68
Статус: Offline
Новая версия для силовой части с детектором нуля и отсутствием введения сетевой синхронизации в контролер на D2. скетч ARDUINO_REWORK_1.4.1
Ввел таймер опроса PID - раз в 200 мкс, период ШИМ тоже сделал таким. Снова расширил значения коэффициентов ПИД от 0 до 255 Поменял их умолчания - как в контролере от LDZ. Необходимо произвести инициализацию памяти по 8 секундном удержанию клавиши Cancel.
при установке PID коэффициентов учитывайте что время ПИД в 2 раза больше чем номинального, соответсвенно удваивается Ki и половинется Kd. Также 200 мкс период ШИМ регулятор включается при переходе через ноль - то есть раз в 10 мкс - получается только 20 значений для 100% мощности, все коеффицинты деляться вроде бы на 10. До конца не могу доанализировать ..... сори
Дата: Понедельник, 16.04.2018, 20:15 | Сообщение # 82
Лейтенант
Группа: Пользователи
Сообщений: 68
Статус: Offline
в догонку еще одна версия 1.4.2
в станции от LDZ есть еще параметр Tpid (10-30) - период ПИД - по умолчанию 10. Не знаю что фактически делает так как исходников никто не оглашал но догадываюсь что тот самый множитель увеличение времени интегрирования - дифиринцирования и вообще вычисления ПИД. В пошлой версии он 2. В этой сделал 10. При установке коэффициентов учитывайте что 10*Ki и Kd/10. с мощностью 1 к 1. Хотя опоздание за установленной температурой увеличилось и недолет к цели.
Dmitrysh Нашел небольшой косячок в скетче "sketch_TFT-320x480_dimer_V3-2". Есть такая функция "loadProfile()", которая читает параметры профилей из eprom. Так вот эта функция располагается в основном цикле программы - loop, т.е когда мы находимся в основном меню происходит постоянное считывание профилей из eprom(около 26 параметров). В этом нет никакого смысла. Такого быть не должно. Дело в том что обращение к eprom это процесс достаточно медленный, а быстродействие у ардуины не такое уже и высокое, чтобы нам тратить его на ненужную никому работу. Поэтому я предлагаю перенести обращение к функции "loadProfile()" из основного цикла loop в подпрограмму setup.
- у нас тоже настройки читает из Eeprom в loop цикле. Переключать профили в IDLE режиме простоя думаете возможно без считывания их вроде бы 29 значенией из Eeprom. Loop цикл крутится - но его можно заворачивать куда хотим. Это зависит от режима работы который мы включили. Выбирается по Case. Быстродействия пока хватает. Особенно если тэнами будут рулить SSR с ZCC. По поводу отсутствия контроля нуля процессором версии 1.4.0 - 1.4.2 - без него. Его вводят чтобы не было помех. Но так как контроль есть в MOSах то помех если демпферная цепочка в схеме есть то не будет. В принципе заводит сигнал детектора нуля в процессор можно но только для подсчета импульсов .... с чем неплохо справляется таймер. Анализируя работу получаем что для версии 1.4.2 как бы не хватает значений коэффициентов PID. Мощность 0-100 полноценно просчитывается. Версия 1.4.1 более точно регулирует температуры хотя мощность регулируется 0-20. Вот и думай что важней шкала мощности или правильные ПИД коэффициенты. Посмотри в сторону параллельного форума LDZ. Тоже нет сетевой синхронизации в процессор и управляет SSR с ZCC, хотя на некоторых силовых схемах SSR без ZCC. Можно было и попробывать на Ардуинке - зашить поверх загрузщика, подпаяться вычислив аналоги выводов по назначению вывод проца и аналогах ардуино. Термодатчики не паять а подстрочники средним выводм на сигнал краями земля и +5в. Но еще кварц на 8 мгц перепаять .....
В sketch_TFT-320x480_dimer корни как у нашего проекта, только экран покруче и ардуина подороже так как код уже не влезает в 32 метра.На днях нашел наш общий исходник на иностранном сайте https://www.mediafire.com/file/bzwf2g26chdg36t/Arduino+Rework+Station.rar - глюков в нем ого-го, начиная что с первого шага включаются оба нагревателя ....
У нас проект открытый ..... и подглядывать у других не всегда получается. Если есть только нех-код то дизассемблерование занимает много времени, особенно меткометание и комментирование по разбору кода.
Сообщение отредактировал snmar4enko - Вторник, 17.04.2018, 14:05
Пользователи поблагодарившие snmar4enko за этот пост:
Проводил эксперименты нагревая снизу керамическим инфракрасным нагревателем 450вт 8*8см на 220 вольт (что купил для верха). Коэффициенты PID зависят от расстояния размещения платы от нижнего нагревателя. Уменьшил расстояние с 3 см (как рекомендовано) до 1.5см. Нижний термодатчик размещаю под платой не прижимая. Вылет температур низа есть 154 - 145 градусов. Верхний термодатчик сверху платы - прижат собственным весом сбоку от выпаиваемого чипа. нагрев показывает 83-90 градусов при нагреве низа до 150 градусов. Так что верх даже не включается - у нас он начинает работать при 10 градусах до температуры максимума низа но измеренный верхним термометром.
Версия 1.4.3 включается верх за 70 градусов до низа.
Пробовал греть низ до 300 градусов - верх медленно показывает максимум 160 градусов. Плата дымит. Получается что запайку всей платы как делают на утюге можно делать только если плата лежит непосредственно на подошве утюга.
Да и металлический кожух вокруг нагревателя тоже сильно нагревается.
И нужно вентилятор включать в конце процесса пайки - охлаждаются очень медленно
Тогда нужно полностью переписать код регулировки а это долговато .....
Общим перепаял MOS3063 на MOS3023 - получил регулятор с фазовой модуляцией .... вернулся к ветке 2.0.*. Соответственно вернул вход нуля синхронизации на D2. Для удобства необходимо добавить 2 светодиода последовательно в цепочку управления оптопарой для визуального контроль подводимой мощности по яркости светодиода. Резистор получается 200ом. А пока на скорости 9600 мощности летят в комп по UART. 0- максимум, 200- минимум, 216- полностью отключен. Когда отстроите ПИД и т д то закоментируете.
Ввел период опроса ПИД 0.1 секунду, убрал мерцание при настройке Температуры нижнего нагревания. Увеличил шкалу мощности до 0.5 процента. Заморозил фиксацию температуры в начале шага по показаниям датчика верхнего нагревателя - один раз в начале (раннее если нагрев шел быстрее то пере фиксировалась). При инициализации памяти после ее стирания должен быть ресет - не всегда срабатывает - 2 варианта прописал - выбираете какой у вас работает.
Когда используем инерционный нагреватель (такой как утюг или плитка, или инфракрасные нагреватели как у
ЦитатаCinema ()
кто использует ACHI IRxxxx
то даже 2% ограничение мощности - все одно делает перелет на 7-15 градусов даже если термодатчик напрямую касается к нагревателю. Получается что аналогичные проблемы на версиях 1.4.* не из - регулятора твердотельного реле.
Возможно что нужно перевести нагреватель четверть мощности путем включения нижнего нагревателя на нечетных полуволнах , а верхнего на четных ведь мощностей 1800вт низа и 450вт верха все равно достаточно ......
Итак скетч 2.0.1
Добавлено (20.04.2018, 17:01) --------------------------------------------- PID адаптивная регулировка: изменение коэффициентов PID в примере в 4 раза!!!!!
Код
#include <PID_v1.h>
#define PIN_INPUT 0 #define PIN_OUTPUT 3
//Define Variables we'll be connecting to double Setpoint, Input, Output;
//Define the aggressive and conservative Tuning Parameters double aggKp=4, aggKi=0.2, aggKd=1; //при разности измеренного и заданного 10 и более double consKp=1, consKi=0.05, consKd=0.25; // при небольшой разности - фактически в 4 раза меньшие коэфф.
//Specify the links and initial tuning parameters PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);
void setup() { //initialize the variables we're linked to Input = analogRead(PIN_INPUT); Setpoint = 100;
//turn the PID on myPID.SetMode(AUTOMATIC); }
void loop() { Input = analogRead(PIN_INPUT);
double gap = abs(Setpoint-Input); //distance away from setpoint if (gap < 10) { //we're close to setpoint, use conservative tuning parameters myPID.SetTunings(consKp, consKi, consKd); } else { //we're far from setpoint, use aggressive tuning parameters myPID.SetTunings(aggKp, aggKi, aggKd); }
snmar4enko, А каким образом считается температура? и как она влияет на термопрофиль? Я вижу в коде некое условие:
//счётчик скорости роста температуры if ((currentMillis - previousMillis) > 4000 / rampRateStep[currentStep - 1]) //seconds counter { previousMillis = currentMillis; counter = counter + 1; setpointRamp = counter + startTemp; lcd.setCursor(7, 0); lcd.print(" "); lcd.setCursor(7, 0); lcd.print(setpointRamp); lcd.write(byte(0));
if (setpointRamp<100) { lcd.print(" "); }
которое опять же вызывается внутри loop и окружено кучей всяких функций с большой задержкой,для себя я вижу только один вариант,вызывать ее точно по времени(а это только в прерывании по таймеру) и сравнивать там разницу температур.
Цитатаsnmar4enko ()
Увеличил шкалу мощности до 0.5 процента
Вы имели ввиду уменьшили шаг? Опять же вернёмся к ПИДу,в коде подсовывается текущая температура и заданная и естественно он стремится ее стабилизировать,и вы естественно будете наблюдать замедление в момент достижения заданной температуры на текущем шаге,таким образом вы получаете волнообразный профиль,а вам он не нужен поэтому вы стремитесь дестабилизировать систему,попросту расшатать, путем диких для неё коэффициентов и в целом, вроде бы будет работать,но стоит изменить температуру окружающей среды,вы опять получите полную кашу в работе. В функции ПИД вы работаете с double и что возвращает эта функция? правильно double,а потом суете ее в DimmerUP=201-Output1; Допустим Output1 == 1.122 или 1.925 ,что будет в uint8_t DimmerUP ? конечно же целое число причем одно и тоже ,а как же 0.122 , 0.925 над которыми так пыхтит ПИД? в тысячи ненужных тактов ? всё испарились...выделение уйму процессорного времени в пустую,вот вам и 4-е байта + флешь под завязку. Или это double kp1;а потом работаете как с целым числом kp1 = kp1 + 1; if (kp1 >= 255) { kp1 = 255; } Думается лишним не будет: http://microsin.net/program....vr.html http://www.gaw.ru/html.cgi/txt/app/micros/avr/AVR035.htm
Температура не считается а меряется, с датчика через фильтр.
Цитатаmon ()
Код
//счётчик скорости роста температуры if ((currentMillis - previousMillis) > 4000 / rampRateStep[currentStep - 1]) //seconds counter { previousMillis = currentMillis; counter = counter + 1; setpointRamp = counter + startTemp; lcd.setCursor(7, 0); lcd.print(" "); lcd.setCursor(7, 0); lcd.print(setpointRamp); lcd.write(byte(0));
if (setpointRamp<100) { lcd.print(" "); }
На этом 2м этапе пайки просчитывается период времени за который задаваемая про профилю температура растает на 1 градус. Сама температура термопрофиля тоже вычисляется начиная с температуры старта, добавляется по 1 градусу до температуры цели (Target) и отображается на экране посредине верхняя строчка. Эта цифра как бы прототип к которому ПИД будет стремится поднять реальную температуру нагрева.
Цитатаmon ()
Увеличил шкалу мощности до 0.5 процентаВы имели ввиду уменьшили шаг?
Да . 100% мощности это теперь от 0 до 200 шкала - то есть 0.5% деление
Цитатаmon ()
Опять же вернёмся к ПИДу,в коде подсовывается текущая температура и заданная и естественно он стремится ее стабилизировать,и вы естественно будете наблюдать замедление в момент достижения заданной температуры на текущем шаге,таким образом вы получаете волнообразный профиль,а вам он не нужен поэтому вы стремитесь дестабилизировать систему,попросту расшатать, путем диких для неё коэффициентов и в целом,вроде бы будет работать,но стоит изменить температуру окружающей среды,вы опять получите полную кашу в работе. В функции ПИД вы работаете с double и что возвращает эта функция? правильно double,а потом суете ее в DimmerUP=201-Output1; Допустим Output1 == 1.122 или 1.925 ,что будет в uint8_t DimmerUP ? конечно же целое число причем одно и тоже ,а как же 0.122 , 0.925 над которыми так пыхтит ПИД? в тысячи ненужных тактов ? всё испарились...выделение уйму процессорного времени в пустую,вот вам и 4-е байта + флешь под завязку. Или это double kp1;а потом работаете как с целым числом kp1 = kp1 + 1; if (kp1 >= 255) { kp1 = 255; } Думается лишним не будет:
Я уже ранее объяснял, что double требует библиотека PID регулятора, а коэффициенты и переменные необходимо записывать в память EEPROM где можно записать только байт 0-255. DimmerUP=201-Output1 - Так как использую фазовую модуляцию в регуляторе то необходимо переворачивать значение .....работает. Если знаете как сделать по другому подскажите.
В скетче 2.0.1 обнаружил что регулятор низа ложно срабатывает - включается на весь период если импульс не успел выключится с прошлого периода. Также есть ложные срабатывания верхнего нагреватя в выключенном состоянии. Пока не знаю что с ними делать, так как вспышки на 1 период раз в 30 секунд.
Также поменял мошности, коэффицинты ......
В регулятор мощности ввел четность , в одну полуволну включается низ, в другую - если верх включен то включается верх. Изменил условие включения верха.
Скетч версии 2.0.2
Оптимизация - я за - тем более что после ввода библиотеки #include <CyberLib.h> //Библиотека от Cyber-Place.ru есть возможность много чего в стиле ассемблера переписать ....