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

Нужна ли статья про Редактор Code-Professional?

Да, очень нужна!
51
75%
Интересно было бы знать.
15
22%
Мне хватает редактора Code-Basiс.
1
1%
Не пользуюсь редактором вообще.
1
1%
 
Всего голосов: 68

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

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

#1

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

По многочисленным вопросам.
.
Теория
.
Довольно часто, на просторах Интернета встречаются примеры кода выполняющие ту или иную задачу и у пользователей FLProg возникает желание добавить данный функционал в свой проект в виде ПБ (Пользовательского блока).
Ничего особо сложного в этом нет. Тем более если данным блоком будете пользоваться только вы. Не надо заботится об универсальности и писать описание. Хотя последнее я бы посоветовал сделать в любом случае, ибо через полгода вы и не вспомните что это и зачем.
Прежде всего хочу сказать, что для грамотного переноса скетча (кода, примера) в блок необходимо обладать базовыми знаниями языка С++. К сожалению для русскоязычного человека к незнанию C++ зачастую накладывается и незнание английского языка, что усложняет задачу вдвойне. Дело в том, что из названия операторов и функций уже становится понятно за что примерно она отвечает.
Возьмем к примеру digitalRead(), analogRead(), digitalWrite(), analogWrite().
Все же довольно прозрачно - Цифровой, Аналоговый, Читаем, Пишем. Очевидно же, что речь идет о цифровых и аналоговых входах/выходах контроллера. Либо мы читаем пин, либо записываем на него значение.
Ориентируясь за что отвечают операторы и функции (их еще обзывают командами Arduino), достаточно просто перенести пример в блок.
Есть в среде ArduinoIDE еще и базовые, основные функции, без которых не обходится ни один скетч:
.
void setup() // установки
{
//Все что здесь, выполняется один раз при старте контроллера
}
void loop() // петля (бесконечный цикл)
{
// Все что здесь будет выполняться после setup() и бесконечно повторяться до отключения питания.
}
.
В FLProg, в базовом редакторе ПБ, для этих функций существуют соответствующие секции.
Setup Loop.jpg
Setup Loop.jpg (12.27 КБ) 3021 просмотр
.
Кроме этого есть секции
DeclareSection
Сюда заносится все то, что находится перед void setup()
А иногда и то, что после, но не входит в состав void loop() и других функций (в скетче, примере).
.
FunctionSection
Сюда заносятся прочие пользовательские функции.
.
С теорией пожалуй хватит.
Единственное, что нам еще потребуется, это Notepad++. Обязательно скачайте и установите. Это ваш первый помощник в создании и корректировке кода.
.
Практика
.
Сразу начнем с не совсем удачного примера.
.
Пример сетча с просторов ИнтернетаПоказать
int led_pin=3; // пин подключения
void setup() {
pinMode(led_pin, OUTPUT); // Инициализируем цифровой вход/выход в режиме выхода.
}
void loop() {
for (int x=0; x<3; x++) {
digitalWrite(led_pin, HIGH);// зажигаем светодиод
delay(250); // ждем 350 милисекунд
digitalWrite(led_pin, LOW); // выключаем светодиод
delay(100); // ждем 300 милисекунд
}
delay(300);
for (int x=0; x<3; x++) {
digitalWrite(led_pin, HIGH);// зажигаем светодиод
delay(500); // ждем 700 милисекунд
digitalWrite(led_pin, LOW); // выключаем светодиод
delay(100); // ждем 300 милисекунд
}
delay(300);
for (int x=0; x<3; x++) {
digitalWrite(led_pin, HIGH);// зажигаем светодиод
delay(250); // ждем 350 милисекунд
digitalWrite(led_pin, LOW); // выключаем светодиод
delay(100); // ждем 300 милисекунд
}
delay(5000); // ждем 5 секунд
}
.
Самый простой способ.
Переносим код в Notepad++, изучаем его, находим void setup() и void loop().
Не забудьте выбрать Синтакс С++
.
Сразу после void setup() находим открывающую фигурную скобку { . Выделяем ее и Notepad++ показывает нам ответную закрывающую скобку } .
Notepad.jpg
.
Все что между этими скобками, за исключением самих скобок копируем в SetupSection.
SetupSection.jpg
.
Точно так же поступаем и с void loop(), переносим содержимое, за исключением открывающей и закрывающей фигурных скобок в LoopSection.
LoopSection.jpg
.
Все что у нас осталось в коде и не вошло в void setup() и void loop(), это первая строчка.
Ее мы копируем в DeclareSection.
DeclareSection.jpg
DeclareSection.jpg (14.28 КБ) 3021 просмотр
.
Не забываем вписать название блока и сохранить.
TestBlock.jpg
TestBlock.jpg (38.2 КБ) 3021 просмотр
.
Наш блок как бы готов.
Почему как бы? Да потому что у нашего блока не ни входов ни выходов.
TestBlock1.jpg
TestBlock1.jpg (24.74 КБ) 3021 просмотр
.
Несмотря на это, если загрузить проект в контроллер, все будет работать. На третьем пине будет генерироваться сигнал SOS - три коротких, три длинных, снова три коротких и пауза 5 секунд. И так по кругу.
.
Продолжение следует...
Последний раз редактировалось Dryundel 27.09.2021{, 12:56}, всего редактировалось 2 раза.

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

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

