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

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

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

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

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

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

#21

Сообщение Dryundel » 08.09.2019{, 12:14}

.
Беседа шестая.
Прерывания и создание функции.


Я обещал без теории, ну извините, мы так высоко забрались, что без этого уже никак. Но постараюсь что бы вам не было совсем уж скучно. :)
Еще меня тут просили не обижать прораба. Но куда же без него?! Все дело встанет!

Итак, что же такое прерывание.
Ситуация:
Все та же стройка, идет мучительный процесс возведения элитного жилого дома. Все занимаются своим делом. Вы копаете траншею от забора и до обеда. Прораб по обычаю мечется по этажам. И вот в этот момент, ваш приятель подает вам условный сигнал. (Помните, как в приключениях Шурика – «Третьим будешь?») Этот сигнал вам хорошо известен. Сигнал этот, так же как и место свершения таинства, гвоздем процарапаны на подкорке вашего мозга. Поэтому, ничуть не мешкая вы прерываетесь и мухой летите в кандейку, там раскатываете 0,5 на троих и так же мухой возвращаетесь к своей траншее. Общий процесс от этого не пострадал, прораб ничего не заметил, ну разве что завершение стройки отодвинулось на очень короткий промежуток времени. На столько короткий что им можно пренебречь.
Вот и весь принцип работы прерывания.

В Ардуино прерывания бывают: Аппаратные, Программные и Внутренние (синхронные).
Рассмотрим аппаратные. К ним можно отнести нажатие на кнопку, подключенную к ножке контроллера. Так вот по этому сигналу, контроллер останавливает выполнение основного кода и выполняет отдельный кусочек программы, находящийся вне этого кода (кандейке). После чего возвращается в основной код, четко в то место на котором прервался. Основной код выполняется дальше.
Сразу оговорюсь. Не все ножки контроллера поддерживают прерывания. К примеру, у Arduino UNO их две – пин2 и пин3. Прерывания тоже пронумерованы 0 и 1.

Пин2 – прерывание 0
Пин3 – прерывание 1

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

В коде функция аппаратного прерывания выглядит так:

attachInterrupt(№прерывания, действие, условие);

№прерывания – это номер кандейки.
Действие – условное название того, что будем делать (в кандейке)
Условие – это тот тайный знак, при котором надо все бросать и бежать.

Условий всего 4

LOW – когда на пине 1
CHANGE – когда сигнал меняется с 0 на 1 и наоборот.
RISING – когда сигнал изменяется строго с 0 на 1.
FALLING – когда сигнал изменяется строго с 1 на 0.

Я специально использовал 0 и 1, так как искренне считаю, что многим, здесь присутствующим, это будет понятней.
Замените 0 на LOW , а 1 на HIGH и получите классическое описание.

Займемся усовершенствованием нашего прорабского калькулятора и прикрутим к нему клавиатуру. Состоять она будет из двух кнопок, которыми мы будем выставлять актуальный этаж.
Условно представим, что наша программа ну очень большая и полетные вычисления — это только маленькая ее часть. Поэтому на выполнение цикла уходит значительное время, а нажатие на кнопку ну очень короткое. Этажей то у нас 50, а время на ввод значения одной кнопкой гораздо меньше секунды. В наших супер возможностях я не сомневаюсь, а вот контроллер может и пропустить какое ни будь нажатие, т.к. за время 1-го цикла их штуки три может произойти. Вот тут-то нам без прерываний не обойтись.

Приступим.
Открываем для редактирования наш блок «Прораб V1», переименовываем его и удаляем вход Etazh, а вместо входа декларируем переменную Etazh и присваиваем ей значение по умолчанию 0. В принципе ноль то можно и не присваивать. При старте он и так там будет, но если стартовое значение должно отличаться от ноля, то это можно сделать подобным образом.

Int Etazh = 0;
.
1.jpg
1.jpg (59.15 КБ) 2632 просмотра
.
Еще нам потребуется визуальный контроль набранного с клавиатуры значения этажа.
Для этого добавим выход Е и приравняем его значение к переменной Etazh

Вот так:

E = Etazh;

Теперь нам не придется считать в уме количество нажатий. Мы сможем видеть результат нажатий на дисплее.
Основной код теперь выглядит так:

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);}
E = Etazh;

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

