Всего понемногу: автомобиль, облако, Raspberry Pi и CAN +12


Развлекательный центр (in-vehicle infotainment, IVI) стал неотъемлемой частью современного автомобиля. Если раньше это был просто радиоприемник, затем кассетный магнитофон, потом музыку можно было слушать просто с флэшки, а теперь едва хватает двух дисплеев по 10.25-дюймов для приборной панели и развлекательного центра в новом Mercedes A-класса. Кстати, IVI – это уже не только музыка, но и навигация, доступ к Интернет и многие другие возможности внутри транспортного средства, которые потихоньку дают старт воплощению концепции «подключенного автомобиля» (Connected Car). Пожалуй, автотранспорт так же очень близок к реализации концепции Интернета вещей (IoT). И все это достигается благодаря «ассимиляции» компьютера и автомобиля.

В продолжении предыдущей заметки «Автомобиль, Интернет вещей и прочие технологии» хотелось бы рассмотреть идеи для воплощения автомобильного компьютера на уровне открытых проектов и немного затронуть современные тенденции в этом ключе.


Image: Bringing its A game: new 2018 Mercedes A-class hatch revealed – CAR Magazine

Интернет вещей – это не призрак далекого будущего, а вполне реализуемая концепция настоящего. Начиная от лампочек и завершая домашними голосовыми ассистентами – все эти устройства уже имеют доступ в Интернет и могут взаимодействовать между собой. Да, сейчас для этого нужно немного настроить, например, сервис IFTTT и т.п., но прогресс уже не остановить. Как следствие – компьютер начинает проникать в автомобиль, как базовый компонент развлекательного центра. Для автопрома есть вполне обоснованные ограничения, которые прямо влияют на скорость развития IVI – это соблюдение всех мер безопасности. В любом случае, нельзя пренебрегать безопасностью как своей, так и других участников дорожного движения. Автомобиль и дорога – не место для экспериментов. Поэтому проекты энтузиастов, которые хочется рассмотреть в этой заметке – лишь идеи, которые возможно перерастут в будущие прототипы, но уже для коммерческих предложений. Конечно, если речь заходит о безопасности, то доверять следует сертифицированным изделиям, за которыми стоят часы разработок и тестирования.

Поскольку речь пошла о Connected Car и IVI, то стает очевидным использование ресурсов облака с функциями IoT, для реализации на «верхнем уровне» соответствующей программно-аппаратной архитектуры. Например, большинство универсальных облачных платформ, таких как Amazon AWS, Microsoft Azure, IBM Watson или др., содержат практически универсальные сервисы для построения Интернета вещей. По сравнению с сними, будут интересны и открытые решения в этой сфере. Проект Kaa является одним из таких примеров.


Picture: Веб-интерфейс платформы Kaa

Разработчики позиционируют Kaa, как многоцелевую платформу промежуточного уровня для решений IoT, нацеленную на создание приложений для подключенных устройств и интеллектуальных систем. Платформа Kaa представляет собой открытый, многофункциональный инструментарий для разработки встраиваемых систем и решений для облака. Платформа выпущена под лицензией Apache Software License 2.0. Для быстрого ознакомления с платформой можно скачать образ для VirtualBox или развернуть систему в облаке AWS.

Идея Kaa заключается в том, что разработчикам предоставляется SDK для создания приложений с использованием API рассматриваемой платформы, и соответствующие сервисы в облаке, включая компиляцию низкоуровневых программ. В текущей версии поддерживаются языки: C, C++, Java, Objective-C и операционные системы Linux, Windows, Android и iOS, а также заявлена поддержка множества встраиваемых аппаратных платформ, например, Raspberry Pi, Intel Edison.

Тут хочется отвлечься и заметить, что, примерно, как когда-то давно в начале 2000-х годов Intel ушла с рынка микроконтроллеров со своим интереснейшим решением – MCS-51, а сейчас, фактически, мы являемся свидетелями подобного – завершение разработки систем Galileo, Joule и Edison, это не осталось не замеченным у сообщества разработчиков и энтузиастов. Многие идеи из предыдущих систем станут началом для новых устройств и решений. Конечно, если для кристалла i8051 (MCS-51), компания Intel продолжила лицензировать его архитектуру, даже после своего ухода с рынка микроконтроллеров, то сейчас, пожалуй, значительно укрепятся позиции Raspberry Pi и Arduino (на классической платформе микроконтроллеров Atmel), как основных инструментов прототипирования встраиваемых устройств. Но не стоит забывать, что для IoT также интересны разработки на основе устройств ESP8266/ ESP32 Espressif и подобные системы с интегрированным интерфейсом Wi-Fi на кристалле.


