Создание пользовательского блока (Code-Basic) простым языком.

Написание кода на языке C++, не зная языка С++.

Статистический опрос.

Мне помогла эта тема разобраться с созданием ПБ.
34
61%
Я уже умел создавать ПБ, но нашел в теме что то новое для себя.
16
29%
Я умею создавать ПБ, ничего нового, но считаю тему полезной.
3
5%
Тема прикольная, но особой пользы от нее я не вижу.
1
2%
Полный бред. Прорабы какие то, квартиранты. Чушь.
2
4%
 
Всего голосов: 56

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (Code-Basic) простым языком.

#1

Сообщение Dryundel » 03.09.2019{, 21:14}

Создание пользовательского блока (CODE) простым языком.
Или написание кода на языке C++, не зная языка С++.

Беседа первая.

Практически все новички сталкиваются с тем, что функционала штатных блоков становится недостаточно. И здесь возникает дилемма – долго и упорно искать подходящий пользовательский блок или окунуться в основы программирования самому. Второе, как правило страшит больше. Однако не так страшен черт, как его малюют.
Сразу оговорюсь, я не являюсь супер знатоком языков программирования, но теми крохами знаний, которые имею, готов поделиться с новичками.
Прекрасно понимая, что самое муторное это теория, опущу ее и перейду сразу к практике.
Вот сейчас у МЭТРОВ забурлит! :)
Спокойней господа, я обращаюсь не к ВАМ, а к новичкам.

Итак, начнем.
Для примера возьмем что ни будь не сложное. Ну скажем формулу расчета времени падения тела (прораба) с определенной высоты
(2-го, 3-го, 5-го этажа). Для упрощения сопротивлением воздуха пренебрежем.
Формула выглядит так:

t=√(2h/g)

где t – время в секундах; h – высота в метрах; g - ускорение свободного падения в м/с²
Переменных всего две, одну имеем вторую хотим получить.

Идем на вкладку «Пользовательские блоки», жмем иконку «Создать»,
.
2019-09-03_155447.jpg
2019-09-03_155447.jpg (33.87 КБ) 4852 просмотра
2019-09-03_155839.jpg
2019-09-03_155839.jpg (21.1 КБ) 4852 просмотра
.
вводим название нашего блока (обратите внимание названий два)
.
2019-09-03_160019.jpg
.
и сохраняем как новый блок.

Блок создан! Больше пол дела сделано! :) Можно закрыть окно редактирования блока.

Теперь находим наш блок и вытаскиваем на рабочее поле.
.
2019-09-03_160652.jpg
2019-09-03_160652.jpg (20.48 КБ) 4852 просмотра
2019-09-03_160909.jpg
2019-09-03_160909.jpg (1.55 КБ) 4852 просмотра
.
Все что нам осталось сделать, это приделать к нему вход и выход и запихать внутрь формулу.

...
Последний раз редактировалось Dryundel 26.09.2021{, 12:10}, всего редактировалось 1 раз.

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#2

Сообщение Dryundel » 03.09.2019{, 21:26}

Жмем правой кнопкой мыши на блок выбираем "Редактировать"
.
2019-09-03_161345.jpg
2019-09-03_161345.jpg (14.45 КБ) 4850 просмотров
.
Заходим на вкладку «Входы блока» и жмем на пиктограмму «Создать вход», называем его h.
Аналогично поступаем с выходом, называем его t.
.
2019-09-03_161543.jpg
2019-09-03_161543.jpg (24.24 КБ) 4850 просмотров
.
Данные нам нужны точные, ибо не просто же так мы высчитываем время. Нам просто необходимо достоверно знать успеем мы замахнуть еще по одной прежде чем бежать вызывать скорую или нет. Поэтому типы переменных выбираем Float.

Вход и выход у нас есть осталось где-то начертать нашу формулу. А делать мы это будем в секции LoopSection.

Ускорение свободного падения известно всем. А вот как записать в программу квадратный корень? И тут все просто. Набираем в Яндексе «Ардуино квадратный корень» и первая же ссылка выдает нам - sqrt(x) так и записываем:

Код: Выделить всё

t=sqrt(2 * h / 9.8);
Не забываем в конце поставить точку с запятой. Зачем? Не заморачивайтесь пока.
Просто запомните что вилька и тарелька пишутся без мягкого знака, а сол и фасол с мягким.
.
2019-09-03_195605.jpg
2019-09-03_195605.jpg (56.18 КБ) 4850 просмотров
.
Все! Наш первый код на языке C++ готов! И новый блок тоже.