#2

Сообщение Dryundel » 23.09.2021{, 12:20}

Продолжаем разговор...
.
Блок мы создали, он работает, но проку от него в FLProg не много, потому как повлиять на его работу мы не можем. Ни включить выключить генерацию SOS, ни изменить пин, ни задать время коротких/длинных импульсов не представляется возможным , кроме как снова лезть в редактор. Попробуем это изменить.
Наверное первое что необходимо, это включить или выключить генерацию SOS. Сделать это можно запретом или разрешением выполнения кода по какому то условию.
.
Создаем вход boolean En в соответствующей вкладке редактора.
Все созданные входы/выходы являются переменными (в базовом редакторе) и автоматически декларируются при компиляции как переменные. Дополнительно декларировать их не надо.

Далее создаем условие выполнения кода если En=1.
Можно записать так:

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

или так, что одно и то же:

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

Теперь у нас появился вход En, при подаче на который логической единицы, наш первоначальный код в LoopSection будет выполняться и будет пропускаться если En=0.
En.jpg
En.jpg (3.18 КБ) 2985 просмотров
Как учебный пример блок работать будет.
Можете запустить и попробовать.
Блок Тест.flp
(65.03 КБ) 74 скачивания
.
Далее можно добавить в параметры время задержек.
Покажу на примере паузы между миганием.
.
Во вкладке "Параметры пользователя" создаем константу Pause и вписываем ее в соответствующие delay()
Pause.jpg
Теперь у блока есть параметр "Pause", а при компиляции delay(Pause) будет заменяться на соответствующее значение.
Pause2.jpg
Pause2.jpg (35.66 КБ) 2976 просмотров
Блок Тест2.flp
(68.31 КБ) 57 скачиваний
То же самое можно проделать и с другими временными параметрами.
.
Так же поступаем с выбором пина на который будет выводиться сигнал.
Pin.jpg
Блок Тест3.flp
(70.27 КБ) 73 скачивания
.
Дальнейшие манипуляции с данным кодом не имеют смысла, т.к. задержки в нем основаны на delay()
Другие блоки в проекте вместе с этим работать не будут
Почему? Читайте здесь
При желании можно попробовать заменить все delay() на таймеры, однако проще будет построить такой алгоритм на других принципах.
.
Продолжение следует...
Последний раз редактировалось Dryundel 27.09.2021{, 12:59}, всего редактировалось 5 раз.

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

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

#3

Сообщение Dryundel » 23.09.2021{, 17:43}