Возвращаясь к проекту Kaa, следует отметить, что существует ряд архитектурных особенностей, которые делают разработку IoT на этой платформе исключительно быстрой и легкой. Решения на Kaa не должны зависеть от конкретной аппаратной платформы и, таким образом, проект является совместим практически с любыми подключенными устройствами, датчиками и шлюзами. Конечно, это достигается за счет использования универсальных протоколов связи и стандартизированных интерфейсов между компонентами системы. Также Kaa обеспечивает четкую структуру функций и расширений IoT для различных типов приложений. Они могут использоваться, почти по аналогии технологии plug-and-play, с минимальным кодом, который все-таки должен доработать разработчик для своих систем и устройств. Эти возможности, в сочетании с аналитикой в облаке, делают Kaa достаточно привлекательной платформой для Connected Car и др. решений.

Проект Kaa успешно развивается и совершенствуется, но есть и другая, можно сказать, обратная задача для построения решений Connected Car. Суть ее лежит в выполнении задач тестирования программной части облачной системы и непосредственной эмуляции поведения множества подключенных к облаку автомобилей. Для этой задачи интересны проекты с открытым кодом, например, AutoSIM компании Automatski, который разрабатывается с поддержкой двух лицензий: GPLv3 и коммерческой. В данной системе используются основные протоколы передачи данных, включая MQTT, AMQP, CoAP и др. Пользователь при помощи Rest/Json API управляет работой сервера для симуляции требуемых процессов. AutoSIM теоретически позволяет имитировать поток данных от более чем 100 миллионов устройств.

Kaa и AutoSIM – замечательные примеры открытых систем и, возможно, решений, которые станут очень востребованными для автопрома. Но уже сейчас, на нижнем уровне встраиваемых систем для автомобиля, есть множество интересных открытых решений, которые успешно взаимодействуют с облачными сервисами. Например, платформа Android Auto компании Google. Это решение базируется на Android Automotive и нацелено на объединение смартфона и автомобильного медиа-центра в единую платформу, расширяющую функционал IVI-систем.


Поскольку в современном автомобиле присутствуют множество блоков, которые непосредственно взаимодействуют с медиа-центром, например, с использованием сетей Controller Area Network (CAN), Local Interconnect Network (LIN), Media Oriented Systems Transport (MOST), а также более привычные Ethernet и протоколы TCP/IP, то Android Automotive предлагает некоторую абстракцию – hardware abstraction layer (HAL) между физическими сетями автомобиля и функционалом операционной системы Android, доступного разработчикам.


Figure: Vehicle HAL and Android automotive architecture

Но, если Android вполне прогнозируемое решение от Google, то использование Linux, в качестве платформы для автомобильного развлекательного центра, пожалуй, уже стала классикой жанра. И, как говорится, кто-нибудь определенно должен был предложить проект, например, Automotive Grade Linux. Это открытая разработка, объединяющая автопроизводителей, поставщиков и технологические компании под эгидой The Linux Foundation. Конечно, AGL доступен в виде исходного кода, а для первоначального знакомства можно скачать образ виртуальной машины, например, для запуска в VirtualBox или вполне можно запустить дистрибутив систему на Raspberry Pi. Для работы с AGL SDK потребуется Docker.


Picture: Automotive Grade Linux – Getting Started

Разработка приложений для AGL предусмотрена на HTML5, Qt OpenGL. Сама платформа автомобильного Linux сосредоточена на безопасности. Например, архитектура решения предполагает гипервизор и, конечно, изоляцию критически-важных приложений, систем мультимедиа и развлечений. Приложения и компоненты AGL строятся по модульному принципу с интерфейсами в виде сигналов/событий, что позволяет скрыть сложную программную реализацию низкоуровневых решений, например, реализацию интерфейса CAN-шины, и предоставить простой API для приложений.


Figure: Upgraded Security Blueprint 2017. AGL security overview — Automotive Grade Linux Documentation