Теперь создаем наши прерывания. Кнопку «+» мы прикрутим ко второй, а «-» к третьей ноге нашего бешеного, считающего таракана с гордым именем Atmega328. А ноги эти привяжем подтяжкой к плюсу (VCC), дабы он ими не дрыгал. И если кнопки, подключенные к земле, не нажаты, то на входах будем иметь «1», а при нажатии «0». Это и есть условие FALLING.

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

pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);

Сразу оговорюсь, внутренняя подтяжка в некоторых схемах не всегда адекватно работает, особенно на прерываниях.

При конфигурации входа как pinMode(2, INPUT); пин будет условно подтянут к земле.

Возвращаясь к функциям, вспомним что они что-то возвращают, но так не всегда. Некоторые функции сами по себе ничего не возвращают. Шурупят там у себя, совершают какие-то вычисления, за чем-то следят, отдают команды, имеют внутри себя другие функции. К таким функциям относится и attachInterrupt();

Записывается эта функция в SetupSection:

attachInterrupt(0, FunсtionPLUS, FALLING);
attachInterrupt(1, FunсtionMINUS, FALLING);

Где FunсtionPLUS – имя действия которое свершится в кандейке по команде FALLING от товарища №0 (пин 2).
Аналогично и с FunсtionMINUS
.
2.jpg
.

Остается только найти эту кандейку. Все просто, методом исключения, находим в редакторе блоков ту единственную вкладку, которую мы еще не рассмотрели под названием FunсtionSection.
В ней то мы и создадим наши личные функции с именами FunсtionPLUS и FunсtionMINUS.
Кликаем в секции FunсtionSection на плюсик и в открывшемся окне вводим:

void FunсtionPLUS()


Почему так?
Про вильку и тарельку помните? Ну вот…

Лингвистические особенности языка разбирать не будем.
Хотя для меня самого до сих пор загадка почему разделы скетча назвали пустотой – void.
Может МЭТРЫ нам подскажут или у кого версии есть. Высказывайтесь. Лишнее потом модераторы подчистят. Думаю, им самим будет интересно. Только без пошлости господа.



Так, теперь в окне тела функции пишем то, что должна делать наша функция.
А должна она инкрементировать (увеличивать на единицу) нашу переменную.

Etazh++;

Подобным образом поступаем с FunсtionMINUS. Только в ней нашу переменную мы будем декрементировать (уменьшать на единицу):

Etazh--;

.
3.jpg
.


С функциями разобрались, со входами выходами тоже. Вроде бы все.

Остался один малюсенький, но очень важный момент. Дело в том, что переменные используемые основным кодом программы, как крепостные в поместье основного кода. И подчиняются они только основному коду и смогут изменить свое значение только по команде этого кода и никакая сила на стороне (вне основного кода) не изменит их значение. Что же делать? На этот случай помещики и придумали вольную для крестьян. Вот и мы давайте дадим вольную нашей переменной Etazh.

А в паспорте ей практически так и запишем:

volatile int Etazh = 0;

Теперь ее сущность смогут изменить даже в кандейке. (Ну о чем я говорю, вы и сами все прекрасно понимаете :))
Следовало сразу это учесть при создании переменной, но я умышленно не сделал этого, дабы обратить ваше внимание на сей факт.

На этом все. Наш блок готов. Не забываем сохранить. И можно пользоваться.
.
4.jpg
4.jpg (12.94 КБ) 2632 просмотра
Прораб_падает_с_высоты_V2_(CODE).ubi
(41.14 КБ) 111 скачиваний
.
Dryundel©

Кто увидит прораба. передавайте привет, и долгих лет жизни ему. :)
.
Последний раз редактировалось Dryundel 10.09.2019{, 12:01}, всего редактировалось 6 раз.

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

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

#22

Сообщение pan » 08.09.2019{, 20:34}

Dryundel писал(а):
08.09.2019{, 18:58}
почему разделы скетча назвали пустотой – void
Dryundel писал(а):
08.09.2019{, 18:58}
Про вильку и тарельку помните?
это не название разделов скетча. все разделы - это такие же функции.
void - это тип возвращаемого значения. если функция ни чего не возвращает то ее объявляют void функция...
так же и с разделами скетча.