Продолжение, оно же и окончание. :)
.
Мы рассмотрели основные принципы создания ПБ (Пользовательского Блока) из скетча. Я специально начал с не совсем удачного примера кода для начинающих. Таких примеров в сети навалом. Все они работают как отдельно взятый скетч, но не смогут работать если кроме него поместить в программу еще что то. Запомните, а лучше нацарапайте на подкорке мозга гвоздем, прописную догму:
Команда delay() - первый враг работы микроконтроллера.
Исключением может быть delay() в void setup(), когда это просто необходимо для правильной настройки подключаемых устройств.
.
Перейдем к более приближенному к реальности примеру.

Итак, вам попался какой то интересный скетч, урок, пример, видосик, функционал из которого захотелось упаковать в Пользовательский Блок. К примеру это:

.
На тринадцатой минуте данного ролика приводится пример не сложного кода из которого получится вполне себе функциональный ПИД регулятор. По ссылке под видео (на YouTube) находим готовый код, дабы не переписывать его руками.
https://github.com/AlexGyver/tutorials/ ... plePID.ino
Код по ссылкеПоказать

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

// функция ПИД регулятора
void setup() {
}

void loop() {
  //analogWrite(pin, computePID(sensorRead, 30, 1.0, 2.0, 3.0, 0.02));
  //delay(20);
}

// (вход, установка, п, и, д, период в секундах)
int computePID(float input, float setpoint, float kp, float ki, float kd, float dt) {
  float err = setpoint - input;
  static float integral = 0, prevErr = 0;
  integral += err * dt;
  float D = (err - prevErr) / dt;
  prevErr = err;
  return (err * kp + integral * ki + D * kd);
}
Внимательно изучаем код и его составляющие.
- Декларируемые переменные отсутствуют.
- В void setup() тоже пусто
- В void loop() закоментированный пример применения.
- Видим наличие пользовательской функции int computePID()
.
Вот с последнего и начнем, благо мы не рассмотрели в первом примере внесение функций в ПБ.
1. Копируем имя функции вместе с ее параметрами и добавляем эту функцию на вкладке FunctionSection, нажав на зеленый плюсик.
2. Копируем все "потроха" данной функции, которые так же ограничены фигурными скобками, и вставляем все это в поле под именем функции. (Без скобок)
Function1.jpg
.
Всё, с функцией разобрались.
Возвращаемся к void loop().
Здесь мы видим функцию delay() и вспоминаем что с врагами, допустим, нужно бороться.
Еще раз, очень внимательно смотрим ролик и понимаем за что она отвечает.
Находим у того же AlexGyver как нам победить delay() и на странице https://alexgyver.ru/lessons/time/, находим вот такую конструкцию:

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

// переменная хранения времени (unsigned long)
uint32_t myTimer1;
void setup() {}
void loop() {
  if (millis() - myTimer1 >= 500) {   // ищем разницу (500 мс)
    myTimer1 = millis();              // сброс таймера
    // выполнить действие
  }
}
Это таймер, который и будет запускать нашу функцию один раз в... , а это мы будем регулировать.
Смело вставляем данный код в LoopSection, а строчку "// выполнить действие", заменяем на вызов функции из примера.
Не забываем задекларировать переменную uint32_t myTimer1, внеся ее в DeclareSektion.
Заметка: uint32_t это то же самое что unsigned long. Можно вписывать и так, проблем не будет.
.
Получилась следующая картина.
PID_millis.jpg
.
Не забыли что время паузы вызова функции и последний параметр функции dt должны совпадать?
Не обратили внимание? Плохо!
Еще раз пересмотрите ролик.
И обратите внимание, что в одном случае это секунды, а в другом миллисекунды.
.
Теперь разбираемся с параметрами передаваемыми в функцию computePID().
Надеюсь, что вы помните за что каждый из них отвечает.
Нет!?
Еще раз внимательно смотрим ролик!
.
Вот теперь легко и не принужденно создаем у блока 6 входов.
- Уставка - Set
- Данные с датчика - Val (обратная связь)
- Kp
- Ki
- Kd
- dt
И вписываем их в соответствующие места функции. Не забываем вписать dt в двух местах, подставив в таймере к нему коэффициент 1000, т.к. там время в миллисекундах.
Получилось следующее:
PID входы.jpg
.
Осталось только разобраться с выходом.
Сейчас наш алгоритм сразу передает на выбранный пин значение вычисленное ПИД регулятором. Но подать это значение на нужный пин можно и средствами FLProg. Поэтому создаем выход P, а
analogWrite(pin, computePID(Val, Set, Kp, Ki, Kd, dt)); заменяем на P = computePID(Val, Set, Kp, Ki, Kd, dt);
.
Вот и всё, наш блок ПИД-регулятор готов.
Блок.jpg
Блок.jpg (6.84 КБ) 2814 просмотров
Блок ПИД.flp
(83.53 КБ) 88 скачиваний
.
Понравилась статья?
Не ограничивайся лайками.
Помоги форуму
.

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