Интересно, что разработчики Automotive Grade Linux присматриваются к реализациям уровня архитектуры из других проектов, впрочем, что характерно для всего движения открытых систем. Например, интересным решением в проекте OpenXC является принцип описания в формате JSON всех сигналов CAN, которые нужно обрабатывать. Программный генератор преобразовывает такое описание в файл на языке C ++, которая может быть скомпилирована и т.п.


Figure: OpenXC is an open source, data-focused API for your car

Если говорить о проекте OpenXC, то в нем используется комбинация аппаратного и программного обеспечения с открытым исходным кодом, которое позволяет расширить функционал автомобиля с помощью специальных приложений и подключаемых модулей. Проект сконцентрирован на получении данных об автомобиле и использует стандартный интерфейс диагностического разъема OBD-II. Фактически проект позволяет разработать свое мобильное приложение под Android, iOS или использовать для разработки Python, а в качестве основной автомобильной платформы выбрана марка Ford.

Возвращаясь к проекту Automotive Grade Linux стоит заметить, что в нем Raspberry Pi используется скорее для целей демонстрации и прототипирования, а вот для промышленной платформы выбраны специализированные решения, например, системы на базе ARM SoCs (система на чипе) компании Renesas Electronics серии R-Car Generation 3 и некоторые др.


Figure: R-Car H3. System Block Diagram – Renesas Electronics

Поскольку можно и дальше рассматривать различные платформы для построения IVI-систем, то хочется сделать небольшой вывод об уже приведенных примерах. Все говорит о том, что текущий, 2018 год, будет годом доставляемых пользователю и разработчику приложений. Ведь, как в проекте облака Kaa, так и решениях для операционной системы AGL, используется принцип предоставления практически готового приложения в виде SDK для разработчика. Также широко используется подход на основе описания критериев разрабатываемой системы, например, в формате JSON, и генерации на их основе каркаса приложения. Это чем-то напоминает идеи раскрытые ранее в публикации: «Быстрое прототипирование устройств Интернета вещей», где были рассмотрены решения, в которых разработчики микросхем предоставляют стартовые наборы и т.п. для быстрого ознакомления с их компонентами. Действительно, для программиста, разрабатывающего проект для IoT, всегда будет удобно начать разработку не с детального ознакомления с «неким» API, а с уже готового каркаса приложения.

Давайте обратим внимание на немного другой уровень IVI, где не используются такие многофункциональные системы, как Renesas или др. Интересно рассмотреть подходы на основе уже традиционного решения Raspberry Pi. Понятно, что все это скорее прототипы, т.к. Raspberry Pi вряд ли можно сравнить с промышленной платой, специально разработанной для автомобильных применений, но всегда интересны идеи и подходы энтузиастов. Так, одним из любопытных решений для медиа-центра стоит отметить проект CarPC, который фактически является разработкой и совершенствованием графического интерфейса и дополнительного функционала для известного кроссплатформенного медиапроигрывателя Kodi (ранее проект XBMC).


Picture: CarPC-touch for Kodi

Но Kodi или другой медиа-центр не позволят получить и отобразить данные из бортовой сети автомобиля. Для этого проще всего подключиться к диагностическому разъему автомобиля, как было рассмотрено в нашей предыдущей публикации: «Разъем диагностики OBD-II, как интерфейс для IoT». И тут интересен проект Carberry, представляющий из себя плату расширения для Raspberry Pi.


Picture: Carberry for RPi 3 – Paser

Плата Carberry итальянской компании Paser стоит 123.83 € (евро). Она подключается к стандартному порту расширения Raspberry Pi 3 и поддерживает: CANBUS, GMLAN, инфракрасный приемник и другой функционал. Плата расширения служит отличным дополнением к программным решениям, например, уже упомянутому CarPC. Следует отметить, что программно-аппаратный проект постоянно развивается в сторону расширения функционала и т.д.


Picture: What is AutoPi and What Does It Do? – AutoPi.io

Так же активно развивается немецкий стартап AutoPi, представляющий собой проект автомобильной IoT-платформы. Интересной в AutoPi является аппаратная часть на базе Raspberry Pi Zero и наличием интерфейса OBD-II, а также: 3G/4G, Bluetooth, WiFi, GPS-приемника и других компонентов, умещающихся в достаточно небольшом устройстве.