Сохраняем блок. На этот раз не как новый, а обновляем его в библиотеке. И можно пользоваться.
.
2019-09-03_195815.jpg
2019-09-03_195815.jpg (2.47 КБ) 4850 просмотров
.
Не верите? Проверьте. :)


Dryundel©
Последний раз редактировалось Dryundel 09.09.2019{, 17:40}, всего редактировалось 2 раза.

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#3

Сообщение Dryundel » 03.09.2019{, 22:26}

Беседа вторая. (теоретическая)

Функция и аргумент
Страшные из-за своей непонятности слова.
Но это только на первый взгляд. Сейчас все разберем по косточкам.
Итак ситуация: Пришли вы со своей стройки домой не совсем рано и слегка помятый.
Функция жены накормить вас но аргументы поздно и помятый не катят и поэтому функция не выполняется. А вот если аргументом будет спасение прораба, который таки выпал с третьего этажа, то Вы герой и функция выполняется.
Вывод: функции нужен аргумент и этот аргумент должен быть правильным.
Хотя есть некоторые функции у жены которые не требуют аргументов. Так же и в С++.

Пример:
В предыдущей беседе мы воспользовались функцией sqrt(x).
Так вот sqrt() это функция, а то что в скобках (x) аргумент или параметр передаваемый в функцию.
Фраза "функция возвращает" означает получение результата при выполнении этой функции.

Для функции sqrt() аргумент х = 4 верный а х = -4 нет, так как вычислять корень из отрицательного числа не имеет смысла.

Но есть например функция millis() которая возвращает время с начала работы контроллера в миллисекундах, так вот ей аргументы не требуются.

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

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


Dryundel©
Последний раз редактировалось Dryundel 07.09.2019{, 11:46}, всего редактировалось 1 раз.

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#4

Сообщение Dryundel » 04.09.2019{, 08:50}

Беседа третья.

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

Итак, рассмотрим ситуацию:
Принес жене цветы - она тебя поцеловала. Т.е. выполнил какое-то условие – получил ответное действие. Пришел без цветов – ничего не произошло.
В С++ для создания подобного условия существует условный оператор if. На человеческом языке он означает – если то.
Нашу ситуацию можно записать так:

if(цветы){поцелуй;} – то что в круглых скобках это если, то что в фигурных это то. В случае отсутствия цветов ничего не произошло. Цветы – условие, поцелуй – следствие. А если жена еще и улыбнулась, то это еще одно действие.
Записываем так:

if(цветы){поцелуй; улыбка;} – вот такая программа зашита у жены в процессоре. Обратите внимания, что все действия, которые должны произойти заканчиваются точкой с запятой.

Еще один момент. Лишние пробелы и переносы в программе не учитываются. Поэтому, чтобы не писать длинных строчек, делаем так:

Код: Выделить всё

if(цветы){
 поцелуй;
 улыбка;
}
Но в жизни не все так однозначно и вшитая в жену программа этим не заканчивается. Если цветов нет, то что-то все-таки произойдет. К примеру жена весь вечер будет ворчать. Поэтому добавляем еще одну причинно-следственную связь. Условие – нет цветов. Отрицание в программе можно отобразить специальным знаком - ! (восклицательный знак)
Дополняем программу.

Код: Выделить всё

if(цветы){
 поцелуй;
 улыбка;
}
if(!цветы){
 ворчание;
}
Но и с цветами не все однозначно. Если в букете 3 цветка – все ок. Но если 4 – то можно и сковородой по голове получить. И все это при условии, что цветы принес. Поэтому внутрь одного условия вкладываем другие.

Код: Выделить всё

if(цветы){
      if(количество==3){
        поцелуй;
        улыбка;
      }
      if(количество==4){
        сковорода;
      }
}
if(!цветы){
 ворчание;
}
И так ветвить цепь событий можно до бесконечности. Лишь бы в контроллере хватило памяти.
Обратите внимание – в условии равенство записывается == (строго равно) Это математический оператор. Есть еще <, >, <=, >=, != и т.д. Список всех вы легко найдете в Яндексе.

Ну и на последок конструкция if…else что означает если то иначе.
Условный оператор if имеет атрибут else который показывает что должно произойти если условие не выполнилось. Соответственно программу с цветами можно записать так:

Код: Выделить всё

if(цветы){
 поцелуй;
 улыбка;
}else{
 ворчание;
}
Результат будет тот же но условный оператор всего один и соответственно программа займет меньше памяти.


