Puede rastrear

El bus CAN en sí ya se usa mucho, donde estoy interesado en su uso en el automóvil, aunque esta área no puede ser limitada. Especialmente hace un par de años surgió esta oportunidad. Miré las especificaciones generales: parece que no hay nada particularmente complicado. Miré los programas que se encuentran en Internet, y no me gustó ninguno, cada uno carecía de algo que me parecía necesario en ese momento. Reinventaré mi bicicleta. Hago mi sniffer más debajo del corte.

CAN bus


Describir los detalles técnicos del bus CAN en detalle es parte de la documentación. En este artículo, es suficiente saber que:

  • tiene una conexión física de dos hilos
  • hay varias velocidades de datos
  • chips listos para usar e incluso tableros listos para usar con piezas soldadas ya están disponibles para la conexión

Después de hojear las páginas de una famosa tienda en línea del Reino Medio, ordené varias opciones diferentes para escudos y fui a estudiar las características de las señales eléctricas en un automóvil. El automóvil experimental fue el LADA Kalina Cross con el motor 127 y una unidad de control electrónico CAN ITELMA M74.5.

Me conecto al conector de diagnóstico OBD (pines 6 y 14) y miro el osciloscopio que está allí. Después de girar la llave de encendido, comienzan a ejecutarse paquetes con una amplitud de hasta 2.5 V. Me detengo en el osciloscopio y miro el paquete.


Los bits de inicio y parada son notables, algunos datos en el paquete. En ese momento ya sabía que se esperaba que la velocidad de transferencia de datos fuera de 500 kbit / s, como la más frecuente para el bus CAN motorizado. La duración del paquete es de aproximadamente 230 μs y antes del paquete hay una pausa bastante grande en la transmisión de datos. Escalo el tiempo y veo tres paquetes y pausas entre ellos.


Si sumamos la duración de la transferencia de datos y la pausa entre paquetes, resulta que la transferencia de una pieza de datos toma aproximadamente 1 ms.

¿Por qué estoy deduciendo todo esto? Y la pregunta es puramente práctica: ¿hay suficiente velocidad de puerto serie para transferir todos los datos? Y en base a lo que vimos, podemos concluir que la velocidad de 500 kbit / s se desarrolla dentro del paquete, lo que lleva aproximadamente una cuarta parte del tiempo de transmisión. Por lo tanto, la tasa de transferencia promedio será cuatro veces menor. En ese momento, todavía no tenía pruebas de velocidad de la interfaz serial Arduino, y mirando hacia el futuro puedo decir que incluso con el convertidor Serial a USB CH340 más común, una velocidad de 2 Mbps funciona de manera estable.

Escáner CAN en Arduino


Llegó el primer escudo para el clásico Arduino UNO. Sí, cuesta significativamente más que sus contrapartes más pequeñas, pero tiene a bordo todo lo que necesita e incluso dos botones.


Fue con él que comencé todos los experimentos. Ensambló un circuito simple con este escudo y una pantalla de cristal líquido de dos líneas. El objetivo era mostrar al menos algunos datos en la pantalla. Seleccioné varias bibliotecas para trabajar con el bus CAN en Arduino (diré de inmediato que la biblioteca correcta y en funcionamiento se llama CAN-BUS Shield de Seeed Studio con el archivo de encabezado mcp_can.h), cambié el resonador de cuarzo en el escudo de 16 MHz (originalmente era de 8 MHz) - No hubo datos.

Se instalan dos microcircuitos en la pantalla: el controlador de bus CAN MCP2515 y el controlador de bus CAN TJA1050. Después de leer la documentación y varios foros, decidí cambiar el TJA1050 a un controlador más canónico MCP2551 y aparecieron los datos. Quizás el TJA1050 fue inicialmente defectuoso, ya que era muy difícil cometer un error al conectarlo con dos cables, además, utilicé conectores OBD y DB9 para la conexión.

