Как сделать триггер в st кодесис
Перейти к содержимому

Как сделать триггер в st кодесис

  • автор:

Как реализовать T-триггер в CoDeSys?

Вот на 2-х Функциональных блоках.
TRIG_Vk(CLK:= knopka, Q=> ); (выделяем фронт нажатия кнопки (ФБ R_TRIG))
SR_Vk(SET1:= TRIG_Vk.Q AND NOT SR_Vk.Q1 , RESET:=TRIG_Vk.Q AND SR_Vk.Q1, Q1=> ); (ФБ SR или RS)

03.03.2010, 11:35

спасибо, получилось. правда это тоже 4 блока, но меньше видно нельзя. я проектирую в Fbd:)

03.03.2010, 12:54
Сообщение от Литрович
спасибо, получилось. правда это тоже 4 блока, но меньше видно нельзя. я проектирую в Fbd:)
выделите в отдельный функциональный блок

30.03.2010, 11:49

можно потробнее? желательно на St.
с кодом для фун. блоков и программы.

30.03.2010, 13:35

вопрос новичка в кодесис ,а что в кодесис нет готовых библиотек фб (счетчики ,регистры сдвига,дешифраторы,и.т.д?)

30.03.2010, 14:33
Николаев Андрей

Ну вот, rovki — прям расстроили ;).
Надо подключить библиотеки Util.lib и Standart.lib — там все есть

30.03.2010, 16:53

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

Как сделать триггер в st кодесис

Тема не указан(-а). Если вы пришли по правильной ссылке, пожалуйста, сообщите администрации о нерабочей ссылке.

  • Навигация
  • Кабинет
  • Личные сообщения
  • Подписки
  • Кто на сайте
  • Поиск по форуму
  • Главная страница форума
  • Форум
  • НОВИНКИ ОВЕН
    1. В продаже
    2. В разработке
  • Оборудование
    1. Подбор Оборудования
    2. Эксплуатация
    3. Разработки
  • Программируемые устройства ОВЕН
    1. ПЛК (среда CODESYS V3.5)
      1. ПЛК2хх
      2. СПК1хх [М01]
      3. СПК1хх
      4. СПК2хх
      5. ПЛК3хх
      6. Библиотеки CODESYS
    2. ПЛК (среда CoDeSys V2.3)
      1. ПЛК1хх [М02]
      2. ПЛК1хх
      3. ПЛК63/73
    3. ПЛК (среда MasterSCADA 4D)
    4. Программируемые реле
    5. Модули ввода/вывода
      1. Мх110
      2. Мх210
    6. Панели оператора (HMI)
    7. Среда программирования OWEN Logic
    8. Архив продукции
      1. Модульные контроллеры Модус
        1. Модус 5684-0
        2. Модус 5680
        3. Модули ввода-вывода
        4. Интерфейсные модули
  • Датчики ОВЕН
    1. Новинки
    2. В помощь инженеру
    3. Подбор датчиков
    4. Вопросы по эксплуатации датчиков
  • Программное обеспечение
    1. Облачный сервис OwenCloud
      1. Облачный сервис OwenCloud
      2. ПМ210
      3. ПЕ210
      4. ПВ210
    2. SCADA
      1. OWEN Proces Manager
      2. Master SCADA 3
      3. Master SCADA 4D
      4. Другие SCADA системы
    3. Телемеханика ЛАЙТ
    4. Сервисное ПО
    5. Помощь Разработчикам
    6. Сетевые технологии
    7. OPC Серверы
  • Электротехническое оборудование MEYERTEC
  • Приводная техника
    1. Приводная техника ОВЕН
    2. Блоки питания
  • Контроллеры для ЖКХ
    1. Контроллеры для систем отопления и ГВС
    2. Контроллеры для систем вентиляции и кондиционирования
    3. Контроллеры для управления насосами
  • Разное
    1. Трёп (Курилка)
    2. Метрология сертификация
    3. Сервисное обслуживание приборов ОВЕН
    4. Наши проекты
    5. Твердотельное реле
    6. В помощь специалистам
  • Обратная связь
  • Контрольно измерительные приборы ПО Овен
  • Архив
  • Вверх

