Доработка. Запись в регистры хранения Modbus для управления питанием прибора Щ3

This commit is contained in:
sasha80
2024-11-19 16:25:46 +03:00
parent 4a2b780a88
commit f92f051918
2 changed files with 121 additions and 28 deletions

View File

@@ -6,44 +6,137 @@ extends "res://scenes/контроль/элемент-я.gd"
## информационного взаимодействия изделия 5П-28
## с аппаратурой УА-РЭП на кораблях проекта 23900
@export var base_input_address: = 0 ## Базовый адрес регистров входов
@export var base_holding_address: = 0 ## Базовый адрес регистров хранения
@export var regs_input_count: = 5 ## Количество регистров входов
@export var regs_holding_count: = 4 ## Количество регистров хранения
@export var modbus_address: = 3 ## Адрес устройства на шине Modbus
var regs_input: = {} ## Регистры входные
var regs_holding: = {} ## Регистры хранения
var write_stack: = [] ## Стек команд для записи
var holding_stack: = [] ## Стек команд для чтения регистров хранения
var input_stack: = [] ## Стек команд для чтения регистров входов
var read_step: = 0
var switches_sync: = false
class StackItem:
var addr: = 0
var data = null
func _init(a: int, d): addr = a; data = d
func _to_string() -> String: return '%s: %s' % [addr, data]
func on_data_received(_data: PackedByteArray): pass
func _enter_tree() -> void:
func _on_timeout(unit_sch3) -> void:
if write_stack.size():
var ad = write_stack.pop_front()
if not unit_sch3.write(ad.addr, ad.data):
write_stack.push_back(ad)
if (read_step == 0) and (input_stack.size() == 0):
var ad = StackItem.new(base_input_address, regs_input_count)
input_stack.push_back(ad)
elif read_step == 1 and (holding_stack.size() == 0):
var ad = StackItem.new(base_holding_address, regs_holding_count)
holding_stack.push_back(ad)
if input_stack.size():
var ad = input_stack.pop_front()
if not unit_sch3.read_input(ad.addr, ad.data):
input_stack.push_back(ad)
if holding_stack.size():
var ad = holding_stack.pop_front()
if not unit_sch3.read_holding(ad.addr, ad.data):
holding_stack.push_back(ad)
read_step += 1
read_step %= 2
func on_toggled_switch(val: bool, unit_sch3: sch_3.Sch3, meta: Array):
var on_addr = meta[0]
var on_bit = meta[1]
var off_addr = meta[2]
var off_bit = meta[3]
if regs_holding.has(on_addr) and regs_holding.has(off_addr):
regs_holding[on_addr] = tools.set_bit(regs_holding[on_addr], on_bit, val)
regs_holding[off_addr] = tools.set_bit(regs_holding[off_addr], off_bit, not val)
var regs_data: = []
var keys = regs_holding.keys()
keys.sort()
for addr in keys:
regs_data.append(regs_holding[addr])
write_stack.push_back(StackItem.new(keys[0], regs_data))
func _ready() -> void:
if Engine.is_editor_hint(): return
var unit_key = settings.get_unit_key(unit_name)
var unit = network.units[unit_key]
unit.connect('resp_input', on_resp_input)
func _exit_tree() -> void:
if Engine.is_editor_hint(): return
var unit_key = settings.get_unit_key(unit_name)
var unit = network.units[unit_key]
unit.disconnect('resp_input', on_resp_input)
func on_line_changed(_unit):
var items = get_tree().get_nodes_in_group('bits_items_good')
var unit_sch3 = network.units[unit_key]
unit_sch3.mb_addr = modbus_address
var items = get_tree().get_nodes_in_group('bits_items_switch')
for item in items:
item.texture = textures[STATE_VAL.ERROR]
var meta = item.get_meta('bits')
item.connect('toggled', on_toggled_switch.bind(unit_sch3, meta))
item.disabled = true
unit_sch3.connect('resp_input', on_resp_input)
unit_sch3.connect('resp_holding', on_resp_holding)
var timer = Timer.new()
timer.connect('timeout', _on_timeout.bind(unit_sch3))
add_child(timer)
timer.start(1.0)
func on_resp_input(addr: int, data: PackedByteArray):
if (addr != 0) or (data.size() < 4):
func on_line_changed(unit_sch3):
for item in get_tree().get_nodes_in_group('bits_items_good'):
item.texture = textures[STATE_VAL.NONE]
if not unit_sch3.online:
for item in get_tree().get_nodes_in_group('bits_items_switch'):
item.disabled = true
regs_holding.clear()
regs_input.clear()
write_stack.clear()
input_stack.clear()
holding_stack.clear()
switches_sync = false
func on_resp_holding(base_addr: int, data: Array):
if (base_addr != base_holding_address) or (data.size() < regs_holding_count):
return
for i in data.size():
regs_holding[base_addr + i] = data[i]
if not switches_sync:
for item in get_tree().get_nodes_in_group('bits_items_switch'):
var bits = item.get_meta('bits')
var byte: int = bits[0]
var bit: int = bits[1]
item.button_pressed = regs_holding[byte] & (1 << bit) > 0
item.disabled = false
switches_sync = true
$margin/vbox/grid1/lbl_freq.text = '<нет данных>'
func on_resp_input(base_addr: int, data: Array):
if (base_addr != base_input_address) or (data.size() < regs_input_count):
return
# "Для контроля состояния управляющего элемента подачи электроэнергии на приборы ..."
# "Для контроля подачи электроэнергии на приборы ..."
# Таблицы 3.13 и 3.14. Ecли значения соответствующих битов в этих
# регистрах равны, то "исправно".
var items = get_tree().get_nodes_in_group('bits_items_good')
for i in data.size():
regs_input[base_addr + i] = data[i]
# Таблица 3.15, Регистр PowerState
$margin/vbox/grid1/lbl_freq.text = '%d' % (regs_input[4] & 0x1ff)
var cnt_good: int = 0
for item in items:
var bits: Array = item.get_meta('bits')
var byte0: int = bits[0]
var bit0: int = bits[1]
var byte1: int = bits[2]
var bit1: int = bits[3]
var byte0: int = bits[0] # Индекс байта в данных "состояния управляющего элемента"
var bit0: int = bits[1] # Индекс бита в данных "состояния управляющего элемента"
var byte1: int = bits[2] # Индекс байта в данных "подачи электроэнергии на приборы"
var bit1: int = bits[3] # Индекс бита в данных "подачи электроэнергии на приборы"
var v = STATE_VAL.GOOD \
if (data[byte0] & (1 << bit0)) \
== (data[byte1] & (1 << bit1)) \