Страница 1 из 1

Редактирование пользовательского блока.

Добавлено: 25 сен 2019, 21:11
Dryundel
Редактирование пользовательского блока.

Довольно часто готовые пользовательские блоки, созданные под определенные задачи, не совсем подходят для других задач. Нахватает входа Enable, требуется вход вместо параметра, неудобно (не в том порядке) расположены входы/выходы.
Исправить такие мелочи совсем не сложно. Для такого редактирования особых познаний в языках программирования не требуется.
Однако существует еще и психологический фактор – боязнь что-то испортить, сломать. Вот этот враг пострашней всего остального. Его то мы и будем выжигать каленым железом, ну или как говорил Антон Палыч, «выдавливать из себя раба по капле». :)

Итак, набираемся смелости, кликаем по блоку правой кнопкой мыши и жмем «Редактировать»
.
1.jpg
.

Вход вместо параметра.

Для примера возьмем пользовательский блок RtrigTimer
Все входы, выходы и параметры пользователя это переменные со своими именами.
Все что нам надо сделать это перенести переменную из параметров пользователя во входы блока
.
2.jpg
.
Для этого дважды кликаем на нужном параметре, копируем в буфер имя параметра и запоминаем тип переменной данного параметра.
.
3.jpg
.
После чего закрываем окно редактирования параметра и смело удаляем сам параметр, выделив его и нажав на крестик.
Переходим на вкладку «Входы блока» и жмем на пиктограмму «добавить вход»
.
4.jpg
.
В открывшемся окне вставляем скопированное имя и выставляем тип переменной. После чего жмем «готово».
.
5.jpg
.
Вот в принципе и все. Осталось сохранить наш новый блок. Для этого в основных параметрах изменяем его имя и сохраняем как новый блок.
.
6.jpg
.
Теперь у нас в библиотеке два блока. Один исходный, второй исправленный.
.
7.jpg
.
В результате имеем вот такие блоки.
.
8.jpg
.

Добавление входа Enable


Вход En это тоже переменная типа Boolean. Поэтому первое что мы должны сделать, это создать вход-переменную с таким именем.
.
9.jpg
.
Основной исполнительный код блока находится в секции LoopSection.
Соответственно все что нам надо сделать это создать условие при котором этот код будет выполняться только когда En = 1
Для этого нам потребуется условный оператор if (подробней читай здесь)
В итоге требуется создать следующее дополнение к коду:

if(En==1){
//Здесь весь код из секции LoopSection
}

Для переменных boolean условие принято писать сокращенно:

if(En) соответствует if(En==1)
if(!En) соответствует if(En==0)

Поэтому чаще всего в коде вы встретите следующее написание

if(En){
//Здесь весь код из секции LoopSection
}

В итоге имеем следующее:
.
10.jpg
11.jpg
.

Расположение входов/выходов

Эта глава будет самой короткой, т.к. данная операция осуществляется соответствующими стрелочками. Думаю пояснения здесь излишни.
.
12.jpg
.

Ну и как итог:
.
13.jpg
.
R-триггер_с_задержкой_импульса_(CODE).ubi
R-триггер_с_задержкой_импульса_1_(CODE).ubi
R-триггер_с_задержкой_импульса_2_(CODE).ubi
.
Dryundel

Отправлено спустя 3 часа 6 минут 15 секунд:
Дополнение.
(Спасибо [ref=#ff8000]Sancho[/ref], за напоминание)

Есть один небольшой но важный нюанс при создании входа Enable.
Дело в том, что момент остановки работы блока с помощью входа En может совпасть с моментом когда на выходе Q инициировалась единица (высокий уровень). В этом случае предполагаемый короткий импульс превратится в постоянный сигнал. И хотя в данном случае такая вероятность не велика, все-таки произойти это может. Поэтому, при создании входа En, необходимо позаботится о том, в каком состоянии должны остаться выходы блока. Если выходов несколько, то для каждого следует прописать его состояние после остановки работы блока.

Применительно к нашему блоку RtrigTimer, необходимо сделать так что при остановке его работы входом En, на выходе Q в обязательном порядке должен быть инициирован "0" (низкий уровень).

Другими словами: если на входе En - "1" то код блока работает в штатном режиме, а если на входе En - "0" то на выходе Q - "0"

В коде это будет выглядеть так:

if(En){
if (I) { if (tr2) {tr1 = 0;} else {tr1 = 1; tr2 = 1;} } else {tr1 = 0; tr2 = 0;}
if (tr1) T = millis();
if (millis() - T >= Time && T != 0) { if (tr3) {Q = 0;} else {Q = 1; tr3 = 1;} } else {Q = 0; tr3 = 0;}
}else{
Q = 0;}


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

если на входе En - "1" то код блока работает в штатном режиме, иначе на выходе Q - "0"

Что с точки зрения программирования почти одно и то же. :)

Редактирование пользовательского блока.

Добавлено: 25 сен 2019, 23:53
belyx
А ещё расширить функционал?
если на входе En - "0" то блок работает без таймера как обычный Rtrig
если на входе En - "1" то блок работает с таймером
а вдруг кому пригодится?

Редактирование пользовательского блока.

Добавлено: 26 сен 2019, 08:15
Goosr
belyx писал(а): 25 сен 2019, 23:53 если на входе En - "0" то блок работает без таймера как обычный Rtrig
Ну так для этого есть штатный блок Выделение переднего фронта. :smile198:

Редактирование пользовательского блока.

Добавлено: 26 сен 2019, 08:46
Dryundel
belyx писал(а): 25 сен 2019, 23:53 А ещё расширить функционал?
если на входе En - "0" то блок работает без таймера как обычный Rtrig
если на входе En - "1" то блок работает с таймером
а вдруг кому пригодится?
Не вижу в этом смысла. Поставьте Time = 0 и получится обычный Rtrig.

Редактирование пользовательского блока.

Добавлено: 22 окт 2022, 18:42
dVo
Как заменить ПБ целиком, сохранив связи? Например на новую версию.

Редактирование пользовательского блока.

Добавлено: 22 окт 2022, 18:52
Phazz
Ни как к сожалению

Редактирование пользовательского блока.

Добавлено: 22 окт 2022, 19:36
aidar_i
Если приходится создавать вход String из параметра, а в блоке в коде он в char array применяется, нужно String превратить в char array.
Dryundel, про это напиши с примерами красиво, как умеешь.
В начале , когда я начинал создавать блоки, это для меня был большим препятствием, здесь никто мне не ответил, как это сделать, пока я сам не нашел как это сделать.