Текущее время: 20:26 . Часовой пояс GMT +3.

Triggers

Triggers can be used to perform actions such as switching on a tool when a defined position on the path is reached, or with a time shift before or after. For this purpose, CODESYS SoftMotion provides the capability of configuring triggers to movements and then continuously reading out the remaining time until the position is reached.

When using triggers, pay attention to the following:

  • The time until a trigger is reached can be retrieved only when the axis group has approached the trigger up to the time of a configurable forecast. How this forecast is configured and which impacts the settings have is explained in the Configuring the application to use triggers section.
  • The trajectory is not changed by the use of triggers. In particular, the trajectory is not slowed down in order to comply with the configured forecast. If, for example, the position of a trigger at the beginning of a movement is already reached after 0.01 seconds, then even a higher forecast cannot achieve that a notification is provided about reaching the point more than 0.01 seconds beforehand.

Configuring the application to use triggers

Configuration of the forecast duration

The forecast duration determines how far in the future the planning is done. This is set by the fPlanningForecastDuration parameter of the SMC_TuneCPKernel function block. How this parameter should be set depends on the requirements of the application. There are two principally contradictory requirements:

  1. Longest possible forecast duration
  2. Lowest possible latency. The latency when starting a movement increases because the forecast has to be established first. The size of this additional latency depends mainly on the performance of the controller used and is generally much lower than the configured forecast. Moreover, the latency of the axis group to react to aborting movements and interrupts increases by the configured forecast. The forecast does not have any impact on MC_GroupHalt and MC_GroupStop . Both function blocks always act immediately and independently of the configured forecast.

The fPlanningForecastDuration parameter of the SMC_TuneCPKernel function block should therefore be set as high as necessary but as low as possible. If a forecast is not required, then the parameter can be left at the default value of 0.

The actual available forecast can differ from the configured one for various reasons, for example, if the end of the last movement is already almost reached. The current available forecast can be monitored by means of the CurrentPlanningForecast output of MC_GroupReadStatus .

Configuration of the maximum number of triggers per movement

As delivered, CODESYS SoftMotion supports up to 8 triggers per movement. If this number is not enough, then the MAX_NUM_TRIGGERS_PER_MOVEMENT parameter can be changed as a library parameter. This is possible with the Library Manager and the respective editor for the library parameters. For using library parameters, a CODESYS version >= SP19 is recommended.

Commanding and evaluating triggers

Two function blocks are available for commanding triggers: SMC_GroupPrepareTrigger and SMC_GroupReadTrigger.

Triggers are assigned to a movement. Each individual trigger has to be prepared using the SMC_GroupPrepareTrigger function block. The position can be specified relative, absolute, or as an intersection with a plane (see SMC_TriggerPositionType). The call order of SMC_GroupPrepareTrigger and the respective movement is of particular importance because the prepared triggers are assigned to the next movement commanded in the same cycle. Therefore, in every application you need to pay attention to the following:

  1. SMC_GroupPrepareTrigger always has to be called before the movement function block.
  2. Triggers and the respective movement always have to be commanded in the same cycle. If no movement is started in the cycle, then the prepared triggers are discarded and the CommandAborted output of the SMC_GroupPrepareTrigger function blocks is set.

When the trigger is assigned to a movement, information about a trigger can be retrieved using SMC_GroupReadTrigger . As soon as the trigger is within the available forecast duration, the status changes to SMC_TRIGGER_STATUS.Active and the time until the trigger is reached can be read out. The time always refers to the start time of the current cycle. Depending on when the trigger should be triggered (before, during, or after the position is reached), the desired action can be executed in the application in a suitable cycle.

Triggers cannot be aborted when they have been assigned to a movement. Instead, they can simply be ignored.

If a movement is aborted by a second movement with MC_BUFFER_MODE.Aborting , then the triggers assigned to the first movement also disappear.

Triggers for movements with blending

