El CAN-BUS
Bueno, entremos en palabras mayores. Para seguir teniendo el control sobre la configuración del vehículo necesitamos enviar las ordenes al sistema
central del vehículo (BSI). Dichas órdenes fluyen por el CAN-BUS, sistema industrial que está actualmente implantado en la mayoría de los automóviles
y sistemas industriales. En la web hay multitud de información de como funciona el estándar, pero no así, de lo que hace cada fabricante cuando lo
aplica.
Para nuestro caso podemos ir por el camino más corto, que sería comprar módulos que venden algunos fabricantes de radios para seguir utilizando los
mandos del volante y/o evitar la perdida del control del menú de la pantalla multifunción. Como estamos en tiempo de crisis y la parienta no nos deja
gastar más dinero, hay que investigar como los señores de Peugeot se han currado lo del CAN-BUS.
Investigación profunda
Hay que realizar un sistema capaz de capturar tráfico (información) que fluye por la línea CAN-BUS que nos interesa. Digo lo de la línea que nos
interesa, por que el Peugeot 308 dispone de diferentes buses que enlaza elementos según su funcionalidad y prioridad a la hora de gestionar los
sistemas internos. Todos los buses confluyen en la BSI (Unidad de Servicios Inteligente) para compartir la información que pueda se útil entre
diferentes sistemas.
El bus que nos interesa es el encargado de controlar los elementos más superficiales (radio,
climatización, asientos, indicadores, etc), y recibe el nombre de CAN CONFORT.
Trabaja a una velocidad de 125kbit/s en formato estándar (no he podido detectar ninguna
transmisión en modo extendido).
Desarrollando un pequeño circuito conversor que conectado a un PC, se realizan capturas de
todo el tráfico que se genera cada vez que se ejecuta una operación en el vehículo.
El dispositivo lo conecto directamente a la línea CAN CONFORT (no al conector de diagnosis
OBD) e investigo la información que solo fluye por dicho bus.
Resumo brevemente el proceso en el siguiente dibujo:
CAN CONFORT
BSI
Convertidor CAN RS-232
Soft-Hard
El circuito convertidor CAN -> RS232 está basado en el microcontrolador PIC 18F2480 que tiene implementado
en su hardware un puerto CAN-BUS. Toda la información que captura es formateada y enviada vía RS232 al
PC donde es nuevamente formateada y filtrada para un mejor estudio del tráfico que se genera.
Dada la gran cantidad de datos que circula por el CAN-BUS, la aplicación del PC también se ha
desarrollado para enviar al PIC una serie de máscaras que proporciona un filtrado previo y por ello una
limpieza en el gran flujo de información.
Para el estudio y entendimiento de lo que estamos capturando, he formateado la información tal y como
se muestra en el siguiente ejemplo:
Manos a la obra
En las siguientes tablas se refleja los datos reales de información que se generan cada vez que se actúa sobre los diferentes elementos del vehiculo,
(se ha omitido el valor “Nº de datos” ya que no es relevante):
Mando del volante
Relación de identificadores y paquetes de datos CAN-BUS generados por el mando situado en la columna de dirección.
T
ec
l
a mando volante
>>
(avanzar)
21F 80 00 00
<<
(retroceder)
21F 40 00 00
Vol+
(subir volumen)
21F 08 00 00
Vol-
(bajar volumen)
21F 04 00 00
Memo
(giro horario)
21F 00 xx 00
Memo
(giro antihorario)
21F 00 xx 00
Source
(fuente de señal)
21F 02 00 00
21F 0C 00 00
I
D y dat
os
ge
ne
r
ados
Reposo
(ninguna tecla pulsada)
21F 00 00 00
Evento generado
MENU
ESC
Tecla derecha
Tecla izquierda
Tecla arriba
Tecla abajo
OK
DARK
Reposo
3E5 40 00 00 00 00
3E5 00 00 10 00 04
3E5 00 00 00 00 04
3E5 00 00 00 00 01
3E5 00 00 00 00 40
3E5 00 00 00 00 10
3E5 00 00 40 00 00
3E5 00 00 04 00 00
I
D y dat
os
convertidos
3E5 00 00 00 00 00
Vol+ y Vol-
(subir y bajar volumen)
Trama generada cada 250ms aprox.
* valor xx comprende desde 00 hasta FF en función del giro del mando “Memo”
Radio-cd (RD4)
Identificadores y datos CAN-BUS que se generan pulsando la botonera del radio-cd:
Trama generada cada 500ms aprox.
De forma gráfica se muestra el flujo de información entre los diferentes elementos y la nueva filosofía de control del sistema:
CAN CONFORT
BSI
Radio-CD
Presentación menú en display
Instalación original
CAN CONFORT
BSI
Mando volante
Convertidor
Presentación menú en display
Instalación modificada
En la siguiente tabla se detalla la asociación de cada uno de los códigos generados por el mando en el volante y los que corresponderían a los enviados
desde el radio-cd.
Descargar
El esquema eléctrico mostrado, es el mismo que se utilizó para el estudio del tráfico CAN-BUS.
La única modificación a sido la eliminación del MAX232, y de diferentes elementos como
pulsadores e indicadores LED que me servían para la depuración del software.
Todo el circuito se ha metido en una pequeña caja alojada en el interior del salpicadero.
En la foto todavía tengo puesto el conector DB9 que utilizaba en un principio para poder realizar
actualizaciones del firmware.
Circuito utilizado durante el desarrollo del proyecto. Convierte la
información generada en el CAN-BUS a RS232 para su posterior análisis.
;------------------------------------------------------------------------
LIST P=18F2480, F=INHX32
;procesador.
#include <P18F2480.INC>
;include procesador.
;------------------------------------------------------------------------
; Configuracion bits
CONFIG
FCMEN = OFF, OSC = HS, IESO = OFF
CONFIG
PWRT = OFF, BOREN = BOHW, BORV=1
CONFIG
WDT=OFF, WDTPS = 16
CONFIG
MCLRE = ON
CONFIG
LPT1OSC = OFF, PBADEN = OFF
CONFIG
DEBUG = OFF
CONFIG
XINST = OFF, LVP = OFF, STVREN = ON, CP0 = OFF
CONFIG
CP1 = OFF, CPB = OFF, CPD = OFF, WRT0 = OFF, WRT1 = OFF, WRTB = OFF
CONFIG
WRTC = OFF, WRTD = OFF, EBTR0 = OFF, EBTR1 = OFF, EBTRB = OFF
;------------------------------------------------------------------------
; Definir variables.
;------------------------------------------------------------------------
CBLOCK 0
BufferRueda
; Valor del mando rueda.
DivMensaREPOSO
; Divisor de mensajes REPOSO.
ENDC
;------------------------------------------------------------------------
;------------------------------------------------------------------------
; Reset vector
;------------------------------------------------------------------------
ORG
0x0000
goto
Main
; Go to start.
;------------------------------------------------------------------------
;------------------------------------------------------------------------
; Inicio.
;------------------------------------------------------------------------
ORG
0x00A0
Main:
movlw
.4
movwf
DivMensaREPOSO
; Inicio variable.
call
IniPort
; Inicializa puertos.
call
ConfCAN
; Config. CAN.
call
MensaREPOSO
; Enviar teclas en reposo.
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;
Lectura mensajes CAN.
;------------------------------------------------------------------------
LecturaCAN:
btfss
RXB0CON, RXFUL
; ¿Contiene mensage CAN?
bra
LecturaCAN
; Lectura de mensajes CAN.
bcf
RXB0CON, RXFUL
; Limpiar flag RXFUL mensage CAN.
clrf
PIR3
movlw
B'00000000'
cpfseq
RXB0D0
bra
TeclaPulsada
; Procesar las teclas pulsadas.
; Comprobar si se ha movido en mando rueda.
ControlRueda:
movf
BufferRueda, W
cpfseq
RXB0D1
; ¿Son iguales?
bra
MovMandoRueda
bsf
PORTC,0
call
MensaREPOSO
; Enviar teclas en reposo.
bcf
PORTC,0
bra
LecturaCAN
; No hay movimiento de mando rueda. Salir.
; Comprobar si el movimiento mando rueda es ARRIBA o ABAJO.
MovMandoRueda:
movf
BufferRueda, W
cpfsgt
RXB0D1
; ¿Nuevo valor es mayor que el último?
bra
MovMandoRuedaABJ
; Movimiento mando rueda ARRIBA.
MovMandoRuedaARR:
movf
RXB0D1, W
; Guardar nuevo valor del mando rueda.
movwf
BufferRueda
call
MensaARR
; Enviar mensaje ARRIBA.
bra
LecturaCAN
; Salir.
; Movimiento mando rueda ABAJO.
MovMandoRuedaABJ:
movf
RXB0D1, W
; Guardar nuevo valor del mando rueda.
movwf
BufferRueda
call
MensaABA
; Enviar mensaje ABAJO.
bra
LecturaCAN
; Salir.
; Procesamiento de la tecla pulsada.
TeclaPulsada:
movlw
b'00001100'
; Pulsado vol.+ y vol.- a la vez.
cpfseq
RXB0D0
; para generar "DARK".
bra
TeclaPulsada_Bis
; No se han pulsado a la vez.
call
MensaDARK
; Generar mensaje "DARK".
bra
LecturaCAN
TeclaPulsada_Bis
btfsc
RXB0D0,3
; Pulsado volumen + (21F 08 00 00).
call
MensaMENU
; Generar mensaje "MENU".
btfsc
RXB0D0,2
; Pulsado volumen - (21F 04 00 00).
call
MensaESC
; Generar mensaje "ESC".
btfsc
RXB0D0,6
; Pulsado Retroceder << (21F 40 00 00).
call
MensaIZQ
; Generar mensaje "IZQ".
btfsc
RXB0D0,7
; Pulsado Abanzar >> (21F 80 00 00).
call
MensaDER
; Generar mensaje "DER".
btfsc
RXB0D0,1
; Pulsado Source (21F 02 00 00).
call
MensaOK
; Generar mensaje "OK".
bra
LecturaCAN
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;
Mensaje REPOSO (ninguna tecla pulsada).
;------------------------------------------------------------------------
MensaREPOSO:
; Se divide la cadencia del número de mensajes de REPOSO.
decfsz
DivMensaREPOSO, F
return
movlw
.4
movwf
DivMensaREPOSO
; Inicio variable.
movlb
.15
; Preparación mensaje a enviar.
movlw
00h
movwf
TXB0D0
movlw
00h
movwf
TXB0D1
movlw
00h
movwf
TXB0D2
movlw
00h
movwf
TXB0D3
movlw
00h
movwf
TXB0D4
movlw
00h
movwf
TXB0D5
call
CabeceraCAN
return
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;
Mensaje MENU.
;------------------------------------------------------------------------
MensaMENU:
movlb
.15
; Preparación mensaje a enviar.
movlw
40h
movwf
TXB0D0
movlw
00h
movwf
TXB0D1
movlw
00h
movwf
TXB0D2
movlw
00h
movwf
TXB0D3
movlw
00h
movwf
TXB0D4
movlw
00h
movwf
TXB0D5
call
CabeceraCAN
return
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;
Mensaje ESC.
;------------------------------------------------------------------------
MensaESC:
movlb
.15
; Preparación mensaje a enviar.
movlw
00h
movwf
TXB0D0
movlw
00h
movwf
TXB0D1
movlw
10h
movwf
TXB0D2
movlw
00h
movwf
TXB0D3
movlw
00h
movwf
TXB0D4
movlw
00h
movwf
TXB0D5
call
CabeceraCAN
return
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;
Mensaje IZQ.
;------------------------------------------------------------------------
MensaIZQ:
movlb
.15
; Preparación mensaje a enviar.
movlw
00h
movwf
TXB0D0
movlw
00h
movwf
TXB0D1
movlw
00h
movwf
TXB0D2
movlw
00h
movwf
TXB0D3
movlw
00h
movwf
TXB0D4
movlw
01h
movwf
TXB0D5
call
CabeceraCAN
return
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;
Mensaje DER.
;------------------------------------------------------------------------
MensaDER:
movlb
.15
; Preparación mensaje a enviar.
movlw
00h
movwf
TXB0D0
movlw
00h
movwf
TXB0D1
movlw
00h
movwf
TXB0D2
movlw
00h
movwf
TXB0D3
movlw
00h
movwf
TXB0D4
movlw
04h
movwf
TXB0D5
call
CabeceraCAN
return
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;
Mensaje OK.
;------------------------------------------------------------------------
MensaOK:
movlb
.15
; Preparación mensaje a enviar.
movlw
00h
movwf
TXB0D0
movlw
00h
movwf
TXB0D1
movlw
40h
movwf
TXB0D2
movlw
00h
movwf
TXB0D3
movlw
00h
movwf
TXB0D4
movlw
00h
movwf
TXB0D5
call
CabeceraCAN
return
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;
Mensaje ARRIBA.
;------------------------------------------------------------------------
MensaARR:
movlb
.15
; Preparación mensaje a enviar.
movlw
00h
movwf
TXB0D0
movlw
00h
movwf
TXB0D1
movlw
00h
movwf
TXB0D2
movlw
00h
movwf
TXB0D3
movlw
00h
movwf
TXB0D4
movlw
40h
movwf
TXB0D5
call
CabeceraCAN
return
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;
Mensaje ABAJO.
;------------------------------------------------------------------------
MensaABA:
movlb
.15
; Preparación mensaje a enviar.
movlw
00h
movwf
TXB0D0
movlw
00h
movwf
TXB0D1
movlw
00h
movwf
TXB0D2
movlw
00h
movwf
TXB0D3
movlw
00h
movwf
TXB0D4
movlw
10h
movwf
TXB0D5
call
CabeceraCAN
return
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;
Mensaje DARK.
;------------------------------------------------------------------------
MensaDARK:
movlb
.15
; Preparación mensaje a enviar.
movlw
00h
movwf
TXB0D0
movlw
00h
movwf
TXB0D1
movlw
04h
movwf
TXB0D2
movlw
00h
movwf
TXB0D3
movlw
00h
movwf
TXB0D4
movlw
00h
movwf
TXB0D5
call
CabeceraCAN
return
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;
Cabecera comun mensaje CAN.
;------------------------------------------------------------------------
CabeceraCAN:
;Nº de datos a transmitir = 6
movlw
06h
movwf
TXB0DLC
; Tamaño datos.
;Transmitir ID = 3E5
movlw
B'10100000'
; SID2 SID1 SID0 ---- EXIDE ---- ESID- ESID-
movwf
TXB0SIDL
; Identificador TXB0SIDL.
movlw
B'01111100'
; SID10 SID9 SID8 SID7 SID6 SID5 SID4 SID3
movwf
TXB0SIDH
; Identificador TXB0SIDH.
movlw
B'00001000'
; Transmitir mensaje.
movwf
TXB0CON
EnvioMesaCAN:
btfsc
TXB0CON, TXREQ
bra
EnvioMesaCAN
movlb
.0
return
;------------------------------------------------------------------------
;------------------------------------------------------------------------
; Configuración PORT:
;
RA0 pulsador P0
;
RA1 pulsador P1
;
;
RC0 Led L0
;
RC1 Led L1
;------------------------------------------------------------------------
IniPort:
movlw
0Fh
; Configura RA como digital.
movwf
ADCON1
setf
TRISA
; RA<7:0> como entradas.
movlw
b'11111100'
; RC<7:2> entrada y RC<1:0> como salida.
movwf
TRISC
clrf
PORTC
return
;------------------------------------------------------------------------
;------------------------------------------------------------------------
;
Configuración CAN.
;------------------------------------------------------------------------
ConfCAN:
movlw
B'10000000'
; Request Configuration mode.
movwf
CANCON
; Set to Configuration Mode.
; Module will wait for CAN bus to be idle before switching to Configuration Mode.
ConfigWait:
movf
CANSTAT, W
; Read current mode state.
xorlw
B'10000000'
; Interested in OPMODE bits only.
tstfsz
WREG
; Is it Configuration mode yet?
bra
ConfigWait
; No. Continue to wait...
; Modulo CAN esta en Configuration mode.
movlw
B'00000100'
; SJW=1, BRP=4 (125Khz).
movwf
BRGCON1
movlw
B'10110001'
; SEG=7, PRSEG=2.
movwf
BRGCON2
movlw
B'00000101'
; SEG2PH=6.
movwf
BRGCON3
movlw
B'00100000'
; Rec. only valid messages SID.
movwf
RXB0CON
; Disable double buffer of RX0
movlb
.15
; Banco 15.
movlw
B'11111111'
movwf
RXM0SIDH
; Colocar valores Mascara byte RXM0SIDH.
movlw
B'11100000'
movwf
RXM0SIDL
; Colocar valores Mascara byte RXM0SIDL.
;Leer solamente el ID=21F (códigos generados desde el mando volante).
movlw
B'01000011'
movwf
RXF0SIDH
; Colocar valores Filtro byte RXF0SIDH.
movlw
B'11100000'
movwf
RXF0SIDL
; Colocar valores Filtro byte RXF0SIDL.
movlb
0
; Banco 0.
movlw
B'00000000'
movwf
CANCON
; Request Normal Mode.
return
;------------------------------------------------------------------------
;End of program
END
Firmware microcontrolador
Detalle del conector Frakra donde se toma la alimentación y la línea CAN-CONF.
Bricos Peugeot 308