En un par de horas, se escribió un escáner CAN simple, que mostraba el número del paquete capturado, su ID y hasta 8 bytes de datos para este paquete en la pantalla LCD.


Aquí es donde los botones en el escudo fueron útiles, que usé para cambiar entre el número del paquete que se muestra.

Sobre botones
En general, estos botones fueron útiles para muchas cosas. Fue con ellos que comencé a probar el control de algunos dispositivos del automóvil.

El comienzo fue establecido, debemos pasar a una implementación más interesante.

Puede rastrear en Arduino


La tarea fue bastante simple:

  • aceptar paquete del bus CAN
  • ponemos los datos recibidos en nuestra estructura
  • enviar estructura a través del puerto serie

No vi ningún problema con las dos primeras tareas. La biblioteca proporcionó una interrupción al recibir el siguiente paquete de datos y funciones convenientes para recibir datos. Pero decidí enviar datos a la computadora a través de la biblioteca CyberLib, que elimina parte de la sobrecarga de toda la plataforma Arduino, debido a lo cual puede descargar ligeramente el procesador para procesar los datos. Más tarde, esta biblioteca tuvo que ser abandonada.

Para garantizar que los datos enviados se procesen correctamente en el lado de la computadora, se inserta un prefijo de cuatro bytes 0xAA55AA55 en la secuencia antes de cada siguiente pieza de datos (por alguna razón, estos bytes se recordaron para los últimos dos bytes del sector de arranque de DOS, solo que estaban en un orden diferente). La lógica es esta:

  • la computadora lee toda la transmisión desde el puerto serie y encuentra la secuencia de prefijo deseada 0xAA55AA55 en ella
  • inmediatamente después del prefijo habrá 4 bytes del identificador de paquete
  • Además de la longitud de datos de este paquete, controla la longitud de todo el paquete
  • hasta 8 bytes de datos

En esto, la parte del software en Arduino, en ese momento, se completó. Más tarde se rehizo significativamente, pero el concepto general no ha cambiado.

También escribí un generador simple de paquetes de datos para la depuración que se depurará en casa: simplemente envía paquetes con datos aleatorios al puerto serie, lo que le permite depurar la aplicación en su computadora en condiciones cómodas.

Casi al mismo tiempo, llegaron los componentes más pequeños del escudo Arduino Nano y Mini CAN.


Diseñé una caja pequeña, la imprimí y coloqué todos los componentes dentro.


En el exterior, hay un conector OBD en un lado y Mini USB en el otro. En el interior hay un interruptor para una resistencia terminal.

Puede rastrear en la PC usando wxWidgets


Dibujé un borrador simple de un programa en C #, que muestra los datos recibidos en la cuadrícula. Y fue a registrar el auto. Simplemente no fui con mi computadora portátil, ya que su batería me había ordenado vivir durante mucho tiempo y se usaba como una computadora estacionaria, pero tomé una netbook con un procesador muy débil. Lo que vi ... no vi nada. Ambos núcleos están 100% cargados, la interfaz de la aplicación no responde. Pero en mi computadora, que todavía es mucho más rápida que una netbook, con el generador de paquetes aleatorios, la aplicación funcionó bien y mostró datos. A partir de esto, llegué a la conclusión de que la plataforma .NET en computadoras débiles no funcionaría para mí, ya que podía depurar en el campo en ese momento solo con esa netbook.

Anteriormente, utilicé la biblioteca wxWidgets en varios proyectos y solo tengo una experiencia agradable al respecto. Es liviano, no hay necesidad de llevar varias bibliotecas e incluso multiplataforma, lo que da la esperanza de que la parte de la interfaz del código se pueda transferir sin alteraciones significativas a otras plataformas. Al final del artículo habrá un enlace al programa compilado, si no desea molestarse con todo esto.

Cómo instalar y compilar wxWidgets para Visual Studio
Instalación y compilación.
1. Descargue wxWidgets de Windows Installer e instálelo, por ejemplo, en la carpeta C: \ wxWidgets