For movements with Blending , the triggers are projected onto the blending path. The following image qualitatively shows a case in which a movement from P1 to P2 as well as a following movement were each commanded with blending. Blending to the first movement ends at point B, and blending to the preceding movement starts at point A. The blue trigger is located between P1 and B. It gets projected onto the back half of the first blending movement (highlighted by the blue line). In the same way, the red trigger, located between A and P2, is projected onto the front half of the second blending movement (highlighted by the red line). The green trigger is outside of the blending areas and is not shifted.

_sm_img_digital_switches.png

When blending with triggers, there is a special feature concerning the status of the movement and the respective triggers. The command function block for moving from P1 to P2 reports Done as soon as point A is reached. However, the red trigger associated with this movement remains active until the position on the blending element to which it was projected is reached.

  • Triggers
  • Configuring the application to use triggers
  • Commanding and evaluating triggers
  • Triggers for movements with blending

Таймеры и триггеры CODESYS. Еще один шаг Arduino к классическому ПЛК

Случается программировать контроллеры (ПЛК) в среде CODESYS. Все, кто имел дело с этой системой, знают, что в любом проекте присутствует библиотека Standard.lib, в которой реализованы базовые таймеры, триггеры, счетчики и некоторое кол-во других функций и функциональных блоков. Многие из этих блоков постоянно используются в программах для ПЛК. А сама библиотека, как и языки программирования CODESYS, является воплощением стандарта IEC 61131-3, т.е. призвана помочь при программировании классических ПЛК задач.

Одна из особенностей программ для ПЛК в том, что основной цикл программы должен выполняться без существенных задержек, в нем не должно быть внутренних циклов с неопределенным временем выхода или синхронных вызовов «задумчивых» функций, особенно это касается коммуникаций по медленным каналам. Обновление входных и выходным образов процесса происходит только на границе основного цикла, и чем дольше мы будем «сидеть» внутри одной итерации цикла, тем меньше мы будет знать о реальном состоянии объекта управления, в конечном итоге сработает watchdog переполнения времени выполнения цикла. Многие могут мне возразить, сказав, что современные ПЛК многозначны, есть с поддержкой аппаратных прерываний. Согласен, но разговор о таких системах не входит в мои планы, я же хочу поговорить о (квази, псевдо — выбирайте) ПЛК однозадачной реализации (без прерываний) на базе микропроцессорной платформы Arduino, в котором есть только один основной цикл. Кстати, не лишним будет сказать, что на написание данной заметки меня сподвигла статья Ардуино-совместимый ПЛК CONTROLLINO, часть 1 о попытке аппаратного воплощения Arduino в пром. ПЛК.

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

В однозадачной системе добиться видимой параллельности можно только очень быстрым последовательным сканированием параллельных состояний, не задерживаясь подолгу на каждом вызове функции или проверке условия. С физическими входами-выходами проблем нет, функции отрабатывают достаточно быстро, а вот delay() становится неоправданным тормозом. И вот тут на смену приходят неблокирующие таймеры, те самые, которые в программировании ПЛК являются классикой. Суть в том, что для их работы используется миллисекундный счетчик времени, и все действия привязаны к значениям этого глобального счетчика.

А теперь давайте вспомним ту самую Standard.lib из CODESYS. В ней как раз реализованы МЭК-овские неблокирующие таймеры. Я взял ее за основу и портировал функции таймеров и триггеров в библиотечный код Arduino (С++). Т.е. попытался приблизить Arduino к классическому ПЛК.

Ниже я приведу краткое описание портированных функциональных блоков (FB) CODESYS и их аналоги в моей библиотеке plcStandardLib, все временные диаграммы верны для новой библиотеки Arduino. Подробнее описание исходных блоков можно посмотреть, например, в русскоязычной справке по CODESYS.

TON — функциональный блок «таймер с задержкой включения»

TON(IN, PT, Q, ET)

Входы IN и PT типов BOOL и TIME соответственно. Выходы Q и ET аналогично типов BOOL и TIME. Пока IN равен FALSE, выход Q = FALSE, выход ET = 0. Как только IN становится TRUE, начинается отсчет времени (в миллисекундах) на выходе ET до значения, равного PT. Далее счетчик не увеличивается. Q равен TRUE, когда IN равен TRUE, а ET равен PT, иначе FALSE. Таким
образом, выход Q устанавливается с задержкой PT от фронта входа IN.

В Arduino IDE:
TON TON1(); TON TON1(unsigned long PT); // с заданием интервала времени PT
Q = TON1.Run(boolean IN); // вызов "все в одном" TON1.IN = IN; TON1.Run(); Q = TON1.Q;

Временная диаграмма работы TON:

TOF — функциональный блок «таймер с задержкой выключения»

TOF(IN, PT, Q, ET)

Входы IN и PT типов BOOL и TIME соответственно. Выходы Q и ET аналогично типов BOOL и TIME. Если IN равен TRUE, то выход Q = TRUE и выход ET = 0. Как только IN переходит в FALSE, начинается отсчет времени (в миллисекундах) на выходе ET. При достижении заданной длительности отсчет останавливается. Выход Q равен FALSE, если IN равен FALSE и ET равен PT, иначе — TRUE. Таким образом, выход Q сбрасывается с задержкой PT от спада входа IN.

В Arduino IDE:

Очень похоже на TON, для краткости:

TOF TOF1(unsigned long PT); // с заданием интервала времени PT Q = TOF1.Run(boolean IN); // вызов "все в одном"

Временная диаграмма работы TOF:

TP — функциональный блок «импульс-таймер»

TP(IN, PT, Q, ET)

Входы IN и PT типов BOOL и TIME соответственно. Выходы Q и ET аналогично типов BOOL и TIME. Пока IN равен FALSE, выход Q = FALSE, выход ET = 0. При переходе IN в TRUE выход Q устанавливается в TRUE и таймер начинает отсчет времени (в миллисекундах) на выходе ET до достижения длительности, заданной PT. Далее счетчик не увеличивается. Таким образом, выход Q генерирует импульс длительностью PT по фронту входа IN.

В Arduino IDE:

Очень похоже на TON, для краткости:

TP TP1(unsigned long PT); // с заданием интервала времени PT Q = TP1.Run(boolean IN); // вызов "все в одном"

Временная диаграмма работы TP:

R_TRIG — функциональный блок «дeтектор фронта»

Функциональный блок R_TRIG генерирует импульс по переднему фронту входного сигнала. Выход Q равен FALSE до тех пор, пока вход CLK равен FALSE. Как только CLK получает значение TRUE, Q устанавливается в TRUE. При следующем вызове функционального блока выход сбрасывается в FALSE. Таким образом, блок выдает единичный импульс при каждом переходе CLK из FALSE в TRUE.

Пример CODEDESYS на языке ST:

RTRIGInst : R_TRIG ; RTRIGInst(CLK:= VarBOOL1); VarBOOL2 := RTRIGInst.Q;
В Arduino IDE:
R_TRIG R_TRIG1;
Q = R_TRIG1.Run(boolean CLK); // вызов "все в одном" R_TRIG1.CLK = CLK; R_TRIG1.Run(); Q = R_TRIG1.Q;

F_TRIG — функциональный блок «дeтектор спада»

Функциональный блок F_TRIG генерирует импульс по заднему фронту входного сигнала.
Выход Q равен FALSE до тех пор, пока вход CLK равен TRUE. Как только CLK получает значение FALSE, Q устанавливается в TRUE. При следующем вызове функционального блока выход сбрасывается в FALSE. Таким образом, блок выдает единичный импульс при каждом переходе CLK из TRUE в FALSE.

В Arduino IDE:
F_TRIG F_TRIG1; Q = F_TRIG1.Run(boolean CLK); // вызов "все в одном"

RS_TRIG — функциональный блок RS-триггер / SR_TRIG — функциональный блок SR-триггер

Переключатель с доминантой выключения, RS-триггер:

Q1 = RS (SET, RESET1)

Переключатель с доминантой включения:

Q1 = SR (SET1, RESET)

Входные переменные SET и RESET1 — как и выходная переменная Q1 типа BOOL.