в директории встроенных библиотек есть файл main.cpp
вот так он выглядитПоказать
Изображение

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

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

#23

Сообщение Dryundel » 08.09.2019{, 22:40}

pan писал(а):
08.09.2019{, 20:34}
void - это тип возвращаемого значения. если функция ни чего не возвращает то ее объявляют void функция...
Воооот она истина! :)
Я же сам себе в последней беседе почти ответил на свой вопрос. А связать "пустота" и "ничего не возвращает" не допер.
Теперь и эта мозаика сложилась.
Все больше убеждаюсь что не зря затеял эту эпопею. Глядишь и меня чему то научат.
Последний раз редактировалось Dryundel 09.09.2019{, 09:03}, всего редактировалось 1 раз.

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

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

#24

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

ЭПИЛОГ

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

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

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

solo
Рядовой
Сообщения: 54
Зарегистрирован: 06.12.2016{, 18:04}
Репутация: 0
Откуда: Харьков

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

#25

Сообщение solo » 09.09.2019{, 15:37}

а подскажите пж
Dryundel писал(а):
06.09.2019{, 09:02}
называем кнопку «Knopka»
а деклар секции пишим
ЖБитон Кnopka

если не затруднит что означает следующее
Dryundel писал(а):
07.09.2019{, 11:36}
Knopka.tick(Z);
if (Knopka.hasClicks()) {Zx = Knopka.getClicks();

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

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

#26

Сообщение Dryundel » 09.09.2019{, 16:18}

solo писал(а):
09.09.2019{, 15:37}
если не затруднит что означает следующее
Dryundel писал(а):
07.09.2019{, 11:36}
Knopka.tick(Z);
if (Knopka.hasClicks()) {Zx = Knopka.getClicks();
Нашу конкретную кнопку мы назвали Knopka. Можно создать еще одну кнопку и назвать Knopka2 и т.д.
hasClicks() - библиотечная функция которая возвращает true когда библиотека определила многократное нажатие.
getClicks() - библиотечная функция которая возвращает количество нажатий подряд (до длинной паузы)
Zx - переменная в которой хранится количество нажатий подряд.

Теперь переводим с С++ на русский.

Если определено многократное нажатие то записать в переменную количество нажатий.

Кивни если понял. :)

А Knopka.tick(Z); это функция которая ничего не возвращает, а опрашивает в каждом цикле программы состояние конкретной кнопки.
Это служебная функция для библиотеки. Ее наличие обязательно.

Учитесь читать описания библиотек. Не все там написано напрямую. Кое что надо смотреть в примерах.

Отправлено спустя 6 минут 29 секунд:
solo писал(а):
09.09.2019{, 15:37}
а деклар секции пишим
ЖБитон Кnopka
А вот что это, не понял я. Вроде про ЖБитон ничего не было.

solo
Рядовой
Сообщения: 54
Зарегистрирован: 06.12.2016{, 18:04}
Репутация: 0
Откуда: Харьков

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

#27

Сообщение solo » 09.09.2019{, 17:55}

я про это
в декларе секции
почему перед Knopka есть GButton чем регламентируется
и еще дополнительный вопрос, в каких случаях нужно указывать, что блок пользователя можно использовать в проекте один раз
Вложения
10.jpg
10.jpg (34.73 КБ) 2506 просмотров

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

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

#28

Сообщение Dryundel » 09.09.2019{, 18:20}

solo писал(а):
09.09.2019{, 17:55}
я про это
в декларе секции
почему перед Knopka есть GButton чем регламентируется
:smile171: А я то дурень, все посты перерыл. Всё Битон искал.

Регламентируется это используемой библиотекой. (смотри примеры)
Так инициализируются кннопки или набор кнопок если их не одна.

GButton Knopka1(3)
GButton Knopka2(5)
GButton Knopka3(9)

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

Если с boolean более менее понятно, и функция Knopka.tick(Z) отслеживает состояние этой переменной ( 0 или 1 ), то integer используется для резистивных клавиатур (на аналоговом пине). Пример в библиотеке есть. А можно посмотреть еще и здесь.

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

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

#29

Сообщение Dryundel » 09.09.2019{, 19:06}

solo писал(а):
09.09.2019{, 17:55}
в каких случаях нужно указывать, что блок пользователя можно использовать в проекте один раз
В каких случаях нужно указывать, что блок пользователя можно использовать в проекте один раз.

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

Забыл про это рассказать. Очень хорошо что спросили.

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

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

#30

Сообщение Sancho » 09.09.2019{, 19:08}

Дополню немного.
GButton Knopka1(3)
GButton Knopka2(5)
GButton Knopka3(9)
это значит - при помощи инструмента GButton, описанного в библиотеке,
создаём три объекта с названиями Knopka1, Knopka2, Knopka3 и их аргументами, входными параметрами в данном случае.
Затем к каждому свойству/функции каждого можно обратится, набрав
Knopka1. а после точки свойство/функцию с необходимым аргументом.
это типа как адрес: гагарина17.сколько_глаз или гагарина18.сколько_глаз - постройки/квартиры/подвалы одинаковые, а население разное :)
Может сумбурно, но примерно как-то так.
мой ник в нете и почте omelchuk890, если что. запомните на всякий. многие знают номер тлф.

