Work ID test
This commit is contained in:
parent
e80f04d857
commit
207b889fef
4 changed files with 164 additions and 89 deletions
|
@ -1,12 +1,23 @@
|
|||
import can
|
||||
import time
|
||||
import sys
|
||||
|
||||
# Конфигурация
|
||||
CAN_INTERFACE = 'can0'
|
||||
OLD_DEVICE_ID = int(sys.argv[1]) # Текущий ID устройства (по умолчанию)
|
||||
OLD_DEVICE_ID = int(sys.argv[1]) # Текущий ID устройства
|
||||
REG_READ = 0x7 # Код команды чтения
|
||||
REG_ID = 0x01 # Адрес регистра с ID устройства
|
||||
|
||||
def flush_can_buffer(bus, duration=0.3):
|
||||
"""Очистка входного буфера CAN"""
|
||||
start_time = time.time()
|
||||
flushed_count = 0
|
||||
while time.time() - start_time < duration:
|
||||
msg = bus.recv(timeout=0)
|
||||
if msg:
|
||||
flushed_count += 1
|
||||
print(f"Очищено сообщений из буфера: {flushed_count}")
|
||||
|
||||
def send_can_message(bus, can_id, data):
|
||||
"""Отправка CAN-сообщения"""
|
||||
try:
|
||||
|
@ -23,14 +34,14 @@ def send_can_message(bus, can_id, data):
|
|||
return False
|
||||
|
||||
def receive_response(bus, timeout=1.0):
|
||||
"""Ожидание ответа от устройства"""
|
||||
"""Ожидание ответа от устройства (сохраняем вашу оригинальную логику)"""
|
||||
start_time = time.time()
|
||||
while time.time() - start_time < timeout:
|
||||
msg = bus.recv(timeout=0.1)
|
||||
if msg:
|
||||
print(f"[Прием] CAN ID: 0x{msg.arbitration_id:03X}, Данные: {list(msg.data)}")
|
||||
return msg
|
||||
print("[Ошибка] Таймаут")
|
||||
print("[Ошибка] Таймаут приема")
|
||||
return None
|
||||
|
||||
def validate_crc16(data):
|
||||
|
@ -45,64 +56,91 @@ def validate_crc16(data):
|
|||
crc >>= 1
|
||||
return crc
|
||||
|
||||
# Инициализация CAN-интерфейса
|
||||
bus = can.interface.Bus(channel=CAN_INTERFACE, bustype='socketcan')
|
||||
def main():
|
||||
# Инициализация CAN-интерфейса
|
||||
try:
|
||||
bus = can.interface.Bus(
|
||||
channel=CAN_INTERFACE,
|
||||
bustype='socketcan',
|
||||
bitrate=1000000 # Совпадает с устройством
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Ошибка инициализации CAN: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
# ======= 1. Запрос текущего ID устройства =======
|
||||
# ======= 1. Подготовка запроса =======
|
||||
can_id_read = (OLD_DEVICE_ID << 4) | REG_READ
|
||||
data_read = [REG_ID, 0x00]
|
||||
|
||||
# Формируем полные данные для расчета CRC:
|
||||
full_data_for_crc = list(can_id_read.to_bytes(2, 'little')) + data_read
|
||||
|
||||
# Рассчитываем CRC
|
||||
crc = validate_crc16(full_data_for_crc)
|
||||
crc_bytes = list(crc.to_bytes(2, 'little'))
|
||||
|
||||
# Собираем итоговый пакет
|
||||
packet_read = data_read + crc_bytes
|
||||
|
||||
# Формируем CAN ID для чтения: (OLD_DEVICE_ID << 4) | REG_READ
|
||||
can_id_read = (OLD_DEVICE_ID << 4) | REG_READ
|
||||
|
||||
# Данные для запроса: [регистр, резервный байт]
|
||||
data_read = [REG_ID, 0x00]
|
||||
|
||||
# Формируем полные данные для расчета CRC:
|
||||
# - CAN ID разбивается на 2 байта (little-endian)
|
||||
# - Добавляем данные запроса
|
||||
full_data_for_crc = list(can_id_read.to_bytes(2, 'little')) + data_read
|
||||
|
||||
# Рассчитываем CRC и разбиваем на байты (little-endian)
|
||||
crc = validate_crc16(full_data_for_crc)
|
||||
crc_bytes = list(crc.to_bytes(2, 'little'))
|
||||
|
||||
# Собираем итоговый пакет: данные + CRC
|
||||
packet_read = data_read + crc_bytes
|
||||
|
||||
print("Запрос на чтение ID:", packet_read)
|
||||
send_can_message(bus, can_id_read, packet_read)
|
||||
|
||||
# ======= 2. Получение и проверка ответа =======
|
||||
response = receive_response(bus)
|
||||
if response:
|
||||
# ======= 2. Отправка запроса с повторами =======
|
||||
max_retries = 3
|
||||
response = None
|
||||
|
||||
for attempt in range(max_retries):
|
||||
print(f"\nПопытка {attempt+1}/{max_retries}")
|
||||
|
||||
# Очистка буфера перед отправкой
|
||||
flush_can_buffer(bus, 0.3)
|
||||
|
||||
# Отправка запроса
|
||||
print(f"Отправка запроса на чтение ID: {packet_read}")
|
||||
if not send_can_message(bus, can_id_read, packet_read):
|
||||
print("Ошибка отправки, повтор...")
|
||||
time.sleep(0.2)
|
||||
continue
|
||||
|
||||
# Ожидание ответа
|
||||
response = receive_response(bus, timeout=0.5)
|
||||
if response:
|
||||
break
|
||||
|
||||
print("Ответ не получен, повтор...")
|
||||
time.sleep(0.2)
|
||||
|
||||
# ======= 3. Обработка ответа =======
|
||||
if not response:
|
||||
print("Устройство не ответило после всех попыток")
|
||||
bus.shutdown()
|
||||
sys.exit(1)
|
||||
|
||||
data = response.data
|
||||
|
||||
if len(data) < 4:
|
||||
print("Слишком короткий ответ")
|
||||
bus.shutdown()
|
||||
sys.exit(1)
|
||||
|
||||
# Проверяем минимальную длину ответа (данные + CRC)
|
||||
id_bytes = response.arbitration_id.to_bytes(1, byteorder='little')
|
||||
full_data = list(id_bytes) + list(data[:-2])
|
||||
print(f"Полные данные для CRC: {full_data}")
|
||||
|
||||
received_crc = int.from_bytes(data[-2:], byteorder='little')
|
||||
calc_crc = validate_crc16(full_data)
|
||||
|
||||
print(f"Расчитанный CRC: 0x{calc_crc:04X}, Полученный CRC: 0x{received_crc:04X}")
|
||||
|
||||
if received_crc == calc_crc:
|
||||
print(f"Текущий ID устройства: 0x{data[1]:02X}")
|
||||
else:
|
||||
id_bytes = response.arbitration_id.to_bytes(1,byteorder='little')
|
||||
#buff with id and data without CRC
|
||||
full_data = list(id_bytes) + list(data[:-2])
|
||||
print(f"Received full_data: {list(full_data)}")
|
||||
received_crc = int.from_bytes(data[-2:], byteorder='little')
|
||||
#calc CRC
|
||||
calc_crc = validate_crc16(full_data)
|
||||
|
||||
print(f"Расчитанный CRC PYTHON : 0x{calc_crc:02X}")
|
||||
if received_crc == calc_crc:
|
||||
# Если CRC совпадает, проверяем структуру ответа:
|
||||
print(f"Текущий ID устройства: 0x{data[1]:02X}")
|
||||
else:
|
||||
print("Ошибка: CRC не совпадает")
|
||||
else:
|
||||
print("Устройство не ответило")
|
||||
|
||||
# Завершаем работу с шиной
|
||||
bus.shutdown()
|
||||
print("Ошибка: CRC не совпадает")
|
||||
|
||||
# Завершаем работу с шиной
|
||||
bus.shutdown()
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
if len(sys.argv) != 2:
|
||||
print("Использование: python3 can_flasher.py address")
|
||||
print("Использование: python3 can_flasher.py <адрес_устройства>")
|
||||
print("Пример: python3 can_flasher.py 1")
|
||||
sys.exit(1)
|
||||
|
||||
main()
|
Loading…
Add table
Add a link
Reference in a new issue