2. Crear una variable de entorno:
WXWIN = C: \ wxWidgets

3. Ejecute el símbolo del sistema de Visual Studio y vaya al directorio:
% WXWIN% \ build \ msw

4. Escriba dos comandos para compilar:
nmake / f makefile.vc BUILD = debug RUNTIME_LIBS = static
nmake / f makefile.vc BUILD = release RUNTIME_LIBS = static

Configurar un proyecto en Visual Studio
1. En Visual Studio, cree un Proyecto Win32, con el parámetro Proyecto vacío.

2. En las propiedades del proyecto para Toda la configuración, especifique las rutas en la sección de directorios de VC ++:
Incluir directorios:
$ (WXWIN) \ include
$ (WXWIN) \ include \ msvc

Directorios de bibliotecas:
$ (WXWIN) \ lib \ vc_lib

3. En la sección C / C ++ - Generación de código, cambie:
Biblioteca de tiempo de ejecución para depuración: / configuración de MTd
Biblioteca de tiempo de ejecución para configurar Release: / MT

4. En la sección General, cambie:
Conjunto de caracteres: use el conjunto de caracteres Unicode

5. Para agregar un icono a un archivo exe, debe agregar un archivo de recursos con el siguiente contenido:
#include "wx \ msw \ wx.rc"
wxicon icon app_icon.ico

6. Además, si necesita usar UAC, en la sección Linker - Manifest File:
Nivel de ejecución de UAC: requireAdministrator

El primer prototipo implementado en C ++ y wxWidgets mostró que incluso una netbook se adapta a la visualización de datos en una tabla, y comencé a desarrollar lo que había planeado.

Arquitectónicamente, el programa consta de dos flujos: interfaz y flujo de trabajo con un puerto serie. No se aplicaron algoritmos increíblemente interesantes. El código está muy comentado y debería ser bastante sencillo. Un enlace a la fuente estará al final del artículo.

Lo primero que se hizo fue colorear las celdas de datos en la tabla de acuerdo con la limitación de obtener estos datos. Ya en el primer prototipo, mirando 17 líneas de datos de valores continuamente cambiantes, me di cuenta de que era necesario distinguir de alguna manera entre datos nuevos y datos que no cambian o rara vez cambian. Hizo un colorante en dos etapas:

  • los datos de la primera vez se resaltan en el fondo de la celda verde
  • los datos que llegan repetidamente y se resaltan con un fondo rojo, que se desvanece gradualmente a blanco si estos datos ya no cambian

Inmediatamente quedó claro qué células no se utilizaron en absoluto, cuáles contenían las señales del contador. La búsqueda de valores variables de interés se simplifica enormemente. En adelante, todas las imágenes están animadas. Si la animación no funciona en el artículo (en algunos navegadores móviles), haga clic en la imagen para abrir la versión completa de la animación.



Luego, aún quería comprobar si el puerto serie hace frente al flujo de datos. Para hacer esto, en el lado de Arduino, agregué contadores para la cantidad de paquetes recibidos y un contador de bytes en el paquete. Estos contadores se envían a la computadora en un paquete con el identificador 0x000. Al recibir estos datos, el programa no los muestra en una tabla, sino que los muestra en campos de información separados en la parte superior. Los resultados fueron incluso bastante agradables. En promedio, se reciben hasta 750 paquetes / s a ​​una velocidad de hasta 9.5 kB / s, y aquí es donde en la región hasta 80 kbit / s, que es bastante posible para un puerto serie. Pero de todos modos, el intercambio de datos está configurado por defecto a 500 kbps, por lo que es un mejor stock.

