К сожалению ничего не помогает...((
Вид для печати
Здравствуйте
Пытаюсь установить CODESYS 3.5.17.30 (скачано с сайта Овен) под Windows 11 (пробовал версии 23H2, 24H2 Pro)
Вылазит ошибка Вложение 81711
Система: Intel(R) Core(TM) i9-14900K, 32 Гб оперативной памяти, SSD диск, свободно более 1 Тб
Пытался ставить и на С: и на D: - два разных SSD накопителя
Ставил по инструкции, с правами администратора, антивируса нет
На Windows 10 устанавливается без проблем.
Такая же проблема возникла у коллеги с ноутбуком (тоже под Windows 11).
Решение проблемы:
Добрый день.
Попробуйте сейчас удалить CODESYS и установить заново по инструкции:
https://youtu.be/3KcJWZEVXCg?si=1OCRv6YADoBOGQvX
Добрый день.
Есть плк 210-04 , есть устройство с rs485, устройство подключено к плк к первому rs485 и мне нужно считывать с этого устройства регистры 0x0312 и 0x0313. Я могу использовать какой нибудь функциональный блок?
Я так понимаю мы этим блоком открываем com port 5 (это первый rs485 на нашем плк ) и дальше отправляем команду на чтения этих регистров.
Здравствуйте. Делаю запись регистра по Modbus TCP по триггеру. Устанавливаю триггер через trig_r. А в какой момент сбрасывать триггер и в каком месте программы?
не совсем понимаю как это сделать, устройств у меня 10 штук , у каждого свой сетевой адрес и у каждого свои 2 регистраВложение 81739
или вот так?Вложение 81740
МихаилГл 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
Я могу теперь написать функциональный блок?) или есть готовые решения?
Если у вас в регистрах нестандартные числа (не real, word и т.п.), то придется писать код преобразования. А если стандартные, но в итоге число не то, что в действительности, то надо пробовать менять местами слова в регистрах. В кодесисе в библиотеках овен есть готовые блоки для этого.
Я бы попробовал для начала считать FLOAT, если не правильное отображение, то поменять местами регистры (потом байты) и проверить.
МихаилГл 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()
Это разработчики СТГ-3 так постарались)) Если я любым методом буду считывать концентрацию и пороги, то буду получать значения , что я выше написал, а потом их приходится конвертировать и получать уже , то что нужно...ппц какой то
Вложение 81748
Вложение 81747
Добрый день!
Напомните пожалуйста, в каком документе есть инструкция по загрузке проекта в контроллер через web-интерфейс, что-то с ходу найти не могу
Добрый день.
п. 4.8:
https://ftp.owen.ru/CoDeSys3/11_Docu..._Faq_v.3.4.pdf
не подскажите как лучше сделать?
Вложение 81766
Так еще пытаюсь 2 worda в dword собрать, тоже не получается
Вложение 81767
Для начала надо убрать синюю букву M (наложение адресов регистров) https://owen.ru/forum/showthread.php?t=28167&page=6#52
Вот универсальный пример на указателях, в зависимости от входа и выхода, можно собрать DWORD (REAL), разобрать на WORD и на BYTE
Тут пример функции (ФБ - если нужно разобрать на 2-4 части), меняя входы и выходы, можно собирать, разбирать (переставлять) регистры и байты в любом типе переменных.
https://owen.ru/forum/showthread.php?t=37645&page=3#30
В вашем случае, 2 входа WORD, присваиваете в массив из двух WORD и через указатели собираете DWORD. Вложение 81768 Вложение 81769
Для сборки можно использовать функцию, для разборки только ФБ.
capzap kondor3000 Спасибо вам большое
Сейчас попробовал UNION Вложение 81770
Сейчас так же как kondor3000 советовал , попробую
мне нужно отсечь все лишнее и оставить только 10 , это как раз и будет 1 порог)) Вложение 81772
Тогда вам нужен ФБ HEX_DEC Вложение 81774
Конвертация времени BCD формата панелей, HEX в DEC и обратно DEC в HEX https://owen.ru/forum/showthread.php...39&page=20#200
такая функция Вам должна подойти Вложение 81780
Вы небось скопировали ФБ HEX_DEC не думая, а это написано для Лоджика. Надо разделить ФБ на две части и в конце удалить end_fanction block
Переменные UDINT можно поменять на DWORD.
Что тут может не работать, одна арифметика Вложение 81793
Код:
Q := x/4096 MOD 16*1000+x/256 MOD 16*100+x/16 MOD 16*10+x MOD 16;
Q1:=Q/100; Q2:=Q-Q1*100;
Добрый день.
Пытаюсь подключится к виртуальному контроллеру, при подключении выводится окно ввода пользователя и пароля, какого пользователя у меня требует codesys?
Вложение 81794
capzap , kondor3000 Спасибо вам ! пойду разбираться, пока туплю сильно
Добрый день.
Того, который был создан при первом подключении к виртуальному контроллеру.
Вот тут написано, как его удалить:
https://owen.ru/forum/showthread.php...l=1#post401060
А вот тут - в п. 10 - как сделать так, чтобы CODESYS не просил его создать при первом подключении к виртуальнику:
https://ftp.owen.ru/CoDeSys3/99_Foru...ures_forum.pdf
Что то я совсем запутался;) я точно знаю что 10 это значение порога 1. Запутался, в моменте что куда приходит)
Вложение 81798
Вложение 81799
У меня вот что получается Вложение 81800
А должно вот так https://owen.ru/forum/attachment.php...3&d=1738774406
Нашел у себя ошибку Q1:=Q/100; на 100 делить нужно, а изначально 10 было.
Так ну с порогами вроде как разобрался, теперь с концентрацией буду пробовать.
Спасибо всем за помощь!
;) Я случайно
А я могу часть своего питоновского скрипта адаптировать для расчёта концентрации?
Код:Обрабатываем два регистра, 32-битное число разбиваем на 4 байта.
byte1 = (registers[0] >> 8) & 0xFF # Старший байт первого регистра
byte2 = registers[0] & 0xFF # Младший байт первого регистра
byte3 = (registers[1] >> 8) & 0xFF # Старший байт второго регистра
byte4 = registers[1] & 0xFF # Младший байт второго регистра
Определяем знак и позицию запятой
sign_bit = (byte1 >> 7) & 0x01 # 7-й бит первого байта отвечает за знак (Если sign_bit = 1, то число отрицательное.)
comma_position = byte1 & 0x07 # Младшие 3 бита первого байта — позиция запятой
Формируем число
integer_part = byte2 * 10000 + byte3 * 10 + (byte4 >> 4) # Целая часть
decimal_part = (byte4 & 0x0F) * 100 # Дробная часть
byte2 — это старшая часть целого числа (умножается на 10000).
byte3 — промежуточное значение (умножается на 10).
byte4 >> 4 — младшие разряды целой части.
byte4 & 0x0F — дробные разряды, умноженные на 100.
Применяем знак и делим на 10^comma_position
value = integer_part + decimal_part / 10000 # Объединение частей
value = -value if sign_bit else value # Применение знака
value /= 10 ** comma_position # Сдвиг запятой
value = round(value, 2) # Округление до двух знаков
Всем большое спасибо, все получилось
Вложение 81803