Страница 2 из 4 ПерваяПервая 1234 ПоследняяПоследняя
Показано с 11 по 20 из 34

Тема: Функциональный блок для работы ПЛК100_24_Р_М и аналитическими весами

  1. #11

    По умолчанию

    Доброго времени! Связался с представителем данных весов, они заявили, что моя модель не имеет функции по передачи данных по регистрам. Они работают по простому ASCII-протоколу через RS-232. Нет адресов регистров, нет функций чтения/записи по адресу.
    Обмен происходит только текстовыми командами и ответами. Но есть возможность написать код на ПЛК для создании виртуального регистра. В связи с чем у меня вопрос о том, насколько это сложно и существуют ли примеры, которые были похожи?

  2. #12

    По умолчанию

    Цитата Сообщение от What_is_up Посмотреть сообщение
    Доброго времени! Связался с представителем данных весов, они заявили, что моя модель не имеет функции по передачи данных по регистрам. Они работают по простому ASCII-протоколу через RS-232. Нет адресов регистров, нет функций чтения/записи по адресу.
    Обмен происходит только текстовыми командами и ответами. Но есть возможность написать код на ПЛК для создании виртуального регистра. В связи с чем у меня вопрос о том, насколько это сложно и существуют ли примеры, которые были похожи?
    Где описание команд, и пример что должны ответить весы ?

  3. #13

    По умолчанию

    [Префикс][Знак][Значение][Единица] N - неттон; Знак - +/-; Значение - выравнено пробелами: 2.190; Единица - g. ПРИМЕР: N1 2.190 g Запрашивать данные по кнопке PRINT
    Последний раз редактировалось What_is_up; 04.02.2026 в 16:41.

  4. #14
    Пользователь
    Регистрация
    27.11.2011
    Адрес
    Краснодар
    Сообщений
    13,157

    По умолчанию

    документ от весов запросите, где все это расписано, а не вашими вот словами. Тут все слушали Шаляпина, петь не умеет (Рабинович напел)

  5. #15

    По умолчанию

    What_is_up, работать с COM портом на ПЛК в CODESYS не доводилось.
    А по организации разбора строк я бы сделал посимвольный приём и обработку при помощи конечного автомата на CASE с состояниями:
    1 ожидание заголовка "N"
    2 ожидание знака
    3 ожидание и приём пробелов
    4 ожидание, приём и преобразование символов цифр в целую часть числа - заканчивается приёмом точки
    5 ожидание, приём и преобразование символов цифр в дробную часть числа - заканчивается приёмом пробела
    6 ожидание символа единицы измерения "g"

    Если какой-то шаг выполняется долго, то считаем строку "битой" и переходим к п.1 - ждать хорошую следующую
    Если принято что-то не то - также всё бросаем.

    Период между получением символа можно оценить просто:
    - на один символ отправляется 8 бит данных и 2 бита служебной информации
    - скорость обмена 9600 бит/с, т.е. 960 байт/с - т.е. между приёмом символов пройдёт чуть больше 1 мс - Нужно посмотреть длительность машинного цикла ПЛК и, возможно, обрабатывать не в прерываниях, а в основной программе
    Если по аппаратной части я и заблуждаюсь, то не очень сильно.


    Строку в число преобразовать очень просто.
    Наверное в библиотеках что-то есть, может в библиотеке OSCAT...
    А если нет, то по мере реализации ещё раз задайте вопрос - преобразование строки в число очень простое, кто-нибудь подскажет.
    Я бы не ждал приёма всей строки и по мере получения цифр собирал бы число, да и строку бы нигде не хранил. Но с этим поступите как решите.

  6. #16
    Пользователь
    Регистрация
    27.11.2011
    Адрес
    Краснодар
    Сообщений
    13,157

    По умолчанию

    Много написали. Нужен буфер на 2-3 объема данных. Как вариант ожидание тишины ещё.
    Приняли толпу, потом ищем.

  7. #17

    По умолчанию

    Цитата Сообщение от melky Посмотреть сообщение
    Много написали. Нужен буфер на 2-3 объема данных. Как вариант ожидание тишины ещё.
    Приняли толпу, потом ищем.
    Думаю, буфер требуется при приёме массы важных данных (чисел), когда ошибочность принятого пакета будет проверяться после принятия самого последнего байта.
    А в этом случае принимается всего одно число - временная переменная, в которой будет накапливаться результат - и станет буфером на одно значение. После приёма завершающего байта (символа 'g') значение из этого "как-бы"-буфера будет переписано в заданную переменную из основной программы.

    Т.е. буфер как бы и есть, но не для накопления строк - обработка в потоке.
    Разве только на период отладки ещё выполнять запись в циклический буфер - для визуализации, но не для обработки.

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

    Есть много задач, для решения которых не нужно хранить полностью все данные
    https://acmp.ru/index.asp?main=task&id_task=694
    https://informatics.msk.ru/mod/state...hapterid=915#1
    https://acmp.ru/index.asp?main=task&id_task=120
    Думаю, это одна из них

  8. #18
    Пользователь
    Регистрация
    27.11.2011
    Адрес
    Краснодар
    Сообщений
    13,157

    По умолчанию

    Ну, "бумажки" я так и не увидел.

  9. #19

    По умолчанию

    Здравствуйте! Я пытался найти этот файл, но к сожалению с этим есть трудности. Жду ответа от своего друга из Германии, где в течении месяца попытается связаться с местными представителями и заполучить необходимую информацию. Я попробовал через GPT получить приемлемый код на языке ST чтоб опробовать, но у меня есть большие сомнения, так как он вероятно неправильно написал код. Если вас это не затруднит, не могли бы вы проверить и указать на ошибки, чтоб я смог исправить?

    // ===== FB_WeightParser_ATL =====
    FUNCTION_BLOCK FB_WeightParser_ATL

    TYPE E_PARSE_STATE :
    (
    WAIT_N,
    WAIT_SIGN,
    SKIP_SPACES,
    READ_INT_PART,
    READ_FRAC_PART,
    WAIT_UNIT_G
    );
    END_TYPE

    VAR_INPUT
    Enable : BOOL; // Включить парсинг
    InputChar : BYTE; // Символ от GETBYTE
    CharValid : BOOL; // TRUE, если пришёл новый символ
    END_VAR

    VAR_OUTPUT
    WeightValue : REAL; // Принятое значение (в граммах)
    NewWeightValid : BOOL; // Триггер: TRUE на 1 цикл при успешном приёме
    State : E_PARSE_STATE; // Для отладки
    END_VAR

    VAR
    Sign : REAL := 1.0;
    WeightInt : REAL := 0.0;
    WeightFrac : REAL := 0.0;
    FracDiv : REAL := 10.0;
    LastCharTime : TIME := T#0ms;
    END_VAR

    // --- Тело FB ---
    NewWeightValid := FALSE;

    IF NOT Enable THEN
    State := WAIT_N;
    RETURN;
    END_IF;

    // Обновление таймера активности (предполагается вызов каждые ~1 мс)
    IF CharValid THEN
    LastCharTime := T#0ms;
    ELSE
    LastCharTime := LastCharTime + T#1ms;
    END_IF;

    // Тайм-аут: если >5 мс без символов — сброс
    IF LastCharTime > T#5ms THEN
    State := WAIT_N;
    RETURN;
    END_IF;

    // Обработка только при наличии нового символа
    IF NOT CharValid THEN
    RETURN;
    END_IF;

    // --- Конечный автомат ---
    CASE State OF

    WAIT_N:
    IF InputChar = 78 (* 'N' *) THEN
    State := WAIT_SIGN;
    Sign := 1.0;
    WeightInt := 0.0;
    WeightFrac := 0.0;
    FracDiv := 10.0;
    END_IF;

    WAIT_SIGN:
    IF InputChar = 43 (* '+' *) THEN
    Sign := 1.0;
    State := SKIP_SPACES;
    ELSIF InputChar = 45 (* '-' *) THEN
    Sign := -1.0;
    State := SKIP_SPACES;
    END_IF;

    SKIP_SPACES:
    IF (InputChar >= 48) AND (InputChar <= 57) THEN
    // Цифра — сразу начало числа
    WeightInt := WORD_TO_REAL(InputChar - 48);
    State := READ_INT_PART;
    ELSIF InputChar = 32 (* пробел *) THEN
    // остаёмся в состоянии
    ELSE
    State := WAIT_N;
    END_IF;

    READ_INT_PART:
    IF (InputChar >= 48) AND (InputChar <= 57) THEN
    WeightInt := WeightInt * 10.0 + WORD_TO_REAL(InputChar - 48);
    ELSIF InputChar = 46 (* '.' *) THEN
    State := READ_FRAC_PART;
    ELSE
    State := WAIT_N;
    END_IF;

    READ_FRAC_PART:
    IF (InputChar >= 48) AND (InputChar <= 57) THEN
    WeightFrac := WeightFrac + WORD_TO_REAL(InputChar - 48) / FracDiv;
    FracDiv := FracDiv * 10.0;
    ELSIF InputChar = 32 (* пробел *) THEN
    State := WAIT_UNIT_G;
    ELSE
    State := WAIT_N;
    END_IF;

    WAIT_UNIT_G:
    IF InputChar = 103 (* 'g' *) THEN
    WeightValue := Sign * (WeightInt + WeightFrac);
    NewWeightValid := TRUE; // триггер!
    State := WAIT_N;
    ELSE
    State := WAIT_N;
    END_IF;

    END_CASE;

  10. #20

    По умолчанию

    не могли бы вы проверить и указать на ошибки, чтоб я смог исправить?
    вы серьёзно? это типа новый вид стать тру-программистом - списать код у ИИ и просить проверить у людей забесплатно на форуме?
    вы то сами что сделали для того чтобы сделать свою работу? скопировали вставили текст с экрана?
    берите свой код и грузите в контроллер и проверяйте

Страница 2 из 4 ПерваяПервая 1234 ПоследняяПоследняя

Похожие темы

  1. функциональный блок CTU
    от АлексейI в разделе Среда программирования OWEN Logic
    Ответов: 4
    Последнее сообщение: 05.12.2023, 16:17
  2. Функциональный блок PID
    от Hemann в разделе Программируемые реле
    Ответов: 78
    Последнее сообщение: 04.05.2017, 08:57
  3. LD + функциональный блок
    от дрю в разделе ПЛК1хх
    Ответов: 2
    Последнее сообщение: 26.04.2014, 08:47
  4. Пользовательский функциональный блок
    от fill-forty в разделе ПЛК1хх
    Ответов: 6
    Последнее сообщение: 17.08.2009, 08:49
  5. Программа и функциональный блок
    от Geniu$ в разделе ПЛК1хх
    Ответов: 1
    Последнее сообщение: 27.05.2008, 20:25

Ваши права

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