From e524190581396a9c3dad0f693ad528530daf3551 Mon Sep 17 00:00:00 2001
From: "Sergey A. Glukhov"
Date: Thu, 12 Jun 2025 14:03:04 +0300
Subject: [PATCH 1/6] Add files via upload
---
AnjLabCodeBox.xml | 3231 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 3231 insertions(+)
create mode 100644 AnjLabCodeBox.xml
diff --git a/AnjLabCodeBox.xml b/AnjLabCodeBox.xml
new file mode 100644
index 0000000..3c303da
--- /dev/null
+++ b/AnjLabCodeBox.xml
@@ -0,0 +1,3231 @@
+
+
+
+
+ Helpful ST blocks and functions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Sergey A Glukhov
+ true
+ Anjlab
+ ACB
+ Helpful ST blocks and functions
+ reStructuredText
+ 888cbf53-45a1-47de-9a2a-fbd72e84a196
+ false
+ qualified-access-only
+ AnjlabCodeBox
+ AnjLabCodeBox
+ true
+ false
+ Anjlab Code Box
+ 3.5.17.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входной сигнал
+
+
+
+
+
+
+
+
+
+ Выходной сигнал
+
+
+
+
+
+
+
+
+
+ Время начала
+
+
+
+
+
+
+
+ Память сигнала
+
+
+
+
+ Сглаживание дискретного сигнала
+
+
+
+
+ IF input AND NOT memory THEN
+ startTime := TIME();
+END_IF;
+memory := input;
+output := input AND ((TIME() - startTime) > T#100ms);
+
+
+
+
+ 95ddd795-0967-4fd1-b39a-104236a6cda9
+
+
+
+
+
+
+
+
+
+
+
+ Входной сигнал
+
+
+
+
+
+
+
+
+
+ Выходной сигнал
+
+
+
+
+
+
+
+
+
+ Время начала
+
+
+
+
+
+
+
+ Память сигнала
+
+
+
+
+ Сглаживание дискретного сигнала
+
+
+
+
+ IF (NOT input AND memory) OR (input AND NOT memory) THEN
+ startTime := TIME();
+END_IF;
+memory := input;
+output := input;
+IF ((TIME() - startTime) < T#100ms) THEN
+ output := NOT input;
+END_IF
+
+
+
+
+ 55ebab12-5437-4033-a731-b42ecbacfe06
+
+
+
+
+
+
+
+
+
+
+
+ Входной сигнал
+
+
+
+
+
+
+
+
+
+ Выходной сигнал
+
+
+
+
+
+
+
+
+
+ Время начала
+
+
+
+
+
+
+
+ Память сигнала
+
+
+
+
+ Сглаживание дискретного сигнала
+
+
+
+
+ IF NOT input AND memory THEN
+ startTime := TIME();
+END_IF;
+memory := input;
+output := input;
+IF NOT input AND ((TIME() - startTime) < T#100ms) THEN
+ output := TRUE;
+END_IF
+
+
+
+
+ 30d49b21-1ce3-4ef8-883d-665f4a788870
+
+
+
+
+
+
+
+
+
+
+
+ Входной сигнал
+
+
+
+
+
+
+
+
+
+ Передний фронт
+
+
+
+
+
+
+
+ Задний фронт
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Отфильтрованный вход
+
+
+
+
+
+
+
+
+
+ выделяет передний и задний фронт с фильтром на 100 миллисекунд
+
+
+
+
+ fbDio1(input := input, output => filteredInput);
+raise := fall := FALSE;
+IF filteredInput AND NOT memory THEN
+ raise := TRUE;
+ELSIF NOT filteredInput AND memory THEN
+ fall := TRUE;
+END_IF
+memory := filteredInput;
+
+
+
+
+ 576b0ef3-7dfb-44b9-9d4d-f7a2f2158045
+
+
+
+
+
+
+
+
+
+
+
+ Входной сигнал
+
+
+
+
+
+
+
+
+
+ Выходной сигнал
+
+
+
+
+
+
+
+
+
+ Время начала
+
+
+
+
+
+
+
+ Память сигнала
+
+
+
+
+ Двойной клик
+
+
+
+
+ output := FALSE;
+IF input AND NOT memory THEN
+ IF (TIME() - startTime) > T#100MS AND (TIME() - startTime) < T#800MS THEN
+ output := TRUE;
+ END_IF;
+ startTime := TIME();
+END_IF;
+memory := input;
+
+
+
+
+ d3ac0715-866a-45c1-a900-b774b7c5c01c
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение
+
+
+
+
+
+
+
+ Размер буфера минимум 32 максимум 1000
+
+
+
+
+
+
+
+ Сброс буфера
+
+
+
+
+
+
+
+
+
+ Выходное отфильтрованное значение
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Эта функция хранит до 32-х значений в буфере и выдает среднее значение. Вы сами можете решить, сколько значений сохранить для получения среднего числа.
+
+
+
+
+ (* ограничим bufferSize в размер буфера *)
+bufferSize := MIN(MAX(bufferSize, 1000), 32);
+(* Инициализация *)
+IF NOT isInitialized OR reset THEN
+ isInitialized := TRUE;
+ FOR counter := 1 TO bufferSize DO
+ buffer[counter] := input;
+ END_FOR;
+ sum := input * bufferSize;
+ output := input;
+ RETURN;
+END_IF;
+
+IF counter >= bufferSize THEN
+ counter := 1;
+ELSE
+ counter := counter + 1;
+END_IF
+
+sum := sum + input - buffer[counter];
+{warning disable C0195}
+output := DWORD_TO_WORD(sum / bufferSize);
+buffer[counter] := input;
+
+
+
+
+ 23da4515-91ff-492f-bd6c-a924c27cb1b0
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение
+
+
+
+
+
+
+
+ Временной интервал
+
+
+
+
+
+
+
+
+
+ Выходное отфильтрованное значение
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ возвращает среднее значение за определенный промежуток времени.
+
+
+
+
+ (* Получаем текущее время *)
+currentTime := TIME_TO_DWORD(TIME());
+(* Инициализация *)
+IF NOT isInitialized OR timeInterval = T#0s THEN
+ isInitialized := TRUE;
+ lastTime := currentTime;
+ output := input;
+ELSIF output = input THEN
+ lastTime := currentTime;
+ELSE
+ tempTime := WORD_TO_DWORD(input - output) * (currentTime - lastTime) /
+ TIME_TO_DWORD(timeInterval);
+ IF tempTime <> 0 THEN
+ output := DINT_TO_WORD(WORD_TO_DINT(output) + DWORD_TO_DINT(tempTime));
+ lastTime := currentTime;
+ END_IF;
+END_IF;
+
+
+
+
+ cc4d134d-f449-4f06-8605-2d943310a473
+
+
+
+
+
+
+
+
+
+
+
+ Входной сигнал
+
+
+
+
+
+
+
+ Время нажатия
+
+
+
+
+
+
+
+
+
+ Выходной сигнал
+
+
+
+
+
+
+
+
+
+ Время начала
+
+
+
+
+
+
+
+ Память сигнала
+
+
+
+
+ Долгий клик
+
+
+
+
+ IF input AND NOT memory THEN
+ startTime := TIME();
+END_IF;
+memory := input;
+output := input AND ((TIME() - startTime) > pressTime);
+
+
+
+
+ e847a08d-2858-49e0-b6fb-cbe441c3349b
+
+
+
+
+
+
+
+
+
+
+
+ Запуск генератора
+
+
+
+
+
+
+
+
+
+
+ Время импульсов
+
+
+
+
+
+
+
+
+
+ Выходной сигнал
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ создает импульсы с заданной частотой
+ CLK_PWM(EN := TRUE, PT := T#5ms); На выходе Q будет импульс в один цикл ПЛК, раз в 5 миллисекунд.
+
+
+
+
+ currentTime := TIME();
+IF enable AND NOT memory THEN
+ lastTime := currentTime - pulseTime;
+END_IF;
+memory := enable;
+output := currentTime - lastTime >= pulseTime;
+IF output THEN lastTime := currentTime; END_IF;
+
+
+
+
+ e2565834-4fd9-4a85-b9e7-a4c45a2b4e0b
+
+
+
+
+
+
+
+
+
+
+
+ Частота, раз в секунду (Гц)
+
+
+
+
+
+
+
+ Соотношение
+
+
+
+
+
+
+
+
+
+ Выходной сигнал
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ создает ШИМ-сигнал заданной частоты со смещением соотношения. Каждый цик ШИМ можно разделить на 2 фазы: Ton (время включения) и Toff (время выключения).
+ Соотношение задается от 0 до 1. Например, соотношение 0.5 разделит время каждого цикла шим на 50% на Ton и 50% на Toff .
+
+
+
+
+ (* Если частота ШИМ 0, то прерываем исполнение ФБ *)
+IF frequency <= 0.0 THEN
+ output := FALSE;
+ RETURN;
+END_IF;
+(* Вычисляем сколько миллисекунд требуется на один цикл ШИМ *)
+tempValue := 1000.0 / frequency;
+(* Запускаем генератор сигналов *)
+clock(pulseTime := REAL_TO_TIME(tempValue));
+(* Создаем выдержанный пульс на нужное время *)
+pulseTimer(in := clock.output, pt := REAL_TO_TIME(tempValue * dutyCycle), Q => output);
+
+
+
+
+ 55fa2adc-b14d-4d49-a0d3-ee6618946ede
+
+
+
+
+
+
+
+
+
+
+
+ Частота, раз в секунду (Гц)
+
+
+
+
+
+
+
+ Длина фазы Ton
+
+
+
+
+
+
+
+
+
+ Выходной сигнал
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Создает ШИМ-сигнал с заданным временем фазы Ton . Например, мы можем установить F на 100 раз в секунду. Это значит, один цикл ШИМ будет 10
+ миллисекунд. Теперь поставим PW в T#5ms и получим равное время для фазы Ton и Toff по 50%.
+
+
+
+
+ (* Если частота ШИМ 0 или время одного цикла меньше,
+чем время для фазы Ton, то прерываем исполнение ФБ *)
+IF frequency <= 0.0 OR (REAL_TO_TIME(1000.0 / frequency) < pulseWidth) THEN
+ output := FALSE;
+ RETURN;
+END_IF;
+(* Запускаем генератор сигналов *)
+clock(pulseTime := REAL_TO_TIME(1000.0 / frequency));
+(* Создаем выдержанный пульс на нужное время *)
+pulseTimer(in := clock.output, PT := pulseWidth, Q => output);
+
+
+
+
+ ff93b01a-c5fb-4d17-a425-8e834ffc249d
+
+
+
+
+
+
+
+
+
+
+
+ Широта
+
+
+
+
+
+
+
+ Долгота
+
+
+
+
+
+
+
+ Текущее время в UTC
+
+
+
+
+
+
+
+
+
+
+ Градус над горизонтом, при котором уже считается наступление заката или восхода
+
+
+
+
+
+
+
+
+
+ Время дня солнцестояния
+
+
+
+
+
+
+
+ Время восхода
+
+
+
+
+
+
+
+ Время заката
+
+
+
+
+
+
+
+ Угол наклона солнца в солнцестояние в градусах
+
+
+
+
+
+
+
+
+
+ Угол наклона солнца в полдень в радианах
+
+
+
+
+
+
+
+ Дельта от солнцестояния до восхода или заката
+
+
+
+
+
+
+
+
+
+ расчет времени заката и восхода
+
+
+
+
+ MIDDAY := SunMidday(longitude, utc);
+b := latitude * 0.0174532925199433;
+dk := 0.40954 * SIN(0.0172 * (UINT_TO_REAL(DayOfYear(utc)) - 79.35));
+SUN_DECLINATION := DegreesToRadians(DK);
+IF SUN_DECLINATION > 180.0 THEN
+ SUN_DECLINATION := SUN_DECLINATION - 360.0;
+END_IF;
+SUN_DECLINATION := 90.0 - LATITUDE + SUN_DECLINATION;
+delta := HourToTime(REAL_TO_INT(ACOS((SIN(RadiansToDegrees(H)) - SIN(B) * SIN(DK)) / (COS(B) * COS(DK))) * 3.819718632));
+SUN_RISE := MIDDAY - delta;
+SUN_SET := MIDDAY + delta;
+
+
+
+
+ c0162500-a121-4d9a-a1ba-5801e54027bc
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ IP-адрес как строка, например, '192.168.1.2'
+
+
+
+
+
+
+
+
+
+
+
+ Преобразование в шестнадцатеричный формат для записи IP
+
+
+
+
+ position := FIND(ipStr, '.');
+WHILE position > 0 DO
+ IpDecode := SHL(IpDecode, 8) OR
+ STRING_TO_DWORD(LEFT(ipStr, position - 1));
+ ipStr := DELETE(ipStr, position, 1);
+ position := FIND(ipStr, '.');
+END_WHILE;
+IpDecode := SHL(IpDecode, 8) OR STRING_TO_DWORD(ipStr);
+
+
+
+
+ 370b1e33-b130-432d-82c0-d0ff7d197d76
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение
+
+
+
+
+ Округляет значение и возвращает ближайшее целое значение, которое больше или равно X.
+ ceil(3.14) = 4 ceil(-3.14) = -3
+
+
+
+
+ Ceil := REAL_TO_DINT(input);
+
+IF DINT_TO_REAL(Ceil) < input THEN
+ Ceil := Ceil + 1;
+END_IF;
+
+
+
+
+ 7e9d7ee0-507a-40bb-a5cb-1802edf09ecc
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение
+
+
+
+
+ Вычисляет с основанием степени 10.
+ exp10(2) = 100 exp10(3) = 1000
+
+
+
+
+ Exp10 := EXP(input * 2.30258509299405);
+
+
+
+
+ f6121561-6e17-4f2f-aa33-883772fb1cdc
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение
+
+
+
+
+
+
+
+ Степень
+
+
+
+
+
+
+
+
+
+
+
+ Возведение в степень X^N. Хотя в стандарте есть оператор EXPT, по заявлению OSCAT, данный алгоритм работает в 30 раз быстрее в CoDeSys.
+
+
+
+
+ sign := power.15;
+power := ABS(power);
+IF power.0 THEN ExpN := input; ELSE ExpN := 1.0; END_IF;
+power := SHR(power, 1);
+
+WHILE power > 0 DO
+ input := input * input;
+ IF power.0 THEN ExpN := ExpN * input; END_IF;
+ power := SHR(power, 1);
+END_WHILE;
+
+IF sign THEN ExpN := 1.0 / ExpN; END_IF;
+
+
+
+
+ 9bf63bfe-fe54-48dc-8f90-261ea50d788f
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение
+
+
+
+
+ Округляет значение и возвращает ближайшее целое значение, которое меньше или равно X.
+ floor(3.14) = 3 floor(-3.14) = -4
+
+
+
+
+ FLOOR := REAL_TO_DINT(input);
+IF DINT_TO_REAL(FLOOR) > input THEN
+ FLOOR := FLOOR - 1;
+END_IF;
+
+
+
+
+ 24fdd6dd-18c7-494b-9be5-85e1efccd187
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение
+
+
+
+
+ Эта функция возвращает дробную часть числа с плавающей точкой.
+ fract(3.14) = 0.14
+
+
+
+
+ IF ABS(input) < 2.0E9 THEN
+ FRACT := input - DINT_TO_REAL(DTrunc(input));
+ELSE
+ FRACT := 0.0;
+END_IF;
+
+
+
+
+ 645754da-c783-41eb-83c4-3246b516ea8a
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Делимое
+
+
+
+
+
+
+
+ Делитель
+
+
+
+
+ Вычисляет остаток от деления для чисел с плавающей запятой.
+ modr(5.5, 2.5) = 0.5
+
+
+
+
+ IF divisor = 0.0 THEN
+ MODR := 0.0;
+ELSE
+ MODR := input - DINT_TO_REAL(FLOOR(input / divisor)) * divisor;
+END_IF;
+
+
+
+
+
+ eb5f423f-4ff8-4594-96fb-e59f6014738a
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Число для обработки
+
+
+
+
+
+
+
+ Точность после запятой
+
+
+
+
+ Округляет число с плавающей точкой до указанного количества знаков после запятой.
+ round(12.23456789, 2) = 12.23
+
+
+
+
+ Round := DWORD_TO_REAL(REAL_TO_DWORD(input * Exp10(precision))) / Exp10(precision);
+
+
+
+
+
+ 43eb8e9c-7822-492d-a6d3-b21875b9c65d
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение в Цельсиях
+
+
+
+
+ Преобразование температуры из Цельсия в Фаренгейт
+
+
+
+
+ CelciusToFarenheit := celsiusTemp * 1.8 + 32.0;
+
+
+
+
+ f38a7a17-3c95-415a-9d89-4d5e214e7d67
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение в Цельсиях
+
+
+
+
+
+
+
+
+
+
+
+
+ 0°C в кельвинах
+
+
+
+
+ Преобразование температуры из Цельсия в Кельвин
+
+
+
+
+ CelciusToKelvin := celsiusTemp + physT0;
+
+
+
+
+ c9722344-c925-4350-b9db-68400010e960
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение в радианах
+
+
+
+
+ Конвертирует радианы в градусы.
+
+
+
+
+ DegreesToRadians := ModR(57.29577951308232 * radians, 360.0);
+
+
+
+
+ 00741b76-d02e-4841-9218-cf4e51799c29
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение в Фаренгейтах
+
+
+
+
+ Преобразование температуры из Фаренгейт в Цельсий
+
+
+
+
+ FarenheitToCelcius := (fahrenheitTemp - 32.0) * 0.5555555555555;
+
+
+
+
+ 1c8099aa-563e-4039-baa6-55b2d26aae82
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение в Кельвнах
+
+
+
+
+
+
+
+
+
+
+
+
+ 0°C в кельвинах
+
+
+
+
+ Преобразование температуры из Кельвина в Цельсий
+
+
+
+
+ KelvinToCelcius := kelvinTemp - phys_T0;
+
+
+
+
+ e6d47c81-1b52-487e-bf16-0f77ef5ec08d
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение в Км/ч
+
+
+
+
+ Преобразование скорости: км/ч в м/с
+
+
+
+
+ KmhToMs := kmhSpeed * 0.2777777777777;
+
+
+
+
+ 2027f9e1-f77f-4afa-a939-a7875cdc7b46
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение в м/с
+
+
+
+
+ Преобразование скорости: м/с в км/ч
+
+
+
+
+ MsToKmh := msSpeed * 3.6;
+
+
+
+
+ 89576b24-8a23-496b-abf0-27109c81d84e
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение в градусах
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ конвертирует градусы в радианы
+
+
+
+
+ RadiansToDegrees := ModR(0.0174532925199433 * degrees, pi*2);
+
+
+
+
+ 4b9ad742-ef31-4574-92c8-257046749aee
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение
+
+
+
+
+
+
+
+ Входное минимальное
+
+
+
+
+
+
+
+ Входное максимальное
+
+
+
+
+
+
+
+ Выходное минимальное
+
+
+
+
+
+
+
+ Выходное максимальное
+
+
+
+
+ линейное масштабирование числа с плавающей запятой
+
+
+
+
+ IF inputLow = inputHigh THEN
+ ScaleReal := outputLow;
+ELSE
+ ScaleReal := (outputHigh - outputLow) / (inputHigh - inputLow) * (LIMIT(inputLow, input, inputHigh) - inputLow) + outputLow;
+END_IF;
+
+
+
+
+ 6196bfc8-2183-4935-bc2e-5406080c7841
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Строка
+
+
+
+
+
+
+
+ Символ для подсчета
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Указатель на символ
+
+
+
+
+
+
+
+ Длина строки
+
+
+
+
+
+
+
+ Текущая позиция строки для прохода
+
+
+
+
+ считает, как много указанных символов содержится в строке
+
+
+
+
+ charPointer := ADR(inputString);
+length := LEN(inputString);
+CountChar := 0;
+FOR position := 1 TO length DO
+ IF charPointer^ = charToCount THEN
+ CountChar := CountChar + 1;
+ END_IF;
+ charPointer := charPointer + 1;
+END_FOR;
+
+
+
+
+ 5aa298bd-a611-423a-87e1-7a0a808f20a1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входная строка
+
+
+
+
+
+
+
+ Что удалить
+
+
+
+
+
+
+
+
+
+ Для временной строки
+
+
+
+
+
+
+
+ Позиция найденного символа
+
+
+
+
+ Удаление символа из строки
+
+
+
+
+ tempString := inputString;
+REPEAT
+ position := FIND(tempString, substringToRemove);
+ IF position <> 0 THEN
+ tempString := DELETE(tempString, LEN(substringToRemove), position);
+ END_IF;
+UNTIL (position = 0)
+END_REPEAT;
+RemoveSubString := tempString;
+
+
+
+
+ 0b8ea8fb-1139-4800-98db-52a469579462
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входная строка
+
+
+
+
+
+
+
+ Значение setup.EXTENDED_ASCII может быть или TRUE или FALSE, в зависимости от символьной таблицы, которая поддерживается ПЛК. Обычно стоит в TRUE.
+
+
+
+
+ Изменить регистр символа с маленькой буквы на заглавную. Работает только с латинскими буквами формата ASCII.
+
+
+
+
+ IF input > 96 AND input < 123 THEN
+ ToUpper := input AND 16#DF;
+ELSIF input > 223 AND input <> 247 AND input <> 255 AND useExtendedASCII THEN
+ ToUpper := input AND 16#DF;
+ELSE
+ ToUpper := input;
+END_IF;
+
+
+
+
+ 698221f0-adfb-47db-abeb-4a75818c8180
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входная дата
+
+
+
+
+
+
+
+
+
+ Год
+
+
+
+
+
+
+
+ Месяц
+
+
+
+
+
+
+
+ День
+
+
+
+
+
+
+
+
+
+
+
+ Извлечение года, месяца и дня из DATE
+
+
+
+
+ (* Получаем дату строкой 'D#2000-01-01' *)
+sTemp := DATE_TO_STRING(input);
+year := STRING_TO_UINT(MID(sTemp, 3, 4));
+month := STRING_TO_UINT(MID(sTemp, 8, 2));
+day := STRING_TO_UINT(MID(sTemp, 11, 2));
+
+DateToElements := true;
+
+
+
+
+ 6db1ca07-0a85-498a-b97a-6a21380eb6fc
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входная дата
+
+
+
+
+
+
+
+
+
+
+
+ Определение дня недели
+
+
+
+
+ NumOfDay := DATE_TO_DWORD(input) / 86400;
+NumOfDay := NumOfDay + 3;
+DayOfWeek := DWORD_TO_UINT(NumOfDay MOD 7);
+
+
+
+
+ c2ffe08f-5940-4c7a-9f94-7b20fd25a5b5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входная дата в формате DATE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Вычисление порядкового дня в году
+
+
+
+
+ DateToElements(input := input, year => year, month => month, day => day);
+
+DayOfYear := DaysTillMonth(year, month) + day;
+
+
+
+
+ f45877af-d8f3-4c70-8245-f5113a02d7b2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Год
+
+
+
+
+ Вычисление количества дней в году
+
+
+
+
+ IF IsLeapYear(year) THEN
+ DaysInYear := 366;
+ELSE
+ DaysInYear := 365;
+END_IF;
+
+
+
+
+ 0cb6fbcb-04a1-492a-bc99-f7d781171e05
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Год
+
+
+
+
+
+
+
+ Месяц
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ функция, чтобы определить количество дней от начала года до указанного месяца.
+
+
+
+
+ DaysTillMonth := days[month] + BOOL_TO_UINT(month > 2 AND IsLeapYear(year));
+
+
+
+
+ 998fa9fe-8a9c-4caf-85f6-9d4d58758e09
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Год
+
+
+
+
+ считает сколько прошло дней до указанного года
+
+
+
+
+ (* Получаем количество лет прошло с 1970го года *)
+year := year - 1970;
+DaysTillYear := year * 365 + ((year + 1) / 4) - ((year + 69) / 100) + ((year + 369) / 400);
+
+
+
+
+ 3fd03899-b6a1-4d1d-bd61-e17642c4a73b
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Часы
+
+
+
+
+
+
+
+ Минуты
+
+
+
+
+
+
+
+ Секунды
+
+
+
+
+
+
+
+ Миллисекунды
+
+
+
+
+ Упаковка часов, минут, секунд и миллисекунд в TIME
+
+
+
+
+ HmsToTime := DWORD_TO_TIME(((h * 60 + m) * 60 + sec) * 1000 + ms);
+
+
+
+
+ 3968a562-7bfd-47a8-a79a-14053b959297
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Часы (0..23)
+
+
+
+
+ Преобразовать часы (в виде INT) в TIME
+
+
+
+
+ HourToTime := T#1H * hours;
+
+
+
+
+ 6f15ae17-53ff-4aec-ba86-f5a3d4193b82
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Часы (0..23)
+
+
+
+
+ Преобразовать количество часов (INT) во значение типа TOD (время суток).
+
+
+
+
+ HourToTod := TOD#00:00:00 + T#1h * hours;
+
+
+
+
+ fe41eacd-9f55-4e06-b2b7-479808977dfb
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Год
+
+
+
+
+ Определение високосного года
+
+
+
+
+ IsLeapYear := year MOD 400 = 0 OR year MOD 4 = 0 AND year MOD 100 <> 0;
+
+
+
+
+ 2da9dfda-5b1d-454a-bcdd-873266c15f56
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Широта
+
+
+
+
+
+
+
+ Дата в UTC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ время солнцестояния на заданной широте в заданное время
+
+
+
+
+ T := UINT_TO_REAL(DayOfYear(utc));
+OFFSET := -0.1752 * SIN(0.033430 * T + 0.5474) - 0.1340 * SIN(0.018234 * T - 0.1939);
+SunMidday := HourToTod(REAL_TO_INT(12.0 - OFFSET - lon * 0.0666666666666));
+
+
+
+
+ 8af2c015-46ea-475d-acc8-627981e9c1d4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное время
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Извлечение часов, минут, секунд и миллисекунд из TIME
+
+
+
+
+ (* Теперь время имеет строку типа 'TOD#12:12:59' *)
+sTemp := TOD_TO_STRING(TIME_TO_TOD(input));
+h := STRING_TO_UINT(MID(sTemp, 5, 2));
+m := STRING_TO_UINT(MID(sTemp, 8, 2));
+sec := STRING_TO_UINT(MID(sTemp, 11, 2));
+TimeToElements := TRUE;
+
+
+
+
+ d8de33e6-87c6-4733-b78a-ba4d754deb93
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ текущее время
+
+
+
+
+
+
+
+ нижняя граница
+
+
+
+
+
+
+
+ верхняя граница
+
+
+
+
+ функция определения, что текущее время находится в промежутке между двумя отметками времени TIME_OF_DAY.
+
+
+
+
+ TodBetween := (
+ FromTime > ToTime AND (CurrTime > FromTime OR CurrTime < ToTime)
+ ) OR (FromTime < ToTime AND (CurrTime < ToTime AND CurrTime > FromTime)
+);
+
+
+
+
+
+ c23200b5-1781-4c39-9b57-f0e0e966370c
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ нижняя граница
+
+
+
+
+
+
+
+ верхняя граница
+
+
+
+
+ Вычисление разницы отметок времени
+
+
+
+
+ IF ToTime < FromTime THEN
+ TodDiff := T#24H - TOD_TO_TIME(FromTime) + TOD_TO_TIME(ToTime);
+ELSE
+ TodDiff := ToTime - FromTime;
+END_IF
+
+
+
+
+ 68ceaa4e-735c-48a4-a936-c6b5da48a973
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Текущая дата
+
+
+
+
+ Вычисления порядкового номера недели в году
+
+
+
+
+ WeekOfYear := ((DayOfYear(currentDate) + 6) / 7);
+IF DayOfWeek(currentDate) < DayOfWeek(YearStarts(currentDate)) THEN
+ WeekOfYear := WeekOfYear + 1;
+END_IF;
+
+
+
+
+ 70448faa-ac59-425b-8d39-299263f17006
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Текущая дата
+
+
+
+
+
+
+
+
+
+ Временная строка
+
+
+
+
+ Вычисления с какого дня недели начинается год
+
+
+
+
+ str := DATE_TO_STRING(currentDate); (* получаем строку `D#2000-12-30` *)
+YearStarts := STRING_TO_DATE(CONCAT(CONCAT('D#', MID(str, 3, 4)), '-01-01'));
+
+
+
+
+ 395f1cd0-ef8e-4840-af88-1cc7e4bc199f
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Год
+
+
+
+
+
+
+
+ Месяц
+
+
+
+
+
+
+
+ День
+
+
+
+
+
+
+
+ Час
+
+
+
+
+
+
+
+ Минуты
+
+
+
+
+
+
+
+ Секунды
+
+
+
+
+
+
+
+ Миллисекунды
+
+
+
+
+
+
+
+
+
+
+
+ Упаковка года, месяца, дня, часов, минут, секунд и миллисекунд в DT
+
+
+
+
+ sTemp := CONCAT('DT#', UINT_TO_STRING(y));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(mn));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(d));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(h));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(m));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(sec));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(ms));
+YmdhmsTodt := STRING_TO_DT(sTemp);
+
+
+
+
+ 22b5f20f-f8ae-477a-af67-7efa962518d0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Год
+
+
+
+
+
+
+
+ Месяц
+
+
+
+
+
+
+
+ День
+
+
+
+
+
+
+
+
+
+
+
+ Gеревод год, месяц и день в формат DATE.
+
+
+
+
+ sTemp := CONCAT('D#', UINT_TO_STRING(y));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(m));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(d));
+YmdToDate := STRING_TO_DATE(sTemp);
+
+
+
+
+ 5c9ab7aa-35fb-49a0-b541-53a3c59037e8
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное число
+
+
+
+
+ Cчитает количество бит, равных TRUE в DWORD.
+ Пример: bit_count(3) = 2 Потому что 2 бита равны 1, а остальные равны 0.
+
+
+
+
+ WHILE input > 0 DO
+ IF input.0 THEN
+ BitCount := BitCount + 1;
+ END_IF
+ input := SHR(input, 1);
+END_WHILE;
+
+
+
+
+ 35c5d0b0-50b6-48ad-8ade-487398968ef5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Байт, в котором нужно произвести операцию
+
+
+
+
+
+
+
+ Присваиваемое значение
+
+
+
+
+
+
+
+ Какому по номеру биту
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Загружает значение одного бита в байт.
+ bit_load_b(2#0000_0000, 1, 2) = 2#0000_0010
+
+
+
+
+ IF value THEN
+ BitLoadB := input OR SHL(dat, position);
+ELSE
+ BitLoadB := input AND (NOT SHL(dat, position));
+END_IF;
+
+
+
+
+ 0ee4e802-faae-426e-a4d7-a5fbb5c81186
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное число
+
+
+
+
+
+
+
+ номер бита
+
+
+
+
+ Вычисляем значение единичного бита в переменной типа DWORD.
+
+
+
+
+ BitOfDword := (SHR(input, n) AND 16#00000001) > 0;
+
+
+
+
+ 7c67bd8a-5ab5-43d1-9cc5-4957da9e0079
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение
+
+
+
+
+
+
+
+ Номер инвертируемого бита
+
+
+
+
+ Инвертируем указанный бит в DWORD
+
+
+
+
+ BitToggleDword := SHL(DWORD#1, position) XOR input;
+
+
+
+
+ fbbd32ea-a489-45b8-af81-580307e6eaa4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение X
+
+
+
+
+
+
+
+ Входное значение Y
+
+
+
+
+
+
+
+ Количество сравниваемых разрядов
+
+
+
+
+
+
+
+
+
+
+
+ Сравнивает 2 входных числовых переменных, совпадают ли их первые разрады.
+ Количество сравниваемых разрядов передается в параметре N.
+ cmp(3.141516, 3.141517, 6) вернет TRUE.
+
+
+
+
+ tmp := ABS(x);
+IF tmp > 0.0 THEN
+ tmp := Exp10(DINT_TO_REAL(FLOOR(LOG(tmp))-n+1));
+ELSE
+ tmp := Exp10(tmp);
+END_IF;
+
+CompareReals := ABS(x - y) < tmp;
+
+
+
+
+ 95639908-aef5-4ad0-9463-00d7f35e4750
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение
+
+
+
+
+ Усекает число с плавающей запятой в целое число DINT. 1.5 станет 1, а -1.5 станет -1.
+ Данная функция необходима, потому что REAL_TO_DINT на разных системах может вернуть разный результат.
+
+
+
+
+ DTrunc := REAL_TO_DINT(input);
+
+IF input > 0.0 THEN
+ IF DINT_TO_REAL(DTrunc) > input THEN
+ DTrunc := DTrunc - 1;
+ END_IF;
+ELSE
+ IF DINT_TO_REAL(DTrunc) < input THEN
+ DTrunc := DTrunc + 1;
+ END_IF;
+END_IF;
+
+
+
+
+ e81c8fd1-e716-4f15-a950-9242e8801c85
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение
+
+
+
+
+ Вычисляет, является ли число четным или нет. Если четное, то вернет TRUE, а если нет - вернет FALSE.
+
+
+
+
+ Even := NOT input.0;
+
+
+
+
+ dd31efa8-aa78-41e1-be66-269920045c5c
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Предыдущее значение
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ константа Эйлера
+
+
+
+
+ Вычисляет псевдо-случайное число. Чтобы сгенерировать число, функция
+ считывает таймер ПЛК и создает число с плавающей точкой от 0 до 1. Чтобы
+ использовать эту функцию больше, чем один раз, в одном цикле ПЛК, нужно ее
+ вызывать с разным значением входного параметра last. В него проще внести
+ прошлое число, чтобы исключить повторения.
+
+
+
+
+ tn := TIME_TO_DWORD(TIME());
+tc := BitCount(tn);
+tn.31 := tn.2;
+tn.30 := tn.5;
+tn.29 := tn.4;
+tn.28 := tn.1;
+tn.27 := tn.0;
+tn.26 := tn.7;
+tn.25 := tn.6;
+tn.24 := tn.3;
+tn := ROL(tn, BitCount(tn)) OR 16#80000001;
+tn := tn MOD 71474513 + INT_TO_DWORD(tc + 77);
+Random := FRACT(DWORD_TO_REAL(tn) / 10000000.0 *
+(E - LIMIT(0.0, last, 1.0))
+);
+
+
+
+
+ 8d60497f-9b6b-4c61-877a-775acbca0520
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение
+
+
+
+
+ Поменять байт местами в DWORD
+
+
+
+
+ SwapDwordBytes := (ROR(input, 8) AND 16#FF00FF00) OR (ROL(input, 8) AND 16#00FF00FF);
+
+
+
+
+ 2cf34bc5-a910-4ad8-9cd5-2ccbbf01ed02
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Входное значение
+
+
+
+
+ Поменять байт местами в WORD
+
+
+
+
+ SwapWordBytes := ROL(input, 8);
+
+
+
+
+ 683a7031-edb1-4113-9c5d-4519805b2f16
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
From 3598da81558aa160e0cff6e84d8753167b084a21 Mon Sep 17 00:00:00 2001
From: "Sergey A. Glukhov"
Date: Thu, 12 Jun 2025 14:06:13 +0300
Subject: [PATCH 2/6] Update AnjLabCodeBox.xml
---
AnjLabCodeBox.xml | 544 +++++++++++++++++++++++-----------------------
1 file changed, 278 insertions(+), 266 deletions(-)
diff --git a/AnjLabCodeBox.xml b/AnjLabCodeBox.xml
index 3c303da..062605b 100644
--- a/AnjLabCodeBox.xml
+++ b/AnjLabCodeBox.xml
@@ -1,6 +1,6 @@
-
+
-
+
Helpful ST blocks and functions
@@ -86,10 +86,10 @@
- IF input AND NOT memory THEN
- startTime := TIME();
-END_IF;
-memory := input;
+ IF input AND NOT memory THEN
+ startTime := TIME();
+END_IF;
+memory := input;
output := input AND ((TIME() - startTime) > T#100ms);
@@ -145,13 +145,13 @@ output := input AND ((TIME() - startTime) > T#100ms);
- IF (NOT input AND memory) OR (input AND NOT memory) THEN
- startTime := TIME();
-END_IF;
-memory := input;
-output := input;
-IF ((TIME() - startTime) < T#100ms) THEN
- output := NOT input;
+ IF (NOT input AND memory) OR (input AND NOT memory) THEN
+ startTime := TIME();
+END_IF;
+memory := input;
+output := input;
+IF ((TIME() - startTime) < T#100ms) THEN
+ output := NOT input;
END_IF
@@ -207,13 +207,13 @@ END_IF
- IF NOT input AND memory THEN
- startTime := TIME();
-END_IF;
-memory := input;
-output := input;
-IF NOT input AND ((TIME() - startTime) < T#100ms) THEN
- output := TRUE;
+ IF NOT input AND memory THEN
+ startTime := TIME();
+END_IF;
+memory := input;
+output := input;
+IF NOT input AND ((TIME() - startTime) < T#100ms) THEN
+ output := TRUE;
END_IF
@@ -279,13 +279,13 @@ END_IF
- fbDio1(input := input, output => filteredInput);
-raise := fall := FALSE;
-IF filteredInput AND NOT memory THEN
- raise := TRUE;
-ELSIF NOT filteredInput AND memory THEN
- fall := TRUE;
-END_IF
+ fbDio1(input := input, output => filteredInput);
+raise := fall := FALSE;
+IF filteredInput AND NOT memory THEN
+ raise := TRUE;
+ELSIF NOT filteredInput AND memory THEN
+ fall := TRUE;
+END_IF
memory := filteredInput;
@@ -341,13 +341,13 @@ memory := filteredInput;
- output := FALSE;
-IF input AND NOT memory THEN
- IF (TIME() - startTime) > T#100MS AND (TIME() - startTime) < T#800MS THEN
- output := TRUE;
- END_IF;
- startTime := TIME();
-END_IF;
+ output := FALSE;
+IF input AND NOT memory THEN
+ IF (TIME() - startTime) > T#100MS AND (TIME() - startTime) < T#800MS THEN
+ output := TRUE;
+ END_IF;
+ startTime := TIME();
+END_IF;
memory := input;
@@ -428,28 +428,28 @@ memory := input;
- (* ограничим bufferSize в размер буфера *)
-bufferSize := MIN(MAX(bufferSize, 1000), 32);
-(* Инициализация *)
-IF NOT isInitialized OR reset THEN
- isInitialized := TRUE;
- FOR counter := 1 TO bufferSize DO
- buffer[counter] := input;
- END_FOR;
- sum := input * bufferSize;
- output := input;
- RETURN;
-END_IF;
-
-IF counter >= bufferSize THEN
- counter := 1;
-ELSE
- counter := counter + 1;
-END_IF
-
-sum := sum + input - buffer[counter];
-{warning disable C0195}
-output := DWORD_TO_WORD(sum / bufferSize);
+ (* ограничим bufferSize в размер буфера *)
+bufferSize := MIN(MAX(bufferSize, 1000), 32);
+(* Инициализация *)
+IF NOT isInitialized OR reset THEN
+ isInitialized := TRUE;
+ FOR counter := 1 TO bufferSize DO
+ buffer[counter] := input;
+ END_FOR;
+ sum := input * bufferSize;
+ output := input;
+ RETURN;
+END_IF;
+
+IF counter >= bufferSize THEN
+ counter := 1;
+ELSE
+ counter := counter + 1;
+END_IF
+
+sum := sum + input - buffer[counter];
+{warning disable C0195}
+output := DWORD_TO_WORD(sum / bufferSize);
buffer[counter] := input;
@@ -517,22 +517,22 @@ buffer[counter] := input;
- (* Получаем текущее время *)
-currentTime := TIME_TO_DWORD(TIME());
-(* Инициализация *)
-IF NOT isInitialized OR timeInterval = T#0s THEN
- isInitialized := TRUE;
- lastTime := currentTime;
- output := input;
-ELSIF output = input THEN
- lastTime := currentTime;
-ELSE
- tempTime := WORD_TO_DWORD(input - output) * (currentTime - lastTime) /
- TIME_TO_DWORD(timeInterval);
- IF tempTime <> 0 THEN
- output := DINT_TO_WORD(WORD_TO_DINT(output) + DWORD_TO_DINT(tempTime));
- lastTime := currentTime;
- END_IF;
+ (* Получаем текущее время *)
+currentTime := TIME_TO_DWORD(TIME());
+(* Инициализация *)
+IF NOT isInitialized OR timeInterval = T#0s THEN
+ isInitialized := TRUE;
+ lastTime := currentTime;
+ output := input;
+ELSIF output = input THEN
+ lastTime := currentTime;
+ELSE
+ tempTime := WORD_TO_DWORD(input - output) * (currentTime - lastTime) /
+ TIME_TO_DWORD(timeInterval);
+ IF tempTime <> 0 THEN
+ output := DINT_TO_WORD(WORD_TO_DINT(output) + DWORD_TO_DINT(tempTime));
+ lastTime := currentTime;
+ END_IF;
END_IF;
@@ -596,10 +596,10 @@ END_IF;
- IF input AND NOT memory THEN
- startTime := TIME();
-END_IF;
-memory := input;
+ IF input AND NOT memory THEN
+ startTime := TIME();
+END_IF;
+memory := input;
output := input AND ((TIME() - startTime) > pressTime);
@@ -666,12 +666,12 @@ output := input AND ((TIME() - startTime) > pressTime);
- currentTime := TIME();
-IF enable AND NOT memory THEN
- lastTime := currentTime - pulseTime;
-END_IF;
-memory := enable;
-output := currentTime - lastTime >= pulseTime;
+ currentTime := TIME();
+IF enable AND NOT memory THEN
+ lastTime := currentTime - pulseTime;
+END_IF;
+memory := enable;
+output := currentTime - lastTime >= pulseTime;
IF output THEN lastTime := currentTime; END_IF;
@@ -735,16 +735,16 @@ IF output THEN lastTime := currentTime; END_IF;
- (* Если частота ШИМ 0, то прерываем исполнение ФБ *)
-IF frequency <= 0.0 THEN
- output := FALSE;
- RETURN;
-END_IF;
-(* Вычисляем сколько миллисекунд требуется на один цикл ШИМ *)
-tempValue := 1000.0 / frequency;
-(* Запускаем генератор сигналов *)
-clock(pulseTime := REAL_TO_TIME(tempValue));
-(* Создаем выдержанный пульс на нужное время *)
+ (* Если частота ШИМ 0, то прерываем исполнение ФБ *)
+IF frequency <= 0.0 THEN
+ output := FALSE;
+ RETURN;
+END_IF;
+(* Вычисляем сколько миллисекунд требуется на один цикл ШИМ *)
+tempValue := 1000.0 / frequency;
+(* Запускаем генератор сигналов *)
+clock(pulseTime := REAL_TO_TIME(tempValue));
+(* Создаем выдержанный пульс на нужное время *)
pulseTimer(in := clock.output, pt := REAL_TO_TIME(tempValue * dutyCycle), Q => output);
@@ -803,15 +803,15 @@ pulseTimer(in := clock.output, pt := REAL_TO_TIME(tempValue * dutyCycle), Q =>
- (* Если частота ШИМ 0 или время одного цикла меньше,
-чем время для фазы Ton, то прерываем исполнение ФБ *)
-IF frequency <= 0.0 OR (REAL_TO_TIME(1000.0 / frequency) < pulseWidth) THEN
- output := FALSE;
- RETURN;
-END_IF;
-(* Запускаем генератор сигналов *)
-clock(pulseTime := REAL_TO_TIME(1000.0 / frequency));
-(* Создаем выдержанный пульс на нужное время *)
+ (* Если частота ШИМ 0 или время одного цикла меньше,
+чем время для фазы Ton, то прерываем исполнение ФБ *)
+IF frequency <= 0.0 OR (REAL_TO_TIME(1000.0 / frequency) < pulseWidth) THEN
+ output := FALSE;
+ RETURN;
+END_IF;
+(* Запускаем генератор сигналов *)
+clock(pulseTime := REAL_TO_TIME(1000.0 / frequency));
+(* Создаем выдержанный пульс на нужное время *)
pulseTimer(in := clock.output, PT := pulseWidth, Q => output);
@@ -923,16 +923,16 @@ pulseTimer(in := clock.output, PT := pulseWidth, Q => output);
- MIDDAY := SunMidday(longitude, utc);
-b := latitude * 0.0174532925199433;
-dk := 0.40954 * SIN(0.0172 * (UINT_TO_REAL(DayOfYear(utc)) - 79.35));
-SUN_DECLINATION := DegreesToRadians(DK);
-IF SUN_DECLINATION > 180.0 THEN
- SUN_DECLINATION := SUN_DECLINATION - 360.0;
-END_IF;
-SUN_DECLINATION := 90.0 - LATITUDE + SUN_DECLINATION;
-delta := HourToTime(REAL_TO_INT(ACOS((SIN(RadiansToDegrees(H)) - SIN(B) * SIN(DK)) / (COS(B) * COS(DK))) * 3.819718632));
-SUN_RISE := MIDDAY - delta;
+ MIDDAY := SunMidday(longitude, utc);
+b := latitude * 0.0174532925199433;
+dk := 0.40954 * SIN(0.0172 * (UINT_TO_REAL(DayOfYear(utc)) - 79.35));
+SUN_DECLINATION := DegreesToRadians(DK);
+IF SUN_DECLINATION > 180.0 THEN
+ SUN_DECLINATION := SUN_DECLINATION - 360.0;
+END_IF;
+SUN_DECLINATION := 90.0 - LATITUDE + SUN_DECLINATION;
+delta := HourToTime(REAL_TO_INT(ACOS((SIN(RadiansToDegrees(H)) - SIN(B) * SIN(DK)) / (COS(B) * COS(DK))) * 3.819718632));
+SUN_RISE := MIDDAY - delta;
SUN_SET := MIDDAY + delta;
@@ -970,13 +970,13 @@ SUN_SET := MIDDAY + delta;
- position := FIND(ipStr, '.');
-WHILE position > 0 DO
- IpDecode := SHL(IpDecode, 8) OR
- STRING_TO_DWORD(LEFT(ipStr, position - 1));
- ipStr := DELETE(ipStr, position, 1);
- position := FIND(ipStr, '.');
-END_WHILE;
+ position := FIND(ipStr, '.');
+WHILE position > 0 DO
+ IpDecode := SHL(IpDecode, 8) OR
+ STRING_TO_DWORD(LEFT(ipStr, position - 1));
+ ipStr := DELETE(ipStr, position, 1);
+ position := FIND(ipStr, '.');
+END_WHILE;
IpDecode := SHL(IpDecode, 8) OR STRING_TO_DWORD(ipStr);
@@ -1008,10 +1008,10 @@ IpDecode := SHL(IpDecode, 8) OR STRING_TO_DWORD(ipStr);
- Ceil := REAL_TO_DINT(input);
-
-IF DINT_TO_REAL(Ceil) < input THEN
- Ceil := Ceil + 1;
+ Ceil := REAL_TO_DINT(input);
+
+IF DINT_TO_REAL(Ceil) < input THEN
+ Ceil := Ceil + 1;
END_IF;
@@ -1088,17 +1088,17 @@ END_IF;
- sign := power.15;
-power := ABS(power);
-IF power.0 THEN ExpN := input; ELSE ExpN := 1.0; END_IF;
-power := SHR(power, 1);
-
-WHILE power > 0 DO
- input := input * input;
- IF power.0 THEN ExpN := ExpN * input; END_IF;
- power := SHR(power, 1);
-END_WHILE;
-
+ sign := power.15;
+power := ABS(power);
+IF power.0 THEN ExpN := input; ELSE ExpN := 1.0; END_IF;
+power := SHR(power, 1);
+
+WHILE power > 0 DO
+ input := input * input;
+ IF power.0 THEN ExpN := ExpN * input; END_IF;
+ power := SHR(power, 1);
+END_WHILE;
+
IF sign THEN ExpN := 1.0 / ExpN; END_IF;
@@ -1130,9 +1130,9 @@ IF sign THEN ExpN := 1.0 / ExpN; END_IF;
- FLOOR := REAL_TO_DINT(input);
-IF DINT_TO_REAL(FLOOR) > input THEN
- FLOOR := FLOOR - 1;
+ FLOOR := REAL_TO_DINT(input);
+IF DINT_TO_REAL(FLOOR) > input THEN
+ FLOOR := FLOOR - 1;
END_IF;
@@ -1164,10 +1164,10 @@ END_IF;
- IF ABS(input) < 2.0E9 THEN
- FRACT := input - DINT_TO_REAL(DTrunc(input));
-ELSE
- FRACT := 0.0;
+ IF ABS(input) < 2.0E9 THEN
+ FRACT := input - DINT_TO_REAL(DTrunc(input));
+ELSE
+ FRACT := 0.0;
END_IF;
@@ -1207,11 +1207,11 @@ END_IF;
- IF divisor = 0.0 THEN
- MODR := 0.0;
-ELSE
- MODR := input - DINT_TO_REAL(FLOOR(input / divisor)) * divisor;
-END_IF;
+ IF divisor = 0.0 THEN
+ MODR := 0.0;
+ELSE
+ MODR := input - DINT_TO_REAL(FLOOR(input / divisor)) * divisor;
+END_IF;
@@ -1251,7 +1251,7 @@ END_IF;
- Round := DWORD_TO_REAL(REAL_TO_DWORD(input * Exp10(precision))) / Exp10(precision);
+ Round := DWORD_TO_REAL(REAL_TO_DWORD(input * Exp10(precision))) / Exp10(precision);
@@ -1602,10 +1602,10 @@ END_IF;
- IF inputLow = inputHigh THEN
- ScaleReal := outputLow;
-ELSE
- ScaleReal := (outputHigh - outputLow) / (inputHigh - inputLow) * (LIMIT(inputLow, input, inputHigh) - inputLow) + outputLow;
+ IF inputLow = inputHigh THEN
+ ScaleReal := outputLow;
+ELSE
+ ScaleReal := (outputHigh - outputLow) / (inputHigh - inputLow) * (LIMIT(inputLow, input, inputHigh) - inputLow) + outputLow;
END_IF;
@@ -1674,14 +1674,14 @@ END_IF;
- charPointer := ADR(inputString);
-length := LEN(inputString);
-CountChar := 0;
-FOR position := 1 TO length DO
- IF charPointer^ = charToCount THEN
- CountChar := CountChar + 1;
- END_IF;
- charPointer := charPointer + 1;
+ charPointer := ADR(inputString);
+length := LEN(inputString);
+CountChar := 0;
+FOR position := 1 TO length DO
+ IF charPointer^ = charToCount THEN
+ CountChar := CountChar + 1;
+ END_IF;
+ charPointer := charPointer + 1;
END_FOR;
@@ -1738,14 +1738,14 @@ END_FOR;
- tempString := inputString;
-REPEAT
- position := FIND(tempString, substringToRemove);
- IF position <> 0 THEN
- tempString := DELETE(tempString, LEN(substringToRemove), position);
- END_IF;
-UNTIL (position = 0)
-END_REPEAT;
+ tempString := inputString;
+REPEAT
+ position := FIND(tempString, substringToRemove);
+ IF position <> 0 THEN
+ tempString := DELETE(tempString, LEN(substringToRemove), position);
+ END_IF;
+UNTIL (position = 0)
+END_REPEAT;
RemoveSubString := tempString;
@@ -1784,12 +1784,12 @@ RemoveSubString := tempString;
- IF input > 96 AND input < 123 THEN
- ToUpper := input AND 16#DF;
-ELSIF input > 223 AND input <> 247 AND input <> 255 AND useExtendedASCII THEN
- ToUpper := input AND 16#DF;
-ELSE
- ToUpper := input;
+ IF input > 96 AND input < 123 THEN
+ ToUpper := input AND 16#DF;
+ELSIF input > 223 AND input <> 247 AND input <> 255 AND useExtendedASCII THEN
+ ToUpper := input AND 16#DF;
+ELSE
+ ToUpper := input;
END_IF;
@@ -1853,12 +1853,12 @@ END_IF;
- (* Получаем дату строкой 'D#2000-01-01' *)
-sTemp := DATE_TO_STRING(input);
-year := STRING_TO_UINT(MID(sTemp, 3, 4));
-month := STRING_TO_UINT(MID(sTemp, 8, 2));
-day := STRING_TO_UINT(MID(sTemp, 11, 2));
-
+ (* Получаем дату строкой 'D#2000-01-01' *)
+sTemp := DATE_TO_STRING(input);
+year := STRING_TO_UINT(MID(sTemp, 3, 4));
+month := STRING_TO_UINT(MID(sTemp, 8, 2));
+day := STRING_TO_UINT(MID(sTemp, 11, 2));
+
DateToElements := true;
@@ -1896,8 +1896,8 @@ DateToElements := true;
- NumOfDay := DATE_TO_DWORD(input) / 86400;
-NumOfDay := NumOfDay + 3;
+ NumOfDay := DATE_TO_DWORD(input) / 86400;
+NumOfDay := NumOfDay + 3;
DayOfWeek := DWORD_TO_UINT(NumOfDay MOD 7);
@@ -1945,8 +1945,8 @@ DayOfWeek := DWORD_TO_UINT(NumOfDay MOD 7);
- DateToElements(input := input, year => year, month => month, day => day);
-
+ DateToElements(input := input, year => year, month => month, day => day);
+
DayOfYear := DaysTillMonth(year, month) + day;
@@ -1977,10 +1977,10 @@ DayOfYear := DaysTillMonth(year, month) + day;
- IF IsLeapYear(year) THEN
- DaysInYear := 366;
-ELSE
- DaysInYear := 365;
+ IF IsLeapYear(year) THEN
+ DaysInYear := 366;
+ELSE
+ DaysInYear := 365;
END_IF;
@@ -2101,8 +2101,8 @@ END_IF;
- (* Получаем количество лет прошло с 1970го года *)
-year := year - 1970;
+ (* Получаем количество лет прошло с 1970го года *)
+year := year - 1970;
DaysTillYear := year * 365 + ((year + 1) / 4) - ((year + 69) / 100) + ((year + 369) / 400);
@@ -2297,8 +2297,8 @@ DaysTillYear := year * 365 + ((year + 1) / 4) - ((year + 69) / 100) + ((year + 3
- T := UINT_TO_REAL(DayOfYear(utc));
-OFFSET := -0.1752 * SIN(0.033430 * T + 0.5474) - 0.1340 * SIN(0.018234 * T - 0.1939);
+ T := UINT_TO_REAL(DayOfYear(utc));
+OFFSET := -0.1752 * SIN(0.033430 * T + 0.5474) - 0.1340 * SIN(0.018234 * T - 0.1939);
SunMidday := HourToTod(REAL_TO_INT(12.0 - OFFSET - lon * 0.0666666666666));
@@ -2358,11 +2358,11 @@ SunMidday := HourToTod(REAL_TO_INT(12.0 - OFFSET - lon * 0.0666666666666));
- (* Теперь время имеет строку типа 'TOD#12:12:59' *)
-sTemp := TOD_TO_STRING(TIME_TO_TOD(input));
-h := STRING_TO_UINT(MID(sTemp, 5, 2));
-m := STRING_TO_UINT(MID(sTemp, 8, 2));
-sec := STRING_TO_UINT(MID(sTemp, 11, 2));
+ (* Теперь время имеет строку типа 'TOD#12:12:59' *)
+sTemp := TOD_TO_STRING(TIME_TO_TOD(input));
+h := STRING_TO_UINT(MID(sTemp, 5, 2));
+m := STRING_TO_UINT(MID(sTemp, 8, 2));
+sec := STRING_TO_UINT(MID(sTemp, 11, 2));
TimeToElements := TRUE;
@@ -2409,10 +2409,10 @@ TimeToElements := TRUE;
- TodBetween := (
- FromTime > ToTime AND (CurrTime > FromTime OR CurrTime < ToTime)
- ) OR (FromTime < ToTime AND (CurrTime < ToTime AND CurrTime > FromTime)
-);
+ TodBetween := (
+ FromTime > ToTime AND (CurrTime > FromTime OR CurrTime < ToTime)
+ ) OR (FromTime < ToTime AND (CurrTime < ToTime AND CurrTime > FromTime)
+);
@@ -2451,10 +2451,10 @@ TimeToElements := TRUE;
- IF ToTime < FromTime THEN
- TodDiff := T#24H - TOD_TO_TIME(FromTime) + TOD_TO_TIME(ToTime);
-ELSE
- TodDiff := ToTime - FromTime;
+ IF ToTime < FromTime THEN
+ TodDiff := T#24H - TOD_TO_TIME(FromTime) + TOD_TO_TIME(ToTime);
+ELSE
+ TodDiff := ToTime - FromTime;
END_IF
@@ -2485,9 +2485,9 @@ END_IF
- WeekOfYear := ((DayOfYear(currentDate) + 6) / 7);
-IF DayOfWeek(currentDate) < DayOfWeek(YearStarts(currentDate)) THEN
- WeekOfYear := WeekOfYear + 1;
+ WeekOfYear := ((DayOfYear(currentDate) + 6) / 7);
+IF DayOfWeek(currentDate) < DayOfWeek(YearStarts(currentDate)) THEN
+ WeekOfYear := WeekOfYear + 1;
END_IF;
@@ -2528,7 +2528,7 @@ END_IF;
- str := DATE_TO_STRING(currentDate); (* получаем строку `D#2000-12-30` *)
+ str := DATE_TO_STRING(currentDate); (* получаем строку `D#2000-12-30` *)
YearStarts := STRING_TO_DATE(CONCAT(CONCAT('D#', MID(str, 3, 4)), '-01-01'));
@@ -2614,19 +2614,19 @@ YearStarts := STRING_TO_DATE(CONCAT(CONCAT('D#', MID(str, 3, 4)), '-01-01'));
- sTemp := CONCAT('DT#', UINT_TO_STRING(y));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(mn));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(d));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(h));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(m));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(sec));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(ms));
+ sTemp := CONCAT('DT#', UINT_TO_STRING(y));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(mn));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(d));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(h));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(m));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(sec));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(ms));
YmdhmsTodt := STRING_TO_DT(sTemp);
@@ -2680,11 +2680,11 @@ YmdhmsTodt := STRING_TO_DT(sTemp);
- sTemp := CONCAT('D#', UINT_TO_STRING(y));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(m));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(d));
+ sTemp := CONCAT('D#', UINT_TO_STRING(y));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(m));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(d));
YmdToDate := STRING_TO_DATE(sTemp);
@@ -2716,11 +2716,11 @@ YmdToDate := STRING_TO_DATE(sTemp);
- WHILE input > 0 DO
- IF input.0 THEN
- BitCount := BitCount + 1;
- END_IF
- input := SHR(input, 1);
+ WHILE input > 0 DO
+ IF input.0 THEN
+ BitCount := BitCount + 1;
+ END_IF
+ input := SHR(input, 1);
END_WHILE;
@@ -2778,10 +2778,10 @@ END_WHILE;
- IF value THEN
- BitLoadB := input OR SHL(dat, position);
-ELSE
- BitLoadB := input AND (NOT SHL(dat, position));
+ IF value THEN
+ BitLoadB := input OR SHL(dat, position);
+ELSE
+ BitLoadB := input AND (NOT SHL(dat, position));
END_IF;
@@ -2913,13 +2913,13 @@ END_IF;
- tmp := ABS(x);
-IF tmp > 0.0 THEN
- tmp := Exp10(DINT_TO_REAL(FLOOR(LOG(tmp))-n+1));
-ELSE
- tmp := Exp10(tmp);
-END_IF;
-
+ tmp := ABS(x);
+IF tmp > 0.0 THEN
+ tmp := Exp10(DINT_TO_REAL(FLOOR(LOG(tmp))-n+1));
+ELSE
+ tmp := Exp10(tmp);
+END_IF;
+
CompareReals := ABS(x - y) < tmp;
@@ -2951,16 +2951,16 @@ CompareReals := ABS(x - y) < tmp;
- DTrunc := REAL_TO_DINT(input);
-
-IF input > 0.0 THEN
- IF DINT_TO_REAL(DTrunc) > input THEN
- DTrunc := DTrunc - 1;
- END_IF;
-ELSE
- IF DINT_TO_REAL(DTrunc) < input THEN
- DTrunc := DTrunc + 1;
- END_IF;
+ DTrunc := REAL_TO_DINT(input);
+
+IF input > 0.0 THEN
+ IF DINT_TO_REAL(DTrunc) > input THEN
+ DTrunc := DTrunc - 1;
+ END_IF;
+ELSE
+ IF DINT_TO_REAL(DTrunc) < input THEN
+ DTrunc := DTrunc + 1;
+ END_IF;
END_IF;
@@ -3050,20 +3050,20 @@ END_IF;
- tn := TIME_TO_DWORD(TIME());
-tc := BitCount(tn);
-tn.31 := tn.2;
-tn.30 := tn.5;
-tn.29 := tn.4;
-tn.28 := tn.1;
-tn.27 := tn.0;
-tn.26 := tn.7;
-tn.25 := tn.6;
-tn.24 := tn.3;
-tn := ROL(tn, BitCount(tn)) OR 16#80000001;
-tn := tn MOD 71474513 + INT_TO_DWORD(tc + 77);
-Random := FRACT(DWORD_TO_REAL(tn) / 10000000.0 *
-(E - LIMIT(0.0, last, 1.0))
+ tn := TIME_TO_DWORD(TIME());
+tc := BitCount(tn);
+tn.31 := tn.2;
+tn.30 := tn.5;
+tn.29 := tn.4;
+tn.28 := tn.1;
+tn.27 := tn.0;
+tn.26 := tn.7;
+tn.25 := tn.6;
+tn.24 := tn.3;
+tn := ROL(tn, BitCount(tn)) OR 16#80000001;
+tn := tn MOD 71474513 + INT_TO_DWORD(tc + 77);
+Random := FRACT(DWORD_TO_REAL(tn) / 10000000.0 *
+(E - LIMIT(0.0, last, 1.0))
);
@@ -3139,6 +3139,16 @@ Random := FRACT(DWORD_TO_REAL(tn) / 10000000.0 *
+
+
+
+
+
+ 8c1463b5-02f2-427d-bd06-9e39d42fcbff
+
+
+
+
@@ -3225,7 +3235,9 @@ Random := FRACT(DWORD_TO_REAL(tn) / 10000000.0 *
+
+
-
\ No newline at end of file
+
From 5e5a3a6bf8a10f08552188863b1a1763b476fb75 Mon Sep 17 00:00:00 2001
From: "sergey.glukhov"
Date: Thu, 12 Jun 2025 14:10:28 +0300
Subject: [PATCH 3/6] test
---
AnjLabCodeBox.xml | 530 +++++++++++++++++++++++-----------------------
1 file changed, 265 insertions(+), 265 deletions(-)
diff --git a/AnjLabCodeBox.xml b/AnjLabCodeBox.xml
index 062605b..e0d3192 100644
--- a/AnjLabCodeBox.xml
+++ b/AnjLabCodeBox.xml
@@ -1,4 +1,4 @@
-
+
@@ -86,10 +86,10 @@
- IF input AND NOT memory THEN
- startTime := TIME();
-END_IF;
-memory := input;
+ IF input AND NOT memory THEN
+ startTime := TIME();
+END_IF;
+memory := input;
output := input AND ((TIME() - startTime) > T#100ms);
@@ -145,13 +145,13 @@ output := input AND ((TIME() - startTime) > T#100ms);
- IF (NOT input AND memory) OR (input AND NOT memory) THEN
- startTime := TIME();
-END_IF;
-memory := input;
-output := input;
-IF ((TIME() - startTime) < T#100ms) THEN
- output := NOT input;
+ IF (NOT input AND memory) OR (input AND NOT memory) THEN
+ startTime := TIME();
+END_IF;
+memory := input;
+output := input;
+IF ((TIME() - startTime) < T#100ms) THEN
+ output := NOT input;
END_IF
@@ -207,13 +207,13 @@ END_IF
- IF NOT input AND memory THEN
- startTime := TIME();
-END_IF;
-memory := input;
-output := input;
-IF NOT input AND ((TIME() - startTime) < T#100ms) THEN
- output := TRUE;
+ IF NOT input AND memory THEN
+ startTime := TIME();
+END_IF;
+memory := input;
+output := input;
+IF NOT input AND ((TIME() - startTime) < T#100ms) THEN
+ output := TRUE;
END_IF
@@ -279,13 +279,13 @@ END_IF
- fbDio1(input := input, output => filteredInput);
-raise := fall := FALSE;
-IF filteredInput AND NOT memory THEN
- raise := TRUE;
-ELSIF NOT filteredInput AND memory THEN
- fall := TRUE;
-END_IF
+ fbDio1(input := input, output => filteredInput);
+raise := fall := FALSE;
+IF filteredInput AND NOT memory THEN
+ raise := TRUE;
+ELSIF NOT filteredInput AND memory THEN
+ fall := TRUE;
+END_IF
memory := filteredInput;
@@ -341,13 +341,13 @@ memory := filteredInput;
- output := FALSE;
-IF input AND NOT memory THEN
- IF (TIME() - startTime) > T#100MS AND (TIME() - startTime) < T#800MS THEN
- output := TRUE;
- END_IF;
- startTime := TIME();
-END_IF;
+ output := FALSE;
+IF input AND NOT memory THEN
+ IF (TIME() - startTime) > T#100MS AND (TIME() - startTime) < T#800MS THEN
+ output := TRUE;
+ END_IF;
+ startTime := TIME();
+END_IF;
memory := input;
@@ -428,28 +428,28 @@ memory := input;
- (* ограничим bufferSize в размер буфера *)
-bufferSize := MIN(MAX(bufferSize, 1000), 32);
-(* Инициализация *)
-IF NOT isInitialized OR reset THEN
- isInitialized := TRUE;
- FOR counter := 1 TO bufferSize DO
- buffer[counter] := input;
- END_FOR;
- sum := input * bufferSize;
- output := input;
- RETURN;
-END_IF;
-
-IF counter >= bufferSize THEN
- counter := 1;
-ELSE
- counter := counter + 1;
-END_IF
-
-sum := sum + input - buffer[counter];
-{warning disable C0195}
-output := DWORD_TO_WORD(sum / bufferSize);
+ (* ограничим bufferSize в размер буфера *)
+bufferSize := MIN(MAX(bufferSize, 1000), 32);
+(* Инициализация *)
+IF NOT isInitialized OR reset THEN
+ isInitialized := TRUE;
+ FOR counter := 1 TO bufferSize DO
+ buffer[counter] := input;
+ END_FOR;
+ sum := input * bufferSize;
+ output := input;
+ RETURN;
+END_IF;
+
+IF counter >= bufferSize THEN
+ counter := 1;
+ELSE
+ counter := counter + 1;
+END_IF
+
+sum := sum + input - buffer[counter];
+{warning disable C0195}
+output := DWORD_TO_WORD(sum / bufferSize);
buffer[counter] := input;
@@ -517,22 +517,22 @@ buffer[counter] := input;
- (* Получаем текущее время *)
-currentTime := TIME_TO_DWORD(TIME());
-(* Инициализация *)
-IF NOT isInitialized OR timeInterval = T#0s THEN
- isInitialized := TRUE;
- lastTime := currentTime;
- output := input;
-ELSIF output = input THEN
- lastTime := currentTime;
-ELSE
- tempTime := WORD_TO_DWORD(input - output) * (currentTime - lastTime) /
- TIME_TO_DWORD(timeInterval);
- IF tempTime <> 0 THEN
- output := DINT_TO_WORD(WORD_TO_DINT(output) + DWORD_TO_DINT(tempTime));
- lastTime := currentTime;
- END_IF;
+ (* Получаем текущее время *)
+currentTime := TIME_TO_DWORD(TIME());
+(* Инициализация *)
+IF NOT isInitialized OR timeInterval = T#0s THEN
+ isInitialized := TRUE;
+ lastTime := currentTime;
+ output := input;
+ELSIF output = input THEN
+ lastTime := currentTime;
+ELSE
+ tempTime := WORD_TO_DWORD(input - output) * (currentTime - lastTime) /
+ TIME_TO_DWORD(timeInterval);
+ IF tempTime <> 0 THEN
+ output := DINT_TO_WORD(WORD_TO_DINT(output) + DWORD_TO_DINT(tempTime));
+ lastTime := currentTime;
+ END_IF;
END_IF;
@@ -596,10 +596,10 @@ END_IF;
- IF input AND NOT memory THEN
- startTime := TIME();
-END_IF;
-memory := input;
+ IF input AND NOT memory THEN
+ startTime := TIME();
+END_IF;
+memory := input;
output := input AND ((TIME() - startTime) > pressTime);
@@ -666,12 +666,12 @@ output := input AND ((TIME() - startTime) > pressTime);
- currentTime := TIME();
-IF enable AND NOT memory THEN
- lastTime := currentTime - pulseTime;
-END_IF;
-memory := enable;
-output := currentTime - lastTime >= pulseTime;
+ currentTime := TIME();
+IF enable AND NOT memory THEN
+ lastTime := currentTime - pulseTime;
+END_IF;
+memory := enable;
+output := currentTime - lastTime >= pulseTime;
IF output THEN lastTime := currentTime; END_IF;
@@ -735,16 +735,16 @@ IF output THEN lastTime := currentTime; END_IF;
- (* Если частота ШИМ 0, то прерываем исполнение ФБ *)
-IF frequency <= 0.0 THEN
- output := FALSE;
- RETURN;
-END_IF;
-(* Вычисляем сколько миллисекунд требуется на один цикл ШИМ *)
-tempValue := 1000.0 / frequency;
-(* Запускаем генератор сигналов *)
-clock(pulseTime := REAL_TO_TIME(tempValue));
-(* Создаем выдержанный пульс на нужное время *)
+ (* Если частота ШИМ 0, то прерываем исполнение ФБ *)
+IF frequency <= 0.0 THEN
+ output := FALSE;
+ RETURN;
+END_IF;
+(* Вычисляем сколько миллисекунд требуется на один цикл ШИМ *)
+tempValue := 1000.0 / frequency;
+(* Запускаем генератор сигналов *)
+clock(pulseTime := REAL_TO_TIME(tempValue));
+(* Создаем выдержанный пульс на нужное время *)
pulseTimer(in := clock.output, pt := REAL_TO_TIME(tempValue * dutyCycle), Q => output);
@@ -803,15 +803,15 @@ pulseTimer(in := clock.output, pt := REAL_TO_TIME(tempValue * dutyCycle), Q =>
- (* Если частота ШИМ 0 или время одного цикла меньше,
-чем время для фазы Ton, то прерываем исполнение ФБ *)
-IF frequency <= 0.0 OR (REAL_TO_TIME(1000.0 / frequency) < pulseWidth) THEN
- output := FALSE;
- RETURN;
-END_IF;
-(* Запускаем генератор сигналов *)
-clock(pulseTime := REAL_TO_TIME(1000.0 / frequency));
-(* Создаем выдержанный пульс на нужное время *)
+ (* Если частота ШИМ 0 или время одного цикла меньше,
+чем время для фазы Ton, то прерываем исполнение ФБ *)
+IF frequency <= 0.0 OR (REAL_TO_TIME(1000.0 / frequency) < pulseWidth) THEN
+ output := FALSE;
+ RETURN;
+END_IF;
+(* Запускаем генератор сигналов *)
+clock(pulseTime := REAL_TO_TIME(1000.0 / frequency));
+(* Создаем выдержанный пульс на нужное время *)
pulseTimer(in := clock.output, PT := pulseWidth, Q => output);
@@ -923,16 +923,16 @@ pulseTimer(in := clock.output, PT := pulseWidth, Q => output);
- MIDDAY := SunMidday(longitude, utc);
-b := latitude * 0.0174532925199433;
-dk := 0.40954 * SIN(0.0172 * (UINT_TO_REAL(DayOfYear(utc)) - 79.35));
-SUN_DECLINATION := DegreesToRadians(DK);
-IF SUN_DECLINATION > 180.0 THEN
- SUN_DECLINATION := SUN_DECLINATION - 360.0;
-END_IF;
-SUN_DECLINATION := 90.0 - LATITUDE + SUN_DECLINATION;
-delta := HourToTime(REAL_TO_INT(ACOS((SIN(RadiansToDegrees(H)) - SIN(B) * SIN(DK)) / (COS(B) * COS(DK))) * 3.819718632));
-SUN_RISE := MIDDAY - delta;
+ MIDDAY := SunMidday(longitude, utc);
+b := latitude * 0.0174532925199433;
+dk := 0.40954 * SIN(0.0172 * (UINT_TO_REAL(DayOfYear(utc)) - 79.35));
+SUN_DECLINATION := DegreesToRadians(DK);
+IF SUN_DECLINATION > 180.0 THEN
+ SUN_DECLINATION := SUN_DECLINATION - 360.0;
+END_IF;
+SUN_DECLINATION := 90.0 - LATITUDE + SUN_DECLINATION;
+delta := HourToTime(REAL_TO_INT(ACOS((SIN(RadiansToDegrees(H)) - SIN(B) * SIN(DK)) / (COS(B) * COS(DK))) * 3.819718632));
+SUN_RISE := MIDDAY - delta;
SUN_SET := MIDDAY + delta;
@@ -970,13 +970,13 @@ SUN_SET := MIDDAY + delta;
- position := FIND(ipStr, '.');
-WHILE position > 0 DO
- IpDecode := SHL(IpDecode, 8) OR
- STRING_TO_DWORD(LEFT(ipStr, position - 1));
- ipStr := DELETE(ipStr, position, 1);
- position := FIND(ipStr, '.');
-END_WHILE;
+ position := FIND(ipStr, '.');
+WHILE position > 0 DO
+ IpDecode := SHL(IpDecode, 8) OR
+ STRING_TO_DWORD(LEFT(ipStr, position - 1));
+ ipStr := DELETE(ipStr, position, 1);
+ position := FIND(ipStr, '.');
+END_WHILE;
IpDecode := SHL(IpDecode, 8) OR STRING_TO_DWORD(ipStr);
@@ -1008,10 +1008,10 @@ IpDecode := SHL(IpDecode, 8) OR STRING_TO_DWORD(ipStr);
- Ceil := REAL_TO_DINT(input);
-
-IF DINT_TO_REAL(Ceil) < input THEN
- Ceil := Ceil + 1;
+ Ceil := REAL_TO_DINT(input);
+
+IF DINT_TO_REAL(Ceil) < input THEN
+ Ceil := Ceil + 1;
END_IF;
@@ -1088,17 +1088,17 @@ END_IF;
- sign := power.15;
-power := ABS(power);
-IF power.0 THEN ExpN := input; ELSE ExpN := 1.0; END_IF;
-power := SHR(power, 1);
-
-WHILE power > 0 DO
- input := input * input;
- IF power.0 THEN ExpN := ExpN * input; END_IF;
- power := SHR(power, 1);
-END_WHILE;
-
+ sign := power.15;
+power := ABS(power);
+IF power.0 THEN ExpN := input; ELSE ExpN := 1.0; END_IF;
+power := SHR(power, 1);
+
+WHILE power > 0 DO
+ input := input * input;
+ IF power.0 THEN ExpN := ExpN * input; END_IF;
+ power := SHR(power, 1);
+END_WHILE;
+
IF sign THEN ExpN := 1.0 / ExpN; END_IF;
@@ -1130,9 +1130,9 @@ IF sign THEN ExpN := 1.0 / ExpN; END_IF;
- FLOOR := REAL_TO_DINT(input);
-IF DINT_TO_REAL(FLOOR) > input THEN
- FLOOR := FLOOR - 1;
+ FLOOR := REAL_TO_DINT(input);
+IF DINT_TO_REAL(FLOOR) > input THEN
+ FLOOR := FLOOR - 1;
END_IF;
@@ -1164,10 +1164,10 @@ END_IF;
- IF ABS(input) < 2.0E9 THEN
- FRACT := input - DINT_TO_REAL(DTrunc(input));
-ELSE
- FRACT := 0.0;
+ IF ABS(input) < 2.0E9 THEN
+ FRACT := input - DINT_TO_REAL(DTrunc(input));
+ELSE
+ FRACT := 0.0;
END_IF;
@@ -1207,11 +1207,11 @@ END_IF;
- IF divisor = 0.0 THEN
- MODR := 0.0;
-ELSE
- MODR := input - DINT_TO_REAL(FLOOR(input / divisor)) * divisor;
-END_IF;
+ IF divisor = 0.0 THEN
+ MODR := 0.0;
+ELSE
+ MODR := input - DINT_TO_REAL(FLOOR(input / divisor)) * divisor;
+END_IF;
@@ -1251,7 +1251,7 @@ END_IF;
- Round := DWORD_TO_REAL(REAL_TO_DWORD(input * Exp10(precision))) / Exp10(precision);
+ Round := DWORD_TO_REAL(REAL_TO_DWORD(input * Exp10(precision))) / Exp10(precision);
@@ -1602,10 +1602,10 @@ END_IF;
- IF inputLow = inputHigh THEN
- ScaleReal := outputLow;
-ELSE
- ScaleReal := (outputHigh - outputLow) / (inputHigh - inputLow) * (LIMIT(inputLow, input, inputHigh) - inputLow) + outputLow;
+ IF inputLow = inputHigh THEN
+ ScaleReal := outputLow;
+ELSE
+ ScaleReal := (outputHigh - outputLow) / (inputHigh - inputLow) * (LIMIT(inputLow, input, inputHigh) - inputLow) + outputLow;
END_IF;
@@ -1674,14 +1674,14 @@ END_IF;
- charPointer := ADR(inputString);
-length := LEN(inputString);
-CountChar := 0;
-FOR position := 1 TO length DO
- IF charPointer^ = charToCount THEN
- CountChar := CountChar + 1;
- END_IF;
- charPointer := charPointer + 1;
+ charPointer := ADR(inputString);
+length := LEN(inputString);
+CountChar := 0;
+FOR position := 1 TO length DO
+ IF charPointer^ = charToCount THEN
+ CountChar := CountChar + 1;
+ END_IF;
+ charPointer := charPointer + 1;
END_FOR;
@@ -1738,14 +1738,14 @@ END_FOR;
- tempString := inputString;
-REPEAT
- position := FIND(tempString, substringToRemove);
- IF position <> 0 THEN
- tempString := DELETE(tempString, LEN(substringToRemove), position);
- END_IF;
-UNTIL (position = 0)
-END_REPEAT;
+ tempString := inputString;
+REPEAT
+ position := FIND(tempString, substringToRemove);
+ IF position <> 0 THEN
+ tempString := DELETE(tempString, LEN(substringToRemove), position);
+ END_IF;
+UNTIL (position = 0)
+END_REPEAT;
RemoveSubString := tempString;
@@ -1784,12 +1784,12 @@ RemoveSubString := tempString;
- IF input > 96 AND input < 123 THEN
- ToUpper := input AND 16#DF;
-ELSIF input > 223 AND input <> 247 AND input <> 255 AND useExtendedASCII THEN
- ToUpper := input AND 16#DF;
-ELSE
- ToUpper := input;
+ IF input > 96 AND input < 123 THEN
+ ToUpper := input AND 16#DF;
+ELSIF input > 223 AND input <> 247 AND input <> 255 AND useExtendedASCII THEN
+ ToUpper := input AND 16#DF;
+ELSE
+ ToUpper := input;
END_IF;
@@ -1853,12 +1853,12 @@ END_IF;
- (* Получаем дату строкой 'D#2000-01-01' *)
-sTemp := DATE_TO_STRING(input);
-year := STRING_TO_UINT(MID(sTemp, 3, 4));
-month := STRING_TO_UINT(MID(sTemp, 8, 2));
-day := STRING_TO_UINT(MID(sTemp, 11, 2));
-
+ (* Получаем дату строкой 'D#2000-01-01' *)
+sTemp := DATE_TO_STRING(input);
+year := STRING_TO_UINT(MID(sTemp, 3, 4));
+month := STRING_TO_UINT(MID(sTemp, 8, 2));
+day := STRING_TO_UINT(MID(sTemp, 11, 2));
+
DateToElements := true;
@@ -1896,8 +1896,8 @@ DateToElements := true;
- NumOfDay := DATE_TO_DWORD(input) / 86400;
-NumOfDay := NumOfDay + 3;
+ NumOfDay := DATE_TO_DWORD(input) / 86400;
+NumOfDay := NumOfDay + 3;
DayOfWeek := DWORD_TO_UINT(NumOfDay MOD 7);
@@ -1945,8 +1945,8 @@ DayOfWeek := DWORD_TO_UINT(NumOfDay MOD 7);
- DateToElements(input := input, year => year, month => month, day => day);
-
+ DateToElements(input := input, year => year, month => month, day => day);
+
DayOfYear := DaysTillMonth(year, month) + day;
@@ -1977,10 +1977,10 @@ DayOfYear := DaysTillMonth(year, month) + day;
- IF IsLeapYear(year) THEN
- DaysInYear := 366;
-ELSE
- DaysInYear := 365;
+ IF IsLeapYear(year) THEN
+ DaysInYear := 366;
+ELSE
+ DaysInYear := 365;
END_IF;
@@ -2101,8 +2101,8 @@ END_IF;
- (* Получаем количество лет прошло с 1970го года *)
-year := year - 1970;
+ (* Получаем количество лет прошло с 1970го года *)
+year := year - 1970;
DaysTillYear := year * 365 + ((year + 1) / 4) - ((year + 69) / 100) + ((year + 369) / 400);
@@ -2297,8 +2297,8 @@ DaysTillYear := year * 365 + ((year + 1) / 4) - ((year + 69) / 100) + ((year + 3
- T := UINT_TO_REAL(DayOfYear(utc));
-OFFSET := -0.1752 * SIN(0.033430 * T + 0.5474) - 0.1340 * SIN(0.018234 * T - 0.1939);
+ T := UINT_TO_REAL(DayOfYear(utc));
+OFFSET := -0.1752 * SIN(0.033430 * T + 0.5474) - 0.1340 * SIN(0.018234 * T - 0.1939);
SunMidday := HourToTod(REAL_TO_INT(12.0 - OFFSET - lon * 0.0666666666666));
@@ -2358,11 +2358,11 @@ SunMidday := HourToTod(REAL_TO_INT(12.0 - OFFSET - lon * 0.0666666666666));
- (* Теперь время имеет строку типа 'TOD#12:12:59' *)
-sTemp := TOD_TO_STRING(TIME_TO_TOD(input));
-h := STRING_TO_UINT(MID(sTemp, 5, 2));
-m := STRING_TO_UINT(MID(sTemp, 8, 2));
-sec := STRING_TO_UINT(MID(sTemp, 11, 2));
+ (* Теперь время имеет строку типа 'TOD#12:12:59' *)
+sTemp := TOD_TO_STRING(TIME_TO_TOD(input));
+h := STRING_TO_UINT(MID(sTemp, 5, 2));
+m := STRING_TO_UINT(MID(sTemp, 8, 2));
+sec := STRING_TO_UINT(MID(sTemp, 11, 2));
TimeToElements := TRUE;
@@ -2409,10 +2409,10 @@ TimeToElements := TRUE;
- TodBetween := (
- FromTime > ToTime AND (CurrTime > FromTime OR CurrTime < ToTime)
- ) OR (FromTime < ToTime AND (CurrTime < ToTime AND CurrTime > FromTime)
-);
+ TodBetween := (
+ FromTime > ToTime AND (CurrTime > FromTime OR CurrTime < ToTime)
+ ) OR (FromTime < ToTime AND (CurrTime < ToTime AND CurrTime > FromTime)
+);
@@ -2451,10 +2451,10 @@ TimeToElements := TRUE;
- IF ToTime < FromTime THEN
- TodDiff := T#24H - TOD_TO_TIME(FromTime) + TOD_TO_TIME(ToTime);
-ELSE
- TodDiff := ToTime - FromTime;
+ IF ToTime < FromTime THEN
+ TodDiff := T#24H - TOD_TO_TIME(FromTime) + TOD_TO_TIME(ToTime);
+ELSE
+ TodDiff := ToTime - FromTime;
END_IF
@@ -2485,9 +2485,9 @@ END_IF
- WeekOfYear := ((DayOfYear(currentDate) + 6) / 7);
-IF DayOfWeek(currentDate) < DayOfWeek(YearStarts(currentDate)) THEN
- WeekOfYear := WeekOfYear + 1;
+ WeekOfYear := ((DayOfYear(currentDate) + 6) / 7);
+IF DayOfWeek(currentDate) < DayOfWeek(YearStarts(currentDate)) THEN
+ WeekOfYear := WeekOfYear + 1;
END_IF;
@@ -2528,7 +2528,7 @@ END_IF;
- str := DATE_TO_STRING(currentDate); (* получаем строку `D#2000-12-30` *)
+ str := DATE_TO_STRING(currentDate); (* получаем строку `D#2000-12-30` *)
YearStarts := STRING_TO_DATE(CONCAT(CONCAT('D#', MID(str, 3, 4)), '-01-01'));
@@ -2614,19 +2614,19 @@ YearStarts := STRING_TO_DATE(CONCAT(CONCAT('D#', MID(str, 3, 4)), '-01-01'));
- sTemp := CONCAT('DT#', UINT_TO_STRING(y));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(mn));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(d));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(h));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(m));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(sec));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(ms));
+ sTemp := CONCAT('DT#', UINT_TO_STRING(y));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(mn));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(d));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(h));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(m));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(sec));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(ms));
YmdhmsTodt := STRING_TO_DT(sTemp);
@@ -2680,11 +2680,11 @@ YmdhmsTodt := STRING_TO_DT(sTemp);
- sTemp := CONCAT('D#', UINT_TO_STRING(y));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(m));
-sTemp := CONCAT(sTemp, '-');
-sTemp := CONCAT(sTemp, UINT_TO_STRING(d));
+ sTemp := CONCAT('D#', UINT_TO_STRING(y));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(m));
+sTemp := CONCAT(sTemp, '-');
+sTemp := CONCAT(sTemp, UINT_TO_STRING(d));
YmdToDate := STRING_TO_DATE(sTemp);
@@ -2716,11 +2716,11 @@ YmdToDate := STRING_TO_DATE(sTemp);
- WHILE input > 0 DO
- IF input.0 THEN
- BitCount := BitCount + 1;
- END_IF
- input := SHR(input, 1);
+ WHILE input > 0 DO
+ IF input.0 THEN
+ BitCount := BitCount + 1;
+ END_IF
+ input := SHR(input, 1);
END_WHILE;
@@ -2778,10 +2778,10 @@ END_WHILE;
- IF value THEN
- BitLoadB := input OR SHL(dat, position);
-ELSE
- BitLoadB := input AND (NOT SHL(dat, position));
+ IF value THEN
+ BitLoadB := input OR SHL(dat, position);
+ELSE
+ BitLoadB := input AND (NOT SHL(dat, position));
END_IF;
@@ -2913,13 +2913,13 @@ END_IF;
- tmp := ABS(x);
-IF tmp > 0.0 THEN
- tmp := Exp10(DINT_TO_REAL(FLOOR(LOG(tmp))-n+1));
-ELSE
- tmp := Exp10(tmp);
-END_IF;
-
+ tmp := ABS(x);
+IF tmp > 0.0 THEN
+ tmp := Exp10(DINT_TO_REAL(FLOOR(LOG(tmp))-n+1));
+ELSE
+ tmp := Exp10(tmp);
+END_IF;
+
CompareReals := ABS(x - y) < tmp;
@@ -2951,16 +2951,16 @@ CompareReals := ABS(x - y) < tmp;
- DTrunc := REAL_TO_DINT(input);
-
-IF input > 0.0 THEN
- IF DINT_TO_REAL(DTrunc) > input THEN
- DTrunc := DTrunc - 1;
- END_IF;
-ELSE
- IF DINT_TO_REAL(DTrunc) < input THEN
- DTrunc := DTrunc + 1;
- END_IF;
+ DTrunc := REAL_TO_DINT(input);
+
+IF input > 0.0 THEN
+ IF DINT_TO_REAL(DTrunc) > input THEN
+ DTrunc := DTrunc - 1;
+ END_IF;
+ELSE
+ IF DINT_TO_REAL(DTrunc) < input THEN
+ DTrunc := DTrunc + 1;
+ END_IF;
END_IF;
@@ -3050,20 +3050,20 @@ END_IF;
- tn := TIME_TO_DWORD(TIME());
-tc := BitCount(tn);
-tn.31 := tn.2;
-tn.30 := tn.5;
-tn.29 := tn.4;
-tn.28 := tn.1;
-tn.27 := tn.0;
-tn.26 := tn.7;
-tn.25 := tn.6;
-tn.24 := tn.3;
-tn := ROL(tn, BitCount(tn)) OR 16#80000001;
-tn := tn MOD 71474513 + INT_TO_DWORD(tc + 77);
-Random := FRACT(DWORD_TO_REAL(tn) / 10000000.0 *
-(E - LIMIT(0.0, last, 1.0))
+ tn := TIME_TO_DWORD(TIME());
+tc := BitCount(tn);
+tn.31 := tn.2;
+tn.30 := tn.5;
+tn.29 := tn.4;
+tn.28 := tn.1;
+tn.27 := tn.0;
+tn.26 := tn.7;
+tn.25 := tn.6;
+tn.24 := tn.3;
+tn := ROL(tn, BitCount(tn)) OR 16#80000001;
+tn := tn MOD 71474513 + INT_TO_DWORD(tc + 77);
+Random := FRACT(DWORD_TO_REAL(tn) / 10000000.0 *
+(E - LIMIT(0.0, last, 1.0))
);
@@ -3240,4 +3240,4 @@ Random := FRACT(DWORD_TO_REAL(tn) / 10000000.0 *
-
+
\ No newline at end of file
From cd01f3d222a58ede97c6518c5ded2d4bc0ea815f Mon Sep 17 00:00:00 2001
From: "sergey.glukhov"
Date: Thu, 12 Jun 2025 14:13:58 +0300
Subject: [PATCH 4/6] test
---
AnjLabCodeBox.xml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/AnjLabCodeBox.xml b/AnjLabCodeBox.xml
index e0d3192..fe32fdf 100644
--- a/AnjLabCodeBox.xml
+++ b/AnjLabCodeBox.xml
@@ -1,7 +1,7 @@
-
-
+
+
Helpful ST blocks and functions
@@ -1597,7 +1597,7 @@ END_IF;
- линейное масштабирование числа с плавающей запятой
+ Линейное масштабирование числа с плавающей запятой
From df164cb3572c19fd9c294be6ee14837b96d9229c Mon Sep 17 00:00:00 2001
From: "sergey.glukhov"
Date: Thu, 12 Jun 2025 17:22:02 +0300
Subject: [PATCH 5/6] update
---
.gitignore | 1 +
AnjLabCodeBox.xml | 773 +++++++++++++++++++++++-----------------------
2 files changed, 387 insertions(+), 387 deletions(-)
create mode 100644 .gitignore
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ae0f2e6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+._AnjlabCodeBox.xml
\ No newline at end of file
diff --git a/AnjLabCodeBox.xml b/AnjLabCodeBox.xml
index fe32fdf..eb119c9 100644
--- a/AnjLabCodeBox.xml
+++ b/AnjLabCodeBox.xml
@@ -1,8 +1,8 @@
-
-
- Helpful ST blocks and functions
+
+
+ Comprehensive PLC Utility Library for CoDeSys
@@ -21,14 +21,15 @@
true
Anjlab
ACB
- Helpful ST blocks and functions
+ Comprehensive PLC Utility Library for CoDeSys
reStructuredText
888cbf53-45a1-47de-9a2a-fbd72e84a196
false
qualified-access-only
AnjlabCodeBox
AnjLabCodeBox
- true
+ false
+ https://github.com/anjlab/codebox
false
Anjlab Code Box
3.5.17.1
@@ -48,7 +49,7 @@
- Входной сигнал
+ Input signal
@@ -58,7 +59,7 @@
- Выходной сигнал
+ Output signal
@@ -68,7 +69,7 @@
- Время начала
+ Start time
@@ -76,12 +77,12 @@
- Память сигнала
+ Signal memory
- Сглаживание дискретного сигнала
+ Discrete signal smoothing
@@ -95,7 +96,7 @@ output := input AND ((TIME() - startTime) > T#100ms);
- 95ddd795-0967-4fd1-b39a-104236a6cda9
+ aeabac3a-edf8-4a8d-bfc5-f6579f1a4daf
@@ -107,7 +108,7 @@ output := input AND ((TIME() - startTime) > T#100ms);
- Входной сигнал
+ Input signal
@@ -117,7 +118,7 @@ output := input AND ((TIME() - startTime) > T#100ms);
- Выходной сигнал
+ Output signal
@@ -127,7 +128,7 @@ output := input AND ((TIME() - startTime) > T#100ms);
- Время начала
+ Start time
@@ -135,12 +136,12 @@ output := input AND ((TIME() - startTime) > T#100ms);
- Память сигнала
+ Signal memory
- Сглаживание дискретного сигнала
+ Smoothing of discrete signal
@@ -157,7 +158,7 @@ END_IF
- 55ebab12-5437-4033-a731-b42ecbacfe06
+ ed6dd414-5d7c-46cd-a3e2-dfead0de1e5d
@@ -169,7 +170,7 @@ END_IF
- Входной сигнал
+ Input signal
@@ -179,7 +180,7 @@ END_IF
- Выходной сигнал
+ Output signal
@@ -189,7 +190,7 @@ END_IF
- Время начала
+ Start time
@@ -197,12 +198,12 @@ END_IF
- Память сигнала
+ Signal memory
- Сглаживание дискретного сигнала
+ Smoothing of discrete signal
@@ -219,7 +220,7 @@ END_IF
- 30d49b21-1ce3-4ef8-883d-665f4a788870
+ 1185b75f-604d-4aa1-a1ea-6afa899718f0
@@ -231,7 +232,7 @@ END_IF
- Входной сигнал
+ Input signal
@@ -241,7 +242,7 @@ END_IF
- Передний фронт
+ Rising edge
@@ -249,7 +250,7 @@ END_IF
- Задний фронт
+ Falling edge
@@ -264,7 +265,7 @@ END_IF
- Отфильтрованный вход
+ Filtered input
@@ -274,7 +275,7 @@ END_IF
- выделяет передний и задний фронт с фильтром на 100 миллисекунд
+ Detects rising and falling edges with a 100 millisecond filter
@@ -291,7 +292,7 @@ memory := filteredInput;
- 576b0ef3-7dfb-44b9-9d4d-f7a2f2158045
+ f0c530e2-1802-4730-a7c1-9e5a02094132
@@ -303,7 +304,7 @@ memory := filteredInput;
- Входной сигнал
+ Input signal
@@ -313,7 +314,7 @@ memory := filteredInput;
- Выходной сигнал
+ Output signal
@@ -323,7 +324,7 @@ memory := filteredInput;
- Время начала
+ Start time
@@ -331,12 +332,12 @@ memory := filteredInput;
- Память сигнала
+ Signal memory
- Двойной клик
+ Double click
@@ -353,7 +354,7 @@ memory := input;
- d3ac0715-866a-45c1-a900-b774b7c5c01c
+ d6c942b4-f877-45a8-aaa5-9840654778e6
@@ -365,7 +366,7 @@ memory := input;
- Входное значение
+ Input value
@@ -373,7 +374,7 @@ memory := input;
- Размер буфера минимум 32 максимум 1000
+ Buffer size minimum 32 maximum 1000
@@ -381,7 +382,7 @@ memory := input;
- Сброс буфера
+ Reset buffer
@@ -391,7 +392,7 @@ memory := input;
- Выходное отфильтрованное значение
+ Filtered output value
@@ -423,14 +424,14 @@ memory := input;
- Эта функция хранит до 32-х значений в буфере и выдает среднее значение. Вы сами можете решить, сколько значений сохранить для получения среднего числа.
+ This function stores up to 32 values in a buffer and outputs the average value. You can decide how many values to store to get the average number.
- (* ограничим bufferSize в размер буфера *)
+ // limit the bufferSize
bufferSize := MIN(MAX(bufferSize, 1000), 32);
-(* Инициализация *)
+// Initialize
IF NOT isInitialized OR reset THEN
isInitialized := TRUE;
FOR counter := 1 TO bufferSize DO
@@ -455,7 +456,7 @@ buffer[counter] := input;
- 23da4515-91ff-492f-bd6c-a924c27cb1b0
+ 216bb070-e763-45f3-ab22-f6ba447a7047
@@ -467,7 +468,7 @@ buffer[counter] := input;
- Входное значение
+ Input value
@@ -475,7 +476,7 @@ buffer[counter] := input;
- Временной интервал
+ Time interval
@@ -485,7 +486,7 @@ buffer[counter] := input;
- Выходное отфильтрованное значение
+ Filtered output value
@@ -512,14 +513,13 @@ buffer[counter] := input;
- возвращает среднее значение за определенный промежуток времени.
+ Returns the average value over a specified time interval.
- (* Получаем текущее время *)
-currentTime := TIME_TO_DWORD(TIME());
-(* Инициализация *)
+ currentTime := TIME_TO_DWORD(TIME());
+// Initialize
IF NOT isInitialized OR timeInterval = T#0s THEN
isInitialized := TRUE;
lastTime := currentTime;
@@ -538,7 +538,7 @@ END_IF;
- cc4d134d-f449-4f06-8605-2d943310a473
+ b0642b57-9ee0-4a1f-a6aa-0d37014eaf0e
@@ -550,7 +550,7 @@ END_IF;
- Входной сигнал
+ Input signal
@@ -558,7 +558,7 @@ END_IF;
- Время нажатия
+ Press time
@@ -568,7 +568,7 @@ END_IF;
- Выходной сигнал
+ Output signal
@@ -578,7 +578,7 @@ END_IF;
- Время начала
+ Start time
@@ -586,12 +586,12 @@ END_IF;
- Память сигнала
+ Signal memory
- Долгий клик
+ Long click
@@ -605,7 +605,7 @@ output := input AND ((TIME() - startTime) > pressTime);
- e847a08d-2858-49e0-b6fb-cbe441c3349b
+ 65c343db-a1af-4db4-a7ad-a65316c3f838
@@ -617,7 +617,7 @@ output := input AND ((TIME() - startTime) > pressTime);
- Запуск генератора
+ Start generator
@@ -628,7 +628,7 @@ output := input AND ((TIME() - startTime) > pressTime);
- Время импульсов
+ Pulse time
@@ -638,7 +638,7 @@ output := input AND ((TIME() - startTime) > pressTime);
- Выходной сигнал
+ Output signal
@@ -660,8 +660,8 @@ output := input AND ((TIME() - startTime) > pressTime);
- создает импульсы с заданной частотой
- CLK_PWM(EN := TRUE, PT := T#5ms); На выходе Q будет импульс в один цикл ПЛК, раз в 5 миллисекунд.
+ Creates pulses with specified frequency
+ PwmClock(enable := TRUE, pulseTime := T#5ms); Output Q will have one PLC cycle pulse every 5 milliseconds.
@@ -677,7 +677,7 @@ IF output THEN lastTime := currentTime; END_IF;
- e2565834-4fd9-4a85-b9e7-a4c45a2b4e0b
+ 69fbfb76-4eb7-4d83-95c1-21404034352c
@@ -689,7 +689,7 @@ IF output THEN lastTime := currentTime; END_IF;
- Частота, раз в секунду (Гц)
+ Frequency, times per second (Hz)
@@ -697,7 +697,7 @@ IF output THEN lastTime := currentTime; END_IF;
- Соотношение
+ Duty cycle
@@ -707,7 +707,7 @@ IF output THEN lastTime := currentTime; END_IF;
- Выходной сигнал
+ Output signal
@@ -729,28 +729,28 @@ IF output THEN lastTime := currentTime; END_IF;
- создает ШИМ-сигнал заданной частоты со смещением соотношения. Каждый цик ШИМ можно разделить на 2 фазы: Ton (время включения) и Toff (время выключения).
- Соотношение задается от 0 до 1. Например, соотношение 0.5 разделит время каждого цикла шим на 50% на Ton и 50% на Toff .
+ creates a PWM signal of a given frequency with a ratio offset. Each PWM cycle can be divided into 2 phases: Ton (on time) and Toff (off time).
+ The ratio is set from 0 to 1. For example, a ratio of 0.5 will divide the time of each PWM cycle into 50% for Ton and 50% for Toff .
- (* Если частота ШИМ 0, то прерываем исполнение ФБ *)
+ // If the PWM frequency is 0, then we interrupt the execution of the FB
IF frequency <= 0.0 THEN
output := FALSE;
RETURN;
END_IF;
-(* Вычисляем сколько миллисекунд требуется на один цикл ШИМ *)
+// Calculate how many milliseconds are required for one PWM cycle
tempValue := 1000.0 / frequency;
-(* Запускаем генератор сигналов *)
+// Launching the signal generator
clock(pulseTime := REAL_TO_TIME(tempValue));
-(* Создаем выдержанный пульс на нужное время *)
+// We create a sustained pulse for the required time
pulseTimer(in := clock.output, pt := REAL_TO_TIME(tempValue * dutyCycle), Q => output);
- 55fa2adc-b14d-4d49-a0d3-ee6618946ede
+ b2c549b4-3ee4-4a60-a429-c5dda1b73017
@@ -762,7 +762,7 @@ pulseTimer(in := clock.output, pt := REAL_TO_TIME(tempValue * dutyCycle), Q =>
- Частота, раз в секунду (Гц)
+ Frequency (Hz)
@@ -770,7 +770,7 @@ pulseTimer(in := clock.output, pt := REAL_TO_TIME(tempValue * dutyCycle), Q =>
- Длина фазы Ton
+ Ton phase length
@@ -780,7 +780,7 @@ pulseTimer(in := clock.output, pt := REAL_TO_TIME(tempValue * dutyCycle), Q =>
- Выходной сигнал
+ Output signal
@@ -797,58 +797,57 @@ pulseTimer(in := clock.output, pt := REAL_TO_TIME(tempValue * dutyCycle), Q =>
- Создает ШИМ-сигнал с заданным временем фазы Ton . Например, мы можем установить F на 100 раз в секунду. Это значит, один цикл ШИМ будет 10
- миллисекунд. Теперь поставим PW в T#5ms и получим равное время для фазы Ton и Toff по 50%.
+ Creates PWM signal with specified Ton phase time. For example, we can set F to 100 times per second. This means one PWM cycle will be 10
+ milliseconds. Now if we set PW to T#5ms, we'll get equal time for Ton and Toff phases at 50%.
- (* Если частота ШИМ 0 или время одного цикла меньше,
-чем время для фазы Ton, то прерываем исполнение ФБ *)
+ // If the PWM frequency is 0 or the time of one cycle is less than the time for the Ton phase, then we interrupt the execution of the FB
IF frequency <= 0.0 OR (REAL_TO_TIME(1000.0 / frequency) < pulseWidth) THEN
output := FALSE;
RETURN;
END_IF;
-(* Запускаем генератор сигналов *)
+// Start the signal generator
clock(pulseTime := REAL_TO_TIME(1000.0 / frequency));
-(* Создаем выдержанный пульс на нужное время *)
+// We create a sustained pulse for the required time
pulseTimer(in := clock.output, PT := pulseWidth, Q => output);
- ff93b01a-c5fb-4d17-a425-8e834ffc249d
+ 453b2034-7959-4690-aff2-788eefb570f6
-
+
-
+
- Широта
+ Latitude
-
+
- Долгота
+ Longitude
-
+
- Текущее время в UTC
+ Current time in UTC
-
+
@@ -856,41 +855,41 @@ pulseTimer(in := clock.output, PT := pulseWidth, Q => output);
- Градус над горизонтом, при котором уже считается наступление заката или восхода
+ Degree above horizon at which sunset or sunrise is considered to occur
-
+
- Время дня солнцестояния
+ Time of solar noon
-
+
- Время восхода
+ Sunrise time
-
+
- Время заката
+ Sunset time
-
+
- Угол наклона солнца в солнцестояние в градусах
+ Sun declination angle at solar noon in degrees
@@ -900,7 +899,7 @@ pulseTimer(in := clock.output, PT := pulseWidth, Q => output);
- Угол наклона солнца в полдень в радианах
+ Sun declination angle at noon in radians
@@ -908,7 +907,7 @@ pulseTimer(in := clock.output, PT := pulseWidth, Q => output);
- Дельта от солнцестояния до восхода или заката
+ Time delta from solar noon to sunrise or sunset
@@ -918,27 +917,27 @@ pulseTimer(in := clock.output, PT := pulseWidth, Q => output);
- расчет времени заката и восхода
+ Calculate sunset and sunrise times
- MIDDAY := SunMidday(longitude, utc);
+ midday := SunMidday(longitude, currentTime);
b := latitude * 0.0174532925199433;
-dk := 0.40954 * SIN(0.0172 * (UINT_TO_REAL(DayOfYear(utc)) - 79.35));
-SUN_DECLINATION := DegreesToRadians(DK);
-IF SUN_DECLINATION > 180.0 THEN
- SUN_DECLINATION := SUN_DECLINATION - 360.0;
+dk := 0.40954 * SIN(0.0172 * (UINT_TO_REAL(DayOfYear(currentTime)) - 79.35));
+sunDeclination := DegreesToRadians(DK);
+IF sunDeclination > 180.0 THEN
+ sunDeclination := sunDeclination - 360.0;
END_IF;
-SUN_DECLINATION := 90.0 - LATITUDE + SUN_DECLINATION;
-delta := HourToTime(REAL_TO_INT(ACOS((SIN(RadiansToDegrees(H)) - SIN(B) * SIN(DK)) / (COS(B) * COS(DK))) * 3.819718632));
-SUN_RISE := MIDDAY - delta;
-SUN_SET := MIDDAY + delta;
+sunDeclination := 90.0 - latitude + sunDeclination;
+delta := HourToTime(REAL_TO_INT(ACOS((SIN(RadiansToDegrees(h)) - SIN(b) * SIN(dk)) / (COS(b) * COS(dk))) * 3.819718632));
+sunRise := midday - delta;
+sunSet := midday + delta;
- c0162500-a121-4d9a-a1ba-5801e54027bc
+ cce3bab6-f4dc-4237-acc9-88ac792521e0
@@ -953,7 +952,7 @@ SUN_SET := MIDDAY + delta;
- IP-адрес как строка, например, '192.168.1.2'
+ IP address as string, for example, '192.168.1.2'
@@ -965,7 +964,7 @@ SUN_SET := MIDDAY + delta;
- Преобразование в шестнадцатеричный формат для записи IP
+ Convert IP address to hexadecimal format
@@ -982,7 +981,7 @@ IpDecode := SHL(IpDecode, 8) OR STRING_TO_DWORD(ipStr);
- 370b1e33-b130-432d-82c0-d0ff7d197d76
+ 5816bee8-262c-48e8-8b13-2203371ffb56
@@ -997,12 +996,12 @@ IpDecode := SHL(IpDecode, 8) OR STRING_TO_DWORD(ipStr);
- Входное значение
+ Input value
- Округляет значение и возвращает ближайшее целое значение, которое больше или равно X.
+ Rounds the value and returns the nearest integer value that is greater than or equal to X.
ceil(3.14) = 4 ceil(-3.14) = -3
@@ -1017,7 +1016,7 @@ END_IF;
- 7e9d7ee0-507a-40bb-a5cb-1802edf09ecc
+ 78816cb7-8bcc-46ba-a32f-d1dc6fe2b231
@@ -1032,12 +1031,12 @@ END_IF;
- Входное значение
+ Input value
- Вычисляет с основанием степени 10.
+ Calculates with base 10 to the power.
exp10(2) = 100 exp10(3) = 1000
@@ -1048,7 +1047,7 @@ END_IF;
@@ -1104,7 +1103,7 @@ IF sign THEN ExpN := 1.0 / ExpN; END_IF;
@@ -1287,7 +1286,7 @@ END_IF;
@@ -1330,7 +1329,7 @@ END_IF;
@@ -1360,7 +1359,7 @@ END_IF;
@@ -1390,7 +1389,7 @@ END_IF;
@@ -1433,7 +1432,7 @@ END_IF;
@@ -1463,7 +1462,7 @@ END_IF;
@@ -1493,7 +1492,7 @@ END_IF;
@@ -1545,7 +1544,7 @@ END_IF;
@@ -1611,7 +1610,7 @@ END_IF;
@@ -1687,7 +1686,7 @@ END_FOR;
@@ -1751,7 +1750,7 @@ RemoveSubString := tempString;
@@ -1795,7 +1794,7 @@ END_IF;
- (* Получаем дату строкой 'D#2000-01-01' *)
+ // Get date as a string like 'D#2000-01-01'
sTemp := DATE_TO_STRING(input);
year := STRING_TO_UINT(MID(sTemp, 3, 4));
month := STRING_TO_UINT(MID(sTemp, 8, 2));
@@ -1864,7 +1863,7 @@ DateToElements := true;
@@ -1903,7 +1902,7 @@ DayOfWeek := DWORD_TO_UINT(NumOfDay MOD 7);
@@ -1952,7 +1951,7 @@ DayOfYear := DaysTillMonth(year, month) + day;
@@ -1986,7 +1985,7 @@ END_IF;
@@ -2076,7 +2075,7 @@ END_IF;
- (* Получаем количество лет прошло с 1970го года *)
+ // We get the number of years that have passed since 1970
year := year - 1970;
DaysTillYear := year * 365 + ((year + 1) / 4) - ((year + 69) / 100) + ((year + 369) / 400);
@@ -2162,7 +2161,7 @@ DaysTillYear := year * 365 + ((year + 1) / 4) - ((year + 69) / 100) + ((year + 3
@@ -2192,7 +2191,7 @@ DaysTillYear := year * 365 + ((year + 1) / 4) - ((year + 69) / 100) + ((year + 3
@@ -2222,7 +2221,7 @@ DaysTillYear := year * 365 + ((year + 1) / 4) - ((year + 69) / 100) + ((year + 3
@@ -2252,7 +2251,7 @@ DaysTillYear := year * 365 + ((year + 1) / 4) - ((year + 69) / 100) + ((year + 3
- T := UINT_TO_REAL(DayOfYear(utc));
-OFFSET := -0.1752 * SIN(0.033430 * T + 0.5474) - 0.1340 * SIN(0.018234 * T - 0.1939);
-SunMidday := HourToTod(REAL_TO_INT(12.0 - OFFSET - lon * 0.0666666666666));
+ t := UINT_TO_REAL(DayOfYear(dateInUtc));
+offset := -0.1752 * SIN(0.033430 * T + 0.5474) - 0.1340 * SIN(0.018234 * T - 0.1939);
+SunMidday := HourToTod(REAL_TO_INT(12.0 - offset - longitude * 0.0666666666666));
- (* Теперь время имеет строку типа 'TOD#12:12:59' *)
+ // Now the time is a string like 'TOD#12:12:59'
sTemp := TOD_TO_STRING(TIME_TO_TOD(input));
h := STRING_TO_UINT(MID(sTemp, 5, 2));
m := STRING_TO_UINT(MID(sTemp, 8, 2));
@@ -2368,7 +2367,7 @@ TimeToElements := TRUE;
@@ -2418,7 +2417,7 @@ TimeToElements := TRUE;
@@ -2460,7 +2459,7 @@ END_IF
@@ -2493,7 +2492,7 @@ END_IF;
- str := DATE_TO_STRING(currentDate); (* получаем строку `D#2000-12-30` *)
+ str := DATE_TO_STRING(currentDate);
YearStarts := STRING_TO_DATE(CONCAT(CONCAT('D#', MID(str, 3, 4)), '-01-01'));
@@ -2632,7 +2631,7 @@ YmdhmsTodt := STRING_TO_DT(sTemp);
@@ -2690,7 +2689,7 @@ YmdToDate := STRING_TO_DATE(sTemp);
@@ -2726,7 +2725,7 @@ END_WHILE;
@@ -2825,7 +2824,7 @@ END_IF;
@@ -2863,7 +2862,7 @@ END_IF;
@@ -2925,7 +2924,7 @@ CompareReals := ABS(x - y) < tmp;
@@ -2966,7 +2965,7 @@ END_IF;
@@ -2996,7 +2995,7 @@ END_IF;
@@ -3069,7 +3068,7 @@ Random := FRACT(DWORD_TO_REAL(tn) / 10000000.0 *
@@ -3099,7 +3098,7 @@ Random := FRACT(DWORD_TO_REAL(tn) / 10000000.0 *
@@ -3129,7 +3128,7 @@ Random := FRACT(DWORD_TO_REAL(tn) / 10000000.0 *