Аватара пользователя
SergeyShikal
Лейтенант
Сообщения: 575
Зарегистрирован: 30.08.2018{, 17:15}
Репутация: 47
Откуда: Иркутская область
Имя: Сергей

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

#4

Сообщение SergeyShikal » 23.09.2021{, 18:50}

Dryundel писал(а):
23.09.2021{, 12:20}
Продолжаем разговор...
А как создать именно выход на блоке
СпойлерПоказать
Безымянный.png

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

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

#5

Сообщение Dryundel » 23.09.2021{, 19:00}

SergeyShikal писал(а):
23.09.2021{, 18:50}
А как создать именно выход на блоке
Dryundel писал(а):
23.09.2021{, 12:20}
Дальнейшие манипуляции с данным кодом не имеют смысла, т.к. задержки в нем основаны на delay()
Выход содается точно так же, как и вход.
Если бы не было delay(), то можно было бы создать выход "SOS" и все
digitalWrite(led_pin, HIGH); заменить на SOS = 1;
а
digitalWrite(led_pin, LOW); на SOS = 0;
и всё.
Однако такой вариант с данным кодом в блоке работать не будет.

com
Капитан
Сообщения: 831
Зарегистрирован: 31.05.2018{, 22:12}
Репутация: 83
Откуда: Санкт-Петербург
Имя: Ринат

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

#6

Сообщение com » 23.09.2021{, 20:39}

В закладки

Аватара пользователя
SergeyShikal
Лейтенант
Сообщения: 575
Зарегистрирован: 30.08.2018{, 17:15}
Репутация: 47
Откуда: Иркутская область
Имя: Сергей

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

#7

Сообщение SergeyShikal » 24.09.2021{, 11:22}

