В первой статье «Хакаем CAN шину авто для голосового управления» я подключался непосредственно к CAN шине Comfort в двери своего авто и исследовал пролетающий траффик, это позволило определить команды управления стеклоподъемниками, центральным замком и др.
В этой статье я расскажу как собрать свою уникальную виртуальную или цифровую панель приборов и получить данные с любых датчиков в автомобилях группы VAG (Volkswagen, Audi, Seat, Skoda).
Мною был собран новый CAN сниффер и CAN шилд для Raspberry Pi на базе модуля MCP2515 TJA1050 Niren, полученные с их помощью данные я применил в разработке цифровой панели приборов с использованием 7? дисплея для Raspberry Pi. Помимо простого отображения информации цифровая панель реагирует на кнопки подрулевого переключателя и другие события в машине.
В качестве фреймворка для рисования приборов отлично подошел Kivy для Python. Работает без Иксов и для вывода графики использует GL.
- CAN сниффер из Arduino Uno
- Подслушиваем запросы с помощью диагностической системы VAG-COM (VCDS)
- Разработка панели приборов на основе Raspberry Pi и 7? дисплея
- Софт панели приборов на Python и Kivy (UI framework)
- Видео работы цифровой панели приборов на базе Raspberry Pi
Под катом полная реализация проекта, будет интересно!
Водительская дверь открыта
CAN сниффер из Arduino Uno
Чтобы послушать, что отправляет VCDS в CAN шину я собрал сниффер на макетке из Arduino и модуля MCP2515 TJA1050 Niren.
Схема подключения следующая:
Для прослушивания трафика использовал анализатор CanHackerV2 и прошивку arduino-canhacker для Arduino, которая реализует API совместимое с этой программой. Прошивка в гите https://github.com/autowp/arduino-canhacker.
CanHackerV2 позволяет смотреть пролетающий трафик, записывать и проигрывать команды с заданным интервалом, что очень сильно помогает в анализе данных.
Подслушиваем запросы с помощью диагностической системы VAG-COM (VCDS)
Описание VCDS с официального сайта ru.ross-tech.com:
Программно-аппаратный сканер VCDS предназначен для диагностики электронных систем управления, устанавливаемых на автомобилях группы VAG. Доступ ко всем системам: двигатель, ACP, АБС, климат-контроль, кузовая электроника и т.п., считывание и стирание кодов неисправностей, вывод текущих параметров, активация, базовые установки, адаптация, кодирование и т.п.
Подключив сниффер к линиям CAN_L и CAN_H в диагностическом шнурке я смог увидеть какие запросы делает VCDS и что отвечает авто.
Особенность авто группы VAG в том, что OBD2 разъем подключен к CAN шине через шлюз и шлюз не пропускает весь гуляющий по сети трафик, т.е. подключившись в OBD2 разъем сниффером вы ничего не увидите. Чтобы получить данные в OBD2 разъёме нужно отправлять шлюзу специальные запросы. Эти запросы и ответы видно при прослушивании трафика от VCDS. Например вот так можно получить пробег.
В VCDS можно получить информацию почти с любого датчика в машине. Меня в первую очередь интересовала информация, которой вообще нет на моей приборке, это:
- температура масла
- какая именно дверь открыта
Скорость, обороты, температура ОЖ, пробег, расход, место в баке и другие запросы я тоже получил, для справки размещу.
// Двери
714 03 22 22 0D 55 55 55 55
77E 05 62 22 0D 55 65 AA AA - все закрыты
77E 05 62 22 0D 00 65 AA AA - все открыты
77E 05 62 22 0D 54 65 AA AA - водительская открыта
77E 05 62 22 0D 51 65 AA AA - пассажирская открыта
77E 05 62 22 0D 50 65 AA AA - водительская и пассажирская открыта
77E 05 62 22 0D 45 65 AA AA - задняя левая открыта
77E 05 62 22 0D 15 65 AA AA - задняя правая открыта
77E 05 62 22 0D 44 65 AA AA - водительская и задняя левая открыта
77E 05 62 22 0D 40 65 AA AA - водительская, пассажирская, задняя левая открыты
01010101 = 0x55 (все закрыты)
0 бит - водительская
2 бит - пассажирская
4 бит - задняя левая
6 бит - задняя правая
// Ручник
714 03 22 22 05 55 55 55 55
77E 05 62 22 05 21 AA AA AA - нажат
77E 05 62 22 05 20 AA AA AA - не нажат
// Наружная температура
714 03 22 22 0С 55 55 55 55
77E 04 62 22 0C 55 AA AA AA - -7.5°С
77E 04 62 22 0C 65 AA AA AA - 0.5 101°С
77E 04 62 22 0C 66 AA AA AA - 1 = 102°С
77E 04 62 22 0C 68 AA AA AA - 2 = 104°С
// Наружная температура отображаемая
714 03 22 10 14 55 55 55 55
77E 04 62 10 14 84 AA AA AA - 16°С
// Запас хода
714 03 22 22 94 55 55 55 55
77E 05 62 22 94 00 8E AA AA - 142км
// Уровень топлива
714 03 22 22 06 55 55 55 55
77E 04 62 22 06 2C AA AA AA - 44л
77E 04 62 22 06 16 AA AA AA - 22л
// Положение стрелки указателя уровня топлива
714 03 22 22 96 55 55 55 55
77E 05 62 22 96 01 9A AA AA - 41.0°
// Температура ОЖ
714 03 22 F4 05 55 55 55 55
77E 04 62 F4 05 85 AA AA AA - 52.5°С
77E 04 62 F4 05 87 AA AA AA - 54°С
77E 04 62 F4 05 С5 AA AA AA - 100.5°С
// Обороты двигателя
714 03 22 F4 0C 55 55 55 55
77E 05 62 F4 0C 0B C6 AA AA - 753.5 об/мин; 0BC6 = 3014/4 = 753
77E 05 62 F4 0C 0B DC AA AA - 759 об/мин; 0BDC = 3036
77E 05 62 F4 0C 0B E8 AA AA - 762 об/мин; 0BE8 = 3048
77E 05 62 F4 0C 1C 32 AA AA - 1804.5 об/мин
// Температура масла
714 03 22 20 2F 55 55 55 55
77E 04 62 20 2F 36 AA AA AA - -4°С
77E 04 62 20 2F 67 AA AA AA - 45°С
77E 04 62 20 2F 68 AA AA AA - 46°С
// Температура в салоне
746 03 22 26 13 55 55 55 55
7B0 05 62 26 13 00 5B AA AA - 9.1, 91 == 0x5B
7B0 05 62 26 13 00 5C AA AA - 9.2°С
7B0 05 62 26 13 00 5D AA AA - 9.3°С
// Время
714 03 22 22 16 55 55 55 55
77E 05 62 22 16 11 1E AA AA - 17:30
// Кнопки подрулевого переключателя
714 03 22 22 1B 55 55 55 55
77E 05 62 22 1B 80 AA AA AA - не нажата
77E 05 62 22 1B 81 AA AA AA - нажата вверх
77E 05 62 22 1B 84 AA AA AA - нажата вниз
// Средний расход 2
714 03 22 22 99 55 55 55 55
77E 03 62 22 99 00 91 AA AA - 14.5л/100км
// Текущий расход
714 03 22 22 98 55 55 55 55
77E 05 62 22 98 00 00 AA AA - 0.0л/100км
// Пробег
714 03 22 22 03 55 55 55 55
77E 05 62 22 03 24 С0 AA AA - 94080 км 0x24С0 * 10
Разработка панели приборов на основе Raspberry Pi и 7? дисплея
В качестве аппаратной части я выбрал Raspberry Pi. Была идея использовать Android планшет, но показалось, что на Raspberry Pi будет проще и быстрее. В итоге докупил официальный 7? дисплей, и сделал CAN шилд из модуля TJA1050 Niren.
OBD2 штекер использовал от старого ELM327 адаптер.
Используются контакты: CAN_L, CAN_H, +12, GND.
Тесты в машине прошли успешно и теперь нужно было все собрать. Плату дисплея, Raspberry Pi и блок питания разместил на куске черного пластика, очень удачно подобрал пластмассовые втулки, с ними ничего не болтается и надежно закреплено.
Местом установки выбрал бардачок на торпедо, которым я не пользуюсь. По примеркам в него как раз помещается весь бутерброд.
Напильником довел лист черного пластика до размера крышки бардачка, к нему прикрепил бутерброд и дисплей. Для прототипа сойдет, а 3D модель с крышкой для дисплея и всеми нужными крепежами уже в разработке.
Софт панели приборов на Python и Kivy (UI framework)
Параллельно со сборкой самой панели приборов я вел разработку приложения для отображения информации с датчиков. В самом начале я не планировал какой либо дизайн.
Первая версия панели приборов
По мере разработки решил визуализировать данные более наглядно. Хотел гоночный дизайн, а получилось, что-то в стиле 80-х.
Вторая версия панели приборов
Продолжив поиски более современного дизайна я обратил внимание какие цифровые приборки делают автопроизводители и постарался сделать что-то похожее.
Третья версия панели приборов
Ранее, я никогда не разрабатывал графические приложения под Linux поэтому не знал с чего начать. Вариант на вебе простой в разработке, но слишком много лишних компонентов: иксы, браузер, nodejs, хотелось быстрой загрузки. Попробовав Qt PySide2 я понял, что это займет у меня много времени, т.к. мало опыта. Остановился на Kivy — графический фреймворк для Python, простой в понимании с полной библиотекой графических элементов и дающий возможность быстро создать мобильный интерфейс.
Kivy позволяет запускать приложение без Иксов, прямо из консоли, в качестве рендера используется OpenGL. Благодаря этому полная загрузка системы может происходить за 10 секунд.
import can
import os
import sys
from threading import Thread
import time
os.environ['KIVY_GL_BACKEND'] = 'gl'
os.environ['KIVY_WINDOW'] = 'egl_rpi'
from kivy.app import App
from kivy.properties import NumericProperty
from kivy.properties import BoundedNumericProperty
from kivy.properties import StringProperty
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.uix.scatter import Scatter
from kivy.animation import Animation
messageCommands = {
'GET_DOORS_COMMAND': 0x220D,
'GET_OIL_TEMPERATURE' : 0x202F,
'GET_OUTDOOR_TEMPERATURE' : 0x220C,
'GET_INDOOR_TEMPERATURE' : 0x2613,
'GET_COOLANT_TEMPERATURE' : 0xF405,
'GET_SPEED' : 0xF40D,
'GET_RPM' : 0xF40C,
'GET_KM_LEFT': 0x2294,
'GET_FUEL_LEFT': 0x2206,
'GET_TIME': 0x2216
}
bus = can.interface.Bus(channel='can0', bustype='socketcan')
# -*- coding: utf-8 -*-
import can
import os
import sys
from threading import Thread
import time
os.environ['KIVY_GL_BACKEND'] = 'gl'
os.environ['KIVY_WINDOW'] = 'egl_rpi'
from kivy.app import App
from kivy.properties import NumericProperty
from kivy.properties import BoundedNumericProperty
from kivy.properties import StringProperty
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.uix.scatter import Scatter
from kivy.animation import Animation
messageCommands = {
'GET_DOORS_COMMAND': 0x220D,
'GET_OIL_TEMPERATURE' : 0x202F,
'GET_OUTDOOR_TEMPERATURE' : 0x220C,
'GET_INDOOR_TEMPERATURE' : 0x2613,
'GET_COOLANT_TEMPERATURE' : 0xF405,
'GET_SPEED' : 0xF40D,
'GET_RPM' : 0xF40C,
'GET_KM_LEFT': 0x2294,
'GET_FUEL_LEFT': 0x2206,
'GET_TIME': 0x2216
}
bus = can.interface.Bus(channel='can0', bustype='socketcan')
class PropertyState:
def __init__(self, last, current):
self.last = last
self.current = current
def lastIsNotNow(self):
return self.last is not self.current
class CanListener(can.Listener):
def __init__(self, dashboard):
self.dashboard = dashboard
self.speedStates = PropertyState(None,None)
self.rpmStates = PropertyState(None,None)
self.kmLeftStates = PropertyState(None,None)
self.coolantTemperatureStates = PropertyState(None,None)
self.oilTempratureStates = PropertyState(None,None)
self.timeStates = PropertyState(None,None)
self.outDoorTemperatureStates = PropertyState(None,None)
self.doorsStates = PropertyState(None,None)
self.carMinimized = True
def on_message_received(self, message):
messageCommand = message.data[3] | message.data[2] << 8
if message.arbitration_id == 0x77E and messageCommand == messageCommands['GET_SPEED']:
self.speedStates.current = message.data[4]
if self.speedStates.lastIsNotNow():
self.dashboard.speedometer.text = str(self.speedStates.current)
self.speedStates.last = self.speedStates.current
if message.arbitration_id == 0x77E and messageCommand == messageCommands['GET_RPM']:
self.rpmStates.current = message.data[5] | message.data[4] << 8
if self.rpmStates.lastIsNotNow():
self.dashboard.rpm.value = self.rpmStates.current/4
self.rpmStates.last = self.rpmStates.current
if message.arbitration_id == 0x35B:
self.rpmStates.current = message.data[2] | message.data[1] << 8
if self.rpmStates.lastIsNotNow():
self.dashboard.rpm.value = self.rpmStates.current/4
self.rpmStates.last = self.rpmStates.current
if message.arbitration_id == 0x77E and messageCommand == messageCommands['GET_KM_LEFT']:
self.kmLeftStates.current = message.data[5] | message.data[4] << 8
if self.kmLeftStates.lastIsNotNow():
self.dashboard.kmLeftLabel.text = str(self.kmLeftStates.current)
self.kmLeftStates.last = self.kmLeftStates.current
if message.arbitration_id == 0x77E and messageCommand == messageCommands['GET_COOLANT_TEMPERATURE']:
self.coolantTemperatureStates.current = message.data[4]
if self.coolantTemperatureStates.lastIsNotNow():
self.dashboard.coolantLabel.text = str(self.coolantTemperatureStates.current-81)
self.coolantTemperatureStates.last = self.coolantTemperatureStates.current
if message.arbitration_id == 0x77E and messageCommand == messageCommands['GET_OIL_TEMPERATURE']:
self.oilTempratureStates.current = message.data[4]
if self.oilTempratureStates.lastIsNotNow():
self.dashboard.oilLabel.text = str(self.oilTempratureStates.current-58)
self.oilTempratureStates.last = self.oilTempratureStates.current
if message.arbitration_id == 0x77E and messageCommand == messageCommands['GET_TIME']:
self.timeStates.current = message.data[5] | message.data[4] << 8
if self.timeStates.lastIsNotNow():
self.dashboard.clock.text = str(message.data[4]) + ":" + str(message.data[5])
self.timeStates.last = self.timeStates.current
if message.arbitration_id == 0x77E and messageCommand == messageCommands['GET_OUTDOOR_TEMPERATURE']:
self.outDoorTemperatureStates.current = float(message.data[4])
if self.outDoorTemperatureStates.lastIsNotNow():
self.dashboard.outDoorTemperatureLabel.text = str((self.outDoorTemperatureStates.current - 100)/2)
self.outDoorTemperatureStates.last = self.outDoorTemperatureStates.current
if message.arbitration_id == 0x77E and messageCommand == messageCommands['GET_DOORS_COMMAND']:
self.doorsStates.current = message.data[4]
if self.doorsStates.lastIsNotNow():
self.doorsStates.last = self.doorsStates.current
self.dashboard.car.doorsStates=message.data[4]
# all doors closed -> minimize car
if self.doorsStates.current == 0x55:
self.dashboard.minimizeCar()
self.carMinimized = True
else:
if self.carMinimized:
self.dashboard.maximizeCar()
self.carMinimized = False
class Dashboard(FloatLayout):
def __init__(self,**kwargs):
super(Dashboard,self).__init__(**kwargs)
# Background
self.backgroundImage = Image(source='bg.png')
self.add_widget(self.backgroundImage)
# RPM
self.rpm = Gauge(file_gauge = "gauge512.png", unit = 0.023, value=0, size_gauge=512, pos=(0,0))
self.add_widget(self.rpm)
self.rpm.value = -200
# Speedometer
self.speedometer = Label(text='0', font_size=80, font_name='hemi_head_bd_it.ttf', pos=(0,-15))
self.add_widget(self.speedometer)
# KM LEFT
self.kmLeftLabel = Label(text='000', font_name='Avenir.ttc', halign="right", text_size=self.size, font_size=25, pos=(278,233))
self.add_widget(self.kmLeftLabel)
# COOLANT TEMPEARATURE
self.coolantLabel = Label(text='00', font_name='hemi_head_bd_it.ttf', halign="right", text_size=self.size, font_size=27, pos=(295,-168))
self.add_widget(self.coolantLabel)
# OIL TEMPERATURE
self.oilLabel = Label(text='00', font_name='hemi_head_bd_it.ttf', halign="right", text_size=self.size, font_size=27, pos=(-385,-168))
self.add_widget(self.oilLabel)
# CLOCK
self.clock = Label(text='00:00', font_name='Avenir.ttc', font_size=27, pos=(-116,-202))
self.add_widget(self.clock)
# OUTDOOR TEMPERATURE
self.outDoorTemperatureLabel = Label(text='00.0', font_name='Avenir.ttc', halign="right", text_size=self.size, font_size=27, pos=(76,-169))
self.add_widget(self.outDoorTemperatureLabel)
# CAR DOORS
self.car = Car(pos=(257,84))
self.add_widget(self.car)
def minimizeCar(self, *args):
print("min")
anim = Animation(scale=0.5, opacity = 0, x = 400, y = 240, t='linear', duration=0.5)
anim.start(self.car)
animRpm = Animation(scale=1, opacity = 1, x = 80, y = -5, t='linear', duration=0.5)
animRpm.start(self.rpm)
def maximizeCar(self, *args):
print("max")
anim = Animation(scale=1, opacity = 1, x=257, y=84, t='linear', duration=0.5)
anim.start(self.car)
animRpm = Animation(scale=0.5, opacity = 0, x = 80, y = -5, t='linear', duration=0.5)
animRpm.start(self.rpm)
class Car(Scatter):
carImage = StringProperty("car362/car.png")
driverDoorClosedImage = StringProperty("car362/driverClosedDoor.png")
driverDoorOpenedImage = StringProperty("car362/driverOpenedDoor.png")
passangerDoorClosedImage = StringProperty("car362/passangerClosedDoor.png")
passangerDoorOpenedImage = StringProperty("car362/passangerOpenedDoor.png")
leftDoorClosedImage = StringProperty("car362/leftClosedDoor.png")
leftDoorOpenedImage = StringProperty("car362/leftOpenedDoor.png")
rightDoorClosedImage = StringProperty("car362/rightClosedDoor.png")
rightDoorOpenedImage = StringProperty("car362/rightOpenedDoor.png")
doorsStates = NumericProperty(0)
size = (286, 362)
def __init__(self, **kwargs):
super(Car, self).__init__(**kwargs)
_car = Image(source=self.carImage, size=self.size)
self.driverDoorOpened = Image(source=self.driverDoorOpenedImage, size=self.size)
self.passangerDoorOpened = Image(source=self.passangerDoorOpenedImage, size=self.size)
self.leftDoorOpened = Image(source=self.leftDoorOpenedImage, size=self.size)
self.rightDoorOpened = Image(source=self.rightDoorOpenedImage, size=self.size)
self.driverDoorClosed = Image(source=self.driverDoorClosedImage, size=self.size)
self.passangerDoorClosed = Image(source=self.passangerDoorClosedImage, size=self.size)
self.leftDoorClosed = Image(source=self.leftDoorClosedImage, size=self.size)
self.rightDoorClosed = Image(source=self.rightDoorClosedImage, size=self.size)
self.add_widget(_car)
self.add_widget(self.driverDoorOpened)
self.add_widget(self.passangerDoorOpened)
self.add_widget(self.leftDoorOpened)
self.add_widget(self.rightDoorOpened)
self.bind(doorsStates=self._update)
def _update(self, *args):
driverDoorStates = self.doorsStates&1
passangerDoorStates = self.doorsStates&4
leftDoorStates = self.doorsStates&16
rightDoorStates = self.doorsStates&64
if driverDoorStates != 0:
try:
self.remove_widget(self.driverDoorOpened)
self.add_widget(self.driverDoorClosed)
except:
pass
else:
try:
self.remove_widget(self.driverDoorClosed)
self.add_widget(self.driverDoorOpened)
except:
pass
if passangerDoorStates != 0:
try:
self.remove_widget(self.passangerDoorOpened)
self.add_widget(self.passangerDoorClosed)
except:
pass
else:
try:
self.remove_widget(self.passangerDoorClosed)
self.add_widget(self.passangerDoorOpened)
except:
pass
if leftDoorStates != 0:
try:
self.remove_widget(self.leftDoorOpened)
self.add_widget(self.leftDoorClosed)
except:
pass
else:
try:
self.remove_widget(self.leftDoorClosed)
self.add_widget(self.leftDoorOpened)
except:
pass
if rightDoorStates != 0:
try:
self.remove_widget(self.rightDoorOpened)
self.add_widget(self.rightDoorClosed)
except:
pass
else:
try:
self.remove_widget(self.rightDoorClosed)
self.add_widget(self.rightDoorOpened)
except:
pass
class Gauge(Scatter):
unit = NumericProperty(1.125)
zero = NumericProperty(116)
value = NumericProperty(10) #BoundedNumericProperty(0, min=0, max=360, errorvalue=0)
size_gauge = BoundedNumericProperty(512, min=128, max=512, errorvalue=128)
size_text = NumericProperty(10)
file_gauge = StringProperty("")
def __init__(self, **kwargs):
super(Gauge, self).__init__(**kwargs)
self._gauge = Scatter(
size=(self.size_gauge, self.size_gauge),
do_rotation=False,
do_scale=False,
do_translation=False
)
_img_gauge = Image(source=self.file_gauge, size=(self.size_gauge, self.size_gauge))
self._needle = Scatter(
size=(self.size_gauge, self.size_gauge),
do_rotation=False,
do_scale=False,
do_translation=False
)
_img_needle = Image(source="arrow512.png", size=(self.size_gauge, self.size_gauge))
self._gauge.add_widget(_img_gauge)
self._needle.add_widget(_img_needle)
self.add_widget(self._gauge)
self.add_widget(self._needle)
self.bind(pos=self._update)
self.bind(size=self._update)
self.bind(value=self._turn)
def _update(self, *args):
self._gauge.pos = self.pos
self._needle.pos = (self.x, self.y)
self._needle.center = self._gauge.center
def _turn(self, *args):
self._needle.center_x = self._gauge.center_x
self._needle.center_y = self._gauge.center_y
a = Animation(rotation=-self.value*self.unit + self.zero, t='in_out_quad',duration=0.05)
a.start(self._needle)
class requestsLoop(Thread):
def __init__(self):
Thread.__init__(self)
self.daemon = True
self.start()
canCommands = [
can.Message(arbitration_id=0x714, data=[0x03, 0x22, messageCommands['GET_DOORS_COMMAND'] >> 8, messageCommands['GET_DOORS_COMMAND'] & 0xff, 0x55, 0x55, 0x55, 0x55], extended_id=False),
can.Message(arbitration_id=0x714, data=[0x03, 0x22, messageCommands['GET_SPEED'] >> 8, messageCommands['GET_SPEED'] & 0xff, 0x55, 0x55, 0x55, 0x55], extended_id=False),
can.Message(arbitration_id=0x714, data=[0x03, 0x22, messageCommands['GET_KM_LEFT'] >> 8, messageCommands['GET_KM_LEFT'] & 0xff, 0x55, 0x55, 0x55, 0x55], extended_id=False),
can.Message(arbitration_id=0x714, data=[0x03, 0x22, messageCommands['GET_RPM'] >> 8, messageCommands['GET_RPM'] & 0xff, 0x55, 0x55, 0x55, 0x55], extended_id=False),
can.Message(arbitration_id=0x714, data=[0x03, 0x22, messageCommands['GET_OIL_TEMPERATURE'] >> 8, messageCommands['GET_OIL_TEMPERATURE'] & 0xff, 0x55, 0x55, 0x55, 0x55], extended_id=False),
can.Message(arbitration_id=0x714, data=[0x03, 0x22, messageCommands['GET_FUEL_LEFT'] >> 8, messageCommands['GET_FUEL_LEFT'] & 0xff, 0x55, 0x55, 0x55, 0x55], extended_id=False),
can.Message(arbitration_id=0x714, data=[0x03, 0x22, messageCommands['GET_OUTDOOR_TEMPERATURE'] >> 8, messageCommands['GET_OUTDOOR_TEMPERATURE'] & 0xff, 0x55, 0x55, 0x55, 0x55], extended_id=False),
can.Message(arbitration_id=0x746, data=[0x03, 0x22, messageCommands['GET_INDOOR_TEMPERATURE'] >> 8, messageCommands['GET_INDOOR_TEMPERATURE'] & 0xff, 0x55, 0x55, 0x55, 0x55], extended_id=False),
can.Message(arbitration_id=0x714, data=[0x03, 0x22, messageCommands['GET_COOLANT_TEMPERATURE'] >> 8, messageCommands['GET_COOLANT_TEMPERATURE'] & 0xff, 0x55, 0x55, 0x55, 0x55], extended_id=False),
can.Message(arbitration_id=0x714, data=[0x03, 0x22, messageCommands['GET_TIME'] >> 8, messageCommands['GET_TIME'] & 0xff, 0x55, 0x55, 0x55, 0x55], extended_id=False)
]
def run(self):
while True:
for command in self.canCommands:
bus.send(command)
time.sleep(0.005)
class BoxApp(App):
def build(self):
dashboard = Dashboard();
listener = CanListener(dashboard)
can.Notifier(bus, [listener])
return dashboard
if __name__ == "__main__":
# Send requests
requestsLoop()
_old_excepthook = sys.excepthook
def myexcepthook(exctype, value, traceback):
if exctype == KeyboardInterrupt:
print "Handler code goes here"
else:
_old_excepthook(exctype, value, traceback)
sys.excepthook = myexcepthook
# Show dashboard
BoxApp().run()
Алгоритм работы следующий, используется 3 потока:
- В главном потоке работаем с графическими элементы (спидометр, тахометр, часы, температуры и др) на экране
- Во втором потоке каждые 5 мс делаем опрос следующего датчика
- В третьем потоке слушаем CAN шину, получив ответ парсим его и обновляем соответствующий графический элемент
Работает стабильно, самый долгий процесс в разработке был связан с рисованием дизайна. На данный момент обкатываю решение и потихоньку пишу мобильное приложение для iOS, чтобы любой мог попробовать цифровую панель приборов.
Проект цифровой панель приборов открытый. Рад буду предложениям и комментариям!
https://github.com/aivs/blackCockpit
Видео работы цифровой панели приборов на базе Raspberry Pi
Комментарии (173)
cyber_roach
24.04.2019 11:50+1На данный момент обкатываю решение и потихоньку пишу мобильное приложение для iOS, чтобы любой мог попробовать цифровую панель приборов.
А как данные будут поступать на мобильное ПО? придется какую-то железяжку подключать?aivs Автор
24.04.2019 11:53+1ELM327 Wi-Fi
adlerm
24.04.2019 12:21Если для грубой оценки «как это примерно выглядит», то сильно ли оно будет отличаться от того, же, уже готового, приложения вроде torque в которых можно самостоятельно нагромоздить графиков большинства датчиков и параметров… (плюсом, почитать, стереть ошибки и пр.)
вот пример скрина в описании проги:
aivs Автор
24.04.2019 12:31Я знаю torque. Я хочу сделать панель приборов, которая смогла бы заменить штатную. Дизайн очень важен. Считывание и стирание ошибок пока не планирую, хотя это возможно.
adlerm
24.04.2019 12:35Прекрасная идея и проделанная работа… Основная проблема, предполагаю, это эстетический момент внедрения этого в автомобиль?
aivs Автор
24.04.2019 12:41Спасибо. Да, к сожалению в Octavia единственное нормальное место для установки монитора это место штатной магнитолы, все остальное колхоз.
AllexIn
24.04.2019 12:42Да везде так.
Ни в одной машине «нет штатного пустого дополнительного места для 7'' дисплея».
Кстати, а какая модель дисплея используется? Я тут купил очень похожий на ваш, под такую же задачу… А он, собака, не хочет заводится на RPI.aivs Автор
24.04.2019 13:08+1У меня оригинальный дисплей, но он не очень мне нравится, черный не черный, круглое выглядит как эллипс.
www.raspberrypi.org/products/raspberry-pi-touch-display
А вот как я бы хотел чтобы выглядело в машине. Это системе Carsara.
gibson_dev
24.04.2019 13:43Посмотрите на это
ru.aliexpress.com/item/5-5-AMOLED-AMOLED/32974946179.html
взял отсюда mysku.ru/blog/aliexpress/72287.htmlaivs Автор
24.04.2019 15:32Дисплей крутой, но диагональ поменьше и дороже он. В остальном то, что нужно.
Alexeyslav
24.04.2019 16:53Для АМОЛЕД дисплея нужен ещё алгоритм предотвращения выгорания, для статичных картинок и долгой работы он не очень подходит. И если для основных шкал это ещё терпимо(они-то не меняются, хоть и выгорают) то для цифровых областей где цифры мало меняются(область индикатора топливного бака) это будет проблемой.
tuxi
24.04.2019 14:58Я хочу сделать панель приборов, которая смогла бы заменить штатную
А у экрана какие хар-ки по части рабочих температур?
maxik0
25.04.2019 10:44А обязательно данные снимать по проводам? Что-то такого типа не все данные умеет считывать?
ru.aliexpress.com/item/Elm327-V1-5-Bluetooth-OBD2-elm327-1-5/32961354257.html?spm=a2g0v.search0604.3.72.680e2b59HVlX97&ws_ab_test=searchweb0_0%2Csearchweb201602_8_10065_10068_319_317_10696_453_10084_454_10083_10618_10307_10301_537_536_10059_10884_10889_10887_321_322_10915_10103_10914_10911_10910%2Csearchweb201603_16%2CppcSwitch_0&algo_pvid=0ba785d4-c416-459e-a6a6-b17644826b5c&algo_expid=0ba785d4-c416-459e-a6a6-b17644826b5c-10
aivs Автор
25.04.2019 10:45Сейчас как раз и делаю мобильное приложение, которое теже данные будет получать по wi-fi от elm327.
maxik0
25.04.2019 18:50Ну тут не wifi а bluetooth. Но пойдет, в общем? Кстати, а ведь распберри умеет блютуз, стоило ли провода тащить к разъёму тогда?
aivs Автор
25.04.2019 19:02Через elm327 не получится обновлять обороты каждые 5 мс. Как минимум 50 мс, а в реале все 100 мс.
Хочется максимальноц скорости
pewpew
24.04.2019 11:54+1Круто! Приятно видеть завершённый проект.
Я пытался сделать нечто подобное для своей шеви-нивы, но столкнулся с особенностями подключения по OBD II к ECU Bosh, и так и не смог заставить гонять даже простую диагностику через Torque из-за хитрой инициализации. Так и не вышло подобрать нужную AT-последовательность. В итоге забил и довольствовался штатным БК, который умел только показывать коды ошибок. До сниффа протокола руки не дошли.aivs Автор
24.04.2019 12:17Я провел очень много времени в машине, чтобы добиться того что хотел.
В итоге сейчас добавить функцию это делов на несколько десятков минут.
engine9
24.04.2019 11:55+1Мне понравился дизайн, автор молодец.
А это железо и софт сможет потянуть несложную 3Д графику?
— Поликаунт примерно 400 000 треугольников или меньше
— Текстурирование, в идеале две текстуры в два независимых UV канала (освещение и цвет поверхности, как в играх времен half life 1).
— Шейдеры и всякие модные PBR не обязательно
Например, типа как на картинке. Идея в том, чтобы создавать интерфейс интерактивных схем, планов объектов, навигаторов по помещениям и т.п.
aivs Автор
24.04.2019 12:06На RPi3 Quake 3 работает. В качестве Ui фреймворка у меня Kivy, он умеет с 3d графикой работать, но я не пробовал.
lgorSL
24.04.2019 12:15На википедии пишут, что Raspberri Pi поддерживает OpenGL ES 2.0 — т.е., есть и текстуры и пискльные/вершинные шейдеры. Про производительность можно почитать здесь: https://www.raspberrypi.org/forums/viewtopic.php?t=88058, якобы без текстур и освещения можно рисовать 19миллионов треугольников в секунду.
shaggyone
24.04.2019 12:09Знаете чего не хватает у вас (как и в интерфейсах пожалуй всех авто). Количества топлива в баке тупо в литрах. Сигналка моего прошлого авто умела эту информацию на брелок выводить, скажу вам, это очень удобно.
aivs Автор
24.04.2019 12:23Это не сложно, я же получаю числовое значение в литрах, можно и вывести.
Я отлавливаю нажатия кнопок подрулевого переключателя, могу с его помощью менять отображения, со шкалы на числовое.
AllexIn
24.04.2019 12:32+1Знаете почему ни одна приборка не выводит информацию «тупо в литрах»?
Потому что не знает её.
Датчик топлива показывает плюс минус тонну. Поэтому и показывают стрелку или шкалу с примерным количеством. Показать напрямую значение с датчика — ввести пользователя в заблуждение и словить минус в карму от разгневанных владельцев.shaggyone
24.04.2019 12:47Не поверите, но знаю. Тем не менее я почти 3 года этой информацией руководствовался на заправке и ни разу не прогадал. Точность +- литр. Пожалуй, соглашусь, что в движении это не очень полезная информация, вот на заправке или в начале пути, вполне себе.
AllexIn
24.04.2019 12:49+1Вам повезло с калибровкой.
Обеспечить достаточную точность в каждом автомобиле нельзя/дорого. Поэтому шкала.
Хотя тут конечно кастомная приборка, можно и вывести. Тут согласен.shaggyone
24.04.2019 13:33Я сам сварщик не настоящий, но подозреваю, что не так неплохо у машин с этой калибровкой, просто инерция разработчиков. Потом, всегда ведь можно откалибровать, естественно заложив запас литров в 5, или сколько там обычно на авто делают.
AllexIn
24.04.2019 13:40+1Как?
Датчик что-то адекватно покажет только на ровной поверхности без движения.
Если увеличивать точность — надо дополнитиельные датчики и алгоритмы подключать. Что приведет к удорожанию, и не особо нужно.shaggyone
24.04.2019 13:45По мне, описываем в инструкции все перечисленные проблемы. Показываем цифры только когда машина стоит на месте (либо в режиме парковки). Можно ещё и предупреждение показывать (моя новая Kia, каждый раз напоминает об аккуратности за рулём, могла бы и уровень топлива показывать, с пометкой, что может ошибаться).
Alexeyslav
24.04.2019 17:04Нет, там проблема датчика в другом — у него имеется дискретность. Т.к. он представляет собой полавок подключенный к проволочному переменному резистору. Во многих машинах два поплавка или конструкция поплавка такая что его положение слабо зависит от качки. Проблема именно в дискретности. И соответственно датчик показывает в у.е. в литры переводить надо знать объём бака. А поскольку сами у.е. дискретны, потом ещё умножаем на емкость бака, которая тоже варьируется… получается +- лапоть, значения не кратные литрам и откалибровать очень муторно. По литру топливо заливать и записывать значения. Ну да, конечно же у датчика есть нижняя граница, например меньше 5л в баке он уже не покажет и это тоже зависит от того как этот датчик на заводе поставили и как он на кочках погнулся в процессе эксплуатации.
Tutanhomon
24.04.2019 18:27А еще эта резистивная оплетка имеет свойство менять свою равномерность, ведь по ней постоянно вверх-вних ползает ползунок, который может смещать витки, в итоге пропадает линейная зависимость, и простой формулой для калибровки не обойтись. У меня так на сивике было, замечал что в середине шкалы расход замирал, а потом ускорялся. Разобрал датчик топлива — там неравномерно витки лежали. Да и степень окисления разная. Так что это дело работает «на глазок».
playnet
25.04.2019 11:38Ровная поверхность — ставим датчик наклона. Неподвижность — датчик ускорения. Калибруем всё на 1 машине, «наклон 5 градусов, бензин 20л, предполагается получение информации с датчиков… реальные показания..» и потом на каждой условно калибруемся по пустому баку, 20л, 20л при наклоне 10 градусов, полный бак, полный бак при наклоне -15 градусов. Ускорение — только расчётные данные.
Датчики потянут на пару долларов + сертификация.
Опять же, софтовые изменения — делаются для всех машин сразу, сильно цену не изменят. Другое дело что это сильно не нужно, но я почти уверен что это всё уже в каких-нибудь машинах есть, просто показывают как привычнее пользователю, а привыкли к шкалам. Может через obd можно получить абсолютные значения у каких-то машин.Alexeyslav
26.04.2019 11:34+1Есть масса более простых и предсказуемых датчиков для измерения ровня топлива. При программной коррекции появляется масса мест возникновения погрешности, ньюансов работы которые так просто и не выявишь на этапе проектирования и иные сложности которые в итоге имеют конкретный экономический вес не в пользу грубых но простых датчиков. Знать точный объём топлива в баке? Это фетишь… на самом деле водителю нужно знать перед поездкой на 500км хватит ли топлива чтобы доехать без дозаправки, и если по грубым подсчетам в притык, то это лишь повод заехать на ближайшую заправку. И так если посмотреть, то этим обычно страдают водители которые ВЕЧНО ездят на остатках бензина в баке, дескать бензин дорогой, ага. Буд-то это как-то способно сэкономить денег. Нормальное состояние бака перед любой боле-менее длительной поездкой — это полный бак. Если топлива половина бака — это повод при удобной возможности заехать на заправку.
Squoworode
28.04.2019 07:18Калибруем всё на 1 машине
и потом на каждой условно калибруемся
Но ведь у каждой модели своя геометрия бака. Это ж не параллелепипед.
adlerm
24.04.2019 16:18почему же… у одной и той же модели, одинаковые бензобаки, одинаковые датчики… теоретически, на заводе откалибровать один автомобиль из модельного ряда(дело пары часов), а потом эти данные использовать в ПО…
AllexIn
24.04.2019 16:56В данной ситуации — калибровка, это не только настройка датчика. С этим то проблем нет по большей части.
Много факторов надо учитывать при движении. Сложный алгоритм.
И опять же — зачем?
Зачем знать осталость 5 литров, или 10? В любом случае пора заправляться. Потому что на прямой можно ехать при 5, а на склоне можно и заглохнуть. Словить клин насоса из-за осушения бака. ЗАсрать фильтр осадком с бака.
Бензин — не таштука. которую нужно восполнять на нуле. А если у нас нет требования к знанию точного нуля — то и геморрой с точными показаниями датчика не нужны.
При это я понимаю желание иметь точное значение на приборке. Это фетиш. Я сам на приборку кучу херни сейчас вывожу, потому что это же круто знать всё о машине! Еще и теллеметрию пишу… Но это именно потому что хочется, а не потому что объективно надо.
Alexeyslav
24.04.2019 17:10Бывает, технологически ставят разные баки. Пошла другая партия, бак чуть шире или выше и вмещает +1 литр от предыдущего. Бывает, одна и та же модель но датчик ставят уже другой, с другой нелинейностью и своими особенностями… Пара часов калибровки на заводе на каждый автомобиль выливается в лишние потраченные тысячи человеко-часов на производство автомобиля, а значит упущенная прибыль…
aivs Автор
24.04.2019 12:56+1Я обнаружил 3 разных показания о остатке топлива в баке.
1) Датчик в баке показывает 18л когда стою на месте. При движении показания сильно меняются, от 10 до 30л.
2) Рассчитанный примерный остаток, показывает 16.5л
3) Положение стрелки топлива в баке в градусах
Я ориентируюсь на второй вариантKwisatz
24.04.2019 19:12У меня в BMW E39 большая проблема с жизнеспособностью этих датчиков, спасибо нашему милому бензину: то воды нальют то еще какой фигни (супруга пролила немного при заправке с канистры, в итоге оттереть не могу вообще ничем теперь).
ЗЫ смотрю на вашу штуку, хочу) но с железом возиться просто не умеюaivs Автор
24.04.2019 19:16Я пишу приложение Панель приборов для iPad/iPhone, дизайн будет такой же как в текущем проекте, сначала только для VAG, если будет интерес, то для BMW и других марок возможно будет сделать.
Black_Zerg
24.04.2019 21:41Не знаю у меня показывает остаток топлива в баке в литрах. Точность шага 5 литров. Шкода Йети, концерн ВАГ
200sx_Pilot
24.04.2019 23:17Почему не знают?
Древние Супры, Марки, и прочие Ниссан Либерти…
Точность, правда, ± верста, но её вполне хватает.
kAIST
25.04.2019 09:11Однако же машины показывают остаток по пробегу достаточно дочно. Плюс показывают остаток свободного места в баке в литрах. И если последнее полезно (сколько можно заправить безнина), то остаток бензина именно в литрах, а не по пробегу, даже не знаю чем может быть полезен, в отличии от остатка пробега.
BDI
25.04.2019 12:05Основываясь на каком расходе показывается прогноз пробега в конкретном авто нужно ещё выяснять. Знаю как минимум два варианта:
1. По среднему расходу с момента последнего сброса счётчика в маршрутном компьютере.
2. По среднему расходу за последний период(обычно порядка 10км, возможно у кого-то и по времени период).
При этом диапазон расхода на своём авто обычно представляешь довольно точно — пределы, в зависимости от обстановки. Бортовой комп окружающей обстановкой не владеет. Допустим попал в пробку(например на бетонке), примерно представляешь сколько ты в ней простоишь. Есть две заправки — одна вскоре, прямо на бетонке(но вопрос контроля качества на загородных АЗС очень непредсказуем), другая, проверенная, километров через 70. 70 км это примерно 6 литров(с учётом текущей пробки). У меня бак 54л, и 8 секций на указателе уровня топлива(есть подозрение что две нижние секции по диапазону как одна верхняя — последняя уже минималка, с лампочкой минимального остатка). Получается дискретность показаний уровня топлива примерно 6.75л. И вот смотрю я на уровень — три клетки. А это сколько? 20.25л? Тогда не парюсь, и заправляюсь на проверенной. Или же это уже 13.6л(чуть больше чем при двух секциях уровня)? Тогда лучше рискнуть непроверенной заправкой, и долить в бак чтобы точно хватило до проверенной(не люблю езду с двумя клетками).
Если же ездить только в местности где полно надёжных заправок, тогда да — в большинстве ситуаций хватит даже того недоразумения что у меня штатно на торпеде стоит.
Себе поставил мультитроникс — лежит в бардачке, данные выводит по BT на телефон(у них своё приложение). При тарировке бака по двум точкам дал мне точность остатка примерно ± 1 литр в крайних зонах(легко проверяется заправкой до полного бака, с поправкой на борзость АЗС, и объём приёмной трубы). В середине бака может подвирать больше, но не критично — точность указателя на торпеде гораздо хуже во всём диапазоне. Мне хватает :). Кому мало — есть режим калибровки по 7 точкам, вооружаемся мерной ёмкостью и калибруем бак(но мне кажется это для ситуаций с сильно кривым баком, или сильно нелинейным ДУТ).
По поводу колебания уровня в баке при движении — как минимум мультитрониксовский усредняет показания, и если вы 5 минут(грубо говоря, не мерял) подряд не стоите в горку, то показания не исказятся. Да и стрелочный в зубиле тоже не мгновенно дёргался вслед за поплавком(кстати, потенциометр там был не проволочный).
Stanislavvv
26.04.2019 12:39Хм… Не знаю как, но в моей 2114 аж 2006 г. штатный «компьютер» таки выводил количество топлива в баке с точностью ± литра два в зависимости от того, насколько косо поставил на не особо ровной стоянке. К сожалению, не посмотрел, есть ли это в CAN.
Так что, подозреваю, что тут дело в чём-то другом.AllexIn
26.04.2019 13:12Прочитайте комменты вокруг. Уже все объяснили несколько раз.
Показания колеблются от множества факторов, плюс даже в идеальныхз условиях погрешность плюс минус десяток литров.
Так что то что компьютер что-то там выводи, не значит что он это знает. Это сильно ориентировочное значение.Stanislavvv
26.04.2019 13:33Судя по изменениям после слива/заправки в состоянии со снятым аккумулятором — пересчитывается из показаний поплавкового датчика, так что компьютер — таки знает.
Оно, конечно, ориентировочное, но совпадает с реальностью достаточно неплохо, порядка ± 5% в относительно ровном Екатеринбурге и ± 10% в э… холмистой местности. Для большинства применений такой точности более, чем достаточно.AllexIn
26.04.2019 13:35Совершенно верно. Для большинства применений(собственно применение одно — оценка оставшегося пробега) этого и достаточно. Поэтому и показывают оставшийся пробег, а не количество литров.
Alexeyslav
26.04.2019 13:25Неоднократно видел обсуждение датчиков топлива на радиотехнических форумах, там пытались сделать точный индикатор количества топлива. Так вот это в принципе невозможно со штатными датчиками — это связано с их конструкцией. Датчики эти проволочные ибо дешёвые и меньше стираются со временем и там как раз получается что одному витку такого датчика соответствует шаг уровня топлива в баке порядка 2л. А для грузовых авто с большим баком и того больше.
Есть, конечно, другие датчики измерения объёма топлива в баке но кроме гораздо большей стоимости у них есть и свои недостатки. Например, зависимость от примесей в топливе, смачиваемость датчика топливом(емкостные датчики), низкая надёжность в целом из-за сложности и т.д.
ganzmavag
24.04.2019 18:34У VAG бывает такая опция, можно вывести на дисплей. Причем показывает даже не остаток, а сколько еще войдет литров. С запасом, чтобы не получилось, что вдруг не вошло.
Сколько читал отзывов — говорят, довольно точно, не обманывает.johndow
24.04.2019 20:20Я VCDSом включил её себе.
Перестраховывается он, зараза. До 5 литров как минимум. Люблю заправляться до полного, но чтобы не бегать туда-сюда до кассы. Говорит 30 литров можно заправить, заправляешь 30, а показометр даже не на максимум встаёт.
nevzorofff
25.04.2019 00:54С «не вошло» не испытываю никаких проблем. Возвращаюсь на кассу и всё. У Башнефти при оплате через терминал ВБРР(у них два, один для клиентов Сбера, второй для всех) — можно даже не заходить: пистолет повесил и всё. «Император» за кассой как нажмёт окончание заправки — так деньги на карту и вернутся. А если Сбер, то идёшь, отменяют первую транзкцию, и проводят вторую на фактическую сумму.
Заправляюсь всегда до полного, чтобы реже заезжать на АЗС.
kolyandex
24.04.2019 12:32Использовать диагностические запросы (я правильно понял?) для получения данных не очень удобно, кмк. Не знаю как у вагов, но у японцев все эти данные можно получить не отправляя никаких запросов, в салонной шине все свободно гуляет.
Еще заметил, что у вас не значащие байты в кадрах ISO-TP забиты 0x55 или 0xAA, как положено, а вот все у тех же японцев там мусор, оставшийся от предыдущих сообщений в буфере. VAG — Mitsubishi — 1:0aivs Автор
24.04.2019 12:39У меня есть версия приборки, которая подключается непосредственно к CAN шине, в этом случае не нужно вести опрос. Но вычислять сниффером что означает каждый пакет очень трудоемко, потому что информация с некоторых датчиков не часто обновляется. Вывел только часть приборов и забил.
В япошках и корейцах через OBD2 можно спокойно слушать CAN шину, там проще.
adlerm
24.04.2019 12:57+1У современных ваг 2 кан шины… одна «высокоскоростная» по которой идут «важные данные» и другая «низкоскоростная» по которой шуруют данные, что описаны в статье. Обе они заводятся на блок (вроде, обычно, «19») а он уже подключен к диагностическому разъему. можно, конечно, подключиться непосредственно к низкоскоростной кан шине, но тогда, как написал автор, некоторые датчики редко обновляются. Это первый момент.
Второй, это то, что некоторые блоки(если их можно так назвать) не подключены к кан шине, а на них заведен другой интерфейс- однопроводной LIN, а он уже подключен к тому же блоку «19»… и через него уже становится возможным прочитать данные с этих блоков. (для примера, так подключены, реле регулятора генератора(выдает довольно много параметров), датчик на АКБ (выдает температуру, зарядный/разрядный ток, и др.)и, вроде, компрессор кондиционера).aivs Автор
24.04.2019 13:12Как я понял некоторые данные генерирует сама приборка, например градус стрелки количества литров в баке и этой информации нет в низкоскоростной CAN шине. Эту информацию можно запросить только через диагностический разъем.
kolyandex
24.04.2019 14:09В моем япе сигнал из бака идет прямо в приборку, а она в двух разных пакетах уже выдает обработанные сглаженные данные.
aivs Автор
24.04.2019 14:30Смотрел распиновку приборки и в моей машине датчик в баке напрямую связан с приборкой, а приборка уже в кан шину выплевывает показания.
kolyandex
24.04.2019 14:38То то я смотрю они очень похожи. Сеть построена аналогично, очень похожие диагностические запросы.
esaulenka
24.04.2019 20:59Диагностика везде внешне похожа, это вариации на основе ISO 14229.
Вот со второго взгляда начинаются отличия — другие ID пакетов, нестандартные PID'ы и т.д…
2ruslank
24.04.2019 13:47Как раз на днях тоже заинтересовался этой темой. Кан шина вроде выходит и к магнитоле? Не пытались подключится там?
aivs Автор
24.04.2019 14:27На магнитиле есть кан шина, на нее же выводятся показания температуры, парктроника и др. Я подключался к кан шине в районе приборке, там же и охранная система подключена.
Fox_Alex
24.04.2019 13:48Отличная работа! Тоже думал запилить свою приборку, правда на механических стрелках. Подскажи, там вообще можно читать все в реальном времени? Видел много китайских приблуд, так они работают с задержкой до двух секунд. А для тахометра это большая печаль, там надо шустро реагировать.
kolyandex
24.04.2019 14:10Везде по-разному. В моей машине данные тахометра и спидометра идут в приборку каждые 50 мс.
realimba
24.04.2019 13:51Хорошо когда есть CAN, делал тоже самое (Rpi + Qt) на аналоговый раритет, вот где боль :)
видос
tuxi
Клево!
Только одно уточнение, основная прелесть ваговской реализации (в частности VCDS) не только в том, чтобы получать данные, но и вносить изменения в настройки, вплоть до очень тонких. То есть, не только настроить «сколько сигналов поворотника дать при легком нажатии переключателя», но и внести различные коррективы в режимы работы устройств подключенных к этой шине. Например догреватель вебасто, положение кузова/пневмоподвески, калибровка фар и тп и тд
tuxi
PS: Еще вспомнил пару интересных вещей. Если модель ВАГ-а оборудована датчиком дождя, электростеклоподьемниками и/или люком, то в некоторых моделях через VCDS (или «Васю») можно активировать функцию автозакрытия стекол, при срабатывании этого датчика.
aivs Автор
Активировал много фич через VCDS которые не положены моей комплектации. Хотел активировать автоматическое опускание правого зеркала при заднем ходе, но оказалось, что для этого нужен другой механизм зеркала. А в целом VAG нравится, с детства люблю конструкторы.
tuxi
С зеркалами да, есть такие нюансы. Автоскладывание при постановке на охрану, мне так и не удалось сделать.
LuxLP
насколько я знаю, эта опция связана не с механизмом зеркала (штатный электромеханизм запросто его опустит), а с наличием памяти сиденья. эти опции связаны в по.
esaulenka
Скорее, это связано с датчиком положения зеркала. Т.е. для обычной регулировки нужен только моторчик, за положением следит сам водитель (максимум — концевики надо поставить, чтобы в конце хода ничего не сломать и не сжечь), а чтобы автоматически опустить зеркало и потом поднять его обратно ровно в то же положение, надо измерять, насколько именно оно опустилось и поднялось. В комплектациях «с памятью» эти датчики, очевидно, тоже нужны (но уже везде, не только в зеркалах).
Black_Zerg
Ничего подобного, у меня на Йети этой функции штатно нет так как нужно сиденье водителя с электроприводом и памятью. Однако мы с товарищем с помощью Васи активировали эту функцию. Теперь при включении задней передачи, зеркало (правое пассажирское) опускается, а при движении вперед возвращается на место. Только надо рычажок управления зеркалами поставить на правое зеркало, в других положениях функция не включается
aivs Автор
Кстати, я рычажок не пробовал ставить на правое зеркало, может тоже заработает. Через Васю активировал функцию, но результат не было.
Я на драйве читал, что нужно ставить мезанизм с памятью положения, чтобы это заработало. А так регулировка все равно осуществляется по Кан шине.
Black_Zerg
Через драйв и нашел эту инфу. Работает только когда рычажок на правом зеркале. Это ВАГ ставит эту опцию в комплекте с электро механизмом и памятью кресел. Но повторюсь на моем авто работает
kAIST
Вам повезло — попался подходящий для этого блок зеркала. Мне не повезло )
Из полезного, на йети сделал подсветку в поворотах (работает за счёт противотуманок, фича от Тигуана).
Хочу ещё поменять кондиционер на климат. Блок управления стоит относительно дёшево (в пределах 10 тыс на разборах), правда попадаются в основном от фольцев, поэтому придется подсветку на зелёный перепаивать.
Black_Zerg
Ну на машинах 12-го года выпуска это делается. А подсветка это стандартная фишка всего VAGа (и на Сеате, и на Шкоде), на всех машинах концерна можно сделать. Кондер я тоже думал поменять, но не только блок надо заменить, там гораздо больше переделывать надо и влетает в копеечку
kAIST
C подсветкой, только если электрика позволяет. На фабии, например, не позволяла, хотя можно было кинуть отдельный провод от одной из туманок.
По поводу климата на йети (2012г), насколько узнавал, только блок управления и пару датчиков воткнуть. Все остальное уже и так управляется электроникой, все заслонки сервофицированны, только команды отдает не контроллер а человек.
Ну и в бортовой компьютер прописать что теперь есть климат.
Black_Zerg
Подсветка это не электрика, а блок управления.
Надо посмотреть по ETKA, есть ли различия. Вечером гляну, вы меня заинтриговали
kAIST
Именно электрика. Если две ПТФ по электрике идут на одном проводе, в блок управления смысла нет лезть, они же должны включаться независимо друг от друга. На фабии в комплектации с датчиком света, вроде как идут отдельно, если без, то включаются только вместе.
На йети вроде как всегда отдельно. Если есть датчик поворота руля, можно включить от положения руля, если нет, то только от поворотников. Иногда полезная штука, правда только вправо нормально светит )
Black_Zerg
Датчика света нет. Алгоритм работы следующий. Включается при скорости ниже 40 км/ч, если включен поворотник, то сразу включается, если поворачивается руль, то плавно загорается и также плавно тухнет. Но только при скорости ниже 40 км/ч
prog_san
За опускание зеркала при движении задним ходом отвечает 52-й блок «Блок управления пассажирской двери». У SanchoPanso998 есть подробный отчет по доработке зеркала Опускание правого зеркала при включении задней скорости