Dryundel©
Последний раз редактировалось Dryundel 29.09.2019{, 20:25}, всего редактировалось 2 раза.

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#5

Сообщение Dryundel » 04.09.2019{, 13:12}

Беседа четвертая. (часть первая)

Возвращаемся к нашему прорабу, а то что то далеко мы отошли от пользовательского блока.
В первой беседе я немного слукавил. Изначальным условием было то, что прораб должен упасть с какого-то этажа, а оперировать мы начали метрами. Ничего страшного скажете вы. Можно умножить этажи на метры и все. В принципе если учесть что каждый этаж 2,7м то можно было бы и так, однако высота 1-го этажа всего 1,5м, на первом этаже магазин, а это 4м, а еще существует и подвал. Поэтому без дополнительных вычислений не обойтись. Либо надо прописывать высоту каждого этажа отдельно. Но это не подойдет, т.к. на следующей неделе мы переходим на другой объект и там все высоты будут другими.

Итак, приступим.
Определяемся с высотами этажей.
h0 – высота цоколя. Она везде одинакова поэтому пусть будет константой.
h1 – высота 1-го этажа(магазина). Может быть разной – будет переменной
h2 – высота всех остальных этажей. Тоже переменная т.к. дома бывают элитными.
Высота подвала нас мало интересует, поскольку падать там особо некуда. Единственным условием будет то, что подвал это -1-этаж, т.е. величина отрицательная.

Открываем наш ПБ «Прораб» для редактирования и добавляем вышеперечисленное.
Т.к. h0 константа и изменять ее при пользовании нашим калькулятором мы не будем, поэтому внесем ее в «Параметры пользователя», оставив таким образом возможность другому пользователю, настроить калькулятор под себя.
.
1.jpg
.
Здесь почти все так же, как и с входами/выходами. Добавляется только значение по умолчанию и пределы. Поля можно оставить и пустыми, но «По умолчанию» мы добавим.
Имена h1 и h2 добавляем как входы, для возможности оперативного использования
Вход h удаляем – высота в метрах нам теперь не потребуется.
Вместо него создаем вход Etazh - место нахождения прораба.
.
2.jpg
2.jpg (46.81 КБ) 4624 просмотра
.
Почему я выбрал именно такие типы переменных постарайтесь разобраться сами.
Положение входов/выходов в блоке редактируем стрелочками.
Не забываем писать комментарии. Другие пользователи будут вам за это благодарны.
Теперь давайте сохраним наш блок как новую версию (Сохранить как новый блок) изменив и его название.
.
3.jpg
.
В результате получим уже две версии нашего блока.
.
4.jpg
4.jpg (27.12 КБ) 4624 просмотра
.
Все требуемые входы/выходы и константы мы создали. Можно переписывать формулы. Однако есть один нюанс. Контроллер будет работать только с известными ему переменными. А Arduino IDE, как строгий таможенник даже не допустит к компиляции код в котором присутствуют незадекларированные товарищи.
Я говорю про переменную h которую мы удалили из входов, но которая нам потребуется для вычисления высоты в метрах. Это уже не вход, но и не константа. Что же с ней делать?
Внимательно смотрим и находим DeclareSection. Как раз то, что нам нужно. Вносим ее туда.
.
5.jpg
.
Правила декларирования переменных вы так же легко найдете в Яндексе. Сложного здесь ничего нет. Декларирование состоит из типа, имени, ну и значения по умолчанию (последнее не обязательно). Не забываем про точку с запятой.

...
Последний раз редактировалось Dryundel 10.09.2019{, 11:27}, всего редактировалось 1 раз.

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#6

Сообщение Dryundel » 04.09.2019{, 13:50}

Беседа четвертая. (часть вторая)

Пишем код.
.

Код: Выделить всё

if(Etazh == 0) {h = 0;}
if(Etazh == 1) {h = h0;}
if((Etazh > 1) && (Etazh < 3)) {h = h0 + h1;}
if(Etazh >= 3) {h = h0 + h1 + ((Etazh - 2) * h2);}

if(Etazh < 0) {t = 10800;} else {t = sqrt(2 * h / 9.8);}
Если вы читали предыдущие беседы, первая и вторая строчка вопросов вызвать не должны.
В третьей строчке можно было прямо указать if(Etazh == 2) , но мы же не ищем легких путей. У нас на стройке второй этаж как Волан-де-Морт в Гарри Поттере – «тот который нельзя называть».
Вот мы и обозначили его двумя условиями – больше первого и меньше третьего.
Оператор && как раз и есть логическое И. А условий в условном операторе if может быть сколько угодно.
Ну а с математикой надеюсь у всех присутствующих все хорошо. Поэтому и четвертую строчку разбирать не будем.