В Arduino IDE:
RS_TRIG RS_TRIG1; Q = RS_TRIG1.Run(boolean SET, boolean RESET); // вызов "все в одном"
SR_TRIG SR_TRIG1; Q = SR_TRIG1.Run(boolean SET, boolean RESET); // вызов "все в одном"

Исходный код и пример

plcStandardLib_1.h

/* * plcStandardLib_1.h * * Created on: 01.01.2017 * Author: Admin */ #ifndef PLCSTANDARDLIB_1_H_ #define PLCSTANDARDLIB_1_H_ #if ARDUINO >= 100 #include #else #include #endif /* ------------------- TON ------------------- */ class TON < public: TON(); TON(unsigned long PT); boolean Run(boolean IN); boolean Q; // выходная переменная boolean IN; // входная переменная unsigned long PT; // входная переменная unsigned long ET; // выходная переменная - текущее значение таймера private: boolean _M; // внутренний флаг unsigned long _StartTime; >; /* ------------------- TOF ------------------- */ class TOF < public: TOF(); TOF(unsigned long PT); boolean Run(boolean IN); boolean Q; // выходная переменная boolean IN; // входная переменная unsigned long PT; // входная переменная unsigned long ET; // выходная переменная - текущее значение таймера private: boolean _M; // внутренний флаг unsigned long _StartTime; >; /* ------------------- TP ------------------- */ class TP < public: TP(); TP(unsigned long PT); boolean Run(boolean IN); boolean Q; // выходная переменная boolean IN; // входная переменная unsigned long PT; // входная переменная unsigned long ET; // выходная переменная - текущее значение таймера private: boolean _M; // внутренний флаг unsigned long _StartTime; >; /* ------------------- R_TRIG ------------------- */ class R_TRIG // детектор фронта сигнала < public: R_TRIG(); boolean Run(boolean CLK); boolean CLK; // входная переменная boolean Q; // выходная переменная private: boolean _M; // внутренний флаг >; /* ------------------- F_TRIG ------------------- */ class F_TRIG // детектор спада сигнала < public: F_TRIG(); boolean Run(boolean CLK); boolean CLK; // входная переменная boolean Q; // выходная переменная private: boolean _M; // внутренний флаг >; /* ------------------- RS_TRIG ------------------- */ class RS_TRIG // детектор спада сигнала < public: RS_TRIG(); boolean Run(); boolean Run(boolean SET, boolean RESET); boolean SET; // установка триггера boolean RESET; // сброс триггера boolean Q; // выходная переменная //private: >; /* ------------------- SR_TRIG ------------------- */ class SR_TRIG // детектор спада сигнала < public: SR_TRIG(); boolean Run(); boolean Run(boolean SET, boolean RESET); boolean SET; // установка триггера boolean RESET; // сброс триггера boolean Q; // выходная переменная //private: >; #endif /* PLCSTANDARDLIB_H_ */ 

plcStandardLib_1.cpp