edyapd
Капитан
Сообщения: 768
Зарегистрирован: 20.09.2019{, 11:38}
Репутация: 65
Имя: Эдуард

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

#31

Сообщение edyapd » 25.09.2019{, 18:56}

Dryundel писал(а):
09.09.2019{, 09:02}
В принципе тема исчерпала себя
Тема очень интересна для меня, учитывая, что я вообще не понимаю С.
А можно её немного развить?
Что будет например, когда ваш товарищ подал сигнал, вы кинулись в кандейку, а употреблять оказывается нечего. И ваш товарищ всего лишь предлагает скинуться. Вы скидываетесь и договариваетесь встретиться на этом же месте снова через № кол-во времени. Сверив часы вы разбегаетесь по рабочим местам. И вот час Х настал и вы снова кинулись в кандейку.
Так вот вопрос, можно как-то в ПБ использовать прерывания по таймеру?
Читал, что на AtMega168 можно вызывать прерывания по таймеру каждые 1*10-6 сек., при внутреннем тактировании в 1МГц.
Интересно было бы увидеть как настроить таймер, что бы он инкремировал какую-то переменную. Которая в свою очередь считывалась и сбрасывалась по внешнему прерыванию.
Возможно это всё сделать в ПБ?

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

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

#32

Сообщение Dryundel » 25.09.2019{, 20:19}

edyapd писал(а):
25.09.2019{, 18:56}
Возможно это всё сделать в ПБ?
Сделать возможно всё, ну или почти всё. Вопрос усердия, времени и средств.
Данная тема не предусматривает изучения возможностей микропроцессоров и основ программирования.
Как разместить код в блоке и какая вкладка за что отвечает в редакторе пользовательских блоков, я постарался описать весьма доходчиво.
Как говорится палитру, мольберт и краски предоставил, а уж какой шедевр Вы создадите, мы оценим позже, если покажете. :)

edyapd
Капитан
Сообщения: 768
Зарегистрирован: 20.09.2019{, 11:38}
Репутация: 65
Имя: Эдуард

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

#33

Сообщение edyapd » 25.09.2019{, 20:50}

Dryundel писал(а):
25.09.2019{, 20:19}
если покажете
Эх, боюсь, что не покажу. Художник из меня от слова "худо". Да и программист такой же.

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

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

#34

Сообщение Dryundel » 25.09.2019{, 21:22}

edyapd писал(а):
25.09.2019{, 20:50}
Эх, боюсь, что не покажу. Художник из меня от слова "худо". Да и программист такой же.
Если бы Усэйн Болт в младенчестве после второго приземления на задницу решил что ходить это не моё, вряд ли бы он пробежал стометровку за 9,58 секунды! :)
ОфтопПоказать

Аватара пользователя
magpit
Лейтенант
Сообщения: 382
Зарегистрирован: 01.10.2017{, 12:55}
Репутация: 16
Имя: Сергей

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

#35

Сообщение magpit » 28.09.2019{, 22:02}

Dryundel писал(а):
09.09.2019{, 09:02}
ЭПИЛОГ