А вот на последней строчке слегка задержимся.
Мы помним что у нас есть еще и подвал из которого далеко не упадешь и считать там особо нечего. Однако если прораб там упал значит это не с проста. Видимо он сильно устал и очухается лишь часа через три (10800 секунд). Соответственно у нас полно времени.
А для чего нам знать это время? Если вы помните из первой беседы мы же соображаем на троих.
Исходя из этого, если прораб вырубился в подвале (на минус первом этаже) мы опускаем все расчеты и сразу присваиваем выходной переменной значение 10800 секунд. Но если же наше заветное желание не выполнилось, сработает else (иначе). Оно как раз и держит наготове финальную формулу расчета, которая будет выполняться лишь в том случае если прораб не нажрался в подвале.

На сегодня все.
Ну а это для самых ленивых. :)
.
2019-09-04_134100.jpg
2019-09-04_134100.jpg (9 КБ) 4609 просмотров
Прораб V1 Test.flp
(52.64 КБ) 105 скачиваний

Dryundel©

Отправлено спустя 2 минуты 15 секунд:
ingener писал(а):
04.09.2019{, 13:19}
А будут ли примеры (сорри, если забегаю вперед) с созданием пользовательского блока тоже из блоков стандартных? Типа рисуем мини-проект и компилируем его в готовый блок?
Это немного другая тема. Здесь рассматриваем ПБ типа (CODE)
Последний раз редактировалось Dryundel 07.09.2019{, 11:45}, всего редактировалось 1 раз.

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#7

Сообщение Dryundel » 05.09.2019{, 10:12}

Беседа пятая.
Работа с библиотеками. (вводная часть)

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

Как это работает.
А все очень просто. Мы показываем библиотеке рычаг, а она дает нам четыре лампочки. В зависимости от того в какую сторону мы дернем рычаг, такая лампочка и загорится. Все!

Конечно же на месте рычага может оказаться к примеру модуль GSM и тогда кроме лампочек библиотека сможет выдавать еще и циферки и еще что ни будь, но это уже детали, а суть остается та же.

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

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

Итак, приступим.

Задача.
Есть коммунальная квартира в которой живут Петр Аристархович и тетя Глаша, а кнопка звонка всего одна. Тете Глаше надо звонить один раз. А вот Петр человек весьма занятный, поэтому в инструкции к кнопке написал, что звонить ему надо семь раз подряд. И не дай бог ошибиться в количестве нажатий или сделать слишком большую паузу, Петр начнет счет сначала и ни за что не выйдет, пока инструкция не выполнится в четком соответствии. Тетю Глашу это сильно бесит и на четвертой попытке она будет визжать как потерпевшая.
Петр конечно был бы не против того, что бы звонок звенел один раз но в его комнате, однако феншуй требует именно семь нажатий на кнопку.

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

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

Подсказка:
Все файлы библиотеки в текстовом формате хотя и имеют непонятное расширение.
Описание находится в этих же файлах.

Вам поможет Notepad++
Открывает практически все текстовые форматы, встраивается в контекстное меню Windows. (русский присутствует)

Этот же текстовый редактор поможет вам в написании кода, т.к. уже имеет на борту инструмент подсветки синтаксиса. Синтаксис С++ присутствует по умолчанию. При желании на просторах интернета можно найти плагин для встраивания синтаксиса Ардуино.

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

Терпения вам и усердия!

Dryundel©

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#8

Сообщение Dryundel » 06.09.2019{, 08:57}

Беседа пятая. (продолжение)
Работа с библиотеками. (основная часть)

Надеюсь библиотеку вы уже рассмотрели и наверняка увидели там много интересного. Если еще и заглянули в файлы примеров, то наверняка чувствуете что понимание где то рядом.
Отлично. Давайте продолжим. Или начнем? Да впрочем не важно.
Как установить библиотеку, пожалуй, я учить не буду. Инфы полно и на форуме в том числе.