Вопрос по компиляции: при загрузке в есп-01 без настройки сети компиляция проходит и работает, если настроить модуль на вай фай то выдает ошибку
СпойлерПоказать
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
extern "C"
{
#include "user_interface.h"
}
int _resiveModeCommunication = 0;
String _resiveVariableStringCommunication;
int _resiveVariableIndexCommunication = 0;
String _resiveVariableValueCommunication;
bool En;
int led_pin=2; // пин подключения
bool ESPControllerWifiClient_status = 1;
char ESPControllerWifiAP_SSID[40] = "perviy";
char ESPControllerWifiAP_password[40] = "12345678";
bool ESPControllerWifiAP_IsNeedReconect = 0;
bool ESPControllerWifiAP_workStatus = 1;
IPAddress ESPControllerWifiAP_ip(192, 168, 1, 25);
IPAddress ESPControllerWifiAP_dns (192, 168, 1, 1);
IPAddress ESPControllerWifiAP_gateway (192, 168, 1, 1);
IPAddress ESPControllerWifiAP_subnet (255, 255, 255, 0);
uint8_t ESPControllerWifiAP_mac[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
WiFiUDP Udp;
char _udpPacketBuffer [UDP_TX_PACKET_MAX_SIZE];
bool _RVFC1 = 0;
bool _RVFC2 = 0;
void setup()
{
pinMode(1, OUTPUT);
digitalWrite(1, 0);
WiFi.mode(WIFI_AP);
_esp8266WifiModuleApReconnect();
Udp.begin(8888);
pinMode(led_pin, OUTPUT); // Инициализируем цифровой вход/выход в режиме выхода.
}
void loop()
{
int _udpPacketSize = Udp.parsePacket();
if (_udpPacketSize)
{
Udp.read(_udpPacketBuffer, UDP_TX_PACKET_MAX_SIZE);
for(int i=0; i <= _udpPacketSize; i++)
{
_ressiveByteFromCommunication(_udpPacketBuffer);
}
}
if(ESPControllerWifiAP_IsNeedReconect)
{
_esp8266WifiModuleApReconnect();
ESPControllerWifiAP_IsNeedReconect = 0;
}
//Плата:1
En = _RVFC1;
if (en)
{
for (int x=0; x<3; x++)
{
digitalWrite(led_pin, HIGH); // зажигаем светодиод
delay(250); // ждем 350 милисекунд
digitalWrite(led_pin, LOW); // выключаем светодиод
delay(100); // ждем 300 милисекунд
}
delay(300);
for (int x=0; x<3; x++)
{
digitalWrite(led_pin, HIGH); // зажигаем светодиод
delay(500); // ждем 700 милисекунд
digitalWrite(led_pin, LOW); // выключаем светодиод
delay(100); // ждем 300 милисекунд
}
delay(300);
for (int x=0; x<3; x++)
{
digitalWrite(led_pin, HIGH); // зажигаем светодиод
delay(250); // ждем 350 милисекунд
digitalWrite(led_pin, LOW); // выключаем светодиод
delay(100); // ждем 300 милисекунд
}
delay(5000); // ждем 5 секунд
digitalWrite(1, !(_RVFC2));
}
bool _isTimer(unsigned long startTime, unsigned long period)
{
unsigned long currentTime;
currentTime = millis();
if (currentTime>= startTime)
{
return (currentTime>=(startTime + period));
}
else
{
return (currentTime >=(4294967295-startTime+period));
}
}
void _ressiveByteFromCommunication(byte resiveByte)
{
if (_resiveModeCommunication==0)
{
if (resiveByte == 1)
{
_resiveModeCommunication=1;
_resiveVariableStringCommunication="";
return;
}
}
if (_resiveModeCommunication==1)
{
if((resiveByte == 1)||(resiveByte == 3)|| (resiveByte == 4))
{
_resiveModeCommunication=0;
return;
}
else
{
if(resiveByte==2)
{
_resiveModeCommunication=2;
_resiveVariableIndexCommunication=_resiveVariableStringCommunication.toInt();
_resiveVariableStringCommunication="";
return;
}
else
{
_resiveVariableStringCommunication+= char(resiveByte);
return;
}
}
}
if (_resiveModeCommunication==2)
{
if((resiveByte == 1)||(resiveByte == 2)|| (resiveByte == 4))
{
_resiveModeCommunication=0;
return;
}
else
{
if (resiveByte==3)
{
_resiveModeCommunication=3;
_resiveVariableValueCommunication =_resiveVariableStringCommunication;
_resiveVariableStringCommunication="";
return;
}
else
{
_resiveVariableStringCommunication+= char(resiveByte);
return;
}
}
}
if (_resiveModeCommunication==3)
{
if((resiveByte == 1)||(resiveByte == 2)|| (resiveByte == 3))
{
_resiveModeCommunication=0;
return;
}
else
{
if (resiveByte==4)
{
_resiveModeCommunication=0;
_fillRessiveVariableasFromCommunication();
_resiveVariableStringCommunication="";
return;
}
else
{
_resiveVariableStringCommunication+= char(resiveByte);
return;
}
}
}
}
void _fillRessiveVariableasFromCommunication()
{
long _tempId= _resiveVariableStringCommunication.toInt();
if ((_resiveVariableIndexCommunication == 1) && (_tempId == 148551769))
{
_RVFC1 = ((_resiveVariableValueCommunication).toInt());
}
if ((_resiveVariableIndexCommunication == 2) && (_tempId == 148551769))
{
_RVFC2 = ((_resiveVariableValueCommunication).toInt());
}
}
int hexStrToInt(String instring)
{
byte len = instring.length();
if (len == 0) return 0;
int result = 0;
for (byte i = 0; i < 8; i++) // только первые 8 цыфар влезуть в uint32
{
char ch = instring;
if (ch == 0) break;
result <<= 4;
if (isdigit(ch))
result = result | (ch - '0');
else result = result | (ch - 'A' + 10);
}
return result;
}
void _esp8266WifiModuleApReconnect()
{
if (_checkMacAddres(ESPControllerWifiAP_mac))
{
wifi_set_macaddr(1, const_cast<uint8*>(ESPControllerWifiAP_mac));
}
WiFi.softAPConfig(ESPControllerWifiAP_ip, ESPControllerWifiAP_gateway, ESPControllerWifiAP_subnet);
WiFi.softAP(ESPControllerWifiAP_SSID, ESPControllerWifiAP_password);
if (! (_checkMacAddres(ESPControllerWifiAP_mac)))
{
WiFi.softAPmacAddress(ESPControllerWifiAP_mac);
}
}
bool _checkMacAddres(byte array[])
{
bool result = 0;
for (byte i = 0; i < 6; i++)
{
if (array == 255)
{
return 0;
}
if (array > 0)
{
result = 1;
}
}
return result;
}
void _parseMacAddressString(String value, byte array[])
{
int index;
byte buffer[6] = {255, 255, 255, 255, 255, 255};
byte raz = 0;
String tempString;
while ((value.length() > 0) && (raz <= 6))
{
index = value.indexOf(":");
if (index == -1)
{
tempString = value;
value = "";
}
else
{
tempString = value.substring(0, index);
value = value.substring(index + 1);
}
buffer[raz] = byte(hexStrToInt(tempString));
raz++;
}
if (_checkMacAddres(buffer))
{
for (byte i = 0; i < 6; i++)
{
array = buffer;
}
}
}
bool _compareMacAddreses(byte array1[], byte array2[])
{
for (byte i = 0; i < 6; i++)
{
if (array1 != array2)
{
return 0;
}
}
return 1;
}
bool _compareMacAddresWithString(byte array[], String value)
{
byte buffer[6] = {255, 255, 255, 255, 255, 255};
_parseMacAddressString(value, buffer);
return _compareMacAddreses(array, buffer);
}
bool _checkMacAddresString(String value)
{
byte buffer[6] = {255, 255, 255, 255, 255, 255};
_parseMacAddressString(value, buffer);
return _checkMacAddres(buffer);
}
String _macAddresToString(byte array[])
{
String result = "";
String temp ="";
for (byte i = 0; i < 6; i++)
{
temp=String(array,HEX);
if (temp.length() < 2)
{
temp = String("0") + temp;
}
result = result + temp;
if (i < 5)
{
result = result + String(":");
}
}
result.toUpperCase();
return result;
}
}
прием нов.flp
(88.19 КБ) 51 скачивание

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

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

#8

Сообщение Dryundel » 24.09.2021{, 12:04}

SergeyShikal, когда делаете блок, будьте очень внимательны с кодом.
Dryundel писал(а):
23.09.2021{, 12:20}
if (En == 1)
{
// Здесь весь код из LoopSection
}
Вы забыли про закрывающую скобку в конце.
Это раз.
Вход у Вас имеет имя "En" , а в коде Вы написали if (en)
Это разные переменные. Регистр имеет значение.
Это два.
В третьих, прежде чем делать проекты с созданным блоком, проверьте его на компиляцию.
Ну и последнее, ОНО ЖЕ ПЕРВОЕ.
Dryundel писал(а):
23.09.2021{, 12:20}
Дальнейшие манипуляции с данным кодом не имеют смысла, т.к. задержки в нем основаны на delay()
Другие блоки в проекте вместе с этим работать не будут
Почему? Читайте здесь
Отправлено спустя 2 минуты 36 секунд:
Когда исправите ошибки в блоке, компиляция пройдет успешно.
Однако не забывайте.
Dryundel писал(а):
23.09.2021{, 12:20}
Другие блоки в проекте вместе с этим работать не будут
Сложите время всех delay() умножте на 3, т.к. там трехкратные циклы, и получите время одного цикла программы с этим блоком. Так понятней?

Аватара пользователя
SergeyShikal
Лейтенант
Сообщения: 575
Зарегистрирован: 30.08.2018{, 17:15}
Репутация: 47
Откуда: Иркутская область
Имя: Сергей

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

#9

Сообщение SergeyShikal » 24.09.2021{, 14:30}

Dryundel писал(а):
24.09.2021{, 12:07}

Сложите время всех delay() умножте на 3, т.к. там трехкратные циклы, и получите время одного цикла программы с этим блоком. Так понятней?
Спасибо, не доглядел,вижу что тормозит при выполнении программы.

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

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

#10

Сообщение Dryundel » 25.09.2021{, 15:48}

Обновил (закончил) статью. Всем заинтересованным советую дочитать до конца.
.
Если что то еще не понятно по Редактору ПБ Code-Basic, задавайте вопросы в этой теме.

Anydy

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

#11

Сообщение Anydy » 26.09.2021{, 12:15}

Слегка поправлю --- Delay() зло в цикле а вот в Setup для многих железяк просто необходим!

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

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

#12

Сообщение Dryundel » 26.09.2021{, 12:38}

Anydy писал(а):
26.09.2021{, 12:15}
Слегка поправлю --- Delay() зло в цикле а вот в Setup для многих железяк просто необходим!
Справедливое замечание. Внес поправку в статью.

Naladchik
Капитан
Сообщения: 822
Зарегистрирован: 04.10.2015{, 19:10}
Репутация: 151
Откуда: Новосибирск
Имя: Павел

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

#13

Сообщение Naladchik » 26.09.2021{, 12:46}

Anydy писал(а):
26.09.2021{, 12:15}
Delay() зло в цикле а вот в Setup для многих железяк просто необходим.
И еще в функциях, особенно если они вызываются редко, и городить таймер там, порой, просто бессмысленно.
Win10-64. FLProg Portable.
Изображение

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

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

#14

Сообщение Dryundel » 26.09.2021{, 14:19}

Naladchik писал(а):
26.09.2021{, 12:46}
И еще в функциях, особенно если они вызываются редко, и городить таймер там, порой, просто бессмысленно.
А вот с этим не согласен. Функция должна выполняться по возможности быстро и без задержек.

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

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

#15

Сообщение Dryundel » 27.09.2021{, 10:44}

В шапке темы создан опрос:
Нужна ли статья про Редактор Code-Professional?
Хотелось бы понимать размер аудитории, кому это необходимо.
Прежде чем голосовать, прочитайте написанное ниже.
.
Что же такое Новый редактор ПБ Code-Professional и на сколько он хорош.

Редактор Code-Professional не хуже и не лучше Code-Basic. Он просто другой.
Code-Professional прежде всего актуален в том случае, если Вы хотите и готовы создавать пользовательские блоки для других. Под готовностью я подразумеваю то, что вы имеете базовые знания C++, четко понимаете структуру скетча Arduino, знаете что такое функции и как с ними работать, освоили работу с прерываниями, имеете представление об адресации устройств, хотя бы приблизительно ориентируетесь в разнице контроллеров на AVR, ESP, STM и т.п. Кроме этого в Code-Professional при создании блока накладывается дополнительная нагрузка по структуре и избирательности компиляции кода.
Практически всё, за исключением некоторых нюансов, можно сделать в Code-Basic. Да, не будет возможности например прятать неиспользуемые входы, выходы и параметры. Но в большинстве случаев этого и не нужно.
За то создание ПБ в Code-Basic делается на порядок проще и быстрей.
И если вы не планируете создавать ПБ для других, то наверное стоит отдать свой голос за "Интересно было бы знать".
.
Кроме всего сказанного, хотелось бы услышать мнение тех, кто уже в какой то мере освоил Редактор Code-Professional.
Как по вашему мнению, достаточно ли авторского мануала для освоения?
Если нет, то на какие возможности и принципы работы следует обратить особое внимание?
Какие моменты вызывали у вас сложности в освоении?
.
Буду очень признателен за участие.
.

Аватара пользователя
AlexCrane
Капитан
Сообщения: 895
Зарегистрирован: 20.10.2017{, 13:22}
Репутация: 294
Откуда: Ульяновск
Имя: Александр

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

#16

Сообщение AlexCrane » 27.09.2021{, 13:46}

Dryundel писал(а):
27.09.2021{, 10:44}
За то создание ПБ в Code-Basic делается на порядок проще и быстрей.
Ну не скажи, сейчас самый простой блок мне проще сделать в Code-Professional...

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

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

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

#17

Сообщение Dryundel » 27.09.2021{, 14:19}

AlexCrane писал(а):
27.09.2021{, 13:46}
Ну не скажи, сейчас самый простой блок мне проще сделать в Code-Professional...
Возможно профессионал пилот истребителя то же самое может сказать любителю парапланеристу, про задачу долететь из точки в точку. :)
Но любое мнение сейчас важно. И это здорово, что откликнулись.
Было бы не плохо, если бы Вы поделились особенностями, которые актуальны на старте вхождения в Code-Professional.
На какие моменты стоило бы обратить внимание Автору для упрощения понимания процесса создания ПБ, коротенько, по вашему мнению.

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

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