Después de que conecté el adaptador de diagnóstico ELM327 en paralelo con la interfaz OBD y lo conecté al teléfono, intente leer varios datos. Los datos corrieron tan rápido que era imposible verlos. Después de haber registrado todo esto en un diario, puede sentarse tranquilamente y ver los datos transmitidos. Para hacer esto, incluso los datos de texto ASCII pueden escribirse en el registro. También puede seleccionar el tipo de archivo, el carácter delimitador y configurar el filtro de paquetes haciendo clic en el identificador de paquete especificado en la tabla y haciendo clic en el botón "Agregar ID al filtro" (de forma predeterminada, todos los datos se escriben) si todos los datos se escriben de forma redundante.

Fue entonces cuando se dio cuenta de que todas las aplicaciones telefónicas que realizan todo tipo de "diagnósticos" a través del paquete ELM327 y el teléfono no se comunican directamente con el bus CAN del vehículo. Solo usan la funcionalidad de diagnóstico OBD a través del bus CAN accediendo a la ID CAN 0x7E0. Por lo general, esta es la dirección del controlador del motor (ECU), la respuesta viene en un paquete con el identificador 0x7E8. Pero todos los demás paquetes de datos son los denominados específicos del proveedor y ningún fabricante simplemente los abrirá (aunque hay un ejemplo: Ford lanzó un SDK para sus automóviles ).

Continuando con el estudio de lo que se transmite en estos paquetes, se me ocurrió otra idea: cuando hago clic en una celda de la tabla, en la ventana del programa a la derecha, visualizo el valor binario y decimal de este byte, así como tomar el siguiente byte y agregar a la palabra. Luego, multiplique esta palabra por un cierto coeficiente y obtenga un resultado decimal. No parece muy claro, pero en relación con lo que se hizo: la velocidad del motor viene en paquete CAN ID 0x180, en los primeros dos bytes. Estos dos bytes dan una cierta palabra que es proporcional a los giros. Si el significado de esta palabra se divide por 8, se obtiene el impulso actual. Por lo tanto, se indica un factor de 0.125, como el recíproco de 8. A continuación, esta palabra se visualiza en un gráfico con ajuste dinámico de amplitud. En principio, el multiplicador se puede buscar en el orden inverso: encontré celdas que son muy similares a la velocidad del motor o algo más de acuerdo con el programa, después de lo cual el multiplicador se ajusta para obtener valores reales.


Bueno, la representación binaria le permite buscar varios indicadores de bits. Por ejemplo, la búsqueda de indicadores de dirección se reduce a encenderlos y observar qué celda comienza a cambiar, en el ejemplo a continuación es CAN ID 0x481 byte 2. Después de eso, al hacer clic en una celda se muestra su valor binario en el campo correspondiente, donde los dos conmutadores inferiores ya están visibles bits (izquierda, derecha y, si están juntos, una alarma).


Y finalmente, necesitaba enviar algunos datos de control al bus CAN y ver la reacción a estos comandos. Se agregó un código al programa Arduino que recibe datos de la computadora y los transfiere al bus CAN. Fue en esta etapa que CyberLib tuvo que ser abandonado, ya que no tenía soporte para interrumpir la recepción de datos en el búfer del puerto serie. En el programa en la computadora, agregué varios campos de texto en los que puede ingresar varios parámetros y una tabla para ver la respuesta del actuador. El siguiente ejemplo muestra que los comandos de control habilitan / deshabilitan la primera velocidad del ventilador de enfriamiento (0x0A) y habilitan / deshabilitan el embrague del aire acondicionado (0x0B).



Resumen


Prácticamente no hay ningún lugar para encontrar un descifrado completo de los datos de los fabricantes, especialmente los oficiales. En el mejor de los casos, será la investigación de otra persona en el marco de la implementación de alguna función adicional. El sniffer CAN puede ayudarlo a encontrar esta información. Pude encontrar unos 40 parámetros diferentes del automóvil y, en aras de la experimentación, sobre la base de los datos recibidos, hice mi propio control del ventilador de enfriamiento.


Espero que todo esto sea útil no solo para mí.

Source: https://habr.com/ru/post/479672/


All Articles