Реализация протокола HARTPython

Программы на Python
Ответить
Anonymous
 Реализация протокола HART

Сообщение Anonymous »

Я реализую протокол HART с помощью Python.
На первом этапе я отправляю команду 0, чтобы получить 5-байтовый адрес ведомого устройства с помощью функции Connect():

Код: Выделить всё

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]

data.append(bcc)
ser.setRTS(False)
ser.setDTR(False)
time.sleep(0.002)
ser.setRTS(True)
ser.setDTR(False)
time.sleep(0.002)
ser.write(data)
time.sleep(0.138)
ser.setRTS(False)
ser.setDTR(True)
time.sleep(0.002)
response = ser.read(120)

index = response.find(0xfe)
device_address = bytearray([])

device_address.append(response[index + 1])
device_address.append(response[index + 2])
device_address.append(response[index + 9])
device_address.append(response[index + 10])
device_address.append(response[index + 11])

return device_address
после этого я хочу прочитать сообщение устройства с помощью команды 12:

Код: Выделить всё

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)]]

и я успешно получаю сообщение устройства.

Но когда я хочу написать сообщение по команде 17, устройство не отправляет мне ответ:

Код: Выделить всё

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]]
Я считаю, что команды, которые что-то читают с устройства, правильные, но есть проблемы с командами, которые что-то записывают на устройство, в чем проблема?
все объяснено в предыдущем разделе

Подробнее здесь: https://stackoverflow.com/questions/793 ... t-protocol
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»