Ну вот мы и разобрали до винтика редактор пользовательских блоков.
Как смог, постарался сократить ваш тернистый путь. В принципе тема исчерпала себя. Но если все-таки остались какие то белые пятна, пишите, будем разбираться.
В этой теме мы лишь слегка коснулись программирования. Предполагаю что вопрос программирования на языке С++ у многих весьма актуален, но это уже другая история и в этой теме мы ее развивать наверное не будем.
По стечению обстоятельств, в момент окончания написания сего скромного учебника, вышла новая 6-я версия FLProg.
Уже потираю руки, думаю что будет еще о чем написать. :)

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

Dryundel
А можно по подробней со скобками, где ставятся двойные и для чего или {ghgghjm
}
}
}

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

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

#36

Сообщение pan » 28.09.2019{, 22:40}

magpit, это относится к синтаксису языка, а не к блокам

Аватара пользователя
magpit
Лейтенант
Сообщения: 382
Зарегистрирован: 01.10.2017{, 12:55}
Репутация: 16
Имя: Сергей

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

#37

Сообщение magpit » 29.09.2019{, 23:55}

pan писал(а):
28.09.2019{, 22:40}
magpit, это относится к синтаксису языка
Дак я это и имел ввиду. В сообщении скобки выравнялись при отправке а я их лесенкой выстраивал.
Вопрос как читать код если в конце много скобок и ещё иногда код пишится с отступом от полей, что это
может значить?

edyapd
Капитан
Сообщения: 768
Зарегистрирован: 20.09.2019{, 11:38}
Репутация: 65
Имя: Эдуард

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

#38

Сообщение edyapd » 30.09.2019{, 05:50}

magpit, я не знаток С, но могу предположить, что в скобках пишется тело функции. Если в конце несколько закрывающихся скобок, значит в теле функции присутствует другая функция. А отступы делаются для удобочитаемости. Они как раз и помогают искать где начинается и заканчивается функция.
А по скобкам простой пример: 2*(3+(45-4*(32+2))). У вас же не вызовут трудности несколько скобок в конце. А внутри же тоже функции, сложения, вычитания, умножения.

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

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

#39

Сообщение Dryundel » 30.09.2019{, 08:44}

magpit писал(а):
29.09.2019{, 23:55}
Вопрос как читать код если в конце много скобок и ещё иногда код пишится с отступом от полей, что это
может значить?
magpit, во всех беседах я давал только самое необходимое, в том числе и ссылки на софт, и если бы Вы следовали всем советам, то наверняка скачали бы и установили Notepad++ . В нем есть подсветка синтаксиса C++ . Поставив, к примеру, курсор на одну скобку, Вы сразу увидите вторую, ответную, да еще и кусок кода к ним относящийся будет показан.
.
2019-09-30_083804.jpg
2019-09-30_083804.jpg (77.95 КБ) 2286 просмотров
.

Ну и логику включайте, это помогает. :)
Вот человек правильно Вам говорит:
edyapd писал(а):
30.09.2019{, 05:50}
Если в конце несколько закрывающихся скобок, значит в теле функции присутствует другая функция. А отступы делаются для удобочитаемости. Они как раз и помогают искать где начинается и заканчивается функция.

Аватара пользователя
Ivan_Kornege
Лейтенант
Сообщения: 342
Зарегистрирован: 29.04.2017{, 08:24}
Репутация: 27
Откуда: гАндурас
Имя: Ivan

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

#40

Сообщение Ivan_Kornege » 10.12.2019{, 14:15}

А из этого кода никак ни сделать блок в флпрог?
Код компилируется в IDE но невозможно вставить в БП ни в какой версии от 4 до 6.2.1 проверил везде пишет некорректный блок

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

 //ели вставить в флпрог БП DeclareCection = то блок некорректен.
     
    #define USE_FONTS 1        
     
    #if (USE_FONTS == 1)
    #include "fonts.h"
    #endif                

Отправлено спустя 30 минут 4 секунды:
А из такой конструкции как сделать ПБ

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

#elif (USE_FONTS == 0)
void fillString(String text, uint32_t color) {
  fullTextFlag = false;
  modeCode = MC_TEXT;
  return;
}
#endif

Ответить

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