Итак, создаем новый блок, обзываем его «Коммуналка», приделываем необходимые входы и выходы. Надеюсь еще помним как это делается. Если нет, то перечитываем первую беседу.
Получаем следующее:
.
4.jpg
.
Теперь нам надо как то прицепить библиотеку. Библиотека это такой чемоданчик который мы потащим с собой через таможенника Arduino IDE на компиляцию а значит надо его тоже задекларировать. По правильному называется подключить, но делается это в той же DeclareSection. Как правильно ее туда записать проще всего посмотреть в любом файле примера. Тупо копируем эту строчку и вставляем в наш блок. Кроме этого прицепляем нашу библиотеку к самому блоку, это сильно облегчит задачу того, кто будет пользоваться нашим блоком. Ему не придется искать и устанавливать библиотеку. Для этого идем на вкладку Библиотеки, жмем на пиктограмму «Выбор папки», находим папку с нашей библиотекой, выделяем ее (не открываем) и жмем Choose.
.
5.jpg
6.jpg
.
Подготовительная часть на этом закончена.

Начинаем внимательно исследовать библиотеку. Читаем описание и смотрим примеры. Выясняем что вариантов нажатия всего одной кнопки целая куча, да и кнопок можно подключить много. Для того что бы библиотека понимала с какой кнопкой мы работаем надо ее как то назвать и указать пин к которому она будет подключена.
.
7.jpg
.
...

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#9

Сообщение Dryundel » 06.09.2019{, 09:02}

Кроме этого находим следующие моменты.
.
8.jpg
9.jpg
.
А это значит можно работать не только с пином, но и с переменными как int так и bool.
Вообще, последнее немного сложновато и можно было просто по аналогии с примерами обозначить пин и все, но мне хотелось сделать блок со входом и выходами.
Короче, называем кнопку «Knopka», задаем не существующий пин 100, и вместо него опрашиваем входную переменную Z типа boolean.

Вот так:
(Обратите внимание в каких секциях что прописывается)
.
10.jpg
11.jpg
11.jpg (56.1 КБ) 4361 просмотр
.
Самое сложное позади, можно приступать к основному коду.
Как мы помним надо отслеживать количество нажатий на кнопку и переводить сигнал либо на звонок Петру либо Глаше.
Сначала посчитаем нажатия и помогут нам в этом библиотечные функции.
.
12.jpg
.
...
Последний раз редактировалось Dryundel 06.09.2019{, 11:56}, всего редактировалось 2 раза.

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#10

Сообщение Dryundel » 06.09.2019{, 09:06}

Используются они в паре, как в примере:
.
13.jpg
.
Для сохранения количества нажатий добавим переменную byte Zx в DeclareSection, а в код запишем, а лучше скопипастим из примера и слегка подправим:

if (Knopka.hasClicks()) {Zx = Knopka.getClicks();}

Осталось добавить стрелочника.

if(Zx == 7) {P = 1;} else {P = 0;}
if(Zx == 1) {G = 1;} else {G = 0;}

Почти все. Единственный момент – Если позвонили к примеру 7раз то на переменной Zx повисло значение 7 и звонок у Петра будет звонить до тех пор пока к Глаше не придет соседка за солью.
Поэтому добавляем еще одну строчку.

if(Zx != 0) { Zx = 0;}

(оператор != означает не равно)
Теперь на выходах у нас будут короткие импульсы в один цикл программы, а длину звонка мы потом выставим через таймер.

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

Knopka.tick(Z);
if (Knopka.hasClicks()) {Zx = Knopka.getClicks();}
if(Zx == 7) {P = 1;} else {P = 0;}
if(Zx == 1) {G = 1;} else {G = 0;}
if(Zx != 0) { Zx = 0;}

И это в принципе вся программа. :)

__________________________________
Маленькое отступление:
Вероятнее всего, если вы впервые кодите, не понятно почему же выходу присвоится единица на один цикл. Давайте пошагово разберемся.
Нажали кнопку 7 раз – Zx присвоилось 7
Сразу же, следующей командой, выходу P присвоилось 1
И тут же Zx мы принудительно присваиваем 0
Вроде бы согласно else {P = 0;} выходу P должен присвоится 0.
Но! Программа выполняется сверху вниз поэтому пока процессор не прочитает все строчки ниже, потом начнет сначала и прочитает строчки которые перед, все это время на выходе P будет висеть 1. Это и есть целый цикл.

__________________________________

