Страница 802 из 855 ПерваяПервая ... 302702752792800801802803804812852 ... ПоследняяПоследняя
Показано с 8,011 по 8,020 из 8547

Тема: CODESYS V3.5. Вопросы и ответы

  1. #8011

    По умолчанию

    Цитата Сообщение от Антон_Б Посмотреть сообщение
    Здравствуйте. Делаю запись регистра по Modbus TCP по триггеру. Устанавливаю триггер через trig_r. А в какой момент сбрасывать триггер и в каком месте программы?
    Обычно достаточно просто включить R_Tig на 1 цикл ПЛК, можно вместо триггера использовать таймер ТР, на 100-300 мс, если вам не нужно проверять записанное.
    И таймер и триггер сами сбросят переменную.

  2. #8012

    По умолчанию

    Цитата Сообщение от kondor3000 Посмотреть сообщение
    Обычно достаточно просто включить R_Tig на 1 цикл ПЛК, можно вместо триггера использовать таймер ТР, на 100-300 мс, если вам не нужно проверять записанное.
    И таймер и триггер сами сбросят переменную.
    ТС наверное неправильно написал. Я по триггеру обычно взвожу промежуточную переменную. И свой ответ я писал под это условие. Как у него, пока непонятно. Начальные условия недостаточны...)

  3. #8013

    По умолчанию

    Цитата Сообщение от kondor3000 Посмотреть сообщение
    Чем вас не устраивает обычный обмен, что вы хотите использовать биб-ку ?
    Обычный обмен проще, чем биб-чный, но и тот и другой есть на обучающих видео. И там и там можно назначить нужные вам адреса.
    не совсем понимаю как это сделать, устройств у меня 10 штук , у каждого свой сетевой адрес и у каждого свои 2 регистраВложение 81739

    или вот так?изображение_2025-02-04_131549646.png
    Последний раз редактировалось atomo2; 04.02.2025 в 09:16.

  4. #8014

    По умолчанию

    Цитата Сообщение от atomo2 Посмотреть сообщение
    не совсем понимаю как это сделать, устройств у меня 10 штук , у каждого свой сетевой адрес и у каждого свои 2 регистраВложение 81739

    или вот так?изображение_2025-02-04_131549646.png
    В каналах модбас для каждого из устройств прописывайте читаемые регистры и вперед!

  5. #8015

    По умолчанию

    Цитата Сообщение от atomo2 Посмотреть сообщение
    не совсем понимаю как это сделать, устройств у меня 10 штук , у каждого свой сетевой адрес и у каждого свои 2 регистра

    или вот так?
    Вам надо добавить 10 слейвов с разными сетевыми адресами и добавить в каждом 2 (или больше) регистра, с нужными адресами регистров.
    Точнее лучше настройте 1 слейв, проверьте его, а потом скопируете 10 раз.
    Последний раз редактировалось kondor3000; 04.02.2025 в 09:40.

  6. #8016

    По умолчанию

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

    def display_concentration(registers):
    if len(registers) < 2:
    print("Недостаточно данных для отображения концентрации")
    return

    byte1 = (registers[0] >> 8) & 0xFF # Старший байт первого регистра
    byte2 = registers[0] & 0xFF # Младший байт первого регистра
    byte3 = (registers[1] >> 8) & 0xFF # Старший байт второго регистра
    byte4 = registers[1] & 0xFF # Младший байт второго регистра

    sign_bit = (byte1 >> 7) & 0x01 # Определяем знак (бит 7 в первом байте)
    comma_position = byte1 & 0x07 # Определяем позицию запятой (биты 0-2 в первом байте)

    sign = '-' if sign_bit else '+'
    integer_part = byte2 * 10000 + byte3 * 10 + (byte4 >> 4) # Вычисление целой части
    decimal_part = (byte4 & 0x0F) * 100 # Десятичная часть

    value = integer_part + decimal_part / 10000 # Собираем число
    value = -value if sign_bit else value # Добавляем знак
    value /= 10 ** comma_position # Учитываем запятую
    value = round(value, 2) # Округляем до двух знаков

    print(f"Значение концентрации: {value:.2f}")


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

    def format_value_with_comma(hex_value, comma_position):
    value_str = f"{hex_value:08X}" # Преобразует число в строку из 8 шестнадцатеричных символов
    integer_part = value_str[2:-comma_position] if comma_position < len(value_str) else '0'
    decimal_part = value_str[-comma_position:] if comma_position > 0 else '0'

    formatted_value = f"{integer_part},{decimal_part}".lstrip('0') or '0'
    return f"{formatted_value[:formatted_value.index(',') + 3]}" if ',' in formatted_value else formatted_value

    Я могу теперь написать функциональный блок?) или есть готовые решения?

  7. #8017

    По умолчанию

    Если у вас в регистрах нестандартные числа (не real, word и т.п.), то придется писать код преобразования. А если стандартные, но в итоге число не то, что в действительности, то надо пробовать менять местами слова в регистрах. В кодесисе в библиотеках овен есть готовые блоки для этого.

  8. #8018

    По умолчанию

    Я бы попробовал для начала считать FLOAT, если не правильное отображение, то поменять местами регистры (потом байты) и проверить.

  9. #8019

    По умолчанию

    МихаилГл kondor3000 capzap Значения концентрации и порогов я сейчас получаю в 10 тичной системе , концентрация 1536, порог 1 1040 и порог 2 1056 , если в 16-ричную переводить то 0,0 10 и 20 . Простите ошибся. Получается нужно писать преобразователь, блок или функцию я не нашел

    Код:
    from pymodbus.client.sync import ModbusSerialClient as ModbusClient
    import time
    
    # Параметры подключения
    PORT = 'COM17'
    BAUDRATE = 9600
    client = ModbusClient(
        method='rtu',
        port=PORT,
        baudrate=BAUDRATE,
        stopbits=1,
        parity='N',
        timeout=1
    )
    
    def read_modbus_data(client, unit_id, address, count):
        if not client.connect():
            print("Не удалось подключиться к Modbus серверу")
            return None
    
        result = client.read_holding_registers(address, count, unit=unit_id)
        client.close()
    
        if result.isError():
            print("Ошибка чтения данных: ", result)
            return None
        return result.registers
    
    def format_value_with_comma(hex_value, comma_position):
        value_str = f"{hex_value:08X}"
        integer_part = value_str[2:-comma_position] if comma_position < len(value_str) else '0'
        decimal_part = value_str[-comma_position:] if comma_position > 0 else '0'
    
        formatted_value = f"{integer_part},{decimal_part}".lstrip('0') or '0'
        return f"{formatted_value[:formatted_value.index(',') + 3]}" if ',' in formatted_value else formatted_value
    
    def display_registers(registers):
        if len(registers) < 2:
            print("Недостаточно данных для отображения")
            return
    
        combined_hex = (registers[0] << 16) | registers[1]
        comma_position = (registers[0] >> 8) & 0xFF
    
        formatted_value = format_value_with_comma(combined_hex, comma_position)
        print(f"Значение: {formatted_value}")
    
    def display_concentration(registers):
        if len(registers) < 2:
            print("Недостаточно данных для отображения концентрации")
            return
    
        byte1 = (registers[0] >> 8) & 0xFF
        byte2 = registers[0] & 0xFF
        byte3 = (registers[1] >> 8) & 0xFF
        byte4 = registers[1] & 0xFF
    
        sign_bit = (byte1 >> 7) & 0x01
        comma_position = byte1 & 0x07
        
        sign = '-' if sign_bit else '+'
        integer_part = byte2 * 10000 + byte3 * 10 + (byte4 >> 4)
        decimal_part = (byte4 & 0x0F) * 100
    
        value = integer_part + decimal_part / 10000
        value = -value if sign_bit else value
        value /= 10 ** comma_position
        value = round(value, 2)
    
        print(f"Значение концентрации: {value:.2f}")
    
    def main():
        unit_id = 1
        count = 2
    
        threshold1_address = 0x02
        threshold2_address = 0x04
        concentration_address = 0x00
    
        while True:
            p1_data = read_modbus_data(client, unit_id, threshold1_address, count)
            if p1_data:
                print("Установленное значение порога 1:")
                display_registers(p1_data)
    
            p2_data = read_modbus_data(client, unit_id, threshold2_address, count)
            if p2_data:
                print("Установленное значение порога 2:")
                display_registers(p2_data)
    
            conc_data = read_modbus_data(client, unit_id, concentration_address, count)
            if conc_data:
                print("Измеренное значение концентрации:")
                display_concentration(conc_data)
    
            time.sleep(3)
    
    if __name__ == "__main__":
        main()
    Последний раз редактировалось atomo2; 04.02.2025 в 11:36.

  10. #8020

    По умолчанию

    Цитата Сообщение от capzap Посмотреть сообщение
    тут нужно пояснить, что Вы имеете в виду, числа 1536, 1040 и 1056 в 16-чной системе это 600 410 и 420, это какая то кастомная логика превратить их в 0,0 10 и 20, вряд ли это математические функции и обычное преобразование
    Это разработчики СТГ-3 так постарались)) Если я любым методом буду считывать концентрацию и пороги, то буду получать значения , что я выше написал, а потом их приходится конвертировать и получать уже , то что нужно...ппц какой то


    Снимок экрана 2025-02-04 163745.png
    изображение_2025-02-04_163816263.png

Страница 802 из 855 ПерваяПервая ... 302702752792800801802803804812852 ... ПоследняяПоследняя

Похожие темы

  1. Панели оператора СП3xx. Вопросы и ответы
    от Мурат Ахриев в разделе Панели оператора (HMI)
    Ответов: 3997
    Последнее сообщение: Вчера, 13:05
  2. Панели оператора ИП320. Вопросы и ответы
    от automat в разделе Панели оператора (HMI)
    Ответов: 849
    Последнее сообщение: 16.11.2025, 08:58
  3. ИПП120. Вопросы и ответы
    от Р.Александр в разделе Программируемые реле
    Ответов: 273
    Последнее сообщение: 08.09.2025, 13:21
  4. Индикатор ИП120 , вопросы- ответы
    от rovki в разделе Программируемые реле
    Ответов: 56
    Последнее сообщение: 03.11.2017, 15:58
  5. Панели оператора СП270. Вопросы и ответы
    от Давидюк в разделе Панели оператора (HMI)
    Ответов: 930
    Последнее сообщение: 15.05.2017, 17:12

Ваши права

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