В статье приборная панель от Porsche мы научились через Arduino и CAN модуль выводить данные. Теперь эти данные было бы неплохо получить из какой-нибудь игры. Я начал пробовать с классической AsettoCorsa, ведь там как раз есть пак с разными автомобилями Порше.
Довольно быстро я нашел рабочий код, на питоне, который парсил телеметрию из асетты. В main для проверки отпринтил скорость, обороты и передачу, убедился, что данные консистентны с игрой
telemetry = assettoReader.getData()
speed = telemetry.get("speed")
rpm = telemetry.get("rpm")
gear = telemetry.get("gear")
print('Assetto data:', speed, rpm, gear)
В целом это самое интересное, что мне удалось достать из телеметрии. Хотелось вывести ABS и TractionControl, Но он почему-то не работает в телеметрии AsettoCorsa(. Такую информацию удалось найти на зарубежном форуме.
Hi ! There might be a confusion, ABS and TC active (unlike configured "level") have never been available in Assetto corsa telemetry, but it's available on ACC, Pcars 1/2/3, AMS2
В общем попробовал выводить разные значения, понял что пока остановлюсь на скорости, оборотах и передаче. Вроде еще работает уровень топлива, но на приборке оно отображается путем съема аналоговых значений с разъема (нужно заморочиться, чтобы такое реализовать). Проверял разные показания из телеметрии, на живую, в игре.

Теперь данные нужно отправить в Arduino. Проще всего упаковать в битовую последовательность и отправить в серийный порт. Выбрал максимальную разрядность для значений:
gear = хх
rpm = xxxxx
speed = xxx
Упаковываем:
def pack_to_bytes(speed, rpm, gear):
packed = (speed << 24) | (rpm << 7) | gear
return START + packed.to_bytes(5, byteorder='big')
Также я использовал что-то вроде стартового байта, START = b’\xAA’, который вынес в константы. Без него непонятно с какого момента смотреть байты на стороне Ардуино, и все перемешивалось в кучу
Теперь надо бы расшифровать это на стороне Arduino. Жду, когда накопится 6 байт и от стартового начинаю расшифровывать данные. Код наверняка не идеальный, но это работает без сбоев.
// Этот блок принимает данные на серийный порт от телеметрии.
if (SERIAL_PORT_MONITOR.available() >= 6) {
if (SERIAL_PORT_MONITOR.read() == 0xAA) {
// Читаем полученные данные и сохраняем их в переменные
SERIAL_PORT_MONITOR.readBytes(buf, 5);
for (int i = 0; i < 5; i++) {
input_value = (input_value << 8) | buf[i];
}
s_speed = (input_value >> 24) & 0x3FF;
s_rpm = (input_value >> 7) & 0x1FFFF;
s_gear = input_value & 0x7F;
}
}
В питон-скрипте в цикле, получаем данные, упаковываем и отдаем в серийный порт. С небольшой паузой, а то приборка сходит с ума.
while True:
telemetry = assettoReader.getData()
speed = int(telemetry.get("speed"))
rpm = int(telemetry.get("rpm"))
gear = int(telemetry.get("gear"))
data = pack_to_bytes(speed, rpm, gear)
ser.write(data)
time.sleep(0.02)
Также для быстрого запуска сделал себе на рабочем столе .bat файл, который запускает этот скрипт
echo "dashboard cluster asetto"
start /min cmd /k "cd / & cd PATH(Путь до файла)\Dashboard-for-autosimulators\ & venv\Scripts\activate & python assetto_corsa/assetto_corsa_telemetry_reader.py"
Еще решил сделать env-файл с номером COM-порта, чтобы не лазить в код каждый раз.
# COM
COM='3'
И такой простой код, который спрашивает новый com-порт, если не смог подключиться к указанному в env. Если подключение пройдет успешно, новый порт запишется в env
connected = False
while not connected:
try:
print(f"connecting to COM-{COM_PORT}")
ser = serial.Serial(f'COM{COM_PORT}', 115200)
connected = True
except serial.serialutil.SerialException:
com_input = input(f"Failed to connect to COM-{COM_PORT}\nEnter COM port (number only): ")
COM_PORT = com_input
if connected:
set_key(dotenv_path, "COM", COM_PORT)
Ну что-же. Запускаем, катаемся и проверяем). Как развернуть виртуальное окружение для питон-скрипта и залить прошивку в ардуино, думаю можно найти на других ресурсах. Но попытаюсь позже добавить в README. Код скрипта + ардуино доступен на GitHub.

Жалко не получилось достать давление, температуру и так далее из телеметрии, было бы вообще шик вывести эти параметры на ЖК дисплей приборки
