Как правильо написать макрос?
Работа с панелями оператора Weintek - подключение, программирование, совмещение с ПЛК
Модераторы: kiv, 8bit, VanMo
atomo2 » 18 сен 2024, 13:17
Добрый день. есть код на питоне , который считывает по modbus c газоанализатора СТГ3 , текущую концентрацию и пороги. Теперь я подключил на прямую к входу modbus панели, газоанализатор , помогите с макросом для считывания регистров. Нашел пример , но не совсем понимаю
- Код: Выделить всё
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(1)
if __name__ == "__main__":
main()
-
atomo2
-
- Сообщения: 3
- Зарегистрирован: 26 янв 2024, 09:05
dimensy » 18 сен 2024, 23:09
Вот, наваял я вам конвертер
- Код: Выделить всё
sub float Convert_Data(unsigned int A)
bool Znak
unsigned int Point
float result, p
GETBIT(A, Znak, 31) //Определяем знак
Point = A & 0x7000000 //Определяем количество знаков после запятой
Point = Point >> 24
POW(10, Point, Point)
p = Point
A = A & 0xFFFFFF//Определяем значение
BCD2BIN(A, A)
result = A
result = result / p
if Znak then
result = -1 * result
end if
return result
end sub
Создавать его нужно тут
Далее, макрос для чтения
- Код: Выделить всё
macro_command main()
unsigned int A
float Concentracia, Porog1, Porog2
GetData(A, "MODBUS RTU (HEX Addressing)", 4x_Double, 0, 1)
Concentracia = Convert_Data(A)
SetData(Concentracia, "Local HMI", LW, 0, 1)
GetData(A, "MODBUS RTU (HEX Addressing)", 4x_Double, 2, 1)
Porog1 = Convert_Data(A)
SetData(Porog1, "Local HMI", LW, 2, 1)
GetData(A, "MODBUS RTU (HEX Addressing)", 4x_Double, 4, 1)
Porog2 = Convert_Data(A)
SetData(Porog2, "Local HMI", LW, 4, 1)
end macro_command
На панели выводить в формате float
И, еще, скорее всего в настройках драйвера надо галочки поставить вот тут
результат
-
dimensy
-
- Сообщения: 195
- Зарегистрирован: 14 мар 2018, 17:54
8bit » 19 сен 2024, 11:02
а удобно это они придумали .....
Хороший вопрос содержит половину ответа - A good question contains half the answer
-
8bit
-
- Сообщения: 1164
- Зарегистрирован: 20 апр 2020, 19:07
atomo2 » 19 сен 2024, 15:11
dimensy
Спасибо большое, все работает
8bit
Ну да , так я и написал на питоне скрипт, а с панелью завис чего то(
-
atomo2
-
- Сообщения: 3
- Зарегистрирован: 26 янв 2024, 09:05
Вернуться в Weintek
Кто сейчас на конференции
Сейчас этот форум просматривают: Bing [Bot], Google [Bot] и гости: 13