Сейчас работаем над доработкой документации на Owen Logic. Отразим эти моменты в следующих версиях справки.
Вид для печати
Сейчас работаем над доработкой документации на Owen Logic. Отразим эти моменты в следующих версиях справки.
Мы про Owen Logic?
А вы имели CoDeSys, вероятно:
Код:VAR_GLOBAL (* старшим байтом вперёд как в ПР200 - поменять в <Universal ModBUS device> Trace_mode на Native *)
(* DWORD не работает, только WORD 65536 иногда по ошибке таки прописывается, но не работает *)
TACK, mSek, mSek0, mSek1, mSek2, mSek3, mSek4 :WORD; (* многозадачность *)
St0int, St1int: WORD; (* счёт внутри прерываний *)
INTset:BOOL; (* рулить прерыванием *) INTinit:BOOL:=TRUE; (* Флаг для инициализации прерывания таймера при запуске основной программы *)
Po,PoZ, Pk,PkZ, Io,IoZ, Ik,IkZ :REAL;
(*In1 AT %IX0.0 : BOOL; (* именование I/O как переменны х *)
In2 AT %IX0.1 : BOOL;
In3 AT %IX0.2 : BOOL; (* для ПЛК-160 - нет в ПЛК-110-30м *)
In4 AT %IX0.3 : BOOL; (* для ПЛК-160 - нет в ПЛК-110-30м *) *)
(* замена при прерывании *) In01,In02,In03,In04 : BOOL:=0; (* дублирование при быстрых входах *)
In1, In2, In3, In4 : BOOL:=0; (* дублирование при быстрых входах *)
vIn1,fIn1, vIn2,fIn2, vIn3,fIn3 :WORD:=0; (* Счёт для входов *) In1_4: BYTE; (* входная маска для SysPortIn(0); *)
Sek: WORD; (* секунды программные *) tSTOP, tSTART: BOOL; (* секундомер *)
In5 AT %IX1.0.0 : BOOL; kAlarm AT %IX1.0.0: BOOL; (* дублировать входы *)
In6 AT %IX1.0.1 : BOOL; kStop AT %IX1.0.1: BOOL;
In7 AT %IX1.0.2 : BOOL; kStart AT %IX1.0.2: BOOL;
In8 AT %IX1.0.3 : BOOL; kPause AT %IX1.0.3: BOOL;
In9 AT %IX1.0.4 : BOOL;
In10 AT %IX1.0.5 : BOOL;
In11 AT %IX1.0.6 : BOOL;
In12 AT %IX1.0.7 : BOOL;
In13 AT %IX1.1.0 : BOOL;
In14 AT %IX1.1.1 : BOOL;
In15 AT %IX1.1.2 : BOOL;
In16 AT %IX1.1.3 : BOOL;
OUT1 AT %QX2.0 : BOOL; (* релейные выходы *)
OUT2 AT %QX2.1 : BOOL;
OUT3 AT %QX2.2 : BOOL;
OUT4 AT %QX2.3 : BOOL;
OUT5 AT %QX3.0.0 : BOOL; (* OutADC AT %QX3.0.0 : BOOL; дублировать выходы *)
OUT6 AT %QX3.0.1 : BOOL; (* Out500 AT %QX3.0.1 : BOOL; *)
OUT7 AT %QX3.0.2 : BOOL; (* Out380 AT %QX3.0.2 : BOOL; *)
OUT8 AT %QX3.0.3 : BOOL; OutZUM AT %QX3.0.3 : BOOL;
OUT9 AT %QX3.0.4 : BOOL; (* Out2000 AT %QX3.0.4 : BOOL; *)
OUT10 AT %QX3.0.5 : BOOL; (* AlarmSV AT %QX3.0.5 : BOOL; *)
OUT11 AT %QX3.0.6 : BOOL; (* Out100 AT %QX3.0.3 : BOOL; *)
OUT12 AT %QX3.0.7 : BOOL;
InR AT %IX6.0 : BOOL; ResKEY AT %IX6.0 : BOOL; (* ПЛПK110 тумблер Работа/СТОП/СБРОС *)
ZUM0 AT %QX7.0 : BOOL; (* утробный звук *)
ADC1 AT %IR4.0 : REAL; (* стр 80(87) (старший байт переменной типа REAL) устанавливается специальное значение соответствующее исключительной ситуации *)
ADC2 AT %IR4.1 : REAL; (* результаты измерения заведомо не верны – 0x F1 *)
ADC3 AT %IR4.2 : REAL; (* результаты измерения не готовы – 0x F6 *)
ADC4 AT %IR4.3 : REAL; (* сигнал на входе больше возможного – 0x FA *)
ADC5 AT %IR4.4 : REAL; (* сигнал на входе меньше возможного – 0x FB *)
ADC6 AT %IR4.5 : REAL; (* перегрузка в канале измерения тока – 0x FС *)
ADC7 AT %IR4.6 : REAL; (* обрыв датчика в канале измерения напряжения – 0x FD *)
ADC8 AT %IR4.7 : REAL;
AdcIn AT %IW4.8 :DWORD; (* AI real time (10ms) *)
(* Кроме того, в переменной «Status» отображаются следующие отказы модуля аналогового ввода:
? бит 2 – нет конфигурирования аналоговых входов; ? бит 5 – отказ FLASH-памяти dsPIC33;
? биты 8...11 – отказы автокалибровки аналоговых входов ComI, RefI, ComU, RefU. *)
DAC1 AT %QR5.0 : REAL; (* с периодом 50 мс выводятся в ЦАП *)
DAC2 AT %QR5.1 : REAL;
DAC3 AT %QR5.2 : REAL;
DAC4 AT %QR5.3 : REAL;
(* --- удалённое управление ПР200 4 шт --- сетевые переменные *)
(* объявить только в глобальных невозможно - как группы объявлять? *)
(* ресурсы > глобальные переменные (задать имя) > свойства объекта > связать с файлом (задать имя) > экспортировать *)
ADCa1 AT %QD8.1.0.0 :REAL; (* АЦП1 первый ПР200 512 0x03 *)
ADCb1 AT %QD8.1.1.0 :REAL; (* АЦП2 первый ПР200 514 0x03 *)
ADCc1 AT %QD8.1.2.0 :REAL; (* АЦП3 первый ПР200 516 0x03 *)
ADC4P1 AT %QD8.1.3.0 :REAL; (* АЦП3 первый ПР200 518 0x03 *)
Inp1P1 AT %QW8.1.18.0 :WORD; (* ПР200-1 вход 1 registet 534 *)
Inp2P1 AT %QW8.1.19.0 :WORD; (* ПР200-1 вход 2 registet 535 *)
Inp3P1 AT %QW8.1.20.0 :WORD; (* ПР200-1 вход 3 registet 536 *)
Inp4P1 AT %QW8.1.21.0 :WORD; (* ПР200-1 вход 4 registet 537 *)
Inp5P1 AT %QW8.1.22.0 :WORD; (* ПР200-1 вход 5 registet 538 *)
Inp6P1 AT %QW8.1.23.0 :WORD; (* ПР200-1 вход 6 registet 539 *)
Inp7P1 AT %QW8.1.24.0 :WORD; (* ПР200-1 вход 7 registet 540 *)
Inp8P1 AT %QW8.1.25.0 :WORD; (* ПР200-1 вход 8 registet 541 *)
Out1P1 AT %QW8.1.4.0 :WORD; (* ПР200-1 вых 1 registet 520 0x06 *)
Out2P1 AT %QW8.1.5.0 :WORD; (* ПР200-1 вых 2 registet 521 *)
Out3P1 AT %QW8.1.6.0 :WORD; (* ПР200-1 вых 3 registet 522 *)
Out4P1 AT %QW8.1.7.0 :WORD; (* ПР200-1 вых 4 registet 523 *)
Out5P1 AT %QW8.1.8.0 :WORD; (* ПР200-1 вых 5 registet 524 *)
Out6P1 AT %QW8.1.9.0 :WORD; (* ПР200-1 вых 6 registet 525 *)
Out7P1 AT %QW8.1.10.0 :WORD; (* ПР200-1 вых 7 registet 526 *)
Out8P1 AT %QW8.1.11.0 :WORD; (* ПР200-1 вых 8 registet 527 *)
OutSVz1 AT %QW8.1.12.0 :WORD; (* ПР200-1 вых SVz registet 528 зелёный *)
OutSVk1 AT %QW8.1.13.0 :WORD; (* ПР200-1 вых SVk registet 529 красный *)
OutK1P1 AT %QW8.1.14.0 :WORD; (* ПР200-1 вых K1 registet 530 открытый колектор *)
OutK2P1 AT %QW8.1.15.0 :WORD; (* ПР200-1 вых K2 registet 531 открытый колектор *)
OutK3P1 AT %QW8.1.16.0 :WORD; (* ПР200-1 вых K3 registet 532 открытый колектор *)
OutK4P1 AT %QW8.1.17.0 :WORD; (* ПР200-1 вых K4 registet 533 открытый колектор *)
(* fAIR AT %QB10.1.0 :STRING;
fNOMER AT %QD10.2.0 :REAL;
fITOG AT %QB10.3.0 :STRING;
fFIO AT %QB10.13.0 :STRING:='$20'; *)
END_VAR
> Могли бы в документации указать список зарезервированных слов
Сообщение об ошибке надо сделать более информативным, что-то наподобие "XXX не может быть использовано в качестве имени переменной".
Смотря что считать ненормальным программированием, Вы себя считаете нормальным? Ну так используйте https://ru.wikipedia.org/wiki/%D0%92...86%D0%B8%D1%8F или https://source.android.com/setup/con...ng-conventions и не столкнулись бы с этой проблемой изначально. Всё что Вы здесь предъявили это претензиия к писателю документации, что он скопировал содержание с МЭК-овского стандарта, не учитывая особенности иди возможно понадеясь на дальнейшее развитие языка ST в ОЛ
Сюда бы неплохо пригласить того, кто сейчас пишет/дополняет язык ST.
Заметно, что тема сдвинулась с мёртвой точки.
Исправляются глюки, добавили ф. блоки, что позволило писать нормально, не высовывая руки через ж. - одну четырёхбайтную переменную.
Help обещались подправить.
Королёв Кирилл - возможно такое?
Чтоб народ тут не мучался, а коротко и ясно помогал в развитии ST и Вам и себе в понимании Ваших действий.
Сейчас мы имеем кости, которые нам кидают, не интересуясь - А оно нам съедобно в таком виде... :(
capzap Отчего такая агрессия??
- то вы ошиблись темой
- то переходите на личности
Тут технический форум, а не философия.
Коротко: Вопрос - ответ.
Нечего сказать: Тишина.
Добрый день!
Да, сейчас активно дополняем справку на основании тех вопросов, которые возникали у пользователей. Пожелания к описанию языка ST в справке можете оставлять в этой теме или присылать на почту soft@owen.ru.
> Вам нужно показать из себя здесь возмущенного пользователя который требует на разговор разработчика? Не много спеси в Вас?
Конструктивное взаимодействие разработчика (в данном случае OwenLogic-а) и пользователя продукта -- обычная, нормальная практика.
Ф. Блоки на ST порядок выполнения какой имеют?
Какой блок выполнится первым, какой вторым?
Если они между собой не связаны,
но для другой части программы их данные используют другие макросы.
Привет всем.
Archiver для ПЛК160 я использую.
Документации хватило.
А вот ПР205 - нечто новое.
Накидайте кто примеров работы с архивами.
Это вот это :-) https://ru.wikipedia.org/wiki/Программируемое_реле
Ну так я и о чём грю:
>> разновидность программируемых логических контроллеров (ПЛК).
Таки ПЛК.
>> Обычно программа создается на языке релейной логики (LD) или FBD при помощи компьютера
В ПР уже почти настоящий язык программирования ST.
>> Обычно имеют ограниченное число аналоговых и дискретных каналов ввода-вывода.
ПР102 программируемое реле на 40 каналов ввода/вывода.
>> Коммуникационные возможности зачастую ограничены каким-либо одним интерфейсом
Полный набор.
>> Программируемые реле отличаются от полноценных ПЛК малым числом каналов ввода-вывода,
>> малым объемом памяти программ, невозможностью исполнения сложных математических операций,
>> зачастую моноблочной конструкцией.
Делаем выводы.
Я с глючного ПЛК160 перебрался на ПР205, благо ST сделали вменяемым.
Ставить знак "=" между ПР205 и ПЛК160 некорректно. И зачем столько разношёрстного оборудования в одном шкафу?
Полгода назад было некорректно.
Язык ST ПЛК160,
и ST ФУНКЦИЯ ПР200 - это было несоизмеримо.
Сейчас ST сделали "почти нормальным" для ПРxxx,
в ПР205 появился ЖКИ графический.
Для наших задач связка: 4 канала с ПР200 -> данные на ПЛК160,
и передача на экран через Codesys.
Формирование отчёта в XLS - это было громоздко.
ПР205 позволил это децентрализовать, и получить компактную систему,
с накоплением данных (архивирование - это пока кот в мешке),
и работой с облаком (деньги с Master не принимает),
и возможность почти решить эту нашу глобальную задачу.
Спросить негде - гробовое молчание.
ST в ПЛК160 и ПР205 и сейчас несоизмеримы. Я уже почти всю библиотеку Standart переписал и половину Util. А в Вашем случае я бы поставил один ПЛК210 и WEB панель (наверно даже не Овен) и спал бы спокойно.
А я их и не соизмеряю.
Для решения задачи хватает возможностей ST ПР20x.
Ранее это делал ПЛК110, потом ПЛК160. Там ещё визуализация есть.
А ПРxxx имели функцию, и выход надо было разбирать и собирать из 4-х байт побитно.
Сейчас ST выдаёт сколько угодно переменных.
И задачи (наши) для ПЛК выполняются на ПР.
Это интересно. Если не жалко поделитесь.
Я считаю, что можно сложные задачи писать только на ST.
А все "квадратики" для простых задач.
Не спорю, есть решения и сложнейшие. Кому как.
Всё уже больше года работает.
Просто избавляемся от глючного ПЛК160...
И один ПР205 связан с облаком и формирует отчёт.
Точнее, будет формировать, но как этот "Архив" работает из доки толком не понять,
а примеров нет для ПР205...
А облако с ходу с карточки не смогли оплатить.
В чем сложность?
Открываете кодесисовские библиотеки как проекты и копируете тексты ФБ
Вложение 71836
Вложение 71837
Только Standard.LIB нужно иметь "специфическую"
Я в курсе. :)
https://owen.ru/forum/images/misc/quote_icon.png Сообщение от RV9WFJ https://owen.ru/forum/images/buttons/viewpost-right.png
Я уже почти всю библиотеку Standart переписал и половину Util.
Только вы же не только переписали, но и проверили в работе!
Я иду тем же путём, но стандартных обычно не хватает.
Беру исходники, и перерабатываю под свои задачи.
Вы с архивом под ПР205 случайно не работали?
А с чего вы взяли что в ПР есть полноценные архивы?
Может эта функция и заложена на далекое будущее)
Но сейчас -
" В архиве сохраняются следующие данные:
• состояние батареи;
• статус прибора (служебная информация для обращения в сервисный центр и в группу
технической поддержки)."
Архивация доступна для сетевых переменных. Для этого есть параметр "Архивировать значение".
Вложение 71847
Выгрузить архив можно, например, при помощи Owen Configurator в формате .csv.
Вложение 71848
Ура! Работает! Спасибо! :)
Только вот как по событию писать?
Желательно редактировать архив как массив.
Вложение 71852
А индекс "побегать" по массиву?
Выбрать массив?
Или индекс [50*2048] - это адрес всей памяти?
// ----------------------------------------------------------------
Пришло время писать статистику.
Что понятно из OL настроек "про архив":
1. Период архивирования: от 10 до 3600 секунд. задаю 12
Получаю 01м54c до 02м05с - при каждой перезаписи программы в ПР205 получается разная длительность.
Т.е. через 12 сек, пишется в 2048 байт. Будет больше переменных назначено - не запишутся.
2. Количество архивов: 10-50
3. Размер архива: 200-2048 байт
Т.е. записей до 50, длинной до 2048 байт.
4. Последний индекс архива: 0-65535
В какой из архивов от 0 до 50 последний раз записалось.
Этот массив доступен через сетевые регистры,
и через переменные.
Есть перечисление и назначение в настройках.
Как с этим всем работать, как с линейной областью памяти?
Естественно, не так часто, чтоб не "протереть до дыр".
ПР205 Руководство по эксплуатации 1-ru-110672-1.9.pdf
Максимальное количество файлов архива 300 шт. стр. 11
Хочу спросить, в языке ST я еще новичек, а возможно ли написать фунциональный блок, который будет в определенной последовательности активировать выхода (на пневмоцилиндры), при этом контролируя все получаемыми входными сигналами (с датчиков положения). Важно написать определенную последовательность. И при этом зациклить выполнение блока, с остановкой по входному сигналу.
Да. :)
Например, управление техпроцессом из шести вариантов прогонки электродвигателей.
Это пример рабочего кода под ПЛК160, который сейчас перенесён на ПР205.Код:IF kSTART=1 AND STEP=98 THEN STEP:=40; END_IF (* ПЕРЕзапуск для пров на КЗ [Pк]*)
IF kSTART=1 AND STEP=99 THEN STEP:= 0; OutX0; END_IF (* запуск очередной после полного прохода *)
IF kSTART=1 AND STEP=0 THEN STEP:=10; D00:=0; OutSVz1:=1; (* СТАРТ общий *)
v500:=s500a; v500:=v500*1000; vADC:=sADCa; vADC:=vADC*1000; v2000:=s2000a; v2000:=v2000*1000; (* индексировать *)
v380:=s380a; v380:=v380*1000; v100:=s100a; v100:=v100*1000; END_IF (* и прописать в секундах *)
(* IF kSTART=1 AND D01 <>0 THEN STEP:=D01; D01:=0; END_IF ( * выход из паузы *)
(* IF kPAUSE = 1 AND STEP <>0 THEN D01:=STEP; STEP:=10; END_IF вход в паузу *)
(* IF InR = 1 THEN nw:=0; Out10:=0; ELSE nw:=1; Out10:=1; END_IF *)
(* IF InR = 1 THEN при моделировании Alarm и Stop отключать останов по Alarm и STOP - вкл AlarmSV *)
IF kAlarm=0 OR kSTOP=0 THEN STEP:=0; OutX0; D00:=0; D01:=0; END_IF (* STOP любой *)
IF D00=3 THEN ZUMo:=100; SVzt:=1000; END_IF (* звук START цикла *)
CASE STEP OF (* Out1P1 Out2P1 Out3P1 Out4P1 Красный *)
10: IF D00 = 1 THEN OutX0; Out5P1:=1; Out1P1:=0; END_IF (* все выходы выключить 5 ИНДИКАЦИЯ зел включить *)
(*ADC*) IF D00 = 10 THEN ADC4v:=0;Out9:= 1; END_IF (* обмотка 1-я пара *)
IF D00 = vADC/2 THEN Out10:= 1; END_IF (* обмотка 2-я пара *)
IF D00 > vADC THEN Out10:= 0; END_IF (* Отключить *)
IF D00 > vADC+100 THEN Out9 := 0; END_IF DSS:=(vADC+2000)-D00; (* обратный счёт, откинуть три нуля *)
IF D00 > vADC+2000 THEN STEP:=20; D00:=0; (* OutX0; *) END_IF D00:=D00+1; (* тик программы *)
20: IF D00 = 1 THEN OutX0; Out6P1:= 1; END_IF (* все выходы выключить ИНДИКАЦИЯ включить *)
(*500*) IF D00 = 100 THEN Out12:= 1; END_IF (* Включить *)
IF D00 = 200 THEN Out9 := 1; END_IF (* Включить *)
IF D00 > v500 THEN Out9 := 0; END_IF (* Отключить *)
IF D00 > v500+100 THEN Out12:= 0; END_IF DSS:=(v500+1000)-D00; D00:=D00+1;
IF D00 > v500+1000 THEN STEP:=30; D00:=0; OutX0; END_IF (* Out2P1:=1; *)
30: IF D00 = 1 THEN OutX0; Out7P1:= 1; END_IF (* 380v измерения все выходы выключить *)
(*380*) IF D00 = 100 THEN Out12:= 1; END_IF (* Включить *)
IF D00 = 200 THEN Out11:= 1; END_IF (* Включить *)
IF D00 = 300 THEN Out9 := 1; END_IF (* Включить *)
IF D00 > v380 THEN Out9 := 0; END_IF (* Отключить *)
IF D00 > v380+100 THEN Out11:=Out12:=0; END_IF DSS:=(v380+1000)-D00; D00:=D00+1;
IF D00 > v380+1200 THEN STEP:=40; D00:=0; OutX0; FazA100:=FazB100:=FazC100:=0; (* обнулить перед переходом *) END_IF (* Out3P1:=1; *)
40: IF D00 = 1 THEN OutX0; Out8P1:= 1; STEP:=98; END_IF (* КЗ ротора - ждать фиксации вала TACK1_Motor1.STEP=20 OR TACK1_Motor1.STEP=6 *)
(*100*) IF D00 = 100 THEN Out11:= 1; END_IF (* Включить *)
IF D00 = 200 THEN Out9 := 1; END_IF (* Включить *)
IF D00 > v100 THEN Out9 := 0; END_IF (* Отключить *)
IF D00 > v100+100 THEN Out11:= 0; END_IF DSS:=(v100+2000)-D00; D00:=D00+1;
IF D00 > v100+2000 THEN STEP:=50; D00:=0; OutX0; END_IF (* Out4P1:=1; *)
50: IF D00 = 2000 THEN Out9 := 0; END_IF (* 2000 вольт *)
(*2000*)IF D00 > v2000 THEN Out9 := 0; END_IF DSS:=(v2000+1000)-D00; D00:=D00+1;
IF D00 > v2000+1000 THEN STEP:=99; D00:=0; OutX0; END_IF
90: IF D00 = 0 THEN ; END_IF (* обрыв обмотки *)
91: IF D00 = 0 THEN ; END_IF (* заглушка *)
92: IF D00 = 0 THEN ; END_IF (* заглушка *)
98: IF D00 = 0 THEN ; END_IF (* Pк - зажать вал *)
99: IF D00 = 0 THEN ; END_IF (* СЛЕДУЮЩИЙ - проверка завершена успешно *)
END_CASE IF InR=0 THEN ZUMv:=100; END_IF (* звук от Reset *)
IF ZUMo<>0 OR ZUMo>0 THEN ZUMo:=ZUMo-1; ZUM0 :=1; ELSE ZUM0 :=0; END_IF (* отсчёт длительности звука утробного *)
IF ZUMv<>0 OR ZUMv>0 THEN ZUMv:=ZUMv-1; OutZUM :=1; ELSE OutZUM :=0; END_IF (* отсчёт длительности звука внешнего *)
IF SVzt<>0 OR SVzt>0 THEN SVzt:=SVzt-1; OutSVz1:=1; ELSE OutSVz1:=0; END_IF (* отсчёт длительности светового сигнала *)
Укажите сколько датчиков, примерный алгоритм, и под какой ПЛК или ПР.
Это очень просто, поэтому попробую накидать вам вариант. :)