Страница 64 из 64 ПерваяПервая ... 1454626364
Показано с 631 по 639 из 639

Тема: Создать функцию на ST

  1. #631

    По умолчанию

    Цитата Сообщение от zjWlad Посмотреть сообщение
    Кстати, при последовательном вычислении членов ряда ошибка не возникает. Значение функций SIN_Rad и SIN_Rad2 практически совпадают. По данным fSUB разность 5.96E-8 отмечается лишь на некоторых углах (+/- 50, 245, 255 … - проверял через 5 градусов)). Извиняюсь за грубое редактирование (только для примера).
    Вас не смущает, что добавив цикл вы только усложнили функцию циклом, ничего не улучшив,
    точность не лучше, на 90 и 270 градусах не работает, длительность цикла ПР выросла (по этой причине и отказался от рядов Тейлора). Какой смысл тогда?
    Моя доработка хотя бы исправила работу на 90 и 270 градусах.
    Последний раз редактировалось kondor3000; 10.02.2026 в 08:37.

  2. #632

    По умолчанию

    kondor3000.
    Я действительно поспешил и ошибся в тестировании. Похоже в SIN_Rad ошибка спрятана в выражении:
    b:=(Pi-a) * (bool_to_real(a>1.5707964))+a * bool_to_real(not(a>=1.5707964)) ; // 1,5707964
    Именно оно обращается в ноль при 1,5707964.
    Ну а пятикратный вызов простеньких выражений оформленный в виде цикла скорее всего не тяжелее пятикратного вызова pow()
    ( pow() во все времена была более тяжелой и часто менее точной чем арифметические операции, но возможно в Logic и не так).

  3. #633

    По умолчанию

    kondor3000.
    1 Похоже для устранения ошибки в SIN_Rad в выражении для b надо заменить сравнение «больше или равно»
    на просто «больше», т.е. как то так:
    b:=(Pi-a) * (bool_to_real(a>1.5707964))+a * bool_to_real(not(a>1.5707964)) ; // 1,5707964
    2 В исправленной функции (из-за того что сравнение для исключения проводилось с входным аргументом
    а не преобразованным значением) были исключены только четыре точки. А их гораздо больше, например,
    минус 4,712389, минус 7,853982 и т.п. Можно конечно оговорить область определения, но …

    Вы автор – Вам виднее.

  4. #634

    По умолчанию

    Цитата Сообщение от zjWlad Посмотреть сообщение
    kondor3000.
    1 Похоже для устранения ошибки в SIN_Rad в выражении для b надо заменить сравнение «больше или равно»
    на просто «больше», т.е. как то так:
    b:=(Pi-a) * (bool_to_real(a>1.5707964))+a * bool_to_real(not(a>1.5707964)) ; // 1,5707964
    2 В исправленной функции (из-за того что сравнение для исключения проводилось с входным аргументом
    а не преобразованным значением) были исключены только четыре точки. А их гораздо больше, например,
    минус 4,712389, минус 7,853982 и т.п. Можно конечно оговорить область определения, но …

    Вы автор – Вам виднее.
    А вот это хорошая мысль, достаточно убрать = и оставить > и всё работает правильно во всех точках.
    И я не автор, всего лишь переписал на ST функции и астротаймер с форума.

  5. #635

    По умолчанию

    Приветствую! Прошу помощи с написанием на ST алгоритма:
    1. Алгоритм активен при активном входе "1"
    2. При активации входа "2" (активация по переднему фронту) запускать алгоритм:
    а) открываем выход "1" на время "т1"
    б) закрываем выход "1", ждем время "т2"
    в) открываем выход "2" на время "т1"
    г) закрываем выход "2", ждем время "т2"
    ... и т.д. до последнего выхода
    При повторной активации входа "2" цикл перебора выходов не должен прерываться! Выход из цикла только по прерыванию сигнала на вход "1".

  6. #636

    По умолчанию

    Цитата Сообщение от WKD Посмотреть сообщение
    Приветствую! Прошу помощи с написанием на ST алгоритма:
    1. Алгоритм активен при активном входе "1"
    2. При активации входа "2" (активация по переднему фронту) запускать алгоритм:
    а) открываем выход "1" на время "т1"
    б) закрываем выход "1", ждем время "т2"
    в) открываем выход "2" на время "т1"
    г) закрываем выход "2", ждем время "т2"
    ... и т.д. до последнего выхода
    При повторной активации входа "2" цикл перебора выходов не должен прерываться! Выход из цикла только по прерыванию сигнала на вход "1".
    Сколько всего выходов не написали, какое время тоже!
    Вот пример, на 80% выполняет ваши задачи, Шаги Case_State https://owen.ru/forum/showthread.php...39&page=43#424, выход сделать Битовой маской, для включения нужных выходов.
    или отсюда Шаговик, тоже немного переделать https://owen.ru/forum/showthread.php...39&page=11#105
    Последний раз редактировалось kondor3000; 04.03.2026 в 10:13.

  7. #637

    По умолчанию

    Цитата Сообщение от kondor3000 Посмотреть сообщение
    Сколько всего выходов не написали, какое время тоже!
    Значение времени в данном случае не принципиально, как и количество выходов. Главное сам алгоритм понять как должен работать. За примеры спасибо, буду изучать и думать.

  8. #638

    По умолчанию

    Код:
    function_block func
        
        var_input
            Stop, Start : bool;
        end_var
        
        var_output 
            Q1, Q2, Q3, Q4, Q5 : bool;
        end_var
        
        var 
            tmr : SYS.TON;
            Q : bool;
            nQ : udint;
        end_var
    
        if Start and nQ = 0 then nQ := 1; Q := true; end_if     // Пуск алгоритма
        if Not Stop then nQ := 0; Q := false; end_if            // Стоп алгоритма
        if Q then tmr.T := T#1s; else tmr.T := T#2s; end_if     // Выдача - 1s, пауза - 2s 
    
        tmr(I := nQ > 0);   // Отсчёт времени
        if tmr.Q then       // Смена состояния выхода
            Q := not Q; tmr(I := false);
            if Q then       // Смена выхода
                nQ := nQ + 1; if nQ > 5 then nQ := 0; end_if
            end_if
        end_if
     
        Q1 := Q and nQ = 1;
        Q2 := Q and nQ = 2;
        Q3 := Q and nQ = 3;
        Q4 := Q and nQ = 4;
        Q5 := Q and nQ = 5;
    
    end_function_block

  9. #639

    По умолчанию

    Цитата Сообщение от EFrol Посмотреть сообщение
    Код:
    function_block func
        
        var_input
            Stop, Start : bool;
        end_var
        
        var_output 
            Q1, Q2, Q3, Q4, Q5 : bool;
        end_var
        
        var 
            tmr : SYS.TON;
            Q : bool;
            nQ : udint;
        end_var
    
        if Start and nQ = 0 then nQ := 1; Q := true; end_if     // Пуск алгоритма
        if Not Stop then nQ := 0; Q := false; end_if            // Стоп алгоритма
        if Q then tmr.T := T#1s; else tmr.T := T#2s; end_if     // Выдача - 1s, пауза - 2s 
    
        tmr(I := nQ > 0);   // Отсчёт времени
        if tmr.Q then       // Смена состояния выхода
            Q := not Q; tmr(I := false);
            if Q then       // Смена выхода
                nQ := nQ + 1; if nQ > 5 then nQ := 0; end_if
            end_if
        end_if
     
        Q1 := Q and nQ = 1;
        Q2 := Q and nQ = 2;
        Q3 := Q and nQ = 3;
        Q4 := Q and nQ = 4;
        Q5 := Q and nQ = 5;
    
    end_function_block
    Благодарю! Очень красивое решение! Глядя на свой код в 100+ строк, понимаю что нужно расти.

Страница 64 из 64 ПерваяПервая ... 1454626364

Похожие темы

  1. Ответов: 14
    Последнее сообщение: 01.07.2023, 21:30
  2. Ответов: 6
    Последнее сообщение: 22.12.2021, 10:50
  3. Ответов: 3
    Последнее сообщение: 13.09.2021, 13:31
  4. ПЛК160. Чем заменить функцию записи 0x05?
    от FallenDAY в разделе ПЛК1хх
    Ответов: 4
    Последнее сообщение: 26.08.2017, 13:19
  5. Как написать собственную функцию wait()
    от PavelKazakov в разделе ПЛК1хх
    Ответов: 3
    Последнее сообщение: 23.07.2009, 11:37

Метки этой темы

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •