Ошибка 3728 codesys

PDF-файл Codesys (Руководство пользователя по программированию ПЛК в Codesys), страница 71 Управление процессами и оборудованием ОМД (МТ-6) (84519): Книга - 9 семестр (1 семестр магистратуры)

Если это не поможет, свяжитесь с изготовителем ПЛКCoDeSys V2.310-123Приложение J: Ошибки и предупреждения компилятора3601″<name> is a reserved variable name»Имя данной переменной зарезервировано генератором кода, измените его.3610″ ‘<Name>’ is not supported»Данное свойство не поддерживается в установленной целевой системе.3611″The given compile directory ‘<name>’ is invalid»В ‚Project’ ‚Options’ ‚Directories’ задана несуществующая директория для файлов компилятора.3612″Maximum number of POUs (<number>) exceeded! Compile is aborted.»В проекте используется слишком много POU.

Измените максимум POU в Target Settings / MemoryLayout.3613″Build canceled»Компиляция прервана пользователем.3614″Project must contain a POU named ‘<name>’ (main routine) or a taskconfiguration»Создайте главный POU (т.е. PLC_PRG) или задайте конфигурацию задач.3615″<Name> (main routine) must be of type program»Главный POU (т.е. PLC_PRG) должен иметь тип программа.3616″Programs musn’t be implemented in external libraries»Проект, который предполагается сохранить как внешнюю библиотеку? содержит программы.

Они небудут доступны в библиотеке.3617″Out of memory»Увеличьте размер виртуальной памяти вашего компьютера.CoDeSys V2.310-124Приложение J: Ошибки и предупреждения компилятора3618″BitAccess not supported in current code generator!»Битовый доступ не поддерживается генератором кода данной целевой системы.3619″Object file ‘<name>’ and library ‘<name>’ have different versions!»Убедитесь, что файлы *.lib и *.obj resp. *.hex соответствуют одной версии библиотеки.

Проверьте даты создания этих файлов.3620″The POU ‘<name>’ must not be present inside a library»Вы пытаетесь сохранить библиотеку в формате версии 2.1. В этой версии библиотека не может содержать PLC_PRG, удалите или переименуйте его.3621″Cannot write compile file ‘<name>'»Вероятнее всего, в директории, указанной для файлов компилятора, уже имеется файл с таким именем, имеющий атрибут «Только чтение «. Удалите данный файл либо измените ему права доступа.3622″The symbol file ‘<name>’ could not be created»Вероятнее всего, в директории, указанной для символьных файлов (обычно это директория проекта),уже имеется файл с таким именем, имеющий атрибут «Только чтение «.

Удалите данный файл либоизмените ему права доступа.3623″Cannot write boot project file ‘<name>'»Вероятнее всего, в директории, указанной для загрузочных файлов (специфичных для целевой платформы), уже имеется файл с таким именем, имеющий атрибут «Только чтение «. Удалите данный файллибо измените ему права доступа.3624″Target setting <targetsetting1>=<set value> not compatible with <targetsetting2>=<set value>»Проверьте и исправьте данные установки в диалоге Targetsettings dialogs (вкладка Resources). Если онинедоступны для редактирования, то обратитесь к изготовителю контроллера.3700» POU with name ‘<name>’ is already in library ‘<name>'»Имя POU проекта уже использовано в библиотеке, измените его.CoDeSys V2.310-125Приложение J: Ошибки и предупреждения компилятора3701″Name used in interface is not identical with POU Name»Используйте команду ‘Project’ ‘Rename object’ для изменения памяти POU в организаторе объектовлибо измените имя в окне объявления POU.

Имя POU следует за одним из ключевых слов: PROGRAM, FUNCTION или FUNCTIONBLOCK.3702″Overflow of identifier list»Не более 100 идентификаторов могут быть использованы при объявлении одной переменной.3703″Duplicate definition of identifier ‘<Name>'»Убедитесь, что только один идентификатор ‘<Name>’ присутствует в разделе объявлений POU.3704″data recursion: «<POU 0> -> <POU 1> -> .. -> <POU 0>»»Применен не допустимый вызов экземпляром функционального блока самого себя.3705″<Name>: VAR_IN_OUT in Top-Level-POU not allowed, if there is no Task-Configuration»Создайте конфигурацию задач или убедитесь, что переменные VAR_IN_OUT не используются вPLC_PRG.3720″Address expected after ‘AT'»После ключевого слова AT должен быть указан корректный адрес.3721″Only ‘VAR’ and ‘VAR_GLOBAL’ can be located to addresses»Поместите объявление в область VAR или VAR_GLOBAL.3722″Only ‘BOOL’ variables allowed on bit addresses»Только переменные типа BOOL могут адресовать биты.

Измените адрес или тип переменной.3726″Constants can not be laid on direct addresses»Константы нельзя располагать по прямым адресам.CoDeSys V2.310-126Приложение J: Ошибки и предупреждения компилятора3727″No array declaration allowed on this address»Объявление может быть произведено по указанному адресу. Измените адрес.3728″Invalid address: ‘<address>'»Указанный адрес не определен для заданной конфигурации ПЛК. Измените адрес или конфигурациюПЛК.3729″Invalid type ‘<name>’ at address: ‘<Name>’ «Переменная данного типа не может быть размещена по указанному адресу.

Например: адрес AT%IB1:WORD; не допустим, если включено выравнивание по четным адресам. Данная ошибка можетвозникнуть при попытке разместить массив по недопустимому прямому адресу.3740″Invalid type: ‘<Name>’ «Ошибка в типе данных объявления.3741″Expecting type specification»Ключевое слово или оператор использован вместо типа данных3742″Enumeration value expected»В определении перечисления пропущен идентификатор после скобки либо разделитель.3743″Integer number expected»Перечисления можно инициализировать только целыми значениями (INT).3744″Enum constant ‘<name>’ already defined»Проверьте соблюдение следующих правил при объявлении перечислений:•Все значения в одном перечислении должны быть уникальны.•Во всех глобальных перечислениях все значения должны быть уникальны.•Во всех локальных перечислениях все значения должны быть уникальны.CoDeSys V2.310-127Приложение J: Ошибки и предупреждения компилятора3745″Subranges are only allowed on Integers!»Переменные с ограниченным диапазоном образуются только на целочисленных типах.3746″Subrange ‘<name>’ is not compatible with Type ‘<name>'»Один из пределов диапазона выходит за область значений базового типа.3747″unknown string length: ‘<name>'»Для определения длины строки используется ошибочная константа.3748″More than three dimensions are not allowed for arrays»Нельзя использовать массивы с размерностью более трех.

Используйте ARRAY OF ARRAY при необходимости.3749″lower bound ‘<name>’ not defined»Не задана константа, определяющая нижнюю границу диапазона.3750″upper bound ‘<name>’ not defined»Не задана константа, определяющая верхнюю границу диапазона.3751″Invalid string length ‘<number of characters>'»Заданный размер строки превышает допустимый в данной целевой системе.3752“More than 9 dimensions are not allowed for nested arrays»Массив может быть 1- 2- или 3-мерный. Размерность можно еще увеличить путем вложений массивов(например, «arr: ARRAY [0..2,0..2,0..2] OF ARRAY [0..2,0..2,0..2] OF ARRAY [0..2,0..2,0..2, 0..2] OFDINT».