#18

Сообщение aidar_i » 27.09.2021{, 15:24}

Мне тоже нравится базовый редактор.
Создание блока на профессионале иногда получается сложнее, чем написать программу в коде :), особенно когда хочешь туда засунуть всё что возможно!

ecoins
Полковник
Сообщения: 2924
Зарегистрирован: 12.02.2016{, 11:40}
Репутация: 453
Откуда: Шатура
Имя: Энвер

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

#19

Сообщение ecoins » 27.09.2021{, 18:25}

Anydy писал(а):
26.09.2021{, 12:15}
Слегка поправлю --- Delay() зло в цикле а вот в Setup для многих железяк просто необходим!
Еще одно мнение - setup() само по себе зло почти всегда (если только для присвоения констант) - создает проблемы при реализации управляемого программного сброса проекта.
И delay() всегда зло. Иногда приходиться использовать delayMicroseconds(x), где x не более 100.

ecoins
Полковник
Сообщения: 2924
Зарегистрирован: 12.02.2016{, 11:40}
Репутация: 453
Откуда: Шатура
Имя: Энвер

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

#20

Сообщение ecoins » 27.09.2021{, 18:27}

aidar_i писал(а):
27.09.2021{, 15:24}
Мне тоже нравится базовый редактор.
Создание блока на профессионале иногда получается сложнее, чем написать программу в коде , особенно когда хочешь туда засунуть всё что возможно!
Базовый редактор полезный инструмент. Но код из него лучше (и в некотором смысле удобнее) выносить в отдельную библиотеку.

Ответить

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