На фоне всех рассмотренных систем прямо напрашивается вопрос: как подключить к Raspberry Pi интерфейс OBD-II? Очевидным ответом будет использование готовой платы, например, PiCAN2 CAN-Bus Board for Raspberry Pi 2/3 по цене от ?26.90 (в фунтах без европейского НДС) или что-то похожее. Но очень заманчиво использовать широко распространённый модуль CAN Bus на базе MCP2515/TJA1050, который доступен на AliExpress от USD $1.36 и чуть дороже. Например, такой модуль значительно дешевле плат расширения на базе MCP2515 для Arduino.

Стоит заметить, что низкая цена модуля MCP2515/TJA1050 обусловлена его скромным размером и количеством элементов на плате. Она отлично подходит для работы с платами Arduino, но в таком случае при программировании следует не забывать, что в основном на модуль MCP2515/TJA1050 разработчики устанавливают кристалл кварца 8 MHz, а не 16 MHz, который обычно присутствует на большинстве плат Arduino CAN-BUS Shield. Таким образом, само-собой напрашивается использование модуля MCP2515/TJA1050 для подключения к Raspberry Pi и работа с шиной CAN, например, с эмулятором OBD-II, рассмотренным все в той-же статье «Разъем диагностики OBD-II, как интерфейс для IoT» или напрямую с модулем ELM327 и т.п.


Picture: Модуль CAN Bus на базе MCP2515/TJA1050

Но работая с электронными модулями всегда нужно внимательно относиться к напряжению питания и ограничениям по линиям передачи данных. При использовании стандартного интерфейса расширения GPIO платы Raspberry Pi это достаточно актуально. Дело в том, что на разъеме Raspberry Pi присутствуют напряжения 5В и 3.3В, которыми можно запитать внешние схемы, однако, линии ввода-вывода платы работают только с уровнями до 3.3В. Соответственно, плату модуля MCP2515/TJA1050, рассчитанную только на 5В не следует сразу подключать к Raspberry Pi.


Schematic: CAN bus on raspberry pi with MCP2515 – Raspberry Pi Foundation Forum

Решением может стать простой двухсторонний преобразователь уровней 3.3В/5.5В. Таких готовых модулей для шины SPI предостаточно, но MCP2515 имеет дополнительный вывод прерывания, свидетельствующий о готовности данных. Такой вывод позволит процессору Raspberry Pi выполнять свою работу и реагировать на данные от MCP2515 только в требуемые моменты времени, не отвлекаясь постоянно на мониторинг SPI-интерфейса. Следовательно, готовый модуль сопряжения не будет иметь дополнительного контакта и нужно будет просто сделать свою схему.


Picture: Небольшая доработка модуля CAN Bus на базе MCP2515/TJA1050 для работы с Raspberry Pi

Есть и совершенно простое решение, но конечно, не лучшее. Оно основано на том, что микросхема MCP2515 вполне работоспособна с уровнем напряжений от 2.7В до 5.5В, значит ее можно запитать 3.3В с Raspberry Pi, а линии интерфейса SPI и прерывания INT – подключить к GPIO. Для TJA1050 потребуется питание 5В, которое можно подключить все с того же разъема GPIO, но на модуле MCP2515/TJA1050 потребуется аккуратно перерезать дорожку общего питания и подпаяться к ней.

В качестве правильного усовершенствования такой схемы очень разумно использовать делитель напряжения для согласования уровней 5В микросхемы трансивера TJA1050, кстати, можно использовать аналог MCP2551 от компании Microchip или др., и CAN-контроллера MCP2515 с питанием 3.3В (см. рис.). Также интересен проект CAN Simulator на основе Raspberry Pi и, конечно, MCP2515. В качестве трансивера в симуляторе используется микросхема TJA1049, которая хотя и требует питание 5В, но работает без дополнительных компонентов согласования уровней с 3-х вольтовыми системами. Если выбирать самое интересное решение, то, пожалуй, проект CAN-Bus Interface with galvanic isolation самый интересный, так как предлагает использовать трансивер MCP2562, позволяющий без дополнительных элементов подключить контроллер с напряжениями в диапазоне от 1.8В до 5В.


Schematic: CAN + Raspberry Pi

Определившись с аппаратной частью можно переходить к работе с Raspberry Pi на программном уровне. В качестве операционной системы выберем достаточно традиционное решение Raspbian Stretch. А для работы с CAN поддержку драйвера MCP2515 уровня ядра Linux.