Ну вот основной код мы написали, теперь надо учесть нюансы.
Кнопка звонка это не кнопка мыши и паузы между нажатиями будут 0,5-2 секунды, а еще разъяренная соседка снизу, которую затопила тетя Глаша прибежит и будет держать ее еще дольше, поэтому давайте схитрим и сделаем так что бы в этом случае звонка вообще небыло. Пусть соседка слегка остынет.
Находим в описании следующее:
.
14.jpg
.
Эти параметры надо присвоить один раз в самом начале. Заставлять процессор запинаться об них в каждом цикле смысла нет. Зачем тратить его драгоценное время. Поэтому записываем их в секцию SetupSection так:
Knopka.setClickTimeout(2000); - максимальная пауза 2 сек
Knopka.setTimeout(5000); - после 5 секунд при нажатии, засчитать длинное нажатие (удержание)
.
15.jpg
15.jpg (59.01 КБ) 4362 просмотра
.
Что теперь будет проискодить:
При нажатии на кнопку библиотека будет ждать две секунды и только если последующего нажатия не произошло, значению Zx будет присвоено количество нажатий.
Соответственно звонок у тети Глаши зазвенит не сразу после нажатия один раз, а лишь через эти две секунды. Но что такое две секунды для тети Глаши, если до дверей она ковыляет две минуты, так что все норм.
Если же злая соседка нажала на кнопку и держит то через 5 сек библиотека зачтет удержание, а просто нажатие уже не сработает. Вот такая маленькая хитрость.

...
Последний раз редактировалось Dryundel 06.09.2019{, 12:01}, всего редактировалось 4 раза.

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#11

Сообщение Dryundel » 06.09.2019{, 09:09}

Все! Наш супер блок готов. Можно порадовать обитателей коммуналки.
.
16.jpg
16.jpg (3.72 КБ) 4358 просмотров
17.jpg
.
Комуналка Тест1.flp
(204.29 КБ) 122 скачивания
.
Пока мы утрясали финансовые вопросы с заказчиками, выяснилось следующее.
В ближайшее время в нашу веселую квартирку заселится еще один сосед. И по счастливому стечению обстоятельств, это духовный наставник Петра Аристарховича. А его счастливое число 28.
Но у кого же хватит терпения нажать на кнопку 28 раз и не сбиться. Придется установить рядом с кнопкой дисплей. Да и Петр растет духовно, поэтому лучше перенести количества нажатий в параметры пользователя.


Этим мы займемся в следующей части беседы.
Беседа затянулась? А что делать. Вот такая карма у программера. :)

...

aidar_i
Полковник
Сообщения: 3120
Зарегистрирован: 24.12.2016{, 16:55}
Репутация: 674
Откуда: Уфа
Имя: Айдар
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#12

Сообщение aidar_i » 06.09.2019{, 14:28}

Dryundel писал(а):
05.09.2019{, 10:12}
Есть коммунальная квартира в которой живут Петр Аристархович и тетя Глаша
Уффф, наконец то перестал прорабов обижать, :D , не дай бог они упадут! Как профессиональный строитель говорю. :no:

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#13

Сообщение Dryundel » 07.09.2019{, 10:19}

Беседа пятая. (продолжение)
Работа с библиотеками. (заключительная часть)

Ну что ж. Новый сосед скоро заселится, так что нам надо поторопиться доделать наш проект.
Приступим.
Помня о непрерывном духовном возвышении Петра Аристарховича, мы упростим себе жизнь и сделаем так что перенастройка блока будет осуществляться из параметров пользователя. Мы конечно могли бы предоставить заказчику возможность делать это самостоятельно, но…
Во-первых, Петр Аристархович может слишком рано переоценить свое восхождение и этот момент вызовет когнитивный диссонанс в его тонкой душевной организации. А во-вторых мы так потеряем сервисное обслуживание.
___________________________
Первое правило программера заключается в том, чтобы вверенное ему оборудование работало четко без сбоев, не мешая одерживать победы в очередных сражениях World of Tanks, но лишь до тех пор, пока работодатель не решит, что у него все ок и в вас он больше не нуждается.
___________________________
Поэтому мы, как и планировали, перенесем эти настройки в параметры пользователя.
Добавляем новые параметры количества нажатий для трех квартирантов.
Все дополнительные поля оставляем пустыми.
Так же добавляем еще один выход для третьего соседа.
И переименовываем блок так как это новая версия.
.
18.jpg
.
Отлично, справились. Но что-то видимо пошло не так…
Что же случилось? Где мы ошиблись?

Все нормально. Проверка говорит о том, что параметры не определены. Этот момент поможет и другим пользователям не забыть изменить настройки под своих клиентов. Сохраняем изменения и выходим из редактирования. Видите, название блока выделено красным.
А при попытке компиляции FLProg скажет, что один из блоков не корректен.
.
19.jpg
19.jpg (52.13 КБ) 4235 просмотров
.
Дважды кликаем на блоке, и выставляем оперативные параметры.
.
20.jpg
20.jpg (37.48 КБ) 4235 просмотров
.
Возвращаемся к редактированию.
Теперь нам надо заменить явные присвоения значений переменным P и G на переменные параметров. Заодно добавляем еще одного стрелочника, который будет обслуживать третьего соседа.
.
21.jpg
.
...
Последний раз редактировалось Dryundel 10.09.2019{, 11:47}, всего редактировалось 1 раз.

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#14

Сообщение Dryundel » 07.09.2019{, 10:33}

На этом можно было бы и закончить, но памятуя о несчастных посетителях будущего духовного предводителя коммуналки, облегчим их участь и прикрутим к блоку выход с которого будет выводиться количество нажатий на дисплей рядом с кнопкой звонка.
Вроде бы задача проще простого. Взять переменную Zx и сделать из нее выход. Но не тут-то было. Мы помним, что количество нажатий в переменную Zx записывается только через две секунды после последнего нажатия. Представляете, как будет неудобно. Если нет, попробуйте.
Снова залезаем в библиотечный талмуд и находим функцию isPress()
.
22.jpg
.
Даная функция дает нам сигнал сразу в момент нажатия. То, что и требовалось. Надо только добавить счетчик. Вы не поверите как просто сделать счетчик в коде! Надо всего лишь добавить одну переменную и условие по которому к этой переменной будет прибавляться единица. Этим условием и будет isPress()
А с прибавлением единицы в С++ вообще полная демократия. Как только не пишут.

A=A+1;
A=1+A;
A+=1;
A++;
++A;

Все варианты написания прибавят к текущему значению A единицу. Из них нам точно не подойдет ++A; т.к. он сначала выведет нашу переменную на дисплей а потом прибавит к ней единицу.
Мне больше нравится A++;
Добавляем в наш блок переменную Disp в виде integer выхода и пишем код счетчика.

if(Knopka.isPress()) {Disp++;}

Это все! :) Теперь при нажатии на кнопку, переменная Disp будет увеличиваться на единицу.
Осталось только сбрасывать это значение, в момент когда Zx будет присвоено значение отличное от ноля и у кого то из соседей сработает звонок.
Подобное действие в нашем коде уже есть.

if(Zx != 0) { Zx = 0;}

Поэтому мы просто добавляем еще одно действие по условию (по аналогии цветы – поцелуй, улыбка)

if(Zx != 0) { Zx = 0; Disp=0;}

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

Ну и еще один маленький штришок к нашему произведению.
Помните соседку, которая нажала и держит кнопку звонка. Звонок то не зазвенел, а вот единичка на дисплее высветилась. Надо бы сбросить ее в этом случае.
Добавляем и условие (по аналогии из «Прораба» "выше первого И ниже третьего").
Только в этом случае нам потребуется не И , а ИЛИ. Обозначается ИЛИ знаком ||

Вот так:

if(Zx != 0 || Knopka.isHolded()) { Zx = 0; Disp=0;}

Функцию Knopka.isHolded() мы так же нашли в описании библиотеки. Она возвращает удержание (длинное нажатие) кнопки.

И вот как теперь выглядит наш основной код:

Knopka.tick(Z);
if (Knopka.hasClicks()) {Zx = Knopka.getClicks();}
if(Zx == Pitetr) {P = 1;} else {P = 0;}
if(Zx == Glasha) {G = 1;} else {G = 0;}
if(Zx == Xxx) {X = 1;} else {X = 0;}
if(Knopka.isPress()) {Disp++;}
if(Zx != 0 || Knopka.isHolded()) { Zx = 0; Disp=0;}

Прибавилась всего пара строчек, а функционал заметно возрос.

На этом мы пока оставим умиротворенных соседей коммуналки. Думаю, в скором времени они обратятся за сервисным обслуживанием.
А сами займемся не обязательным, но очень нужным делом. Напишем описание к нашему блоку. Уверяю, потомки его оценят. Да и мы сами через полгода с трудом будем вспоминать как пользоваться нашим блоком.
.
23.jpg
.
24.jpg
24.jpg (20.18 КБ) 4232 просмотра
КоммуналкаV1 Тест2.flp
(248.88 КБ) 101 скачивание
.
Dryundel©