Максимальная размерность не должна превышать 9. Данная ошибка говорит о превышенииэтого ограничения. Уменьшите вложенность массивов.3760″Error in initial value»CoDeSys V2.310-128Приложение J: Ошибки и предупреждения компилятораИспользуйте для инициализации значение, совместимое с типом переменной. Изменяя объявление,воспользуйтесь диалогом объявлений переменных (Shift/F2 или ‘Edit»Autodeclare’).3761″‘VAR_IN_OUT’ variables must not have an initial value.»Удалите инициализацию в объявлении переменной VAR_IN_OUT.3780″‘VAR’, ‘VAR_INPUT’, ‘VAR_OUTPUT’ or ‘VAR_IN_OUT’ expected»В следующей за определением имени POU строке должно быть одно из перечисленных ключевыхслов.3781″‘END_VAR’ or identifier expected»Введите корректное определение END_VAR в данной строке окна объявлений.3782″Unexpected end»В разделе объявлений: добавьте ключевое слово END_VAR в конце раздела.В разделе кода: добавьте инструкцию, заканчивающую команду (например, END_IF).3783″END_STRUCT’ or identifier expected»Проверьте правильность окончания определения типа.3784″The current target doesn’t support attribute <attribute name>»Данная целевая система не поддерживает переменные такого типа (например, RETAIN, PERSISTENT)3800″The global variables need too much memory.

Increase the available memory in the project options.»Увеличьте число сегментов в опциях диалога Project’ ‚Options’ ‚Build’.3801″The variable ‘<Name>’ is too big. (<size> byte)»Переменная использует тип, занимающий более одного сегментаРазмер сегмента определяется настройкой целевой платформы. Если вы не нашли этого параметра вопциях памяти, свяжитесь с изготовителем ПЛК.CoDeSys V2.310-129Приложение J: Ошибки и предупреждения компилятора3802″Out of retain memory. Variable ‘<name>’, <number> bytes.»Израсходована вся память Retain переменных.

Обновлено: 29.01.2023

I am currently working on ABB PLC, I tried to upload the program from PLC but I cann’t make it. Now I got the backup program which have number of errors. The errors are

Error4268:RECIPE(32):Expression expected.
Error4052:RECIPE(32):»must be a declared instance of function block’ADDSUB’

Please help me on this. How to remove this error?

Lifetime Supporting Member
Join Date: Apr 2004
Location: Israel
Posts: 615

Can you upload the code?

Which PLC are you using?

Member
Join Date: Nov 2011
Location: Aurangabad
Posts: 9

I am using CPU PM571, with CD522, DC522, AX521 modules.

Code is attached here with

Member
Join Date: Dec 2012
Location: Koprivnica, HR
Posts: 418
Quote:
Originally Posted by kam

Error4268:RECIPE(32):Expression expected.
Error4052:RECIPE(32):»must be a declared instance of function block’ADDSUB’

Please help me on this. How to remove this error?

First error was probably due to forgotten semicolon at the end or = instead of :=

Second error: you forgot to declare function block instance as variable:

balash
View Public Profile
Find More Posts by balash

Member
Join Date: Nov 2011
Location: Aurangabad
Posts: 9

I checked program many times, we have given all necessary punctuation marks. Also we have declared each function block.

For ex. TRAVERS_MTR: AC500_REAL_AO;
SPOOLADD: ADDSUB;

Attached Files

Program.zip (40.2 KB, 17 views)

Member
Join Date: Dec 2012
Location: Koprivnica, HR
Posts: 418

well i can’t really much compile cause i have codesys integrated with control builder, and i miss lots of your custom libraries and PLC conf but.
if i am not wrong i think you forgot to name the instance of «addsub» box in rung 32. every functionblock box must have instance that is name of the functionblock box.

that would solve one problem i guess.

not much help with second problem cause i’m cripled without conf and libs needed.

balash
View Public Profile
Find More Posts by balash

Member
Join Date: Nov 2011
Location: Aurangabad
Posts: 9

Thanks for your reply.

I have resolved all the errors by following steps.

1. If you observe the PLC configuration you won’t found CD522 module, so to insert this module I upgraded my CoDeSys.

2. The programmer have declared the Function Blocks by some variable name, but forgot to give that variable name to certain block.
For ex. in OUTPUT (11) he used AC500_REAL_AO, but didn’t give the variable name to this function block, but he declared this block by ‘LEFT SPOOLER3’. So I give the same name to function block. and Bingo.

But not while going online I am going through a error. I have attached this for reference.

Читайте также:

  • Плач ярославны что значит выражение
  • Я в курсе выражение
  • Живет же горстка людей откуда фраза
  • Примером применения нормативного подхода в макроэкономическом анализе являются высказывания что
  • В жизни шура человеку должно повезти три раза откуда фраза

Old
April 21st, 2013, 04:26 AM

 
#1

Member

India

kam is offline

 

Join Date: Nov 2011

Location: Aurangabad

Posts: 9

Need help on ABB (CoDeSys) errors


Hi all,

I am currently working on ABB PLC, I tried to upload the program from PLC but I cann’t make it. Now I got the backup program which have number of errors. The errors are

Error4268:RECIPE(32):Expression expected.
Error4052:RECIPE(32):»must be a declared instance of function block’ADDSUB’Please help me on this. How to remove this error?

Thank you

Reply With Quote

Old
April 21st, 2013, 05:30 AM

 
#2

Lifetime Supporting Member

Israel

(8{)} ( .) is offline

 

(8{)} ( .)'s Avatar

 

Join Date: Apr 2004

Location: Israel

Posts: 616

Hi Kam.

Can you upload the code?

Which PLC are you using?

(8{)} (: .)
(Yosi)

Reply With Quote

Old
April 22nd, 2013, 02:39 AM

 
#3

Member

India

kam is offline

 

Join Date: Nov 2011

Location: Aurangabad

Posts: 9

I am using CPU PM571, with CD522, DC522, AX521 modules.

Code is attached here with

Reply With Quote

Old
April 22nd, 2013, 08:28 AM

 
#4

Member

Croatia

balash is offline

 

Join Date: Dec 2012

Location: Koprivnica, HR

Posts: 418

Quote:

Originally Posted by kam
View Post

Hi all,

Error4268:RECIPE(32):Expression expected.
Error4052:RECIPE(32):»must be a declared instance of function block’ADDSUB’Please help me on this. How to remove this error?

First error was probably due to forgotten semicolon at the end or = instead of :=

Second error: you forgot to declare function block instance as variable:


VAR
ADDSUB_inst_1 : ADDSUB;
(... rest of vars)
END_VAR

Reply With Quote

Old
April 23rd, 2013, 03:10 AM

 
#5

Member

India

kam is offline

 

Join Date: Nov 2011

Location: Aurangabad

Posts: 9

Hi balash,

I checked program many times, we have given all necessary punctuation marks. Also we have declared each function block.

For ex. TRAVERS_MTR: AC500_REAL_AO;
SPOOLADD: ADDSUB;

and so on…

Reply With Quote

Old
April 23rd, 2013, 01:49 PM

 
#6

Member

Croatia

balash is offline

 

Join Date: Dec 2012

Location: Koprivnica, HR

Posts: 418

well i can’t really much compile cause i have codesys integrated with control builder, and i miss lots of your custom libraries and PLC conf but…
if i am not wrong i think you forgot to name the instance of «addsub» box in rung 32. every functionblock box must have instance that is name of the functionblock box…

that would solve one problem i guess…

not much help with second problem cause i’m cripled without conf and libs needed…

Reply With Quote

Old
April 24th, 2013, 09:59 AM

 
#7

Member

India

kam is offline

 

Join Date: Nov 2011

Location: Aurangabad

Posts: 9

Hi balash,

Thanks for your reply.

I have resolved all the errors by following steps.

1. If you observe the PLC configuration you won’t found CD522 module, so to insert this module I upgraded my CoDeSys.

2. The programmer have declared the Function Blocks by some variable name, but forgot to give that variable name to certain block.
For ex. in OUTPUT (11) he used AC500_REAL_AO, but didn’t give the variable name to this function block, but he declared this block by ‘LEFT SPOOLER3’. So I give the same name to function block…. and Bingo.

But not while going online I am going through a error. I have attached this for reference.

Reply With Quote

0 / 0 / 0

Регистрация: 14.05.2015

Сообщений: 7

1

14.05.2015, 22:11. Показов 10633. Ответов 10


Добрый день.
Подскажите плиз начинающему.
Установил Codesys 2.3
При попытке виртуального подключения к контроллеру выдает ошибку связи. (для запуска программы)
Может я что-то делаю не так?
Фактически я к нему и не подключаюсь — хочу потренироваться в режиме эмуляции.

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь

0

Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

14.05.2015, 22:11

Ответы с готовыми решениями:

Внутреняя ошибка связи или нет связи с удалённым сервером
Данные сообщения выходят при загрузке сайтов и поэтому не могу загрузить ни одну…

Ошибка связи
Всем привет!
В общем из-за некоторых обстоятельств нужно срочно разобраться с APEX.
Проблема…

Ошибка связи.
Уважаемые знатоки, подскажите, может кто сталкивался…
Клиентская часть выдает ошибку &quot;The TCP/IP…

Ошибка связи
Всем привет, ребят, кому не сложно помогите со схемой БД, делаю АИС мастерской по ремонту бытовой…

10

91 / 86 / 12

Регистрация: 08.08.2013

Сообщений: 667

14.05.2015, 23:01

2

На вкладке «онлайн» галочка «Режим эмуляции» стоит?
Кидайте проект, гляну.

0

0 / 0 / 0

Регистрация: 14.05.2015

Сообщений: 7

14.05.2015, 23:31

 [ТС]

3

Спасибо, заработало!!

Добавлено через 13 минут
Поскажите режим запустился. Но выходной сигнал не меняется от входного. Схема тупо через реле времени.
Записываю в контроллер, нажимаю старт, меняю вход но ничего не проиходит…

0

0 / 0 / 0

Регистрация: 14.05.2015

Сообщений: 7

14.05.2015, 23:59

 [ТС]

4

Или просто вход А = выход В
вход меняю, выход не изменяется

Миниатюры

Ошибка связи в Codesys
 

0

Почетный модератор

Эксперт по компьютерным сетямЭксперт Windows

28037 / 15768 / 981

Регистрация: 15.09.2009

Сообщений: 67,753

Записей в блоге: 78

15.05.2015, 08:29

5

онлайн — логин
онлайн — ран

0

0 / 0 / 0

Регистрация: 14.05.2015

Сообщений: 7

15.05.2015, 08:48

 [ТС]

6

Совершенно верно, уважаемый. Но как увидеть изменение значений выходов?
В Owen logic для прогр. реле все изменяется «в онлайне» — изменил состояние входа, видно изменение выхода. А здесь не пойму.. Нужно делать визуализацию переменных, чтобы отследить работу?

0

0 / 0 / 0

Регистрация: 14.05.2015

Сообщений: 7

15.05.2015, 08:55

 [ТС]

7

Вот

Миниатюры

Ошибка связи в Codesys
 

0

0 / 0 / 0

Регистрация: 14.05.2015

Сообщений: 7

15.05.2015, 08:56

 [ТС]

8

Вход А изменяю, выход В не меняется…

0

Почетный модератор

Эксперт по компьютерным сетямЭксперт Windows

28037 / 15768 / 981

Регистрация: 15.09.2009

Сообщений: 67,753

Записей в блоге: 78

15.05.2015, 08:57

9

не нужно. двойной щелчок — ctrl+F7

1

0 / 0 / 0

Регистрация: 14.05.2015

Сообщений: 7

15.05.2015, 09:20

 [ТС]

10

O my god, заработалааа! Спасибо!

Добавлено через 12 минут
Еще маленький вопрос. В реальном времени отслеживать можно работу?
Имею ввиду задержки TON и TOF, как регулируются в режиме эмуляции?
Я вижу результат на выходе, но как это происходит можно увидеть?
Я выставляю время задержки последовательного пуска двигателей и мне это важно..

0

91 / 86 / 12

Регистрация: 08.08.2013

Сообщений: 667

15.05.2015, 10:06

11

сверху, там где объявляются переменные типа ton1:ton;
ПОСЛЕ того как запустите проект появится маленький плюсик, его надо раскрыть, тем самым вы увидите все внутренние переменные FB.
Если хотите менять время на TON или TOF, то вам необходима создать дополнительную переменную типа TIME и подсоединить её на вход таймера PT, тоесть переменную а не константу.
Пишется значение так «T#100ms» или «T#0,1s» и т.д.
Так же нажимаем F1 в codesys, переходим на вкладку ПОИСК и вбиваем туда интересующий нас блок, там все с примерами.

0

IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

15.05.2015, 10:06

Помогаю со студенческими работами здесь

CodeSYs v 2.3.9.43
здравствуйте форумчане. если возможно, то помогите реализовать в среде CodeSYs v 2.3.9.43 данные…