Picture: Передача данных между Raspberry Pi и Arduino по шине CAN

Для корректной работы Raspberry Pi с платой интерфейса CAN на базе MCP2515 нужно точно знать версию ядра установленной операционной системы. Для этого следует выполнить команду:
$ uname -a

В нашем случае – это Linux raspberrypi 4.9.59+. Более детальную информацию о дистрибутиве и самой плате можно узнать, используя команды:
$ cat /etc/debian_version – версия базового дистрибутива Debian;
$ cat /etc/os-release – особенности релиза;
$ cat /proc/cpuinfo – версия аппаратной платформы (подробности можно узнать из статьи: «How to Check the Software and Hardware Version of a Raspberry Pi»).

Для работы SPI с микросхемой MCP2515 нужно добавить параметры в конфигурационный файл /boot/config.txt операционной системы:
# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=spi=on
dtoverlay=mcp2515-can0, oscillator=8000000, interrupt=25

Понятно, что если кварц на плате 16 МГц, то нужно указать число «16000000».
# dtoverlay=spi-bcm2835-overlay
Драйвер bcm2835 потребуется явно указывать в конфиге только для старых ядер Linux до kernel 4.4.x+

Следующий параметр следует раскомментировать для современных систем:
# dtoverlay=spi1-1cs

А, вот, после долгих поисков нашлась актуальная строчка, которая позволила заработать нужному модулю на ядре Linux raspberrypi 4.9.59+ в текущей системе:
dtoverlay=spi0-hw-cs

После перезагрузки можно просто «поднять» сетевой интерфейс:
$ sudo ip link set can0 up type can bitrate 500000

Действительно, получается очень удобно, что CAN стает в Raspberry Pi своеобразным сетевым интерфейсом и, например, выполнить посылку или получить дамп принимаемых данных, а также узнать статистику работы:
$ cansend can0 127#DEADBEEF
$ candump can0
$ ip -details -statistics link show can0


Чтобы каждый раз при старте системы не «поднимать» интерфейс, можно добавить пару стандартных строк в файл конфигурации /etc/network/interfaces и т.п.

Screenshot: Передача данных между Raspberry Pi и эмулятором OBD-II на базе платы Arduino
Дальше остается писать новый код или использовать готовые библиотеки. Поскольку драйвер MCP2515 фактически дает системе новый сетевой интерфейс, то разработку можно выполнять практически на любом языке. И тут сразу хочется сказать немного о Go, кроссплатформенном, компилируемом, многопоточном языке программирования, разработанным компанией Google. Этот язык однозначно очень интересен в плане разработки встраиваемых систем и, конечно, будет совсем не сложно найти под него уже готовую библиотеку, подходящую для проекта, например, CAN bus in Go. А если зайти дальше, то следует рассмотреть и проект Gobot – фреймворк, направленный на создание роботов, решений для IoT и т.д. Но, пожалуй, для этой публикации это будет уже слишком много.

К вопросам программирования на Go обязательно следует вернуться, но уже в следующих публикациях. Так же нужно будет не забыть об операционной системе Tizen, на которой ранее базировалась Automotive Grade Linux, а также рассмотреть тренд этого года – голосовые ассистенты в салоне автомобиля и многое др. А в завершении авто тематики текущей публикации просто вспомним о платформе цифровой кабины, представленной Samsung и HARMAN на CES 2018 и немного вдохновимся идеями дизайнеров и инженеров, разработавших этот концепт.



