Я реализую протокол HART с помощью Python.
На первом этапе я отправляю команду 0, чтобы получить 5-байтовый адрес ведомого устройства с помощью функции Connect():
def CMD_17(port_name, address, message):
ser = serial.Serial()
ser.close()
ser = serial.Serial(port_name, 1200, timeout=5, parity=serial.PARITY_ODD, rtscts=True,
xonxoff=False) # RTS/CTS enabled
data = []
# Construct the data packet
for i in range(5):
data.append(0xff)
data.append(0x82)
# Add the address to the data packet
for i in range(len(address)):
data.append(address[i])
data.append(0x11)
# Ensure message length is 32 bytes
if len(message) < 32:
a = 32 - len(message)
for i in range(a):
message += " "
message = utility.str2pack(message) # Assuming this function packs the message
data.append(len(message))
print("Message:", message)
# Append the message data
data += message
# Calculate BCC
bcc = 0x00
for i in range(5, len(data)):
bcc ^= data[i]
data.append(bcc)
# Ensure RTS/CTS lines are correctly toggled
ser.setRTS(False) # Make sure RTS is low at the start
ser.setDTR(False) # DTR is low initially
time.sleep(0.002) # Let the modem prepare
ser.setRTS(True) # Toggle RTS high
ser.setDTR(False)
time.sleep(0.002)
print("Transmitting data:")
for i in data:
print(hex(i), end=', ')
print()
# Write data to the serial port
ser.write(data)
time.sleep(0.138) # Wait for modem processing
# Set DTR to high to request the response from the modem
ser.setRTS(False)
ser.setDTR(True)
time.sleep(0.002)
# Read the response from the modem
response = ser.read(120) # Try reading up to 120 bytes
print("Received data:")
for i in response:
print(hex(i), end=', ')
print()
# Check if we received any response
if len(response) == 0:
print("No response received!")
return ["No Response", []]
response = list(response)
try:
response = utility.parse_packet(response) # Attempt to parse the response
except Exception as e:
print(f"Failed to parse response: {e}")
return ["Error", []]
print("Parsed response:", response)
status = response[0]
resp_data = response[3]
# Return the appropriate status message
if status[0] == 0:
status = "Success"
elif status[0] == 5:
status = "Too few data bytes received"
elif status[0] == 6:
status = "Dev-specific cmd error"
elif status[0] == 7:
status = "Device is write protected"
elif status[0] == 100:
status = "Not Implemented"
elif status[0] == 16:
status = "Access Restricted"
elif status[0] == 32:
status = "Busy"
else:
status = "Undefined"
res = utility.packed_bytes2str(data[:24]) # Assuming this decodes the first 24 bytes
return [status, [res]]
Я считаю, что команды, которые что-то читают с устройства, правильные, но есть проблемы с командами, которые что-то записывают на устройство, в чем проблема?
все объяснено в предыдущем разделе
Я реализую протокол HART с помощью Python. На первом этапе я отправляю команду 0, чтобы получить 5-байтовый адрес ведомого устройства с помощью функции Connect(): [code]def connect(port): ser = serial.Serial() ser.close() ser = serial.Serial(port, 1200, xonxoff=True, timeout=2, parity=serial.PARITY_ODD) ser.setRTS(False) ser.setDTR(False) time.sleep(0.002) ser.setRTS(True) ser.setDTR(False) time.sleep(0.002) data = bytearray([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, ]) bcc = 0x00 for i in range(10, len(data)): bcc ^= data[i]
return device_address [/code] после этого я хочу прочитать сообщение устройства с помощью команды 12: [code]def CMD_12(port_name, address): ser = serial.Serial() ser.close() ser = serial.Serial(port_name, 1200, xonxoff=True, timeout=2, parity=serial.PARITY_ODD) data = [] for i in range(5): data.append(0xff) data.append(0x82) for i in range(len(address)): data.append(address[i])
data.append(0x0C) data.append(0x00) bcc = 0x00 for i in range(5, len(data)): bcc ^= data[i] data.append(bcc) ser.setRTS(False) ser.setDTR(False) time.sleep(0.002) ser.setRTS(True) ser.setDTR(False) time.sleep(0.002) # print("transmitted data : ", end=" ") # for i in data: # print(hex(i), end=',') # print()
ser.write(data) time.sleep(0.138) ser.setRTS(False) ser.setDTR(True) time.sleep(0.002) response = ser.read(120) # print("recieved data : ", end=" ") # for i in response: # print(hex(i), end=',') # print() response = list(response) try: response = utility.parse_packet(response) except: pass # print("response was not receive") # print(response) status = response[0] resp_data = response[3]
if status[0] == 0: status = "Success" elif status[0] == 100: status = "Not Implemented" elif status[0] == 6: status = "Dev-specific cmd error" elif status[0] == 8: status = "Update Failure" elif status[0] == 16: status = "Access Restricted" else: status = "Undefined" return [status, [utility.packed_bytes2str(resp_data)]]
[/code] и я успешно получаю сообщение устройства.
Но когда я хочу написать сообщение по команде 17, устройство не отправляет мне ответ: [code]def CMD_17(port_name, address, message): ser = serial.Serial() ser.close() ser = serial.Serial(port_name, 1200, timeout=5, parity=serial.PARITY_ODD, rtscts=True, xonxoff=False) # RTS/CTS enabled data = [] # Construct the data packet for i in range(5): data.append(0xff) data.append(0x82)
# Add the address to the data packet for i in range(len(address)): data.append(address[i])
data.append(0x11)
# Ensure message length is 32 bytes if len(message) < 32: a = 32 - len(message) for i in range(a): message += " " message = utility.str2pack(message) # Assuming this function packs the message data.append(len(message))
print("Message:", message)
# Append the message data data += message
# Calculate BCC bcc = 0x00 for i in range(5, len(data)): bcc ^= data[i] data.append(bcc)
# Ensure RTS/CTS lines are correctly toggled ser.setRTS(False) # Make sure RTS is low at the start ser.setDTR(False) # DTR is low initially time.sleep(0.002) # Let the modem prepare ser.setRTS(True) # Toggle RTS high ser.setDTR(False) time.sleep(0.002)
print("Transmitting data:") for i in data: print(hex(i), end=', ') print()
# Write data to the serial port ser.write(data) time.sleep(0.138) # Wait for modem processing
# Set DTR to high to request the response from the modem ser.setRTS(False) ser.setDTR(True) time.sleep(0.002)
# Read the response from the modem response = ser.read(120) # Try reading up to 120 bytes print("Received data:") for i in response: print(hex(i), end=', ') print()
# Check if we received any response if len(response) == 0: print("No response received!") return ["No Response", []]
response = list(response) try: response = utility.parse_packet(response) # Attempt to parse the response except Exception as e: print(f"Failed to parse response: {e}") return ["Error", []]
print("Parsed response:", response) status = response[0] resp_data = response[3]
# Return the appropriate status message if status[0] == 0: status = "Success" elif status[0] == 5: status = "Too few data bytes received" elif status[0] == 6: status = "Dev-specific cmd error" elif status[0] == 7: status = "Device is write protected" elif status[0] == 100: status = "Not Implemented" elif status[0] == 16: status = "Access Restricted" elif status[0] == 32: status = "Busy" else: status = "Undefined"
res = utility.packed_bytes2str(data[:24]) # Assuming this decodes the first 24 bytes
return [status, [res]] [/code] Я считаю, что команды, которые что-то читают с устройства, правильные, но есть проблемы с командами, которые что-то записывают на устройство, в чем проблема? все объяснено в предыдущем разделе