_________________________________________________________
Отправлено спустя 1 час 3 минуты 14 секунд:
В этой беседе мы рассмотрели библиотеку GyverButton и познакомились с доброй половиной ее функций.
Для одной единственной кнопки данная библиотека предоставляет весьма обширный функционал.
Ознакомиться с ее возможностями, а так же воспользоваться конструктором на базе GyverButton в виде блока можно здесь.

Хочу так же выразить благодарность автору библиотеки AlexGyver.
На страницах его сайта вы сможете найти много интересных проектов и обучающего материала. (не реклама)

pan
Полковник
Сообщения: 2860
Зарегистрирован: 13.04.2017{, 11:57}
Репутация: 204
Имя: noname

Создание пользовательского блока (CODE) простым языком.

#15

Сообщение pan » 07.09.2019{, 20:27}

Dryundel писал(а):
07.09.2019{, 11:36}
А с прибавлением единицы в С++ вообще полная демократия. Как только не пишут.
Извините, вставлю 5 копеек. потом можете удалить.
С записями такого вида:
A++;
++A;
надо быть внимательнее.
не смотря на то, что вроде бы выполняется прибавление единицы в обоих случаях,
тем не менее можно получить разные значения и баги.

если это отдельная запись, то нет разницы.
а если мы присваиваем это значение - то результат будет разный.

int x = 0;
int A = 5;
x = A++;

чему равен х? 6? ну конечно же!!!!...... нет.... х равен 5.

а вот так :
x = ++A;
x будет равен 6.

будьте внимательней.

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#16

Сообщение Dryundel » 07.09.2019{, 20:43}

pan писал(а):
07.09.2019{, 20:27}
int x = 0;
int A = 5;
x = A++;

чему равен х? 6? ну конечно же!!!!...... нет.... х равен 5.

а вот так :
x = ++A;
x будет равен 6.
pan, а не наоборот?
И потом, речь идет об инкременте без участия доп переменных.
И вроде как я предупреждал об использовании префиксного написания.

pan
Полковник
Сообщения: 2860
Зарегистрирован: 13.04.2017{, 11:57}
Репутация: 204
Имя: noname

Создание пользовательского блока (CODE) простым языком.

#17

Сообщение pan » 07.09.2019{, 21:10}

Dryundel писал(а):
07.09.2019{, 20:43}
а не наоборот?
нет.
убедительно?Показать
Изображение
я и говорю, будьте внимательней

Аватара пользователя
Sancho
Полковник
Сообщения: 4066
Зарегистрирован: 25.12.2015{, 17:32}
Репутация: 590
Откуда: Ярославль.
Имя: Александр
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#18

Сообщение Sancho » 07.09.2019{, 21:12}

Dryundel писал(а):
07.09.2019{, 20:43}
а не наоборот?
Всё правильно у Алексея. Это пре.. и пост.. инкремент.

Отправлено спустя 39 секунд:
опоздал :)
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.

pasha71
Лейтенант
Сообщения: 454
Зарегистрирован: 26.08.2017{, 23:44}
Репутация: 34

Создание пользовательского блока (CODE) простым языком.

#19

Сообщение pasha71 » 07.09.2019{, 21:31}

Может кому пригодится.Когда ходил на курсы по оставалась всякая всячина.Это можно скопировать в STUDIO 7 или 6 и пошагово просмотреть выполнение и регистры что бы лучше понять.Может облегчит кому то понимание этой темы
Вложения
Арефметические и порозрядные операции.txt
(2.9 КБ) 130 скачиваний

Аватара пользователя
Dryundel
Полковник
Сообщения: 2401
Зарегистрирован: 22.05.2017{, 23:15}
Репутация: 783
Откуда: Ярославль
Имя: Андрей
Контактная информация:

Создание пользовательского блока (CODE) простым языком.

#20

Сообщение Dryundel » 07.09.2019{, 21:51}

pan писал(а):
07.09.2019{, 21:10}
убедительно?
Убедил. :)
Век живи, век учись.
Никогда так не делал.
Ведь если без переменной х , то как бы наоборот получается. Но здесь другая логика.
Спасибо.

Отправлено спустя 3 минуты 31 секунду:
И господа, новички, в беседе №6 ошибки нет. Там все правильно.
А на пост от pan, обратите внимание!

Прошу модераторов не удалять эту дискуссию. Поучительно.

Ответить

Вернуться в «Обучающие примеры работы в FLProg»