Интересные ресурсы и ссылки:
Mercedes-Benz’s new MBUX in-car assistant and smart UI rocks – TechCrunch
Интерфейс от Mercedes-Benz объявлен другом водителя – Драйв
Getting started. Kaa Sandbox – KaaIoT Technologies
Intel прекращает выпуск Galileo, Joule и Edison — Компьютерное Обозрение
OK Google, what is Android Auto? Here’s everything you need to know about it – Digital Trends
Система Android Auto стала доступна в любом автомобиле – 3DNews
Android на колесах: систему Google «вживят» в автомобили Audi и Volvo – Вести
Toyota Camry станет первым автомобилем, оснащённым платформой Automotive Grade Linux – OpenNET
Raspberry PI 2 CarPC – Engineering(DIY)
Arduino CAN Bus Module Pin Outs and Schematics – Henry's Bench
MCP2515: контроллер шины CAN с интерфейсом SPI – microsin.net — заметки радиолюбителя
Согласование логических уровней 5В и 3.3В устройств – Сообщество EasyElectronics.ru
Хакаем CAN шину авто для голосового управления – Geektimes
Pin Numbering — Raspberry Pi Model B (Revision 2.0) – The Pi4J Project
CAN-Bus with Raspberry Pi: HowTo/Quickstart MCP2515 Kernel 4.4.x+ – vimtut0r's blog
CAN On the Raspberry Pi – Harrison's Sandbox
MyPi CAN-BUS Card Configuration – Embedded Micro Technology
CAN BUS Shield for Raspberry CanBerryDual V2.1 – Industrialberry
Libre Solar CAN interface for Raspberry Pi (Zero W) – GitHub
OBD-Pi – Instructables
SocketCAN userspace utilities and tools – GitHub
CAN Bus – Embedded Linux Wiki
Go on Raspberry Pi — @NET
Need to Create Synergy Korean Connected Car Developers Alleged to Need More Collaboration – Korea's Premier Business Portal
CES 2018: кто главный экспонат? – Geektimes

Вы можете помочь и перевести немного средств на развитие сайта

Теги:



Комментарии (6):

  1. thauquoo
    /#10629675

    Вот поэтому я купил себе старый Форд 80-х годов без бортовых компьютеров, и разнообразной электронной начинки, где всё ещё нет "чёрных ящиков" и недоступных обычному обладателю автомобиля узлов.

  2. port443
    /#10629723

    Самсунг, так же как и Тесла, не понимает, что делает. Испортили даже офигенные крутилки. Остаётся только надеяться, что это так и остенется концептом.

    • m1n7
      /#10630127

      1:27 — она крутит крутилку. Что не так-то?

      • port443
        /#10632219

        Крутилка — это штука, которой можно было бы воспользоваться или не глядя, или глядя мельком (нацелить руку). Они же не просто так туда экран вставили, они снабдили их динамическими функциями! Теперь надо внимательно посмотреть на все, и найти ту, которая сделает то, что нужно. Или ещё веселее — не найти! Тогда придётся лазить по меню на сенсорном экране.
        Хотя, вообще уже то, что они там на экране показывают еду, о многом говорит :)

    • safari2012
      /#10630303

      Три программируемые крутилки сверху. Внизу под правой рукой ещё что-то есть.
      Не всё так уж и плохо.

  3. dunkelfalke
    /#10631349

    Через SocketCAN можно сделать намного интереснее вещи, чем простой дамп.
    В сравнительно новом кернеле есть can.h, там например есть уже определение структуры CAN-пакетов, таким образом можно напрямую брать необходимые данные. Заодно там можно включить фильтр пакетов, чтобы через интерфейс приходили только интересные пользователю.

    Вот к примеру как открыть сокет (его после этого можно держать открытым, пока не сдохнет) и узнать пробег грузовика, который поддерживает стандарт FMS:

    struct sockaddr_can _canaddr;
    struct ifreq ifr;
    
    // открываем
    int _handle = socket(PF_CAN, SOCK_RAW, CAN_RAW);
    can_err_mask_t _errmask = CAN_ERR_MASK; // принимаем все ошибки
    setsockopt(_handle, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &_errmask, sizeof(_errmask));
    _canaddr.can_family = AF_CAN;
    snprintf(ifr.ifr_name, "can0", sizeof(ifr.ifr_name));
    ioctl(_handle, SIOCGIFINDEX, &ifr);
    _canaddr.can_ifindex = ifr.ifr_ifindex;
    bind(_handle, reinterpret_cast<struct sockaddr*>(&_canaddr), sizeof(_canaddr));
    
    // и читаем
    struct can_frame frame;
    
    if ( recvfrom(_handle, &frame, sizeof(frame), 0, reinterpret_cast<struct sockaddr*>(&_canaddr), &len) > 0 )
    {
        if (frame.can_id & 0x00FFFF00 == 0x00fec100)
            double _totalDistance = ( can.data[0] + can.data[1] * 256.0 + can.data[2] * pow(256.0, 2) + can.data[3] * pow(256.0, 3) ) * (5.0 / 1000.0);
    }