Видеоурок по основам программирования контроллеров REGUL на языке ST: разбираются типы данных, структуры и объединения, выравнивание памяти, функциональные блоки, привязка переменных к модулям ввода-вывода, а также отладка в онлайн-режиме с точками останова и фиксацией значений.
- 00:18 Основы программирования контроллеров REGUL и привязка переменных
- 07:08 Атомарные типы данных и их размер в памяти
- 16:17 Особые области памяти и объединения
- 23:07 Атрибут PACKMODE и выравнивание адресов
- 32:02 Создание и использование функциональных блоков
- 46:57 Привязка переменных к модулям ввода-вывода
- 58:03 Привязка структуры к адресам модуля ввода-вывода
- 68:09 Изменение значения переменной в онлайн-режиме
- 81:40 Влияние триггера на загрузку центрального процессора
- 85:55 Точки останова и пошаговое выполнение программы
- REGUL
- ST
- SCADA
Кому полезно: Инженерам АСУ ТП, начинающим программировать ПЛК REGUL на языке ST
Описание составлено автоматически по расшифровке речи в ролике.
Расшифровка видео
0:18 Здравствуйте, в этом видеоуроке мы с вами изучим основные принципы программирования контроллеров Регул, а также рассмотрим способы привязки переменных каналом модули водовывода. Начнем в сегодняшнем видео уроке, мы с вами. Поговорим о основах программирования контроллеров Регул, а также о привязке переменных каналом модули и водовывода. Сейчас у меня открыта среда разработки Астро и 2 и в ней у меня уже подготовлен демонстрационный проект.
0:54 Также у меня имеется еще 1 экземпляр среды разработки, там открыт проект из предыдущего занятия, и в нем я уже добавил некий код в программу Плнца ПРГ. И на примере 2 сред я могу продемонстрировать, как можно копировать программные. Элементы из 1 проекта в другой выделяем необходимую программу, нажимаем контрл, центр переходим в другую среду разработки. Встаем либо на аппликейшен, либо на конкретную папку. Куда мы хотим вставить нашу программу и нажимаем контралвой?
1:34 Программа вставлена. Значит, программа у нас состоит из 2 основных частей, верхняя часть называется область определений. Здесь мы задаем наши переменные, определяем их типы и также можем задавать некие инициализирующие значения. Эти значения будут присвоены переменным при старте нашего проекта. Нижняя часть называется Область исполнения здесь. Мы описываем непосредственно код, который будет выполняться контроллером в цикле определенной задачи либо по какому то событию.
2:17 И этот код будет соответственно использовать те переменные, которые мы определили ранее. Сейчас мы наблюдаем, что в нашей программе. Имеется красное подчеркивание, то есть имеются некие ошибки, которые не позволяют нам полностью скомпилировать наш проект. Мы видим, что подчеркнутыми являются функции Лен и в Лен. При наведении курсора мыши возникает подсказка, по которой мы видим, что данный идентификатор у нас пока еще не задан. Для того чтобы эти функции смогли выполняться нормально, давайте скопируем название этой функции.
3:03 Откроем менеджер библиотек, находится он вот здесь, да был клик. Нажимаем добавить библиотеку, здесь обязательно нажимаем кнопку дополнительно для того, чтобы поиск осуществлялся по всему репозиторию. И верхнем поле вставляем название необходимой функции. Осуществляется поиск, и мы видим, что данное сочетание символов встречается в нескольких библиотеках, в частности. Эта функция описана в библиотеке, стандарт выбираем эту библиотеку, нажимаем ок.
3:49 Вставка библиотеки произошла, и библиотека появилась у нас в списке, вот мы видим, появилась библиотека Стандарт. Среди строковых функций мы можем как раз наблюдать ту самую функцию, ради которой мы добавляли нашу библиотеку. Аналогичным образом мы можем поступить и со следующей функцией. В Лен Ленконтрал Центр, менеджер библиотек, добавить дополнительно вставляем имя.
4:24 И здесь мы увидим, что данная функция расположена в библиотеке, стандарт 64 соответственно также добавляем. Произошло добавление. И вот библиотека стандарт 64 у нас также появился аналогичным образом, можно искать. Необходимые библиотеки для любых необходимых функций. Теперь рассмотрим, каким образом мы можем самостоятельно создать программу, если у нас нету заранее подготовленной. Для этого необходимо на плетейшем нажать правой кнопкой мыши. Выбрать пункт добавления объекта и здесь выбрать пункт полу программ организации Шмении и.
5:15 В данном случае мы создаем обычную программу подобным же образом, можно создавать и функциональные блоки, и функции. Также мы можем выбирать для наших программных компонентов язык, на котором мы предпочитаем писать код. Здесь поддерживается несколько стандартных языков программирования. Язык ст является наиболее универсальным и полнофункциональным. Возможно, кому то более привычно писать на языках в виде диаграмм, связанных по входам и выходам. Проблем никаких нет, пожалуйста, можете выбирать удобный для вас язык. Мы же будем сейчас все примеры рассматривать именно на языке ст, потому что он имеет максимальную функциональность и В. любом случае полностью вряд ли получится вам от него отказаться. Потому что, например, наполнение тех же функциональных блоков все равно будет писаться на том же языке. Ст выбираем язык, ст, имя.
6:19 Имя программы зададим, например, пол 1 нажмем добавить. И у нас создалась программа пол, 1 которая также имеет область определений и область исполнения. Данная программа нам не потребуется, поэтому можем ее удалить.
6:47 Теперь давайте рассмотрим, что у нас непосредственно есть в программе ЛСПРГ, начнем с области определения. Здесь у нас описаны множество различных переменных, 1 2 потребуются чуть позже здесь.
7:08 Блок переменных, по которым мы можем наблюдать примеры использования стандартных так называемых атомарных типов данных. То есть вот тут представлены типы, которые занимает в памяти 1 Байт здесь соответственно 2 Байта? Ниже 4 Байта и ниже 8 Байт, это все целочисленные типы, некоторые из них со знаком + или ты остальные без знака. Тип Булл представляет из себя по сути целый байт в памяти, но может принимать значение либо 0, либо единица, либо можно его также записывать текстом. Словом, тру или файлс, то есть вы можете самостоятельно выбирать режим записи, как вам больше нравится.
8:00 То есть несмотря на то, что это логический тип имеет всего 2 значения либо 0, либо единица в памяти, он занимает, повторюсь, весь байк. Для того чтобы использовать именно биты данных, вам будет необходимо воспользоваться структурами. О них мы поговорим чуть позже, так? Далее у нас идут типы с плавающей запятой. Тип Риел представляет из себя четырехбайтное число. Стандартное, у которого есть. Ограниченное количество значащих символов и в данном видео мы можем задать некое константное значение.
8:46 Префикс Рел необходим для того, чтобы компилятор правильно распознал значение, которое мы ему указываем, если мы не напишем этот префикс. Компилятор может начать ругаться на символ точки сказать, что для него это неизвестный символ в такой записи для компилятора, все будет понятно.
9:07 Следующий тип Эль Рио, по сути, аналог Рио, но удвоенной точности и соответственно в памяти он занимает уже 8 Байт. Далее идут типы для работы с датой и временем тип тайм предназначен для хранения условных временных промежутках, которые отсчитываются в миллиардекундах. Например, это период времени с момента последнего старта контроллера.
9:38 Форма представления. Данного числа выглядит следующим образом. То есть указывается это решетка от слова тайм и далее вот в таком строковом представлении записывается? Интервежация самого значения, повторюсь, что физические значения ячейки памяти хранится как четырехбайтное целое, по сути, по сути, двор. Далее тип ДТ или дейт тайм полное название, он представляет из себя также четырехбайтное целое число, но уже измеряется в секундах и, по сути, содержит именно количество секунд. Прошедшая с 1 января 70 года, по сути, это стандарт Линукс и Линукс Юникс.
10:27 С Данными типами можно осуществлять арифметические операции. Для этого у нас создан еще 1 параметр. ДТ Дельта и ниже, в коде у нас будет пример, где мы будем осуществлять вычитание из. 1 Значения? Дойтаем другого вот эта строка и результатом вычислений будет уже являться тип тайм. То есть еще раз мы из 1 ДТ большего вычитаем другое дт меньше, которая, как мы видим. Отличается у нас на 23 часа, и результирующим значением будет являться уже тип тайм, который будет как раз хранить себе временной промежуток продолжительностью 23 часа.
11:25 Далее работа со строками. Тут мы определяем обычную строку длиной 250 символов из простых аски символов, соответственно, 1 символ занимает 1 Байт. Ну и в данном случае мы присваиваем некое констатное значение, то есть строка будет содержать в себе предложения. Хэллоу Голд ниже пример работы со строками Юникод, называются они в стринга от слова Уайт. То есть широкий длина также 250 символов, и туда мы уже можем записать предложение на русском языке. В данном случае написали такое словосочетание.
12:13 Эти переменные нам потребуются для вычисления длины строк. Далее рассмотрим пример работы с массивами и. Ссылками на переменные массив задается вот таким вот образом. Мы пишем слово Эрей, далее в квадратных скобках задаем диапазон массива. В данном случае он у меня указан с индекса 0 по индекс. 7 То есть это будет 8 элементов? Типа Рел, также вы можете делать массивы структур или массивы функциональных блоков или массивы массивов. Можно делать многомерные массивы, для этого следует указать запятую и дальше продолжить следующий диапазон, пусть так.
13:07 В таком случае мы получаем двухмерный массив размерностью 8 на 10. Теперь по поводу того, что такое референс или ссылка. При помощи референдов мы можем задавать альтернативные имена для неких наших переменных, например, для нашего массива, а и, возможно, возможно, нам будет. Неудобно в ходе программы обращаться по конкретным индексом, потому что мы можем запутаться, особенно если у нас несколько сотен таких переменных, в каком же? Индексе какое именно значение у нас лежит? Но при этом мы не хотим создавать дублирующие переменные, в которой нам придется туда сюда осуществлять. Перекладку данных тогда мы можем создать переменные с осмысленными именами, например, т. Это температура, п это давление и л это какой нибудь уровень жидкости.
14:09 И таким образом мы назначаем альтернативное имя на. Конкретный элемент массива в целом мы можем ссылаться вообще на любую переменную. Главное, чтобы они совпадали по типу, и при этом мы еще можем в программе переназначать наши референс ссылки или как мы уже. Их называли альтернативные имена на другие переменные тех же типов. Делается это следующим образом, то есть используется специальный оператор реф, равно и мы переназначаем наш референс на некую переменную.
14:52 Далее. Рассмотрим возможность работы с указателями. В языке ст возможно использовать указатели, для этого используется специальный. Термин Пойнтер, в данном случае мы определили переменную ПВР, 1 как пойнтер на Рел. И для того, чтобы получить в нее значение, мы в коде программы должны будем воспользоваться функцией АДР, то есть. В качестве аргумента мы указываем обычную переменную, которая, где то в памяти расположена и в результате вызова функции. Адр в переменную повар 1 будет помещен адрес размещения этой переменной.
15:38 Сразу хочется отметить, что мы настоятельно не рекомендуем использовать указатели, потому что это связано с высоким риском ошибки и. Подобные ошибки с неверными указателями могут повлечь за собой крайне негативные последствия вплоть до остановки контроллера по исключению поэтому, чтобы. Не допустить случайно подобных ошибок мы все таки рекомендуем воздержаться от использования указателей и прибегать к ним только при крайней необходимости.
16:17 Далее рассмотрим работу с особыми областями памяти. Помимо общей памяти, в контроллере есть также 3 специализированные области. Это м память, ай, память и кью, память здесь у меня объявлены. Несколько переменных по Специальным адресам переменная в 1 у меня расположена по адресу процент м. То есть таким образом мы указываем, что она размещается именно в м памяти, далее д 1 говорит, что. Переменная сдвинута на 1 двор относительно начала области нашей м памяти. Ну, Дворт Буковка, да это значит 4 Байта и ниже переменная. В 2 у меня определена по адресу процент м дабл. Ю 2 Дабл Ю это от слова Ворд, то есть мы сдвинулись на 2 Ворда дважды. 2 Равно 4 таким образом переменная, по сути, расположена в той же области памяти, ну и 3 переменная процент. М. Б. 4 говорит о том, что она сдвинута уже на 4 Байта непосредственно. И таким образом мы видим, что все вот эти 3 переменные, они, по сути, наложены друг на друга в 1 и той же. области памяти, в каких то случаях это бывает полезно, в частности, к наложению различных интерпретаций одних и тех же данных. Мы на практике перейдем при работе с протоколом мобаз.
17:58 И также есть еще специальный. Вариант для указания бита, то есть м Икс. Это означает, что мы адресуемся по Байтова и дальше через точку. Мы указываем номер бита в этом байте, на который мы можем повесить нашу уже булавскую переменную. Далее идут 2 переменные, которые мы будем использовать для сохранения в энергонезависимой памяти, точнее их копии. К этому мы подойдем сейчас чуть попозже. И теперь несколько слов о структурных или так называемых пользовательских типов данных.
18:42 У меня здесь. Объявлена переменная, у 1 которая имеет такой тип, Ю деф Дата. Давайте посмотрим, что такое этот ю див дата, вот он здесь, у меня определен в структурах. Заходим. И видим, что на самом деле это не структура, а Юнион или по русски это объединение. Юнион отличается от структуры тем, что. Все элементы, которые в нем описаны, они в памяти расположены поверх друг друга, то есть все они начинаются с 1 и того же адреса и по сути. Юнион дает нам возможность именно интерпретации одних и тех же данных в разной форме зависимости от нашей потребности, сейчас мы на. Преду посмотрим, как это можно использовать. Мы видим, что у нас имеется массив из 8 вордов, то есть это получается всего 16 байт длина. Этого массива также имеется массив уже Байт, их соответственно непосредственно 16. То есть длины этих массивов совпадают, есть массив из?
20:10 6 Вордов, то есть получается это то же самое, что верхний, но просто чуть короче, то есть он занимает не до конца всю эту область 16. Байтов чуть меньше и также имеется еще. Переменная Дейта, которая определена также как некий особый тип. Давайте еще на 1 шаг глубже погрузимся и посмотрим, что это за тип ТФ, дата определена как структура заходим.
20:41 И здесь мы уже видим, что внутри этой структуры у нас расположено несколько различных переменных. Вот здесь они уже будут в памяти расположены друг за другом последовательно. В начале у нас идет блок из 8 битовых переменных, которым мы можем задавать. Непосредственно символьные имена, и таким образом в программе будет очень удобно к ним обращаться, не запоминая, в каком именно последовательно бить. И у нас лежит тот или иной флаг, а мы их сразу можем осмысленно называть.
21:18 После этого у нас идет переменная типа Ворд, в нее мы запишем константу и. Из 4 символов б запишем мы ее в шестнадцатеричном виде, значит. Значит, вот такая запись 16 решетка означает, что мы задаем значение именно в шестнадцатеричном виде в нашем примере. Также. Был приведен подобный вариант, здесь мы задавали значение в двоичном виде, и здесь также в шестнадцатеричном. В принципе мы можем использовать и восьмеричные. Какой угодно, вот ну традиционно чаще всего будут, бывает, востребованы именно двоичный, шестнадцатеричный десятичной. Итак, вернемся к нашей структуре.
22:15 У нас имеется. 8 Бит, которые, естественно, будут упакованы в рамках 1 Байта. Далее у нас имеется 1 Ворд с констатным значением ВББ и имеется 1 Эльворд. То есть это восьмибайтная, переменная и все 8 Байт у нас заполнены шестнадцатеричными символами Ц.
22:42 Теперь попробуем представить, как данные переменные будут располагаться в нашей оперативной памяти. На 1 взгляд может показаться, что все достаточно. Очевидно, и они будут следовать непосредственно друг за другом без всяких пропусков. Но на самом деле это не всегда так на это оказывает влияние атрибут.
23:07 Пакмолт. Если данный атрибут не задан, а по умолчанию при создании структуры он не задан. Вот сейчас я как бы убрал в таком случае по умолчанию. Применяется Покмот равный, 8 что на практике для нас это означает. В случае покмот отличного от единицы у нас происходит выравнивание в памяти всех переменных в соответствии с их размером. То есть постараемся осмыслить, что это значит переменная ворд? У нее размер 2 Байта, соответственно, она должна располагаться в памяти по адресу кратной двойки.
23:55 Переменная Эльворт, у нее размер 8 байт, соответственно, в памяти она должна располагаться по адресу кратном восьмерки. И таким образом, в случае, если у нас по КМУ отсутствует, означает, что это равно 8 мы можем получить пустые области памяти между этими переменными. Давайте рассмотрим это дело на картинке.
24:29 Без атрибута Пакмот. Все мои биты, упакованные в рамках 1 Байта, будут находиться вот здесь. Мы их условно назвали, а а это если их через 1 указывать, 0 1 0 1 0 1 то мы как раз. Получим шестоперичное значение, а А. А когда мы вернемся в программу и будем рассматривать режим онлайн, мы как раз это продемонстрируем, далее у нас следует.
25:00 Переменная типа Ворд, которая содержит в себе шестнадцатиричные символы ББ, и в конце располагается наша восьмибайтная переменная. И как мы можем наблюдать за счет выравнивания? У нас произошла сдвижка, то есть имеется пустая. Область вот здесь, Вадим Байк, для того чтобы переменной тип порты встала на свой выровненный адрес, а для выравнивания большой переменной размерностью. 8 Байт, нам требуется сдвинуть еще дополнительно на 4 Байта, чтобы получить.
25:36 Адрес кратный 8 начало структуры, она по умолчанию всегда выровнены. Следующий вариант мы можем также. Не использовать атрибут Акмот, но при этом мы осмысленно описываем переменные таким образом, чтобы они располагались без пустот. То есть мы сюда добавили отдельную переменную типа Байт и сюда добавили отдельную переменную? Типа Риел, в данном случае мы решили присвоить ей значение 12 1 шестнадцатеричное представление. Это будет выглядеть вот так, и тогда даже при.
26:25 Покмот 8 у нас все переменные будут расположены последовательно, без пустот, но вручную подбирать типы по их размеру, естественно, очень затруднительно и неудобно. Следующий вариант мы можем изначально, формируя нашу структуру, располагать все типы по убыванию их размера. То есть мы располагаем сначала все переменные больших типов? Восьмибайтовых потом, соответственно, четырехбайтные двухбайтные и однобайтные. В таком случае уже по определению переменные будут оказываться на выровненных адресах и никакие. Сдвижки нам не потребуются, но в данном случае структура у нас все равно будет занимать 16 Байт, потому что ее размер будет выровнен кратно максимальному элементу в данном. случае у нас максимальный элемент восьмибайтный. Соответственно, структура должна быть кратная 8 по размеру, и мы получаем в конце вот такой хвост из пустых ячеек памяти.
27:33 И последний вариант. Мы видим, что при использовании атрибута покмот равным единице у нас происходит сдвижка в памяти вплотную всех переменных. То есть, по сути, это 1 вариант только уже без пустот. Какие есть плюсы и минусы всех этих вариантов? И почему нам нельзя задать, 1 какой то покмот на всю жизнь и больше к этому вопросу не возвращаться? Дело в том, что скорость работы.
28:08 Нашего контроллера, а точнее, его процессора достаточно сильно зависит от выравнивания переменных. То есть, когда мы работаем с невыравненным переменными последний 4 вариант процессору, перед тем как выполнять некие операции? С переменными сначала приходится их выравнивать, потом выполнять операцию и потом задвигать их обратно. На это требуются лишние ресурсы, то есть вариант с Пахмут 8 будет работать быстрее, также очень важный момент, что на.
28:40 Процессорах 2 типа, которые АРМ. Более бюджетные версии на них. Работа с невыровненными переменными в некоторых случаях не во всех, но в некоторых может приводить к исключению. И соответственно, контроллер у вас вообще может сразу остановиться. При обращении к 1 же неверно определенной переменной, которая не выровнена в памяти. Поэтому там, конечно, более безопасно оставлять переменные именно в выровненном состоянии.
29:20 Но, с другой стороны, плотная упаковка данных вот вариант 4. Соответственно, нам может потребоваться для передачи данных, по какому либо протоколу верхнего уровня. Например, когда мы перейдем, к примеру, с протоколом от вас нам как раз потребуется упаковать. Последовательно в памяти различные переменные и единым блоком через холдинг регистры все это передавать клиентам вот вот если мы. Будем передавать, так сказать, рыхлые данные. Вот с такими дырами то на принимающей стороне они могут неверно наложиться на входную.
30:00 Структуры и таким образом возникнут ошибки, вот поэтому вот эти моменты нужно иметь ввиду и выбирать оптимальный вариант, исходя из вашей конкретной задачи. Получается, мы сформировали вот такую структуру? Точнее, тип назвали его т. Девдата и определили экземпляр этой структуры внутри нашего Юниона и За. Счет юниона получается, мы можем обращаться к нашим данным либо как к отдельным переменным лежащим внутри нашей структуры, либо представить эти же. Самые данные просто в виде массива Байт или Ворд. В данном случае Ворд в данном случае Байт, то есть записав обычные переменные, далее мы можем их. Представить, как массив вордов, то есть, по сути, холдинг регистров и уже именно эти холдинг Регистры далее передавать по тому же Мак Бас протокол.
31:05 Возвращаемся к нашей программе и. Мы рассмотрели с вами структурные типы. Если нам необходимо добавить свой собственный новый структурный тип, то мы можем можем на аплекейшем нажать правой кнопкой мыши. Добавление объекта и здесь мы уже выбираем дуд дата юзер тайп. Соответственно, тут можно выбрать структуру объединения. Это вот тот самый юнион, также можно выбрать перечисление. Это Нумерейшен, либо просто некий псевдоним для уже существующей структуры. Сейчас мы добавлять ничего нового не будем.
31:57 Идем далее. Теперь рассмотрим работу с функциональными блоками. Тут мы создали некую служебную переменную симка унтер, которая. Будет у нас в программе увеличиваться постоянно. Задаем экземпляр от некого функционального блока ФБ Синус. ВБ Синус Икс у нас создан. Да, повторюсь, что функциональный блок создается также как программа, то есть мы выбираем апликейшен. Правая кнопка, добавление объекта пол и здесь просто выбираем функциональный блок, они могут. Быть наследованы от родительских функциональных блоков. По сути, мы можем уже использовать полноценное объектно ориентированное программирование, но сейчас мы не будем усложнять пример и.
33:02 И вернемся к нашему существующему функциональному блоку. Заййдем в него, вот у нас ФБ Синус Икс. Он также, как и программа, может иметь, ну, точнее, не может иметь. А именно имеет область определений и исполняемую область, которая называется основным методом функционального блока. В области определений мы задали. 4 Входных аргумента это некие параметры Хайлоу и период и переменная х, от которой будет непосредственно вычисляться наш Синус. В качестве выходной переменной мы обозначили переменную вылью, то есть в нем будем возвращать итоговое значение в основном методе функционального блока мы. Производим простейшее вычисление, то есть входной аргумент Х. Мы умножаем на 2 пи по правилам тригонометрии, и у нас определено как константа, сейчас мы на нее. Тоже посмотрим, делим на период, который у нас задан в качестве входного аргумента и далее производим масштабирование за счет параметров. Хай и Лоу таким образом. Мы можем задать Синусоиду, которая будет ограничена конкретными пределами и соответственно сверху лоу снизу и будет колебаться с необходимым нам периодом.
34:35 Естественно, должен постоянно. Измененный приходить в наш функциональный блок. Стоит также обратить внимание на варианты определения экземпляров функциональных блоков. То есть еще раз вот это у нас сам функциональный блок, который должен быть. Определен, где то ниже, а это его конкретный экземпляр. То есть мы можем создать несколько экземпляров от одних и тех же функциональных блоков, причем с разными параметрами?
35:10 И в данном случае у меня пример несколько усложнен дополнительно за счет создания так называемого конструктора функционального блока. Здесь мы видим метод ФБ и нет, чтобы его создать вручную. Можно нажать правой кнопкой на функциональном блоке. Выбрать функциональный блок, правая кнопка, добавление объекта, и здесь можно выбрать метод. В данном случае у нас задан метод со специальным названием ФБ ИНИТ, которая является конструктором. При формировании конструктора необходимо также обязательно всегда задавать вот такие 2 служебные переменные. И только после них следует уже ваши собственные переменные, которые вам необходимо в данном случае у меня в конструкторе.
36:05 Заданы 3 параметра. И в основном методе конструктора я просто перекидываю значения этих входных параметров в мои внутренние переменные хайлоу и период уже самого функционального блока. То есть вот в эти перемены, для чего нам нужен конструктор? 1 Сейчас давайте вернемся. Сюда. В случае, если у нас конструктор не задан. Вот этот вариант, то мы можем определять экземпляры с произвольным порядком и количеством входных аргументов, то есть в данном случае. Мы помним, да что у нас всего 4 входных параметра в наш функциональный блок, но мы здесь указали всего 2 из них. явным образом, причем и поменяли еще их местами. Да, то есть у нас в области определений Лоу был определен раньше, чем то есть, это вполне допустимо. В случае именно отсутствия конструктора, то есть, если бы у нас вот этого ФБ и нет, здесь не было.
37:20 Это позволяет пользователю иметь достаточно широкую свободу и создавать, в том числе функциональные блоки вообще без каких либо инициализирующих значений. Ну и в каких то случаях это может привести к проблемам, если вдруг пользователь забудет задать? Необходимый аргумент для функционального блока, который, например, вы для него подготовили, а он не внимательно прочитал документацию по используемым блоком. В случае же, если мы используем конструктор ФБ и нет, мы в нем задаем фиксированный набор параметров.
37:57 Давайте я обратно верну комментарий, и в таком случае нам потребуется уже обязательно указывать необходимое количество параметров именно. В том порядке, как они следуют в конструкторе, то есть в данном случае у меня указано 3 параметра. Ну или 3 аргумента, да это тоже самое.
38:17 Потому что в самом конструкторе их как раз таки 3. То есть в момент, когда будет запущен наш проект, однократно всегда вызывается конструктор, происходит вызов основного метода конструктора. И дальше он уже в процессе работы контроллера не используется.
38:45 Вот таким образом мы подготовили наш экземпляр функционального блока Синус Икс, 1 который будет вычислять нам измененное значение Синуса. Эти переменные нам потребуются также чуть позже и рассмотрим специальные переменные. Которая определяется в области варитейн и ВАР пер систент. Обычные переменные, которые мы определяем в области ВАР у нас. Инициализируется именно в момент старта контроллера в процессе исполнения алгоритмов. Как то изменяются, но в случае, если мы перезагрузили контроллер. Или пропало питание, естественно, все значения этих переменных теряются. И после загрузки контроллер начинает, так сказать, с чистого листа на работу.
39:42 Но при этом есть специальные переменные, которые позволяют нам сохранять значение в энергонезависимой памяти. Ну, по сути, на жестком диске либо в новых модификациях контроллерах у нас будет использоваться специальный блок памяти типа Срам. Для хранения этих переменных чем же, как это работает и чем же отличается ретейн от? Переменные и персидскопеременные записываются после их изменения в течение ближайших 10 секунд автоматически, то есть в этом плане. Можно сказать, что они одинаковы. То есть, если мы в переменную ряд 1 в нашем программе в программном коде запишем некое значение, то? Гарантировано именно в течение 10 секунд не мгновенно, а вот именно где то в этом промежутке она будет сохранена на жесткий диск, если. Естественно, мы записали переменную, а буквально через полсекунды у нас контроллер перезагрузился. Переменная может не успеть сохраниться.
40:49 В этом плане. Наши области ретейн и персистан одинаковы. Отличие состоит в том, что мы можем выполнять в процессе. Работы нашего контроллера специальные операции, это сброс сброс, холодный и сброс заводской обычный сброс позволяет нам. Вернуть значения обычных переменных, которые определены в области ВАР к своим первоначальным значениям, которые возникают в момент старта нашего проекта. То есть это простой сброс, сброс холодный, позволяет сделать то же самое, + обнуляется значение.
41:37 Ретоеин переменных. И наконец сброс заводской. Обнувляет, ну или правильнее сказать, возвращает первоначальные значения всем переменным, то есть и Вар, и Вар. Ретейный Вар Персистан и + еще удаляет приложение. Из контроллера Поэтому Рекомендуются уставки хранить все таки именно в ВАР Персистан. Также немаловажный момент, что при полной загрузке нашего проекта в контроллер, то есть не онлайн изменения, а именно полная загрузка происходит перезатирание. Переменных ретейных, ну и обычные вар перемены, естественно, также переинициализируется. А вот Персистен переменная можно изменить либо удалить только явным образом, то есть либо присвоить новое значение в проекте, либо выполнить.
42:41 Сброс заводской. То есть, ну, условно, можно сказать, что персидском переменная, надежный? При этом ретейн переменные можно определять отдельно в каждой программе, то есть они. Могут быть локальными, а персисты переменные обязательно должны быть продублированы в специализированной области. Пересистен тварств, вот я в нее зашел, она. Добавляется также через апликейшен апликейшен правая кнопка добавить объект. И вот здесь, в списке, у вас будет присутствовать вот этот самый персисный варс у. Меня он здесь сейчас отсутствует по причине того, что я его уже добавил. А этот объект может быть только уникальным соответственно из списка, здесь он пропал.
43:30 И при Плении специальной операции правая кнопка добавить все пути экземпляров. Компилятор пробегается по проекту, обнаруживают все наши области. Перечистим Кварц в частности. Нашу область определенную в программе ПЛЦ ПРГ. Вот эту и дублирует наши переменные автоматически. Вот сюда, то есть, вот мы видим, что уже у меня добавлена переменная, которая определена именно в программе ПЛЦ ПРГ. Повторюсь, что выполнить эту операцию можно именно. Таким образом, добавить все пути экземпляров. Теперь давайте перейдем непосредственно к рассмотрению в нашей программы, которая расположена в области исполнения.
44:23 Данную часть нам будет удобнее смотреть непосредственно в режиме онлайн. Мы к ней вернемся чуть позже, а пока давайте поговорим о циклах и операторах ветвления. В принципе, они достаточно стандартные, как и в любых других языках, программирования вообще в целом. Наверное, вы уже заметили, что синтаксис языка ст очень сильно похож на Паскаль и, собственно, многие операторы прямо также и выглядит. Например, мы рассмотрим простейший оператор ветвления, это ив, то есть мы указываем некое логическое условие. Если она выполняется, то выполняется код внутри самого Ифа, в противном случае выполняется то, что указано по. После Элс, в данном случае мы сделали такой пример, в котором при взведении Триггера Хайлова Триггер, то есть присвоение ему значения. 1 Мы будем проваливаться вот сюда, и у нас будет выполняться цикл Вайл, в котором у нас.
45:30 Это 100000 раз будет присваиваться некое константное значение в переменную типа Элерил. То есть таким образом мы создаем достаточно высокую нагрузку на процессор? Да, то есть в каждом цикле нашей программы будет вызываться вот этот вот цикл из 100000. операций с плавающей точкой, ну и мы сможем посмотреть наглядно, как это влияет на загрузку нашего процессора. Вот, ну и соответственно, если мы Триггер опускаем в 0, то у нас просто записывается некая Константа, и никакой лишней нагрузки не происходит.
46:09 Цикл Уайл, он, соответственно, выполняется до тех пор, пока исполняется указанное здесь условие, выполняется, точнее сказать. Также имеется. Оператор ветвления кейс он, он осуществляет переход на конкретное место программы в зависимости от значения входной переменной. То есть переменная степ у нас будет принимать различные значения. И в зависимости от того, какое именно значение она приняла. Мы перейдем либо сюда, либо сюда, либо сюда, вот если степ не равен ни единицы, ни двойки, не тройки, тогда мы перейдем уже в Элс.
46:55 Ну и теперь. Теперь можно еще несколько слов сказать о привязки переменных. У нас имеются модули ввода вывода, в частности модуль, а и 0 8 0 41 можем в него зайти через Дабл Клик. На 1 странице я закладок мы видим, что у нас. Есть возможность для каждого канала выбрать тип величины, которые этот канал будет отображать всего существует 3 типа. Это код АЦП электрическая величина, которая пересчитывается уже в. соответствии с калибровочными коэффициентами либо инженерная величина. В случае, если выбираем именно инженерную, то нам будет необходимо указать коэффициенты к большое 0 и к большое 1, и тогда.
47:53 Будет уже самим модулем осуществляться, пересчет к нашей инженерной величине. Но пока давайте оставим электрическую величину, мы выбираем тип. канала в данном случае я выбрал для 1 3 каналов токовый режим 4 20 миллиампер. Эти каналы у меня работают по напряжению, ну и Нижний опять потоку.
48:16 На данной закладке мы можем осуществить привязку переменных к нашим каналам. Вот здесь давайте остановимся поподробнее. Такие вообще существуют способы привязки переменных. Самый простой и очевидный способ это. Создать собственную переменную необходимого типа Все значения в каналах у нас имеет тип рел. Вот Рел, вот Рел, вот Рел и соответственно. Мы можем создать переменную типа Риел и явным образом ее сюда привязать. То есть у меня уже определена переменная сеяч. 3 Давайте посмотрим, где она у меня определена, у меня имеется область, Дживэль.
49:13 Это Глобал Варей был лист, то есть список глобальных переменных, и здесь я создал переменную си Эйч. 3 У которой тип это пользовательский тип канал Т. Сеич, а и мы этот тип уже создали. И, по сути, эта структура, у которой есть всего 2 поля, это риловское значение и 1 Байт статус, то есть, по сути, это структура данных как раз таки повторяет реальную структуру нашего. канала, который состоит из реловского значения и Байта со статусными битами. И таким образом мы можем прямо на весь канал привязать уже вот эту нашу структурную переменную, которая. Сразу будет в себе содержать и значение, и статуса также можем и обычную реал переменную привязать уже непосредственно к полю. Значения здесь уже зависит от нас, как нам удобнее.
50:19 К 1 2 каналам у меня привязаны. Специальные переменные, которые определены в отдельной библиотеке. Давайте перейдем к определению этих переменных. Сейчас мы находимся в менеджере библиотек и. Автоматически осуществился переход на ту самую библиотеку, где была определена наша структура. То есть мы сейчас смотрим на библиотеку ПС Диагон, это наша собственная библиотека. И в ней определены структуры для всех типов модулей, существующих на сегодняшний день. В частности, мы работаем сейчас с модулем, а и 0 8 41 вот его структура, и она состоит соответственно из таких вот полей, то есть. Мы видим, что у нас имеются каналы, это соответственно тоже структуры, похожие на ту, которую мы с вами перед этим рассмотрели. То есть там всего лишь 2 значения, это Реал и Байт, и таких каналов у нас определено 8.
51:24 Также имеется статус. ХВ Рор, который отвечает за весь модуль целиком и также еще 2 дополнительных параметра о аппаратной версии. К сожалению, у нас нет возможности взять целиком эту структуру и спроецировать на наш модуль и приходится поочередно привязывать все каналы к конкретному каналу нашего модуля. То есть вот в нашем примере мы видим у меня таким вот образом привязан 1 и 2 канал.
52:08 В целом может показаться, что это излишнее усложнение. Вот, но здесь вопрос привычки. И опять же вы можете можете самостоятельно выбрать, каким именно способом осуществлять? Перевязки каналом, но именно вот данным способом через структуры расположены в библиотеке ПС Диагон. Вы будете пользоваться, если будете использовать именно наш ПТК Астрорегу?
52:37 Если же вы им не будете пользоваться, то можете определять переменной, так как вам проще и удобнее. Например, вот таким вот способом теперь поговорим о нашей. области, Джоэль, почему именно в ней мы расположили нашу переменную, которую впоследствии стали привязывать к каналам? Дело в том, что переменная, описанная в.
53:02 Простой программе те, которые являются локальными. Они могут быть прочитаны из любой другой программы, при этом всего лишь следует указывать префикс самой программы. Да, то есть не напрямую, мы обращаемся к переменная сначала. Пишем имя программы Точка и далее имя переменной. Ну, примерно вот таким же образом, как мы, это уже видели в наших персидских варс. Но записать в такие локальные переменные уже в. Некоторых случаях будет невозможно, поэтому для того, чтобы гарантировать возможность из любой программы и писать и читать в определенную переменную, удобнее всего расположить такую. Переменную в области Джи в Эль, то есть в списке глобальных переменных. Это объект, который добавляется стандартным образом аппликейшен, правая кнопка добавить объект здесь есть.
54:00 Давайте его найдем, здесь есть вот он. Наш список глобальных переменных выбираем, задаем ему некое уникальное имя, и он добавляется в наше дерево. устройств вы можете создавать неограниченное, неограниченное количество таких списков, и главное, чтобы у них у всех были уникальные имена.
54:26 Теперь посмотрим еще на привязку. В модуле АО здесь, в общем, то все аналогично на 1 закладке задаются параметры самого модуля и в области соотнесений. Мы привязываем конкретные перемены, в данном случае все максимально просто мы задали. Привязали, точнее, горел переменную к 1 каналу, а для 3 канала мы поступили следующим образом. То есть у нас на самом деле переменная АО 3 вообще нигде не определена, то. Есть, если мы попросим компилятор перейти к определению, то он никуда не переходит. Остается здесь, то есть дело в том, что мы можем не создавать предварительно переменную, а?
55:21 Написать ее имя прямо тут. И в момент нажатия на энтер переменная уже формируется, и при этом она будет размещена в специальной скрытой области. Ее можно увидеть, если нажать на многоточие. Мы попадаем в ассистент Вуда, где мы можем осуществлять привязку. И в данном случае она у нас привязалась. Вот сюда в область глобальную область Глобал Мэппинг. То есть эта переменная будет доступна из любой программы, но неудобство заключается в том, что если мы таких переменных сделаем много. Они будут все лежать в 1 месте и может возникнуть путаница, при этом их не видно напрямую из нашего основного. Дерева устройств, поэтому таким способом можно пользоваться именно для оперативности. Когда вам хочется быстро посмотреть значения по определенным каналом? Ну, тогда можно переменные быстро таким образом задать, посмотреть и потом их, например, удалить.
56:34 Давайте вернем имя, которое было изначально, она у нас дальше будет использоваться в программе. Вот ну а привязка обычной переменной традиционно выглядит таким образом, то есть мы нажимаем именно на многоточие. И находим в Нашей программе Необходимую переменную в данном случае она у нас определена, была не в Пэл Сапэрго, а именно в области Дживэль. Переменная, а у 1 типа релы. Мы ее вернули. Возвращаемся в нашу программу. Когда уже открыто, очень много закладок бывает сложно в них ориентироваться, можно запутаться. В таком случае очень удобно воспользоваться такой операции, нажимаем правой. Кнопкой по любому элементу и выбираем закрыть все редакторы. У нас мгновенно все окна, кроме текущего, закрываются еще 1 вариант привязки. Мы можем увидеть в области Джавель.
57:49 Мы создаем. Переменную, а вот вам. И располагаем ее по. Специальному адресу в области Ку памяти в данном случае. По адресу д. 1, если мы посмотрим на наш модуль Алло. То мы можем увидеть, что адрес куды 1 соответствует каналу. 2 То есть, несмотря на то, что здесь никакой привязки, мы не видим на самом деле переменная. А вот 2 вот таким вот образом уже привязана к нашему 2 каналу, и в нее реально будут поступать данные.
58:44 Ну, точнее говоря, те данные, которые мы будем записывать в нашу переменную, а у 2 будут поступать на выход номер 2 нашего модуля Ау. Подобным способом мы можем привязать целую структуру. Вот он, вот в этом примере мы видим, что создан экземпляр с таким названием. Он у нас спроецирован на адрес и памяти д 1 и имеет тип структуры. Структура у нас вот так называется, давайте посмотрим, где у нас эта структура. Вот здесь она определяется, заходим внутрь, видим, что. Она состоит из массива и на 8 элементов, и в конце булавский хавей Рор Массив у нас состоит, в свою очередь, тоже из структур, которая. Определена уже вот здесь, мы в нее уже заходили. То есть это реловское значение, статус и риеловское значение и статус, то есть таким образом? Вот это наша структура, она полностью повторяет весь набор данных, которые у нас реально сейчас есть в модуле АИ, 0 8 и мы разместили.
1:00:00 По адресу и д. 1 вернемся в модуль, а и и видим, что действительно у нас. Все наши данные конкретного модуля начинаются с адреса и д. 1 и получилось, что мы за счет всего лишь 1 строки. Вот этой. Разместили нашу структуру, полностью повторяющую. Все данные из модуля таким образом получилось, что мы всего лишь 1 строкой спроецировали нашу структуру на весь модуль, 1 из такой это очень удобно. Но тут следует иметь в виду такую опасность. Сейчас действительно адрес у нас совпадает, который мы видим в модуле, и тот, который мы указали в нашей. Программе, если мы не будем трогать конфигурацию устройств в нашем дереве, то адреса никуда не съедут. Но когда мы будем добавлять новое устройство? Например, мы добавим еще 1 корзину с модулями ввода вывода или, например, мы добавим какие нибудь устройства типа Матбаз, Слейф или Мастер, они также. Используют каналы и при этом описываются выше нашей шины, то есть их адреса они получаются в строится раньше. И вся привязка у нас может съехать.
1:01:32 Таким образом, наша переменная она будет получать данные вообще, из какой то непонятной области это очень опасно. Поэтому мы в целом не рекомендуем такой способ, но если вам все. Таки хочется удобство, и вы хотите привязывать структуру целиком. То следует обязательно перед финальной компиляции проверять правильность всех указанных адресов либо также можно.
1:01:58 Фиксировать конкретные адреса каналов, то есть, например, вот этот канал у меня сейчас ни к чему не привязан. Я могу в него зайти, нажать энтер, ну либо изменить его. Да, допустим, указать там не 7, а примерно 50. И у меня данный канал переносится в указанную область и памяти, то есть значок М. От слова Мемори говорит о том, что данный адрес зафиксирован и. Компилятором автоматически никуда перенесен, быть не может. Но если опять же вы все таки создадите устройством от вас и вы попытаетесь скомпилировать ваш? Проект у вас могут возникнуть ошибки, что уже каналы самого устройства на БАС невозможно разместить в тех областях памяти, куда ему хочется, и вам все. Равно придется идти сюда и вручную вносить изменения. Поэтому еще раз повторюсь, что данный способ с прямой адресации мы не рекомендуем к использованию.
1:02:59 Для того чтобы вернуть адреса по умолчанию, достаточно удалить содержимое ячейки, нажать энтер и выставляется 1 свободный адрес. Теперь вернемся в нашу программу и загрузим ее на контроллер для того, чтобы уже в онлайн режиме посмотреть. На процесс исполнения внутри контроллера. Сохраняемся. Нажимаем на кнопку логин, предварительно необходимо осуществить соединение с нашим контроллером для этого заходим. На наше таргет устройство закладка установки соединения видим, что от контроллера мы отключены сканируем сеть, находим наш контроллер. Да был клик, соединяемся.
1:04:02 Предварительно, Логин и пароль я уже вводил однократно, поэтому сейчас у меня не спросил Логин и Пароль, и мы уже готовы. Загружать наш проект в контроллер нажимаем на кнопку логин. И мы подключились к нашему контроллеру, возвращаемся в программу ЛДПР г. Давайте опять же лишнее все позакрываем, чтобы она нам не мешала. И сейчас мы в реальном времени в режиме онлайн наблюдаем непосредственно за значениями переменных внутри нашего контроллера. Давайте, например, посмотрим, как у нас происходит вычисление времени. Вот вот, мы помним, что у нас было 2 переменных ДТ, разница у них была на 11 часов. Вот мы вычитали из большей величины меньше, и итоговое значение уже имеет.
1:05:11 Тип тайм и содержит у нас соответственно 23 часа. При работе со строками. Мы используем функцию сайзов для вычисления размеров памяти, которая у нас занимает. Данная переменная 1 строка переменная, состоящая из аски символов размером. 250 Штук у нас памяти занимает 251 Байт, потому что последний байт используется как ну терминатор. Это всегда так, то есть в памяти занимает на 1 байк больше. Чем мы определили в 2 переменная, содержит строку Юникод соответственно 1 символ. Это 2 байка + также 2 байка на ну терминатор и того получаем 502 Байта по. поводу строковых переменных еще нужно отметить такой момент, что стандартный размер строки подразумевает ограничение в 255 символов, если вы вообще в кругу. Скобках не указываете размер строки по умолчанию, строка будет длиной 80 символов. Что будет, если вы укажете значение длинной строки больше, чем 255 в целом? Ничего страшного, можно делать большие строки и по несколько тысяч символов. Но дело в том, что со стандартной строковой функции, например, Лен и в Лен, который вот. Мы здесь используем, они умеют работать только строками, к у которых ограничение длины имеет 255 символов. Теперь мы видим, что функция Лен у нас возвращает. Реальную длину заполненности нашей строки Хеллоу Голд. Это у нас получается 11 символов и в строке привет. Мир с восклицательным знаком у нас также 11 символов.
1:07:08 Вот то есть длина строки, у нас получилось одинаково, но при этом в памяти эти 2 строки занимают разное место, включающееся в 2 раза. Также мы можем использовать склейку строк, для этого у нас есть функция канкад. То есть мы? Вычитываем текущее время наработки контроллера с момента последнего старта и. Далее преобразуем это значение в строковый вид и склеиваем вот с такой строкой префиксом, и результат записываем в строку МСГ, и мы можем. Посмотреть строкой мозга в онлайне, как она у нас выглядит вот таким вот образом. То есть у нас в строке меняется количество секунд?
1:08:05 Здесь мы. Используем референс на конкретную переменную реал ВАР. И давайте попробуем изменить значение нашего ареалвара, найдем его в списке переменных и запишем новое значение. Например, она будет не 3 14, а, например, 23. Нажимаем энтер, именно мы сейчас находимся в колонке, подготовленные значения. Теперь мы нажимаем контрал, ф 7 либо можно зайти. В режим отладка и выполнить данную функцию из меню, записать значение здесь мы видим, у нас подписан ходки и контралаксия.
1:09:01 Значение записалось в переменную релвар и референс на эту переменную. У нас тут же поменялся, да потому что, повторюсь, референс. Это, по сути, альтернативное имя той же самой переменной. Ну либо другими словами, той же самой ячейки памяти. Ниже Мы получаем адрес некой переменной, выглядит он в 16 величном виде, нам сейчас не особо интересен. Здесь мы. Вычисляем размер. Нашей структуры и нашего Юниона, и вот на этом моменте можно остановиться чуть подробнее.
1:09:49 Давайте найдем, где у нас находится. Списки наша структура. Вот это у нас Юнион. И внутри него находится структура. Мы можем вручную выставить значения для конкретных битов таким вот образом. Давайте через 1 поставим, чтобы как раз. Сформировать шестнадцатиричное значение, но Ликс, а? Нажимаем контралы в 7. Почему то сюда они не записались, а потому, что они у меня также участвует в привязке и перезаписываются поверх другими значениями для того? Чтобы принудительно записать значение в переменные и не позволить им перезаписываться из других источников, можно нажать просто ф 7 и.
1:10:52 Либо у меня просто на ф 7 регулировка громкости назначена, также мы можем выбрать. Данный пункт меню фиксировать значение. Теперь мы можем изменить формат отображения данных в шестнадцатеричный вид. Нажмем правая кнопка, режим отображения и выберем шестнадцатеричный. И в таком виде удобнее наблюдать значения наших переменных, которые мы изначально задали внутри структуры. То есть вот эти самые БББ и ЦЦЦ? Теперь те же самые данные мы хотим видеть уже не в структуре, а в форме представления массива, который наложен на нашу структуру в рамках того же самого Юниум. Откроем массив Вордов, здесь у нас 8 Вордов и.
1:11:58 Переменная в памяти расположены следующим образом. Мы видим, что у нас идет значение, а а это вот те самые наши биты через 1 тру Фелс. Ру Фелс и также имеется еще байт с нулями, потом идет вордовское значение БББ и потом целых 2 ворда с нулями. То есть это то самое, что я вам? Показывал в диаграмме, да то есть у нас сейчас отключен Пакмолт соответственно значение Пакмолда по умолчанию равно 8. И поэтому мы получили вот такую дыру. Теперь при помощи атрибута Пак Мод постараемся избавиться от ненужных дыр.
1:12:44 Идем в нашу структуру. Отключаемся от контроллера. Соглашаемся на освобождение всех фиксаций и. И задаем Пакмот 1. Сохраняемся. Загружаем изменения в контроллер, так как изменения незначительные. Программа предлагает выбор, как именно осуществить загрузку в онлайн режиме либо полный режим загрузки. Если мы выбираем логин с онлайн заменой, то текущий рабочий процесс у нас не останавливается. Изменения подставляются на ходу, но такой режим возможен не всегда, а только если мы не затрагивали аппаратную конфигурацию и не затрагивали параметры наших задач, но логин. С загрузкой он, соответственно, останавливает приложение на контроллере, удаляет его. После этого полностью загружается обновленный проект и запускается, ну, так сказать, с 0.
1:14:01 В данном случае мы можем выбрать простой режим заменой. Возвращаемся в нашу программу. Находим. Наш юнион раскрываем. И теперь мы можем наблюдать, что все наши. Переменные упакованы плотно друг за другом. Вот можем также открыть байтовое представление для удобства. Здесь мы наблюдаем, что символами с заполнен наш массив до конца, это, по сути, оставшиеся данные еще с предыдущего запуска. Мы можем выполнить онлайн сброс, то есть вернуть всем переменным значения по умолчанию.
1:15:29 Вот контроллер при этом переходит в состояние стоп. Возвращаем состояние ран и видим, что действительно внутри. Нашего массива, ну в данном случае все биты у нас опустились. Далее идет вордовская, переменная из символа ББ, далее 4 восьмибайтная переменная сила в Цеце и 5 последних байт, в нашей структуре остались пустыми.
1:16:04 Таким образом работает у нас выравнивание за счет атрибута пак мод. Давайте рассмотрим, что происходит в нашей программе далее. У нас. Постоянно изменяется значение, вычисленное в функциональном блоке Синусом. Это значение мы записываем в выходную переменную АУ 1. И как мы помним, я уже говорил, что эта переменная у нас привязана к 1 каналу модуля АО. То есть таким образом вычисленное значение Синуса физически у нас выходит на 1 канал и при помощи Анти?
1:16:57 Метра мы можем его реально наблюдать. Давайте посмотрим. Изменения значений к привязанным переменным, которые у нас были указаны для каналов модуля АИ. Это у нас переменная сеич 0 1 и сеч 0 2. К 1 каналу у меня подключен источник тока, который я могу менять в реальном времени. Значение которого я могу менять, и вот мы здесь можем наблюдать изменения, соответствующие. Выставим контровное значение. Пример в 10 еще стоит обратить внимание на. Экшены, которые у нас присутствуют внутри нашей программы ПЛЦ ПРГ.
1:17:59 1 Из них называется и Нитритейн, другой называется Сэфрикой. Для того чтобы самостоятельно добавить подобный экшен, необходимо правой кнопкой нажать на программе и выбрать действий. По сути, Экшен, это подпрограмма, которую мы можем вызывать извне в данном случае.
1:18:22 Здесь у нас присутствует минимальный код в случае ИНИТ Ретейн, мы производим некую инициализацию. То есть у нас имеется переменная из старта, которая по умолчанию изначально равно 0 соответственно в 1 цикле программы, когда мы сюда? Зайдем, у нас переменная старт от изначально равно 0 мы сразу переключаем в единицу и однократно выполняем некий код и при последующих запусках. Мы, соответственно, сюда уже попадать не будем. В нашем коде мы некие внешние переменные. Которые, ну, например, могут использоваться для записи команд со стороны Скада системы. Вот для того, чтобы мы их сохранили у себя внутри контроллера и при перезагрузке контроллера не ждали, когда очередной раз подобные команды прилетят. Да, могли сразу же продолжать работу с последних заполненных значений. Мы эти внешние значения сохраняем свои внутренние переменные, их мы назвали вот таким вот образом. Ексцимодеалт и Ексцимодеал, 2 они у нас определены именно как.
1:19:29 То есть они у нас хранятся в энергонезависимой памяти, вот то есть при старте мы внешние переменные сохраняем в своей внутренней метод имит ретейн. Мы будем использовать для того, чтобы однократно при очередном запуске проекта вычитать ранее сохраненные значения из контроллера и применить их для.
1:19:57 Локальных переменных, которые могут использоваться в алгоритме, то есть вот эти команды у нас находятся в энергонезависимой памяти. Они объявлены в области пестик персистенд Варс вот здесь. И И при инициализации однократно за счет флага бы старт, который мы при 1 же запуске сбросим. Мы вычитываем эти сохраненные значения и перекладываем их в наши обычные локальные переменные, а уже в ходе исполнения самой программы. Эти переменные могут изменяться за счет любых источников, например, через протоколы верхнего уровня от Скады по ним могут выполняться. Какие то действия и в конце нашей программы мы будем вызывать уже метод сейф ретейн, то есть. Уже наоборот, наши текущие локальные переменные помещать в энергонезависимую память. И таким образом в нашей программе самой 1 строкой вызывается метод. Ну и правильно сказать, Экшен и Нитрите, и в самом конце вызывается экшен. Сейфри Тайм таким образом, если в какой то момент неожиданно произойдет перезагрузка контроллера либо его отключения, то при последующем старте за счет метода и Нитрите мы сможем восстановить последние сохраненные значения.
1:21:29 Так вернемся к программе. Давайте посмотрим в режиме онлайн, перейдем соответственно назад в онлайн. Как влияет наш Триггер на загрузку центрального процессора? Сейчас у нас триггер имеет значение файлс соответственно. Вот эти циклы файл у нас не исполняются, посмотрим на загрузку центрального процессора. Заходим в Таргет. Переходим в. В сервис ПЛК Здесь выбираем загрузка полка и нажимаем рефреш. Вот мы видим, что загрузка по нулевому ядру, на котором, собственно, исполняется наш проект, сейчас не превышает 20.% Теперь перейдем в нашу программу. Можно вот так закладочку передвинуть поближе, чтобы было удобнее.
1:22:40 Перейдем в нашу программу и. Переведем значение триггеров ТРУ. Записать значение? Теперь каждый раз при вызове нашей программы будет исполняться цикл Вайл 10000 раз. Возвращаемся. К нашему центральному процессору и видим, что загрузка нулевого ядра выросла примерно до 50.% Идем обратно в программу, соответственно, обратно включаем триггер. Записать значение и загрузка у нас должна вернуться к изначальным значениям. Вот таким образом мы можем использовать режим онлайн.
1:23:46 В котором мы не только наблюдаем значение всех переменных, но также можем их записывать и использовать фиксацию принудительно. Давайте еще раз посмотрим на фиксацию на примере переменной интвар, которая у нас в программе каждый раз перезаписывается значением 5. Давайте вернем отображение к десятичному виду для удобства. Вот у нас переменная интвар, которая сейчас равно 5. И если в подготовленное значение я запишу, что то другое, например 8. Записываю значение, она тут же пропадает, потому что в очередном цикле программы у нас оно снова перезаписалось значением. 5 Но мы очень хотим, чтобы она изменилась, поэтому давайте еще раз поставим 8.
1:24:46 И выполним. Фиксацию значения. Значение зафиксировано. Теперь она равно 8 независимо от того, что у нас должно происходить в алгоритме и какие значения прилетают по привязанным каналам. Если мы их используем, то есть значение жестко стоит, не меняется при этом, если мы попытаемся отключиться от контроллера. Нам будет предложено. Выбрать действие, то есть либо мы оставляем фиксации в контроле, это естественно, очень опасно отключиться от контроллера и навсегда оставить эти замороженные значения, либо перед отключением все таки снять фиксации.
1:25:35 Снять все фиксации без отключения от контроллера можно таким образом. Команда освободить значение? И соответственно значение сразу же переписалось самой программой. Теперь давайте рассмотрим точки остановок. То есть сейчас у нас программа бесконечно выполняется на контроллере, и мы хотим увидеть, что произойдет, если поставить точку остановок. Давайте поставим точку останова, например, вот сюда, во внутрь Кейза, на определенное значение. Пока у нас выполняется в штатном режиме.
1:26:33 Исполнение нашей программы. И давайте зададим в степ значение 1. Вот давайте запишем. Применим это значение. Вот тут же мы провалились вовнутрь. Кейза наткнулись на эту строку и произошла остановка контроллера в. О том, что он находится в специальном режиме, нам говорит строка состояния, то есть мы находимся на точке останова и также особым образом у нас теперь мигает. Индикатор Ран на контроллере, то есть при штатном исполнении он горит непрерывно, а в таком режиме он мигает раз в секунду. Давайте отключим нашу точку останова.
1:27:38 Выберем пункт переключить точку остановок, чтобы она убралась и нажимаем клавишу в 5 либо здесь нажимаем на кнопку старт. Контроллер перешел штатный режим исполнения. Можно поставить точку основного в любом другом месте. Переключить точку остановок. Тут же мы на нее наткнулись и теперь при помощи нажатия на клавишу в 10 либо непосредственно нажатием. Вот этой кнопки я могу переходить последовательно по строкам и таким образом отслеживать. Процесс исполнения операторов, вот если я сейчас нажму опять же в 5.
1:28:26 Контроллер пойдет по основному циклу и наткнется на ту же самую точку остановок. Давайте ее снимем переключить точку основного, выбрали. Опять же запустили контроллер полноценный режим, и мы видим, что теперь мы находимся в режиме работа мы. Таким образом, мы с вами закончили рассмотрение основных принципов программирования, контроллеров. Регул привязку переменных и возможности отладки в режиме онлайн. На сегодня это все спасибо за внимание, увидимся в следующих видео уроках.
Расшифровка сделана автоматически (Yandex SpeechKit) и может содержать ошибки в терминах.