Codesys
Здравствуйте. Недавно скачал среду программирования Codesys v3.5, и не смог обнаружить под неё(и…

ошибка в связи с базой
Всем привет! вообщем ситуация такая дали готовые коды а базы не было . по запросам я пытался…

WAIT на CODESYS 2.3
Добрый день.
Задача следующая, необходимо после каждого цикла поставить счетчик обратного времени,…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

11

Продолжаем повествование о прагма-выражениях, которые были описаны в обзорной статье. 
Напомню что условные прагмы влияют на генерацию кода во время прекомпиляции и компиляции, но не во время исполнения программы.
С помощью условных прагм вы влияете, учитывается ли код реализации при компиляции. Например, вы можете сделать это зависимым от того, объявлена ​​ли определенная переменная, существует ли определенный функциональный блок и т.д.

Прагма {define}

Имеет синтаксис:

{define <identifier> <string>}

Задает какой либо идентификатор, который в последствии будет использоваться. Стоит помнить про область видимости. Данный идентификатор будет виден только в пределах того места где он был определен прагмой {define}.

Определение возможно только в разделе кода.

Чтобы было понятнее приложу скриншоты объявления и результаты выполнения.

Если вы заметили, то там еще есть флаги для идентификаторов С и D, С объявлен в глобальных данных, а D в POU программа, где мы и вызываем этот FB.

Прагма {undefine}

Оператор {define} идентификатора <identifier> отменяется, и с этого момента идентификатор снова становится неопределенным. Прагма игнорируется, если указанный идентификатор вообще не определен.

Рассмотрим несколько идентификаторов.

Определение нескольких идентификаторов прагмой {define}

В результате выполнения все хорошо скомпилировалось и все биты были взведены.

Теперь мы немного усложним данные директивы.

Логика здесь в следующем. Если нет C, то определяем идентификатор D.

Результат выполнения

Прагмы для условной компиляции

Назначение условных прагм - повлиять на генерацию кода в процессе пре-компиляции или в процессе компиляции. Язык реализации ST поддерживает эти прагмы.
Это как раз те условия, что мы писали выше. Единственное, что в блоке {IF} есть специальные операторы, которые позволяют нам гибко контролировать условия компиляции.

Оператор defined(<identifier>)

Этот оператор приводит к тому, что выражению присваивается значение ИСТИНА. Требование состоит в том, чтобы идентификатор <identifier> был определен с помощью инструкции {define} и не определялся снова после этого с помощью инструкции {undefine}; в противном случае возвращается ЛОЖЬ.

Примером этому служит все что было выше.

Оператор defined (variable: variable)

Этот оператор приводит к тому, что выражению присваивается значение ИСТИНА, если переменная объявлена ​​в текущей области; в противном случае возвращается ЛОЖЬ.

Если мы возьмем и напишем следующий код:

И попытаемся скомпилировать данную программу, то получим сообщение:

Результат выполнения компиляции

Следует только объявить данную переменную, как все скомпилируется без сообщения и переменной rSum будет присвоено значение 5.

Оператор defined (type: identifire)

Возвращает TRUE когда у нас есть объявленная переменная с соответствующим пользовательским типом данных.

Например: Нам требуется понять есть ли в данном функциональном блоке переменная с каким-то определенным пользовательским типом.

В исходном коде у нас есть и данный тип и прагма условие и какие-то действия.

Никогда не присваивайте значения каким-то объявленным переменным во время прагма выражений для условной компиляции если вы не полностью осознаете последствия.

При выполнении кода у нас будет присвоено значение равное 45.

Результат выполнения

В то же время стоит помнить

Прагма выражения чувствительны к регистру

И если type вдруг изменится на TYPE то мы получим ошибку

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

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

Оператор defined (pou: <pou name> )

Условный оператор возвращает TRUE если есть FB или Action с таким именем.

Вопрос. Какое значение будет у переменной xInit в следующем примере:

Пример

Когда я только начал разбираться, то был уверен, что xInit будет FALSE, однако:

Результат выполнения

Весь фокус заключался в том, что у меня в проекте есть POU TCPLogic. Так что данное условие удобно применять при проверки целостности. а все ли мы подтянули из нужных нам библиотек.

Оператор defined (task: <identifire)

Возвращает True если мы имеем task с нужным именем.

Рассмотрим список моих задач

Список задач

В нем есть ровно две задачи. Одна основная другая на визуализацию. В FB я создам условие, при котором, если будет отсутствовать в проекте необходимый TASK, переменная xError станет True.

Так как TASK с идентификатором MainTask1 у меня нет, то мы получили ошибку.

Оператор defined (IsSimulationMode)

Возвращает True, Когда мы находимся в режиме симуляции(эмуляции).

Ну тут даже не нужен пример.

Оператор defined (IsLittleEndian)

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

Стандартный SOFTPLC от Codesys

Итог

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

Как я могу выбросить стандартные системные исключения (и, если возможно, создать собственные исключения и выбросить их тоже).

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

Я нашел упоминания о функции AppGenerateException в библиотеке CmpApp, но не могу найти для нее ни документации, ни примеров. Может ли кто-нибудь указать мне на какую-то документацию по этому поводу?

1 ответ

Лучший ответ

Из любопытства я проверил AppGenerateException и убедился, что он работает. Получил некоторую помощь от этой справочной страницы Codesys .

Я по-прежнему считаю, что это не лучший способ добиться того, что вам нужно, но он может сработать.

К сожалению, у меня 64-битная система, а TRY..CATCH пока не работает в других, кроме 32-битных систем, насколько мне известно, поэтому я не смог проверить отлов.

Добавьте следующие библиотеки:

  • CmpApp
  • SysExcept

Тогда кажется, что следующий код работает. Установите для ThrowErr значение true, чтобы получить системное исключение.

PROGRAM PRG_TestThrow
VAR CONSTANT
    MY_PRIVATE_EXCEPTION : DWORD := 32001;
END_VAR
VAR
    ThrowErr    : BOOL; //Set this to TRUE to throw an error

    //The next two are for getting App instance
    _pApp       : POINTER TO CmpApp.APPLICATION;
    _Result     : SysExcept.SysTypes.RTS_IEC_RESULT;
END_VAR



//Get App instance
_pApp := AppGetCurrent(pResult := ADR(_Result));

IF ThrowErr THEN
    ThrowErr := FALSE;

    IF _pApp <> 0 THEN
        //Throw divide by zero exception
        AppGenerateException(pApp:=_pApp,   ulException:=RtsExceptions.RTSEXCPT_DIVIDEBYZERO);

        //You could use probably any available number as your own custom exception. 
        //For example the following works BUT not sure if it's ok to this.
        //AppGenerateException(pApp:=_pApp,   ulException:=MY_PRIVATE_EXCEPTION);

        //See RtsExceptions type for available exception codes. 
        //For my Codesys version, it has largest exception number of 0x2000 so all larger number are free (for now...)
    END_IF
END_IF

Кажется, что можно использовать любой пользовательский код исключения, например:

AppGenerateException(pApp:=_pApp,   ulException:=MY_PRIVATE_EXCEPTION);

Но это не задокументировано, поэтому я буду осторожен.


1

Quirzo
4 Июн 2020 в 08:48

Если это не поможет, свяжитесь с изготовителем ПЛКCoDeSys V2.310-123Приложение J: Ошибки и предупреждения компилятора3601″<name> is a reserved variable name»Имя данной переменной зарезервировано генератором кода, измените его.3610″ ‘<Name>’ is not supported»Данное свойство не поддерживается в установленной целевой системе.3611″The given compile directory ‘<name>’ is invalid»В ‚Project’ ‚Options’ ‚Directories’ задана несуществующая директория для файлов компилятора.3612″Maximum number of POUs (<number>) exceeded! Compile is aborted.»В проекте используется слишком много POU.

Измените максимум POU в Target Settings / MemoryLayout.3613″Build canceled»Компиляция прервана пользователем.3614″Project must contain a POU named ‘<name>’ (main routine) or a taskconfiguration»Создайте главный POU (т.е. PLC_PRG) или задайте конфигурацию задач.3615″<Name> (main routine) must be of type program»Главный POU (т.е. PLC_PRG) должен иметь тип программа.3616″Programs musn’t be implemented in external libraries»Проект, который предполагается сохранить как внешнюю библиотеку? содержит программы.

Они небудут доступны в библиотеке.3617″Out of memory»Увеличьте размер виртуальной памяти вашего компьютера.CoDeSys V2.310-124Приложение J: Ошибки и предупреждения компилятора3618″BitAccess not supported in current code generator!»Битовый доступ не поддерживается генератором кода данной целевой системы.3619″Object file ‘<name>’ and library ‘<name>’ have different versions!»Убедитесь, что файлы *.lib и *.obj resp. *.hex соответствуют одной версии библиотеки.

Проверьте даты создания этих файлов.3620″The POU ‘<name>’ must not be present inside a library»Вы пытаетесь сохранить библиотеку в формате версии 2.1. В этой версии библиотека не может содержать PLC_PRG, удалите или переименуйте его.3621″Cannot write compile file ‘<name>’»Вероятнее всего, в директории, указанной для файлов компилятора, уже имеется файл с таким именем, имеющий атрибут «Только чтение «. Удалите данный файл либо измените ему права доступа.3622″The symbol file ‘<name>’ could not be created»Вероятнее всего, в директории, указанной для символьных файлов (обычно это директория проекта),уже имеется файл с таким именем, имеющий атрибут «Только чтение «.

Удалите данный файл либоизмените ему права доступа.3623″Cannot write boot project file ‘<name>’»Вероятнее всего, в директории, указанной для загрузочных файлов (специфичных для целевой платформы), уже имеется файл с таким именем, имеющий атрибут «Только чтение «. Удалите данный файллибо измените ему права доступа.3624″Target setting <targetsetting1>=<set value> not compatible with <targetsetting2>=<set value>»Проверьте и исправьте данные установки в диалоге Targetsettings dialogs (вкладка Resources). Если онинедоступны для редактирования, то обратитесь к изготовителю контроллера.3700» POU with name ‘<name>’ is already in library ‘<name>’»Имя POU проекта уже использовано в библиотеке, измените его.CoDeSys V2.310-125Приложение J: Ошибки и предупреждения компилятора3701″Name used in interface is not identical with POU Name»Используйте команду ‘Project’ ‘Rename object’ для изменения памяти POU в организаторе объектовлибо измените имя в окне объявления POU.

Имя POU следует за одним из ключевых слов: PROGRAM, FUNCTION или FUNCTIONBLOCK.3702″Overflow of identifier list»Не более 100 идентификаторов могут быть использованы при объявлении одной переменной.3703″Duplicate definition of identifier ‘<Name>’»Убедитесь, что только один идентификатор ‘<Name>’ присутствует в разделе объявлений POU.3704″data recursion: «<POU 0> -> <POU 1> -> .. -> <POU 0>»»Применен не допустимый вызов экземпляром функционального блока самого себя.3705″<Name>: VAR_IN_OUT in Top-Level-POU not allowed, if there is no Task-Configuration»Создайте конфигурацию задач или убедитесь, что переменные VAR_IN_OUT не используются вPLC_PRG.3720″Address expected after ‘AT’»После ключевого слова AT должен быть указан корректный адрес.3721″Only ‘VAR’ and ‘VAR_GLOBAL’ can be located to addresses»Поместите объявление в область VAR или VAR_GLOBAL.3722″Only ‘BOOL’ variables allowed on bit addresses»Только переменные типа BOOL могут адресовать биты.

Измените адрес или тип переменной.3726″Constants can not be laid on direct addresses»Константы нельзя располагать по прямым адресам.CoDeSys V2.310-126Приложение J: Ошибки и предупреждения компилятора3727″No array declaration allowed on this address»Объявление может быть произведено по указанному адресу. Измените адрес.3728″Invalid address: ‘<address>’»Указанный адрес не определен для заданной конфигурации ПЛК. Измените адрес или конфигурациюПЛК.3729″Invalid type ‘<name>’ at address: ‘<Name>’ «Переменная данного типа не может быть размещена по указанному адресу.

Например: адрес AT%IB1:WORD; не допустим, если включено выравнивание по четным адресам. Данная ошибка можетвозникнуть при попытке разместить массив по недопустимому прямому адресу.3740″Invalid type: ‘<Name>’ «Ошибка в типе данных объявления.3741″Expecting type specification»Ключевое слово или оператор использован вместо типа данных3742″Enumeration value expected»В определении перечисления пропущен идентификатор после скобки либо разделитель.3743″Integer number expected»Перечисления можно инициализировать только целыми значениями (INT).3744″Enum constant ‘<name>’ already defined»Проверьте соблюдение следующих правил при объявлении перечислений:•Все значения в одном перечислении должны быть уникальны.•Во всех глобальных перечислениях все значения должны быть уникальны.•Во всех локальных перечислениях все значения должны быть уникальны.CoDeSys V2.310-127Приложение J: Ошибки и предупреждения компилятора3745″Subranges are only allowed on Integers!»Переменные с ограниченным диапазоном образуются только на целочисленных типах.3746″Subrange ‘<name>’ is not compatible with Type ‘<name>’»Один из пределов диапазона выходит за область значений базового типа.3747″unknown string length: ‘<name>’»Для определения длины строки используется ошибочная константа.3748″More than three dimensions are not allowed for arrays»Нельзя использовать массивы с размерностью более трех.

Используйте ARRAY OF ARRAY при необходимости.3749″lower bound ‘<name>’ not defined»Не задана константа, определяющая нижнюю границу диапазона.3750″upper bound ‘<name>’ not defined»Не задана константа, определяющая верхнюю границу диапазона.3751″Invalid string length ‘<number of characters>’»Заданный размер строки превышает допустимый в данной целевой системе.3752“More than 9 dimensions are not allowed for nested arrays»Массив может быть 1- 2- или 3-мерный. Размерность можно еще увеличить путем вложений массивов(например, «arr: ARRAY [0..2,0..2,0..2] OF ARRAY [0..2,0..2,0..2] OF ARRAY [0..2,0..2,0..2, 0..2] OFDINT».

Максимальная размерность не должна превышать 9. Данная ошибка говорит о превышенииэтого ограничения. Уменьшите вложенность массивов.3760″Error in initial value»CoDeSys V2.310-128Приложение J: Ошибки и предупреждения компилятораИспользуйте для инициализации значение, совместимое с типом переменной. Изменяя объявление,воспользуйтесь диалогом объявлений переменных (Shift/F2 или ‘Edit»Autodeclare’).3761″‘VAR_IN_OUT’ variables must not have an initial value.»Удалите инициализацию в объявлении переменной VAR_IN_OUT.3780″‘VAR’, ‘VAR_INPUT’, ‘VAR_OUTPUT’ or ‘VAR_IN_OUT’ expected»В следующей за определением имени POU строке должно быть одно из перечисленных ключевыхслов.3781″‘END_VAR’ or identifier expected»Введите корректное определение END_VAR в данной строке окна объявлений.3782″Unexpected end»В разделе объявлений: добавьте ключевое слово END_VAR в конце раздела.В разделе кода: добавьте инструкцию, заканчивающую команду (например, END_IF).3783″END_STRUCT’ or identifier expected»Проверьте правильность окончания определения типа.3784″The current target doesn’t support attribute <attribute name>»Данная целевая система не поддерживает переменные такого типа (например, RETAIN, PERSISTENT)3800″The global variables need too much memory.

Increase the available memory in the project options.»Увеличьте число сегментов в опциях диалога Project’ ‚Options’ ‚Build’.3801″The variable ‘<Name>’ is too big. (<size> byte)»Переменная использует тип, занимающий более одного сегментаРазмер сегмента определяется настройкой целевой платформы. Если вы не нашли этого параметра вопциях памяти, свяжитесь с изготовителем ПЛК.CoDeSys V2.310-129Приложение J: Ошибки и предупреждения компилятора3802″Out of retain memory. Variable ‘<name>’, <number> bytes.»Израсходована вся память Retain переменных.

kobrik писал(а):

Михайло писал(а):
1. Проверь, поддерживают ли контроллеры протокол Modbus TCP.

В даташитах обоих контроллеров указано что поддерживается Modbus TCP. Я впрочем уже использовал этот протокол для соединения по ОРС. Для меня сейчас загадка, как будет правильно сделать это в Овен.

Пробуй!

kobrik писал(а):

Михайло писал(а):2. Как ты думаешь, имеет ли значение, какой из контроллеров будет клиентом, а какой — сервером? Применительно к нашей задаче автоматизации, конечно.

Да имеет. Т.к. основная программа будет в Сиеменсе, который будет запрашивать данные у ПЛК110.

Действительно, имеет значение, но не настолько, чтобы совсем критично. На самом деле можно настроить обмен по обеим схемам: «Сименс — клиент» и «Сименс — сервер». По схеме «Сименс — сервер» Овен будет запрашивать входные значения для ПИД-регулятора у Сименса, а затем записывать в память Сименса выход ПИД-регулятора. То есть все будет работать.
Но все же логичнее клиентом делать тот узел, который является наиболее важным в системе. Что значит «важным»? Ну это тот узел, который управляет общим процессом. Дело в том, что клиент в отличие от сервера может произвольно приостанавливать обмен, определять ошибки обмена, изменять частоту запросов. Если сетевой кабель между клиентом и сервером оборвался, то такой случай можно обрабатывать в клиенте по определенной программе, например, можно зажечь светодиод, остановить обмен на 30 секунд, затем попробовать сделать один запрос, затем — через каждые 5 минут, через 1 час попыток связи включить сирену и т.д.

kobrik писал(а):

Михайло писал(а):3. Вопрос посложнее: могут ли контроллеры одновременно совмещать функции клиента и сервера? Например, контроллер S7-1200 пишет в память ПЛК110, а ПЛК110 в свою очередь пишет в память S7-1200.

Думаю могут, если правильно распределить адресацию и использовать отдельные блоки Мастер-Слейв.

Фишка в том, что протоколы TCP/IP обеспечивают логическое разделение нескольких разных соединений, то есть по одному кабелю Ethernet можно работать по нескольким протоколам одновременно и они не будут путаться. Главное, чтобы все эти протоколы поддерживали TCP/IP (протоколы-надстройки над TCP/IP). Если пытаться разбираться в TCP/IP, то там довольно сложная организация данных (стек TCP/IP, программные порты и т.д.). Главное для себя выяснить те свойства, которые придаются протоколам, которые поддерживают TCP/IP.
Свойства:
1. Адресация осуществляется через IP-адреса. Для сравнения: есть еще более простая, но негибкая адресация по MAC-адресам.
2. Можно создавать разветвленные Ethernet-сети с коммутаторами, маршрутизаторами.
3. Не нужно контролировать контрольную сумму (это уже делает TCP)
4. Можно совмещать несколько протоколов в одном «проводе». Например, можно работать по Modbus TCP и предоставлять веб-интерфейс. Также можно совместить два совершенно разных Modbus-соединения и они не запутаются друг с другом.

Может я сейчас еще какие-то свойства забыл упомянуть…

0 / 0 / 0

Регистрация: 14.05.2015

Сообщений: 7

1

14.05.2015, 22:11. Показов 10946. Ответов 10


Добрый день.
Подскажите плиз начинающему.
Установил Codesys 2.3
При попытке виртуального подключения к контроллеру выдает ошибку связи. (для запуска программы)
Может я что-то делаю не так?
Фактически я к нему и не подключаюсь — хочу потренироваться в режиме эмуляции.

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

14.05.2015, 22:11

Ответы с готовыми решениями:

Внутреняя ошибка связи или нет связи с удалённым сервером
Данные сообщения выходят при загрузке сайтов и поэтому не могу загрузить ни одну…

Ошибка связи
Всем привет!
В общем из-за некоторых обстоятельств нужно срочно разобраться с APEX.
Проблема…

Ошибка связи.
Уважаемые знатоки, подскажите, может кто сталкивался…
Клиентская часть выдает ошибку &quot;The TCP/IP…

Ошибка связи
Всем привет, ребят, кому не сложно помогите со схемой БД, делаю АИС мастерской по ремонту бытовой…

10

91 / 86 / 12

Регистрация: 08.08.2013

Сообщений: 667

14.05.2015, 23:01

2

На вкладке «онлайн» галочка «Режим эмуляции» стоит?
Кидайте проект, гляну.



0



0 / 0 / 0

Регистрация: 14.05.2015

Сообщений: 7

14.05.2015, 23:31

 [ТС]

3

Спасибо, заработало!!

Добавлено через 13 минут
Поскажите режим запустился. Но выходной сигнал не меняется от входного. Схема тупо через реле времени.
Записываю в контроллер, нажимаю старт, меняю вход но ничего не проиходит…



0



0 / 0 / 0

Регистрация: 14.05.2015

Сообщений: 7

14.05.2015, 23:59

 [ТС]

4

Или просто вход А = выход В
вход меняю, выход не изменяется

Миниатюры

Ошибка связи в Codesys
 



0



Почетный модератор

Эксперт по компьютерным сетямЭксперт Windows

28037 / 15768 / 981

Регистрация: 15.09.2009

Сообщений: 67,753

Записей в блоге: 78

15.05.2015, 08:29

5

онлайн — логин
онлайн — ран



0



0 / 0 / 0

Регистрация: 14.05.2015

Сообщений: 7

15.05.2015, 08:48

 [ТС]

6

Совершенно верно, уважаемый. Но как увидеть изменение значений выходов?
В Owen logic для прогр. реле все изменяется «в онлайне» — изменил состояние входа, видно изменение выхода. А здесь не пойму.. Нужно делать визуализацию переменных, чтобы отследить работу?



0



0 / 0 / 0

Регистрация: 14.05.2015

Сообщений: 7

15.05.2015, 08:55

 [ТС]

7

Вот

Миниатюры

Ошибка связи в Codesys
 



0



0 / 0 / 0

Регистрация: 14.05.2015

Сообщений: 7

15.05.2015, 08:56

 [ТС]

8

Вход А изменяю, выход В не меняется…



0



Почетный модератор

Эксперт по компьютерным сетямЭксперт Windows

28037 / 15768 / 981

Регистрация: 15.09.2009

Сообщений: 67,753

Записей в блоге: 78

15.05.2015, 08:57

9

не нужно. двойной щелчок — ctrl+F7



1



0 / 0 / 0

Регистрация: 14.05.2015

Сообщений: 7

15.05.2015, 09:20

 [ТС]

10

O my god, заработалааа! Спасибо!

Добавлено через 12 минут
Еще маленький вопрос. В реальном времени отслеживать можно работу?
Имею ввиду задержки TON и TOF, как регулируются в режиме эмуляции?
Я вижу результат на выходе, но как это происходит можно увидеть?
Я выставляю время задержки последовательного пуска двигателей и мне это важно..



0



91 / 86 / 12

Регистрация: 08.08.2013

Сообщений: 667

15.05.2015, 10:06

11

сверху, там где объявляются переменные типа ton1:ton;
ПОСЛЕ того как запустите проект появится маленький плюсик, его надо раскрыть, тем самым вы увидите все внутренние переменные FB.
Если хотите менять время на TON или TOF, то вам необходима создать дополнительную переменную типа TIME и подсоединить её на вход таймера PT, тоесть переменную а не константу.
Пишется значение так «T#100ms» или «T#0,1s» и т.д.
Так же нажимаем F1 в codesys, переходим на вкладку ПОИСК и вбиваем туда интересующий нас блок, там все с примерами.



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

15.05.2015, 10:06

Помогаю со студенческими работами здесь

CodeSYs v 2.3.9.43
здравствуйте форумчане. если возможно, то помогите реализовать в среде CodeSYs v 2.3.9.43 данные…

Codesys
Здравствуйте. Недавно скачал среду программирования Codesys v3.5, и не смог обнаружить под неё(и…

ошибка в связи с базой
Всем привет! вообщем ситуация такая дали готовые коды а базы не было . по запросам я пытался…

WAIT на CODESYS 2.3
Добрый день.
Задача следующая, необходимо после каждого цикла поставить счетчик обратного времени,…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

11

Время прочтения
8 мин

Просмотры 8.8K

Введение

За время работы инженером-программистом ПЛК очень часто в ходе разработки находились не самые очевидные, но довольно простые и красивые решения как типовых, так и специализированных задач. В этой статье хочу поделиться опытом и рассказать как сделать разработку под ПЛК приятнее и эффективнее.

Об опыте автора

Опыт работы с ПЛК: 3 года.

Разработка под ПЛК: Beckhoff CX series, SE Modicon M221, WAGO 750 series.

Среды разработки: TwinCAT 3, EcoStruxure Machine Expert-Basic, CODESYS V2.3.

Основная часть опыта приходится на ST+TwinCAT 3, который базируется на CODESYS и IEC 61131.

Статью решил написать так как покидаю OT и перехожу в мир IT. Хочется поделится опытом, чтобы эти 3 года не прошли даром.

Среда разработки

Если часто приходиться комментировать части кода — то узнайте какое сочетание клавиш позволит вам это сделать, это сэкономит много времени. В TwinCAT XAE Shell для комментирования выделенного кода: Ctrl+K+C и Ctrl+K+U для расскомментирования.

Обезвредьте кнопку Stop, чтобы случайно не остановить ПЛК, иногда такое случайное нажатие может привести к нежелательным последствиям. В TwinCAT XAE Shell можно выбрать какие кнопки выводить на toolbar. После локальной отладки программы рекомендую скрыть кнопку остановки ПЛК.

Structured Text

STRING vs WSTRING

В TwinCAT 3 есть возможность использовать Unicode строки. Они могут пригодиться, если необходимо передовать специфические символы, но без необходимости лучше не использовать WSTRING.

STRING

WSTRING

Format

ASCII

Unicode

Size of character

BYTE (1 byte)

WORD (2 bytes)

Terminator

Null character

0

Date and time

Почти в любом проекте необходимо знать точное время, вычислять временные интервалы. Часто работа с временем и датами доставляет много проблем и боли. Для себя я нашёл решение, уверен, оно упростит многим жизнь.

F_GetSystemTime() (Функция из модуля Tc2_System)

Эта функция может быть использована для считывания метки времени операционной системы. Временная метка представляет собой 64-разрядное целое значение с точностью до 100 нс. Помимо прочего, его можно использовать для синхронизации задач или измерения времени. Одна единица соответствует 100 нс. Время представляет собой количество интервалов в 100 нс с 1 января 1601 года.

Хранятся отметки в переменных типа ULINT. Зная всё это мы можем без труда рассчитывать интервалы времени с точностью до 100нс! Нужно просто найти разность между отметками.

К сожалению, стандартных функций для преобразования отметки в тип DATETYPE я не нашёл, поэтому пришлось реализовать такую функцию самостоятельно:

(*
:Description: Convert time since 1 January 1601 in 100 ns to DATE_AND_TIME  (Преобразует время с 1 Января 1601 года в 100 нс в DATE_AND_TIME)
:Usability: Convert timestamp to datetime

:Note: check then nSystemType more then 01.01.1970 00:00:00

Version history:
Kozhemaykin E. A. | Creating | 16.08.2021;
*)

FUNCTION F_SystemTimeToDT : DT
VAR CONSTANT
    SECONDS_BETWEEN_1601_AND_1970 : ULINT := 11_644_473_600;
END_VAR
VAR_INPUT
    nSystemTime : ULINT; // One unit is 100 ns since 1 January 1601
END_VAR
VAR
    nSeconds : ULINT;
END_VAR
nSeconds := (nSystemTime / 10_000_000) - SECONDS_BETWEEN_1601_AND_1970;
F_SystemTimeToDT := ULINT_TO_DT(nSeconds);

Как видно из кода, сложность заключалась в расчёте интервала между начальным отсчётом системного времени ПЛК и типа DATETIME.

Функция для получения текущей даты/времени в формате DATETIME

(*
:Description: Return datetime now in format DATE_AND_TIME (DT)
:Usability: For getting datetime now in format DATE_AND_TIME (DT)

Version history:
Kozhemaykin E. A. | Creating | 16.08.2021;
*)

FUNCTION F_DateTimeNow : DT
F_DateTimeNow := F_SystemTimeToDT(F_GetSystemTime());

Функция для получения прошедшего времени в формате TIME

(*
:Description: Time passed since tStart (Прошло времени c tStart)
:Usability: If need check how long time past

Version history:
Kozhemaykin E. A. | Creating | 16.08.2021;
*)

FUNCTION F_TimePassed : TIME
VAR_INPUT
    tStart: ULINT; (* Время начала в 100нс от 01.01.1601,
                    текущее время в данном формате предоставляет функция F_GetSystemTime()*)
END_VAR
F_TimePassed := ULINT_TO_TIME((F_GetSystemTime() - tStart) / 10000);

Числовые константы

Большинство документаций по обмену по промышленным протоколам содержит шестнадцатиричные адреса регистров, номера функций, обозначения комманд и т.д. Для битовых операций необходимо представлять числа в двоичном виде. Чтобы эффективно решать задачи, где приходиться отходить от десятичной системы счисления необходимо знать о возможности задания константных чисел заданного типа в заданной системе счисления.

В общем виде задание числовой константы выглядит так:

{datetype}#{numeral system}#value 

Пример: DINT#16#A1

Числовые значения могут быть двоичными числами, восьмеричными числами, десятичными числами или шестнадцатеричными числами. Если целое значение не является десятичным числом, его основание должно быть записано перед целочисленной константой, за которой следует символ хэша (#). Для шестнадцатеричных чисел цифры для чисел от 10 до 15, как обычно, представлены буквами A-F.

Типом этих числовых значений может быть BYTE, WORD, DWORD, SINT, USINT, INT, UINT, DINT, UDINT, REAL или LREAL.

ANY type

В языках программирования со статической типизацией довольно сложно делать универсальные функции/функциональные блоки. Когда мне поставили задачу собирать и анализировать различные данные, я решил, что копировать функциональные блоки и изменять в них только тип входного значения — не лучший вариант. Тогда появилась идея приводить все типы к одному и по объективным причинам это тип LREAL.

При реализации функции или метода вы можете объявлять входные данные (VAR_INPUT) как переменные с типом данных ANY. Далее вы можете получить указатель на значение, тип данных и размер переданной на этот вход переменной.

Структура типа данных ANY

TYPE AnyType :
STRUCT
    // the type of the actual parameter
    typeclass : __SYSTEM.TYPE_CLASS ;
    // the pointer to the actual parameter
    pvalue : POINTER TO BYTE;
    // the size of the data, to which the pointer points
    diSize : DINT;
END_STRUCT
END_TYPE

Кроме типа ANY существуют также дочерние типы:

Дерево наследования типов

Дерево наследования типов

Хочу обратить внимание что на вход типа ANY не может быть подана константа, поэтому в некоторых случаях придётся создавать дополнительную переменную.

Зная про этот тип мне удалось реализовать функцию, которая приводила данные разных типов к LREAL.

Функция по преобразованию числовых типов в LREAL

(*
:Description: Convert ANY_NUM and ANY_BIT to LREAL
:Usability: For development universal functions

:Note:
Valid types is:
ANY_NUM:
    - ANY_REAL: REAL, LREAL
    - ANY_INT: USINT, UINT, UDINT, ULINT, SINT, INT, DINT, LINT
ANY_BIT:
    - BYTE, WORD, DWORD, LWORD

Version history:
Kozhemaykin E. A. | Creating | 01.06.2021;
Kozhemaykin E. A. | {CLASS_TO_LREAL -> TO_LREAL | 03.11.2021;
 
*)

FUNCTION F_AnyNumToLREAL : LREAL
VAR_INPUT
    AnyNum: ANY; // Variable for converting, need have address
END_VAR
VAR
    pReal : POINTER TO REAL;   // pointer to a variable of the type REAL
    pLReal : POINTER TO LREAL;  // pointer to a variable of the type LREAL
    
    pUSInt : POINTER TO USINT;   // pointer to a variable of the type USInt
   	pUInt : POINTER TO UINT;  // pointer to a variable of the type UInt
   	pUDInt : POINTER TO UDINT;  // pointer to a variable of the type UDInt
    pULInt : POINTER TO ULINT;   // pointer to a variable of the type ULInt
    
   	pSInt : POINTER TO SINT;  // pointer to a variable of the type SInt
    pInt : POINTER TO INT;   // pointer to a variable of the type Int
   	pDInt : POINTER TO DINT;  // pointer to a variable of the type DInt
    pLInt : POINTER TO LINT;   // pointer to a variable of the type LInt
    
    pByte : POINTER TO BYTE;  // pointer to a variable of the type Byte
    pWord : POINTER TO WORD;   // pointer to a variable of the type Word
   	pDWord : POINTER TO DWORD;  // pointer to a variable of the type DWord
    pLWord : POINTER TO LWORD;   // pointer to a variable of the type LWord

END_VAR
VAR_OUTPUT
    OrginalType: __SYSTEM.TYPE_CLASS;
    bInvalidType: BOOL := FALSE;
END_VAR
// Real numbers
IF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_REAL) THEN
    pReal := AnyNum.pValue;
    OrginalType := __SYSTEM.TYPE_CLASS.TYPE_REAL;
    F_AnyNumToLREAL := TO_LREAL(pReal^);
ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_LREAL) THEN
    pLReal := AnyNum.pValue;
    OrginalType := __SYSTEM.TYPE_CLASS.TYPE_LREAL;
    F_AnyNumToLREAL := pLReal^;

// Bit's numbers
ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_BYTE) THEN
    pByte := AnyNum.pValue;
    OrginalType := __SYSTEM.TYPE_CLASS.TYPE_BYTE;
    F_AnyNumToLREAL := TO_LREAL(pByte^);
ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_WORD) THEN
    pWord := AnyNum.pValue;
    OrginalType := __SYSTEM.TYPE_CLASS.TYPE_WORD;
    F_AnyNumToLREAL := TO_LREAL(pWord^);
ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_DWORD) THEN
    pDWord := AnyNum.pValue;
    OrginalType := __SYSTEM.TYPE_CLASS.TYPE_DWORD;
    F_AnyNumToLREAL := TO_LREAL(pDWord^);
ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_LWORD) THEN
    pLWord := AnyNum.pValue;
    OrginalType := __SYSTEM.TYPE_CLASS.TYPE_LWORD;
    F_AnyNumToLREAL := TO_LREAL(pLWord^);

// Unsigned integers
ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_USINT) THEN
    pUSInt := AnyNum.pValue;
    OrginalType := __SYSTEM.TYPE_CLASS.TYPE_USINT;
    F_AnyNumToLREAL := TO_LREAL(pUSInt^);
ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_UINT) THEN
    pUInt := AnyNum.pValue;
    OrginalType := __SYSTEM.TYPE_CLASS.TYPE_UINT;
    F_AnyNumToLREAL := TO_LREAL(pUInt^);
ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_UDINT) THEN
    pUDInt := AnyNum.pValue;
    OrginalType := __SYSTEM.TYPE_CLASS.TYPE_UDINT;
    F_AnyNumToLREAL := TO_LREAL(pUDInt^);
ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_ULINT) THEN
    pULInt := AnyNum.pValue;
    OrginalType := __SYSTEM.TYPE_CLASS.TYPE_ULINT;
    F_AnyNumToLREAL := TO_LREAL(pULInt^);

// Signed integers
ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_SINT) THEN
    pSInt := AnyNum.pValue;
    OrginalType := __SYSTEM.TYPE_CLASS.TYPE_SINT;
    F_AnyNumToLREAL := TO_LREAL(pSInt^);
ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_INT) THEN
    pInt := AnyNum.pValue;
    OrginalType := __SYSTEM.TYPE_CLASS.TYPE_INT;
    F_AnyNumToLREAL := TO_LREAL(pInt^);
ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_DINT) THEN
    pDInt := AnyNum.pValue;
    OrginalType := __SYSTEM.TYPE_CLASS.TYPE_DINT;
    F_AnyNumToLREAL := TO_LREAL(pDInt^);
ELSIF (AnyNum.TypeClass = __SYSTEM.TYPE_CLASS.TYPE_LINT) THEN
    pLInt := AnyNum.pValue;
    OrginalType := __SYSTEM.TYPE_CLASS.TYPE_LINT;
    F_AnyNumToLREAL := TO_LREAL(pLInt^);
    
//Invalid type
ELSE
    F_AnyNumToLREAL := 0;
    bInvalidType := TRUE;
END_IF

REFERENCE

Все знают про указатели (POINTER) и связанные с ними проблемы, так вот многие из них можно избежать, если использовать ссылки(REFERENCE):

  • Ссылки проще в использовании: ссылку не нужно разыменовывать (с помощью ^), чтобы получить доступ к содержимому объекта, на который ссылается ссылка.

  • Более чистый синтаксис для передачи значений: Если вход является ссылкой, то нет необходимости писать ADDR(value).

  • В отличие от указателей, для ссылок компилятор проверяет типы данных при передаче значений.

Стоит отметить, что не всегда ссылкой можно заменить указатель, но когда это возможно, то сделайте это.

Pragmas

Инструкции pragma влияют на свойства переменных, относящихся к процессу компиляции или предкомпиляции. Не поленитесь просмотреть возможности каждого типа pragmas — обязательно найдёте что-то полезное для своего проекта.

Типы pragmas:

  • Message pragmas

  • Attribute pragmas

  • Conditional pragmas

  • Region pragma

  • Pragmas for warning suppression

Union

Union — тип структуры, который позволяет представлять значение в разных типах данных. Данная структура полезна при отладке кода а также при обработке входных значений.

В случае, если нужно обращаться к битам, то это можно сделать через точку. Но у этого способа я вижу огромный недостаток: нет возможности итерироваться по битам. Если нужно разобрать переменную на байты или по 16-бит или другим сложным образом, то вместо написания сложных функций попробуйте сначала сделать это с помощью Union.

SEL, MIN, MAX, LIMIT

Многим программистам ПЛК часто не хватает синтаксического сахара, которого много в других языках программирования. На примере функции SEL хочется показать, что возможно этот «сахар» в виде тернарного оператора не особо нужен.

Если вам нужно выбрать значение в зависимости от условия, выможете сделать это в одну строку:

value := SEL(condition, if false, if true);

Если вам нужно ограничить значение сверху и/или снизу, это также можно сделать в одну строку:

value := MIN(value, max_limit);
value := MAX(value, min_limit);
or
value := LIMIT(min_limit, value, max_limit); 

Многие функции и операторы, которых нам не хватает уже написаны — нужно только поискать.

Заключение

В статье описано,то на что лично мне захотелось обратить внимание (ООП решил не трогать). Буду рад если мой опыт принесёт кому-то пользу. Попрошу при использовании предоставленных функций оставлять продолжать version history.

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

Понравилась статья? Поделить с друзьями:
  • Ошибка 3д секьюр авторизации
  • Ошибка 3714 каменс
  • Ошибка 2afc bmw
  • Ошибка 2acb bmw e87
  • Ошибка 2abc бмв