/* * plcStandardLib_1.h * * Created on: 01.01.2017 * Author: Admin */ #include "plcStandardLib_1.h" /* ------------------- TON ------------------- */ TON::TON() < IN = false; PT = 0; _M = false; _StartTime = 0; Q = false; ET = 0; >TON::TON(unsigned long PT) < IN = false; TON::PT = PT; _M = false; _StartTime = 0; Q = false; ET = 0; >boolean TON::Run(boolean IN) < TON::IN = IN; if (!TON::IN) < Q = false; ET = 0; _M = false; >else < if (!_M) < _M = true; // взводим флаг М _StartTime = millis(); // ET = 0; // сразу = 0 >else < if (!Q) ET = millis() - _StartTime; // вычисляем время >if (ET >= PT) Q = true; > return Q; > /* ------------------- TOF ------------------- */ TOF::TOF() < IN = false; PT = 0; _M = false; _StartTime = 0; Q = false; ET = 0; >TOF::TOF(unsigned long PT) < IN = false; TOF::PT = PT; _M = false; _StartTime = 0; Q = false; ET = 0; >boolean TOF::Run(boolean IN) < TOF::IN = IN; if (TOF::IN) < Q = true; ET = 0; _M = true; >else < if (_M) < _M = false; // сбрасываем флаг М _StartTime = millis(); // ET = 0; // сразу = 0 >else < if (Q) ET = millis() - _StartTime; // вычисляем время >if (ET >= PT) Q = false; > return Q; > /* ------------------- TP ------------------- */ TP::TP() < IN = false; PT = 0; _M = false; _StartTime = 0; Q = false; ET = 0; >TP::TP(unsigned long PT) < IN = false; TP::PT = PT; _M = false; _StartTime = 0; Q = false; ET = 0; >boolean TP::Run(boolean IN) < TP::IN = IN; if (!_M) < if (TP::IN) < _M = true; // взводим флаг М _StartTime = millis(); if (ET < PT) Q = true; >> else < if (Q) < ET = millis() - _StartTime; // вычисляем время if (ET >= PT) Q = false; > else < if (!TP::IN) < _M = false; ET = 0; >> > return Q; > /* ------------------- R_TRIG ------------------- */ R_TRIG::R_TRIG() < CLK = false; _M = false; Q = false; >boolean R_TRIG::Run(boolean CLK) < R_TRIG::CLK = CLK; Q = R_TRIG::CLK && !_M; _M = R_TRIG::CLK; return Q; >F_TRIG::F_TRIG() < CLK = false; _M = true; Q = false; >boolean F_TRIG::Run(boolean CLK) < F_TRIG::CLK = CLK; Q = !F_TRIG::CLK && !_M; _M = !F_TRIG::CLK; return Q; >/* ------------------- RS_TRIG ------------------- */ RS_TRIG::RS_TRIG() < SET = false; RESET = false; Q = false; >boolean RS_TRIG::Run(boolean SET, boolean RESET) < RS_TRIG::SET = SET; RS_TRIG::RESET = RESET; Q = !RESET and (SET or Q); return Q; >boolean RS_TRIG::Run() < Q = !RESET and (SET or Q); return Q; >/* ------------------- SR_TRIG ------------------- */ SR_TRIG::SR_TRIG() < SET = false; RESET = false; Q = false; >boolean SR_TRIG::Run(boolean SET, boolean RESET) < SR_TRIG::SET = SET; SR_TRIG::RESET = RESET; Q = SET or (!RESET and Q); return Q; >boolean SR_TRIG::Run()

plcStandardLib_1_example.ino

#include "plcStandardLib_1.h" #define LED 13 #define ButtonIn 7 TON TON1(500); // Инициализация задержки включения, 500мс. TON TON2(1000); // Инициализация задержки включения, 1000мс. TOF TOF1(500); // Инициализация задержки выключения, 500мс. TP TP1(300); // Инициализация единичного импульса, 300мс. TP TP2(200); // Инициализация единичного импульса, 200мс. R_TRIG R_TRIG1; // Инициализация триггера фронта для кнопки void setup() < pinMode(ButtonIn, INPUT_PULLUP); pinMode(LED, OUTPUT); >void loop() < digitalWrite(LED, TP1.Run(R_TRIG1.Run(TON1.Run(digitalRead(ButtonIn))))); // TON1 - фильтрует дребезг контакта // R_TRIG1 - детектирует фронт сигнала // TP1 - генерирует импульс по фронту digitalWrite(LED, TP2.Run(TON2.Run(!TON2.Q))); // генератор импульса на базе TON и TP // TON2.Run(!TON2.Q)) - генератор единичного импульса // TP2 - генерирует импульс по фронту digitalWrite(LED, TOF1.Run(TON1.Run(digitalRead(ButtonIn)))); // Задержка включения и отключения >

Например, чтобы отфильтровать дребезг контактов кнопки (при размыкании тоже!) достаточно вот такого кода:

FiltredButtonIn = TON1.Run(digitalRead(ButtonIn))

В качестве заключения: вот так в CODESYS выглядит работа генератора импульса на базе цепочки таймеров TON и TP. В начале TON охватывается обратной связью с инверсией, и из него получается генератор единичного импульса, который запускает работу импульс-генератора TP. В моем примере Arduino аналог этого выглядит так:

digitalWrite(LED, TP2.Run(TON2.Run(!TON2.Q)));

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *