← Índice del curso

Comunicación entre Dispositivos · Tema 27 · CAN

CAN: el bus de los vehículos

En un automóvil moderno hay decenas de unidades electrónicas (motor, frenos, tablero, puertas, airbag) que necesitan intercambiar datos todo el tiempo, con muy poco cable, mucho ruido eléctrico y sin margen para perder un mensaje urgente. CAN (Controller Area Network) nació para eso y se extendió a la industria, la maquinaria agrícola, los equipos médicos y la robótica. Se distingue de todo lo que vimos hasta ahora en tres cosas: los mensajes no llevan dirección de destino sino un identificador que dice qué contienen; cuando dos nodos hablan a la vez gana el más urgente sin destruir el mensaje; y la propia trama trae confirmación, detección de errores y reintento automático. Este tema recorre la señal, el arbitraje, la trama, el relleno de bits, el CRC, los errores, los filtros y la carga del bus.

01 · Del cableado al bus

Un bus pensado para el automóvil

Hasta mediados de los años ochenta, cada función de un vehículo que necesitaba compartir un dato con otra unidad usaba cables propios: un hilo del sensor de velocidad al tablero, otro a la central del motor, otro a los frenos. Los mazos de cables se volvían enormes, pesados y poco confiables. La empresa Bosch desarrolló CAN para reemplazarlos por un único par de hilos compartido, y lo presentó en 1986; la norma ISO 11898 lo formalizó en los años noventa. Hoy cada vehículo trae varios buses CAN, y el mismo protocolo se usa en ascensores, máquinas herramienta, tractores, barcos, prótesis y drones.

Lo que hace especial a CAN, frente a RS-485 (que también es diferencial y multipunto), es que fue diseñado para tiempo real con múltiples maestros:

  • No hay maestro. Todos los nodos son iguales (multi-master) y cualquiera puede transmitir cuando el bus está libre. No hace falta un sondeo, y un nodo urgente no espera su turno.
  • No hay direcciones de nodo. Cada mensaje lleva un identificador que describe su contenido («velocidad de las ruedas», «temperatura del refrigerante»). Todos los nodos reciben todo, y cada uno decide, con filtros, qué le interesa.
  • El identificador es también la prioridad. Si dos nodos empiezan a transmitir a la vez, un mecanismo de arbitraje hace que gane el de identificador menor, y lo hace sin perder el mensaje ganador y sin retrasarlo.
  • Los errores se tratan en el protocolo. Cada trama lleva un CRC, todos los receptores la confirman, se detecta un error de cinco maneras distintas, y el transmisor reintenta solo. Un nodo defectuoso se aísla a sí mismo.

02 · Dos niveles, uno gana

La señal: dominante y recesivo

Niveles físicos del bus CAN En estado recesivo, CANH y CANL están ambas en unos 2,5 voltios y la diferencia es cercana a cero. En estado dominante, CANH sube a unos 3,5 voltios y CANL baja a unos 1,5 voltios, con una diferencia de unos 2 voltios. El estado dominante representa el bit 0 y prevalece sobre el recesivo cuando varios nodos transmiten a la vez. 3,5 V2,5 V1,5 V 0 V≈ 2 V CANHCANLCANH − CANL recesivo (1)dominante (0)recesivo (1)recesivo (1)dominante (0)dominante (0)recesivo (1)recesivo (1)

CAN usa un par trenzado diferencial (CANH y CANL, tema 23), pero con una peculiaridad: los dos niveles del bus no son equivalentes.

  • Recesivo (bit 1). Ningún nodo maneja el bus. CANH y CANL quedan en unos 2,5 V y la diferencia es cercana a 0 V.
  • Dominante (bit 0). Un nodo maneja activamente la línea: CANH sube a unos 3,5 V y CANL baja a unos 1,5 V, con una diferencia de unos 2 V.

Si un nodo transmite un dominante mientras otros transmiten recesivo, el bus queda en dominante: el nivel dominante prevalece. Es el mismo comportamiento de AND cableado del colector abierto (tema 16), aplicado a un par diferencial: el 0 gana al 1. Los transceptores CAN no mantienen el recesivo con una resistencia sino que dejan las salidas en alta impedancia, y las resistencias terminadoras (que unen ambas líneas) devuelven el bus al recesivo.

Esta asimetría es lo que hace posible el arbitraje de la sección 04: un nodo que envía un 1 y lee un 0 sabe que otro está transmitiendo un dominante, y puede retirarse sin dañar nada.

Parámetros eléctricos principales de CAN de alta velocidad (ISO 11898-2).
ParámetroValor
MedioPar trenzado de 120 Ω de impedancia característica
Tensión diferencial dominante (driver)Unos 2 V (CANH ≈ 3,5 V, CANL ≈ 1,5 V)
Tensión diferencial recesiva≈ 0 V (CANH ≈ CANL ≈ 2,5 V)
Umbral del receptorDominante por encima de unos 0,9 V; recesivo por debajo de unos 0,5 V
Rango de modo común del receptorAproximadamente de −2 V a +7 V
Terminación120 Ω entre CANH y CANL en cada extremo del bus (60 Ω medidos entre las líneas, con el equipo apagado)
VelocidadHasta 1 Mbit/s (CAN clásico)
NodosDecenas por bus; el límite lo da el transceptor (hasta 110 nodos en la norma)

La topología es un bus lineal con terminadores en los dos extremos y derivaciones cortas, igual que RS-485 (temas 24 y 26). Las normas de cableado son las mismas: par trenzado, sin estrellas, sin terminadores en el medio. La velocidad y la longitud máxima se compran una a la otra (sección 09), porque el arbitraje exige que la señal se propague hasta el nodo más lejano y vuelva en un tiempo menor que el de un bit.

Los transceptores CAN se ocupan del paso entre los niveles lógicos del microcontrolador (la salida TX y la entrada RX del controlador) y los dominantes/recesivos de la línea. Modelos comunes: MCP2551 y TJA1050 (5 V), SN65HVD230 y TCAN1042 (3,3 V). El controlador CAN (que arma las tramas y hace el arbitraje) puede ser un periférico del microcontrolador (el ESP32 lo trae) o un chip aparte, como el MCP2515 (se estudia en el tema 28).

03 · Qué se dice, no a quién

Mensajes con identificador

En I²C, Modbus o RS-485 el mensaje lleva la dirección del destinatario. En CAN, el mensaje lleva un identificador que dice qué contiene: es un esquema de productor y consumidores.

  • Cada identificador lo transmite un único nodo (el que produce ese dato). Dos nodos nunca deben usar el mismo identificador, porque no habría forma de resolver el arbitraje entre ellos.
  • Todos los nodos reciben todas las tramas (es un bus compartido). Cada nodo configura un filtro con los identificadores que le interesan y descarta el resto en hardware (sección 08).
  • Un mismo dato puede ser consumido por muchos nodos a la vez sin costo adicional: la velocidad de las ruedas la leen a la vez el tablero, el control de estabilidad y la central del motor, y se envía una sola vez.
  • Agregar un consumidor no requiere cambiar al productor: basta configurar su filtro.

El identificador cumple una segunda función: define la prioridad. Un identificador numéricamente menor tiene más prioridad (gana el arbitraje). Por eso, al diseñar una red CAN se asignan identificadores bajos a los mensajes críticos y de tiempo real (control de frenos, motor) y altos a los informativos (estado de las puertas, temperatura). Un esquema de ejemplo, puramente ilustrativo:

Asignación de identificadores de un sistema ficticio (el número menor es el de mayor prioridad).
IdentificadorMensajeProductorPeríodo
0x010Parada de emergenciaControl centralpor evento
0x0C0Revoluciones y torqueMotor10 ms
0x1A0Velocidad de las ruedasFrenos20 ms
0x3A0Estado de las puertasCarrocería100 ms
0x500Temperatura del habitáculoClimatización1000 ms

El contenido de cada mensaje (qué bits del campo de datos son la velocidad, en qué unidad, con qué factor de escala) no lo define CAN sino la aplicación, y se documenta en una tabla de señales (en la industria automotriz, un archivo DBC). Es el equivalente del mapa de registros de Modbus (tema 25), pero ordenado por mensaje.

Existen también protocolos de capa superior que fijan esa asignación para un área: J1939 (camiones y maquinaria), CANopen (automatización industrial), NMEA 2000 (náutica), OBD-II (diagnóstico de vehículos, tema 28). Todos usan las tramas CAN tal cual y organizan el significado de los identificadores.

04 · Quién habla primero

Arbitraje por prioridad

Arbitraje bit a bit entre tres nodos Tres nodos empiezan a transmitir a la vez con los identificadores 0x2C4, 0x2C0 y 0x2D0. Cada uno compara lo que envía con lo que lee en el bus. El nodo C envía un 1 en el bit 7 pero el bus está en 0, y se retira. El nodo A envía un 1 en el bit 9 donde el bus está en 0, y se retira. El nodo B, con el identificador menor, gana y sigue transmitiendo su trama sin pérdida. Identificador, del bit más significativo (1) al menos significativo (11) 1234567891011Nodo A0x2C4 0 1 0 1 1 0 0 0 1 · ·pierde en el bit 9Nodo B0x2C0 0 1 0 1 1 0 0 0 0 0 0ganaNodo C0x2D0 0 1 0 1 1 0 1 · · · ·pierde en el bit 7Bus01011000000 Un 0 (dominante) prevalece sobre un 1 (recesivo): gana el identificador numéricamente menor, sin destruir su trama.

Cuando el bus está libre (tres bits recesivos de silencio), cualquier nodo con algo para enviar puede empezar. Si dos o más empiezan al mismo tiempo, no se produce una colisión destructiva: se resuelve bit a bit, mientras se transmite el identificador, con esta regla simple:

  1. Cada nodo transmite su identificador, del bit más significativo al menos significativo.
  2. Al mismo tiempo, cada nodo lee el bus y compara lo que lee con lo que acaba de enviar.
  3. Si un nodo envió un 1 (recesivo) y lee un 0 (dominante), concluye que otro nodo con identificador menor está transmitiendo: pierde el arbitraje, deja de transmitir y se pasa a recibir esa trama.
  4. Si lee lo mismo que envió, sigue.

En la figura, los nodos A (0x2C4), B (0x2C0) y C (0x2D0) coinciden en los seis primeros bits. En el bit 7, C envía un 1 y el bus está en 0 (porque A y B envían 0): C se retira. En el bit 9, A envía un 1 y B un 0: A se retira. B sigue y termina su trama completa, sin haberse enterado de que tuvo competencia. El nodo que perdió reintenta apenas el bus queda libre.

Las consecuencias de este esquema son importantes para el diseño:

  • El arbitraje no cuesta tiempo ni pierde datos: el mensaje ganador se transmite como si estuviera solo. La capacidad del bus no se desperdicia en colisiones (a diferencia de Ethernet con hub).
  • La latencia depende de la prioridad. Un mensaje de máxima prioridad espera, a lo sumo, a que termine la trama que ya estaba en curso (como máximo 135 bits). Uno de baja prioridad puede esperar mucho si hay muchos mensajes más urgentes (inanición posible si el bus se satura).
  • Los identificadores deben ser únicos por productor. Si dos nodos transmitieran el mismo identificador, el arbitraje no los distingue y seguirían juntos hasta el campo de datos, donde empezarían los errores de bits.
  • Solo funciona porque todos los nodos se escuchan en el mismo bit, y por eso hay una relación entre la velocidad y la longitud del bus: la señal debe llegar a todos dentro del tiempo de un bit.

Por esta razón, CAN no es adecuado para «sondear» como Modbus: se diseña para que cada nodo publique sus datos cuando cambian o con un período fijo, y los demás los consuman.

05 · Campos y bits

La trama de datos

Trama de datos CAN estándar Una trama de datos empieza con un bit de inicio dominante, sigue con el identificador de 11 bits y el bit RTR, que forman el campo de arbitraje, el campo de control con IDE, un bit reservado y el código de longitud de 4 bits, de 0 a 8 bytes de datos, un CRC de 15 bits con su delimitador, el espacio de confirmación ACK con su delimitador, siete bits recesivos de fin de trama y tres de separación. SOF 1 Identificador 11 RTR 1 IDE 1 r0 1 DLC 4 Datos 0 a 64 CRC 15 D 1 ACK 1 D 1 EOF 7 IFS 3 arbitrajecontrolCRCACK zona con relleno de bits (después de 5 iguales se inserta uno opuesto) Sin contar el relleno: 44 + 8·n bits (n = bytes de datos), más 3 de separación entre tramas. D = delimitador (recesivo). El transmisor envía recesivo en ACK; cualquier receptor que recibió bien la trama lo baja a dominante.

La trama estándar (CAN 2.0A, identificador de 11 bits) tiene los siguientes campos:

Campos de una trama de datos CAN estándar.
CampoBitsContenido
SOF (inicio de trama)1Un bit dominante. Sincroniza a todos los nodos
Identificador11Qué mensaje es; define la prioridad. El primer bit enviado es el más significativo
RTR (solicitud remota)1Dominante (0) en una trama de datos; recesivo (1) en una trama remota
IDE (extensión del identificador)1Dominante (0) en el formato estándar; recesivo en el extendido
r0 (reservado)1Dominante
DLC (código de longitud)4Cantidad de bytes de datos, de 0 a 8
Datos0 a 64De 0 a 8 bytes, el más significativo primero
CRC15Código de redundancia cíclica calculado sobre todos los bits anteriores
Delimitador del CRC1Recesivo
ACK1El transmisor envía recesivo; los receptores que recibieron bien la trama lo ponen en dominante
Delimitador del ACK1Recesivo
EOF (fin de trama)7Siete bits recesivos
IFS (separación entre tramas)3Tres bits recesivos antes de que otro nodo pueda empezar

Sumando los campos fijos, una trama con n bytes de datos mide 44 + 8 · n bits sin contar el relleno, y 47 + 8 · n con la separación entre tramas. Una trama de 8 bytes son 111 bits; a 500 kbit/s, 222 µs. El «peso» de la información útil es modesto: solo 64 de esos 111 bits son datos (el 58 %), el resto es identificación, control y protección.

Además de la trama de datos hay otros tres tipos:

  • Trama remota. Igual que la de datos, pero con RTR recesivo y sin campo de datos. Un nodo la usa para pedir que el productor de un identificador envíe su dato. Se usa poco: es más frecuente que los productores publiquen por su cuenta.
  • Trama de error. La envía cualquier nodo que detecte un error: 6 bits dominantes seguidos (una violación a propósito de la regla de relleno, que hace que todos los nodos descarten la trama en curso) y 8 recesivos de delimitador.
  • Trama de sobrecarga. Pedido de una pausa a un nodo que no está listo (casi no se ve en la práctica).

El formato extendido (CAN 2.0B) ofrece un identificador de 29 bits: después de los 11 bits altos se envían un SRR recesivo y un IDE recesivo (que distingue el formato), seguidos de los 18 bits restantes del identificador. Es el que usan J1939 y muchos sistemas industriales con espacios de direccionamiento grandes. En el arbitraje, una trama estándar le gana a una extendida cuyos 11 bits altos sean iguales (porque su IDE es dominante donde el de la extendida es recesivo). Un bus puede mezclar los dos formatos.

06 · Mantener la sincronía y proteger los datos

Relleno de bits y CRC

Relleno de bits Una secuencia de datos con cinco unos seguidos y cinco ceros seguidos. El transmisor inserta un 0 después de los cinco unos y un 1 después de los cuatro ceros que, junto con el 0 insertado, forman cinco ceros seguidos. El receptor quita los bits insertados. Bits a transmitir 111110000011 Bits en el cable (14: 2 de relleno) 111110relleno00001relleno011

CAN no tiene una línea de reloj, y su codificación es NRZ (el nivel es el bit): una larga cadena de bits iguales no tendría ningún flanco, y los receptores perderían la sincronía. Para evitarlo, el transmisor aplica el relleno de bits (bit stuffing): después de cinco bits consecutivos iguales, inserta un bit de valor opuesto. El receptor, que conoce la regla, quita ese bit.

Detalles de la regla:

  • Se aplica desde el SOF hasta el final del campo CRC (inclusive). No se aplica al delimitador del CRC, el ACK, el EOF ni el IFS.
  • El bit insertado cuenta para la secuencia siguiente: en la figura, después del 0 insertado, cuatro ceros más ya son una nueva cadena de cinco, y exige otro bit de relleno.
  • Cinco bits iguales o más en el cable son, por lo tanto, un error de relleno (se usa a propósito en la trama de error).
  • El relleno alarga la trama: en el peor caso, una trama de 8 bytes pasa de 111 a 135 bits (con IFS). La fórmula del máximo de bits de relleno es ⌊(34 + 8 · n − 1) / 4⌋.
Largo de una trama estándar con la separación entre tramas (IFS), según los bytes de datos.
Bytes de datos nSin relleno (47 + 8n)Peor caso con rellenoDuración a 500 kbit/s (sin relleno · peor caso)
0475594 µs · 110 µs
15565110 µs · 130 µs
26375126 µs · 150 µs
47995158 µs · 190 µs
8111135222 µs · 270 µs

El CRC de CAN es de 15 bits y se calcula sobre todos los bits transmitidos antes de él (SOF, identificador, control y datos), sin contar los bits de relleno. Usa el polinomio x15 + x14 + x10 + x8 + x7 + x4 + x3 + 1 (0x4599). El algoritmo es un registro de desplazamiento de 15 bits, que arranca en cero: por cada bit de entrada, se hace XOR del bit con el bit más alto del registro; se desplaza el registro un lugar a la izquierda; y si ese XOR dio 1, se hace XOR del registro con 0x4599. Al final, el registro es el CRC. Tiene una distancia de Hamming de 6: detecta con certeza hasta 5 bits erróneos en una trama y cualquier ráfaga de hasta 15 bits.

Una propiedad para comprobar el cálculo: si se pasa por el mismo algoritmo el mensaje seguido de su CRC, el registro queda en cero. Es lo que hace un receptor: corre el CRC sobre todo lo que llega, incluido el CRC, y verifica que dé cero. Un resto distinto de cero es un error de CRC. Como CAN lo tiene incorporado en hardware, no hace falta calcularlo a mano en un programa corriente; sí conviene entenderlo para leer capturas de un analizador.

07 · Un protocolo que se vigila a sí mismo

Confirmación y detección de errores

La confirmación (ACK) es un único bit dentro de la trama. El transmisor envía recesivo en el campo ACK, y todos los receptores que recibieron la trama sin errores lo ponen en dominante. Si el transmisor ve el bit en dominante, sabe que al menos un nodo la recibió bien. Si lo ve recesivo, nadie la recibió (un error de ACK): por ejemplo, un nodo solo en el bus, que transmite sin nadie que escuche. Nótese que el ACK dice «al menos uno la recibió», no «todos».

Cada nodo vigila la trama con cinco mecanismos, y cualquiera que detecte un error lo señala con una trama de error:

Los cinco tipos de error de CAN.
ErrorQuién lo detectaQué significa
Error de bitEl transmisorLee en el bus un valor distinto del que envió (fuera del arbitraje y del ACK)
Error de rellenoLos receptoresAparecen seis bits iguales seguidos donde debía haber un bit de relleno
Error de CRCLos receptoresEl CRC recibido no coincide con el calculado
Error de formaLos receptoresUn campo de formato fijo (delimitadores, EOF) tiene un valor incorrecto
Error de ACKEl transmisorEl campo ACK llega recesivo: nadie confirmó

Cuando un nodo detecta un error, transmite una trama de error: seis bits dominantes (que violan la regla del relleno y hacen que todos los nodos se den cuenta) más ocho recesivos. La trama en curso se descarta en todos, y el transmisor la reintenta automáticamente apenas puede. El resultado es que, mientras el bus sea capaz de transmitir, un error transitorio se corrige solo y la aplicación ni se entera.

Estados de error de un nodo CAN Un nodo empieza en error activo. Si uno de sus contadores de errores llega a 128 pasa a error pasivo. Si el contador de errores de transmisión supera 255 pasa a bus apagado, donde no participa en el bus. Vuelve a error activo tras detectar 128 veces once bits recesivos seguidos o por reinicio. Error activo envía banderas dominantes Error pasivo bandera recesiva; espera extra Bus apagado no transmite ni recibe TEC o REC ≥ 128 TEC > 255 tras 128 secuencias de 11 bits recesivos (o reinicio) TEC = contador de errores de transmisión · REC = contador de errores de recepción

Para que un nodo defectuoso no arruine al resto, cada nodo mantiene dos contadores: el de errores de transmisión (TEC) y el de recepción (REC). En esencia, un error de transmisión suma 8 al TEC, un error de recepción suma 1 al REC, y cada trama correcta resta 1. De ellos sale el estado:

  • Error activo (TEC y REC < 128): funcionamiento normal. Al detectar un error envía una trama de error con bandera dominante.
  • Error pasivo (TEC o REC ≥ 128): el nodo sigue transmitiendo y recibiendo, pero su bandera de error es recesiva (no puede interrumpir a los demás) y, después de transmitir, espera 8 bits extra antes de volver a intentarlo.
  • Bus apagado (bus-off, TEC > 255): el nodo se desconecta del bus y no transmite ni recibe. Vuelve cuando detecta 128 veces 11 bits recesivos seguidos, o por reinicio por software.

Como cada error de transmisión suma 8, bastan 16 errores seguidos para llegar a error pasivo (TEC = 128) y 32 para apagarse (TEC = 256). Un nodo con un cable roto o un transceptor dañado se aísla en unas decenas de tramas, sin necesidad de ningún supervisor. Una excepción importante: un nodo en error pasivo que no recibe ACK no sigue subiendo su TEC, por lo que un nodo solo en el bus reintenta indefinidamente sin apagarse.

08 · Escuchar solo lo que importa

Filtros de aceptación

Como todos los nodos ven todas las tramas, cada controlador CAN tiene en hardware uno o varios filtros de aceptación, que deciden cuáles tramas se entregan al microcontrolador. Un filtro se define con dos valores:

  • un código (el identificador buscado), y
  • una máscara que indica qué bits del identificador se comparan: los bits con 1 en la máscara deben coincidir con el código; los bits con 0 son «no importa».
aceptar si (identificador & máscara) == (código & máscara)
Ejemplos de filtros de 11 bits.
Quiero aceptarCódigoMáscaraCuántos identificadores pasan
Solo el 0x1230x1230x7FF (todos los bits)1
Los 16 identificadores 0x100 a 0x10F0x1000x7F0 (se ignoran los 4 bits bajos)16
0x123 y 0x1270x1230x7FB (se ignora el bit 2)2
Todoscualquiera0x0002048

Con una máscara, un filtro acepta una cantidad de identificadores que es potencia de 2 (2 elevado a la cantidad de bits «no importa»), y por eso se diseña la tabla de identificadores agrupando los mensajes de un mismo consumidor en un rango alineado. Los controladores traen varios filtros (el MCP2515, 6; muchos STM32, 14 bancos) y buzones de recepción. La ventaja del filtrado por hardware es que el microcontrolador no se interrumpe por tramas que no le interesan: en un bus muy cargado, es la diferencia entre atender 100 interrupciones por segundo o 5000.

Una advertencia práctica: algunos controladores usan la convención inversa para la máscara (un 1 significa «no importa»); es el caso del ESP32. Por eso hay que leer la documentación de cada uno y probar con un identificador conocido.

09 · Cuánto cabe

Carga del bus y velocidad

La carga del bus es la fracción del tiempo que el bus está ocupado transmitiendo. Se calcula sumando, por segundo, los bits de todas las tramas y dividiendo por la velocidad en bits por segundo:

carga = (Σ tramas por segundo × bits por trama) / velocidad

Por ejemplo, 1000 tramas de 8 bytes por segundo a 500 kbit/s: 1000 × 111 / 500 000 = 22,2 % con el largo mínimo, y 1000 × 135 / 500 000 = 27,0 % con el peor caso de relleno. Un bus a 100 % de carga no puede transmitir nada más, y mucho antes de eso las tramas de baja prioridad empiezan a esperar. Como regla de diseño, se apunta a mantener la carga media por debajo del 30 al 50 % en redes con mensajes críticos, para que cualquier mensaje urgente tenga una latencia acotada.

La velocidad máxima se limita por la longitud del bus. El arbitraje requiere que un bit viaje hasta el nodo más lejano y regrese dentro del tiempo de un bit, que además debe cubrir los retardos de los transceptores. Las reglas orientativas para un cable bien hecho:

Velocidad y longitud máxima orientativa de un bus CAN.
VelocidadDuración de un bitLongitud máxima orientativa
1 Mbit/s1 µsunos 40 m
500 kbit/s2 µsunos 100 m
250 kbit/s4 µsunos 250 m
125 kbit/s8 µsunos 500 m
50 kbit/s20 µsunos 1000 m

Las velocidades de uso más común son 500 kbit/s (automotriz), 250 kbit/s (camiones y maquinaria, J1939) y 125 kbit/s o menos (carrocería y confort). Todos los nodos deben usar la misma velocidad, y además la misma configuración del tiempo de bit interno (el punto de muestreo y la sincronización), tema del siguiente capítulo.

10 · Con el microcontrolador

Con el microcontrolador

El ESP32 trae un controlador CAN en el propio chip (llamado TWAI, Two-Wire Automotive Interface, compatible con CAN 2.0). Solo hace falta un transceptor externo (por ejemplo un SN65HVD230 de 3,3 V) entre los pines TX/RX del ESP32 y el par CANH/CANL. El primer programa transmite cada 100 ms un mensaje con identificador 0x200 que lleva un contador y una temperatura, e informa el estado de los contadores de error:

#include "driver/twai.h"

const gpio_num_t PIN_TX = GPIO_NUM_5;            // al pin TX (D) del transceptor
const gpio_num_t PIN_RX = GPIO_NUM_4;            // al pin RX (R) del transceptor
uint16_t contador = 0;

void iniciarCan() {
    twai_general_config_t general = TWAI_GENERAL_CONFIG_DEFAULT(PIN_TX, PIN_RX, TWAI_MODE_NORMAL);
    twai_timing_config_t tiempos = TWAI_TIMING_CONFIG_500KBITS();          // 500 kbit/s: igual en todos los nodos
    twai_filter_config_t filtro = TWAI_FILTER_CONFIG_ACCEPT_ALL();
    if (twai_driver_install(&general, &tiempos, &filtro) != ESP_OK) { Serial.println("No se pudo instalar el controlador CAN"); while (true) delay(1000); }
    if (twai_start() != ESP_OK)                                          { Serial.println("No se pudo arrancar el controlador CAN");  while (true) delay(1000); }
    Serial.println("CAN a 500 kbit/s");
}

void informarEstado() {
    twai_status_info_t s;
    twai_get_status_info(&s);
    Serial.print("estado "); Serial.print(s.state == TWAI_STATE_RUNNING ? "activo" : s.state == TWAI_STATE_BUS_OFF ? "BUS APAGADO" : "otro");
    Serial.print(" | TEC "); Serial.print(s.tx_error_counter);
    Serial.print(" | REC "); Serial.print(s.rx_error_counter);
    Serial.print(" | transmisiones fallidas "); Serial.println(s.tx_failed_count);
    if (s.state == TWAI_STATE_BUS_OFF) twai_initiate_recovery();            // empieza la recuperación (128 × 11 bits recesivos)
}

void setup() {
    Serial.begin(115200);
    iniciarCan();
}

void loop() {
    static unsigned long ultimo = 0;
    static unsigned long ultimoInforme = 0;
    if (millis() - ultimo >= 100) {
        ultimo = millis();
        float temperatura = 23.5;                               // un dato de ejemplo
        int16_t decimas = (int16_t)lroundf(temperatura * 10);

        twai_message_t m = {};
        m.identifier = 0x200;                                   // qué mensaje es, y su prioridad
        m.extd = 0;                                             // formato estándar (11 bits)
        m.data_length_code = 4;
        m.data[0] = contador >> 8; m.data[1] = contador & 0xFF;     // el byte más significativo primero (convención nuestra)
        m.data[2] = decimas >> 8;  m.data[3] = decimas & 0xFF;
        if (twai_transmit(&m, pdMS_TO_TICKS(50)) == ESP_OK) contador++;
        else Serial.println("No se pudo encolar la trama");
    }
    if (millis() - ultimoInforme >= 2000) { ultimoInforme = millis(); informarEstado(); }
}

Si este nodo está solo en el bus, twai_transmit encola la trama pero nadie la confirma: el campo ACK llega recesivo, el controlador reintenta una y otra vez y el TEC sube hasta el límite de error pasivo (127) y se queda ahí. Para probar un nodo solo se puede usar el modo TWAI_MODE_NO_ACK (autoprueba), que acepta la trama sin confirmación. En una red real, con al menos otro nodo conectado, el ACK llega y el contador se mantiene en cero.

El segundo programa es un receptor con filtro: solo acepta los identificadores 0x200 a 0x20F, y decodifica el mensaje anterior. Ojo con la convención del filtro del ESP32: un 1 en la máscara significa «no importa», y el identificador de 11 bits se coloca desplazado a la izquierda en el campo de 32 bits.

#include "driver/twai.h"

void setup() {
    Serial.begin(115200);
    twai_general_config_t general = TWAI_GENERAL_CONFIG_DEFAULT(GPIO_NUM_5, GPIO_NUM_4, TWAI_MODE_NORMAL);
    twai_timing_config_t tiempos = TWAI_TIMING_CONFIG_500KBITS();
    twai_filter_config_t filtro;
    filtro.acceptance_code = (uint32_t)0x200 << 21;           // el identificador de 11 bits ocupa los bits 31 a 21
    filtro.acceptance_mask = ~((uint32_t)0x7F0 << 21);        // aquí un 1 = «no importa»: se comparan solo los 7 bits altos
    filtro.single_filter = true;
    if (twai_driver_install(&general, &tiempos, &filtro) != ESP_OK || twai_start() != ESP_OK) {
        Serial.println("No se pudo iniciar el controlador CAN");
        while (true) delay(1000);
    }
}

void loop() {
    twai_message_t m;
    if (twai_receive(&m, pdMS_TO_TICKS(200)) == ESP_OK) {
        if (m.rtr) { Serial.print("Trama remota, id 0x"); Serial.println(m.identifier, HEX); return; }
        Serial.print("id 0x"); Serial.print(m.identifier, HEX);
        Serial.print(" dlc "); Serial.print(m.data_length_code);
        Serial.print(" datos");
        for (int i = 0; i < m.data_length_code; i++) { Serial.print(' '); if (m.data[i] < 16) Serial.print('0'); Serial.print(m.data[i], HEX); }
        if (m.identifier == 0x200 && m.data_length_code == 4) {
            uint16_t cuenta = (m.data[0] << 8) | m.data[1];
            int16_t decimas = (int16_t)((m.data[2] << 8) | m.data[3]);
            Serial.print(" -> cuenta "); Serial.print(cuenta);
            Serial.print(", temperatura "); Serial.print(decimas / 10.0, 1); Serial.print(" C");
        }
        Serial.println();
    }
}

Tres cosas para tener presentes. El formato del campo de datos lo decide la aplicación: aquí usamos el byte alto primero y enteros escalados (como en Modbus), pero no es obligatorio. El controlador hace todo lo demás: arbitraje, relleno de bits, CRC, ACK, reintentos y contadores. La velocidad, igual en todos: un nodo a otra velocidad ve tramas rotas y empieza a generar tramas de error que perturban al resto.

11 · Analogía con programación

CAN en Python

Las partes de CAN con aritmética propia (el CRC de 15 bits, el relleno de bits, el arbitraje, los filtros, la carga y los contadores de error) caben en pocas líneas. El modelo siguiente arma una trama estándar bit a bit, la rellena, la «recibe» quitando el relleno y comprobando el CRC, y calcula su duración; simula un arbitraje entre tres nodos; aplica un filtro y estima una carga.

Python en tu navegador. Los bloques son editables: cambiá los valores y presioná «Ejecutar Python». La primera vez tarda unos segundos en cargar.

def bits(valor, n):
    return [(valor >> (n - 1 - i)) & 1 for i in range(n)]


def crc15(secuencia):
    crc = 0
    for b in secuencia:
        siguiente = b ^ ((crc >> 14) & 1)
        crc = (crc << 1) & 0x7FFF
        if siguiente:
            crc ^= 0x4599
    return crc


def rellenar(secuencia):
    salida, insertados, racha, ultimo = [], [], 0, None
    for b in secuencia:
        salida.append(b)
        racha = racha + 1 if b == ultimo else 1
        ultimo = b
        if racha == 5:                                   # cinco iguales: se inserta uno opuesto
            salida.append(1 - b)
            insertados.append(len(salida) - 1)
            ultimo, racha = 1 - b, 1
    return salida, insertados


def quitar_relleno(secuencia):
    salida, racha, ultimo, i = [], 0, None, 0
    while i < len(secuencia):
        b = secuencia[i]
        salida.append(b)
        racha = racha + 1 if b == ultimo else 1
        ultimo = b
        if racha == 5:
            i += 1                                       # el siguiente es un bit de relleno: se descarta
            if i < len(secuencia):
                if secuencia[i] == b:
                    raise ValueError("error de relleno")
                ultimo, racha = secuencia[i], 1
        i += 1
    return salida


def trama(identificador, datos):
    cabecera = [0] + bits(identificador, 11) + [0, 0, 0] + bits(len(datos), 4)          # SOF, ID, RTR, IDE, r0, DLC
    previo = cabecera + [b for byte in datos for b in bits(byte, 8)]
    crc = crc15(previo)
    relleno, insertados = rellenar(previo + bits(crc, 15))
    return previo, crc, relleno, insertados


def bits_totales(relleno):
    return len(relleno) + 10 + 3                          # delimitador del CRC, ACK, delimitador, EOF (7) y separación (3)


def arbitraje(ids):
    perdio = {i: None for i in ids}
    for b in range(11):
        envian = {i: (i >> (10 - b)) & 1 for i in ids if perdio[i] is None}
        bus = min(envian.values())                       # el 0 (dominante) prevalece
        for i, v in envian.items():
            if v > bus:
                perdio[i] = b + 1
    return perdio


def acepta(identificador, codigo, mascara):
    return identificador & mascara == codigo & mascara


def peor_caso(n):
    return 47 + 8 * n + (34 + 8 * n - 1) // 4


previo, crc, enviado, ins = trama(0x123, [0xDE, 0xAD, 0xBE, 0xEF])
print(f"Trama 0x123 con DE AD BE EF: CRC {crc:#06x}")
print(f"  {len(previo) + 25} bits sin relleno, {len(ins)} bits de relleno, {bits_totales(enviado)} bits con separación = {bits_totales(enviado) / 500000 * 1e6:.0f} µs a 500 kbit/s")
print("  el receptor recupera la secuencia original:", quitar_relleno(enviado) == previo + bits(crc, 15))
print("  resto del CRC sobre mensaje + CRC:", crc15(previo + bits(crc, 15)))
dañada = list(previo + bits(crc, 15))
dañada[20] ^= 1
print("  con un bit alterado, el resto del CRC es:", crc15(dañada), "(distinto de cero: error de CRC)")

ceros = trama(0x000, [0] * 8)
mixto = trama(0x2C0, [1, 2, 3, 4, 5, 6, 7, 8])
print(f"Trama 0x000 con ocho ceros: {len(ceros[3])} bits de relleno, {bits_totales(ceros[2])} bits")
print(f"Trama 0x2C0 con 1 a 8:      {len(mixto[3])} bits de relleno, {bits_totales(mixto[2])} bits")
print("Relleno de 1 1 1 1 1 0 0 0 0 0 1 1:", "".join(map(str, rellenar([1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1])[0])), "en las posiciones", rellenar([1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1])[1])
print("Bits con 0, 1, 2, 4 y 8 bytes (sin relleno / peor caso):", [(47 + 8 * n, peor_caso(n)) for n in (0, 1, 2, 4, 8)])

print()
print("Arbitraje entre 0x2C4, 0x2C0 y 0x2D0 (bit en el que pierde cada uno):", {f"{i:#x}": p for i, p in arbitraje([0x2C4, 0x2C0, 0x2D0]).items()})
print("Filtro 0x100 / 0x7F0:", [acepta(i, 0x100, 0x7F0) for i in (0x105, 0x10F, 0x110)], "| filtro 0x123 / 0x7FB:", [acepta(i, 0x123, 0x7FB) for i in (0x123, 0x127, 0x12B)])
print(f"1000 tramas de 8 bytes por segundo a 500 kbit/s: {1000 * 111 / 500000 * 100:.1f} % (mínimo), {1000 * peor_caso(8) / 500000 * 100:.1f} % (peor caso)")
print("TEC tras 16, 32 y 33 errores de transmisión seguidos:", [8 * e for e in (16, 32, 33)], "(128 = pasivo, más de 255 = bus apagado)")

Resultado: la trama 0x123 con los datos DE AD BE EF tiene un CRC de 0x4e6b, 76 bits sin relleno y 2 bits de relleno; con los delimitadores, el ACK, el EOF y la separación suma 81 bits, es decir 162 µs a 500 kbit/s. El receptor, al quitar el relleno, recupera la secuencia original y el resto del CRC sobre mensaje y CRC da 0; con un bit alterado da un valor distinto de cero (un error de CRC). Una trama con identificador 0 y ocho bytes en cero tiene 16 bits de relleno y 127 bits en total; la 0x2C0 con los datos 1 a 8, 11 bits de relleno y 122 bits. El relleno de 1 1 1 1 1 0 0 0 0 0 1 1 da 11111000001011, con bits insertados en las posiciones 5 y 10. Los largos con y sin relleno de peor caso para 0, 1, 2, 4 y 8 bytes son 47/55, 55/65, 63/75, 79/95 y 111/135. En el arbitraje, el nodo 0x2D0 pierde en el bit 7, el 0x2C4 en el 9, y el 0x2C0 gana. El filtro 0x100/0x7F0 acepta 0x105 y 0x10F y rechaza 0x110; el 0x123/0x7FB acepta 0x123 y 0x127 pero no 0x12B. 1000 tramas de 8 bytes por segundo a 500 kbit/s ocupan el 22,2 % del bus en el mejor caso y el 27,0 % en el peor. Y el TEC llega a 128 (error pasivo) con 16 errores y a 256 (bus apagado) con 32.

Observá que ninguno de estos cálculos depende del hardware: el controlador de un microcontrolador los hace por vos. Pero son los que aparecen cuando se lee la captura de un analizador, o se dimensiona la carga de una red antes de armarla.

12 · Exploración interactiva

Laboratorio: arbitraje, tramas, filtros, carga y errores

El laboratorio tiene cinco herramientas. La primera simula el arbitraje entre hasta cuatro nodos. La segunda arma una trama completa: campos, CRC-15, relleno de bits y duración. La tercera prueba filtros de aceptación con código y máscara. La cuarta calcula la carga del bus y la longitud máxima. La quinta sigue los contadores de error y el estado del nodo.

1. Arbitraje

Bits que se ven en el bus (11)—
Ganador—
Dónde pierde cada nodo—
Veredicto—

Escribí los identificadores (de 000 a 7FF).

2. Armar una trama

Identificador · DLC · CRC-15—
Bits sin relleno · con relleno · de relleno—
Duración con separación entre tramas—
Relleno de bits en el cable (SOF a CRC; los bits de relleno entre corchetes)—
Comprobación del CRC (mensaje + CRC)—

Elegí el identificador y los datos.

3. Filtro de aceptación

Identificador (binario)—
Código (binario)—
Máscara (binario)—
Resultado—
Qué acepta este filtro—

Escribí el identificador, el código y la máscara.

4. Carga del bus y longitud

Bits por trama (sin relleno · peor caso)—
Duración de una trama—
Carga del bus (mínima · peor caso)—
Tramas por segundo al 100 % · al 50 %—
Longitud máxima orientativa—
Veredicto—

Elegí la velocidad y el tráfico.

5. Contadores de error

TEC (errores de transmisión)—
REC (errores de recepción)—
Estado del nodo—
Cómo se comporta—

Cargá los errores y las tramas correctas.

En la herramienta 1, un identificador vacío significa que el nodo no transmite. En la 2, la trama es de datos con formato estándar; el CRC se calcula sobre los bits sin relleno, y el relleno se aplica desde el SOF hasta el final del CRC. En la 4, la longitud máxima es una regla orientativa para un cable bien hecho y los largos «peor caso» usan la fórmula de relleno máximo. En la 5, el modelo suma 8 por error de transmisión, 1 por error de recepción y resta 1 por trama correcta, sin tener en cuenta el orden de los eventos.

Recorrido guiado

  1. Con los valores iniciales (0x2C4, 0x2C0 y 0x2D0), el bus muestra 01011000000: el nodo C (0x2D0) pierde en el bit 7, el nodo A (0x2C4) en el bit 9, y B (0x2C0) gana. El ganador es siempre el identificador numéricamente menor.
  2. Agregá un nodo D con 000: gana en el bit 2 (el segundo bit de los demás es 1). Poné el nodo A en 2C0, igual que el B: «identificadores repetidos», porque el arbitraje no puede distinguirlos y el conflicto aparece más tarde, en los datos.
  3. En la herramienta 2, con los valores iniciales (0x123, DE AD BE EF): CRC 0x4E6B, 76 bits sin relleno, 2 bits de relleno y 81 bits en total con la separación: 162 µs a 500 kbit/s. La comprobación del CRC sobre mensaje y CRC da 0.
  4. Probá el identificador 000 con ocho bytes 00: muchísimo relleno (16 bits) y 127 bits en total. Con el identificador 2C0 y los datos 01 02 03 04 05 06 07 08: 11 bits de relleno y 122 bits. Sin datos, 44 bits sin relleno.
  5. Bajá la velocidad a 125 kbit/s: la misma trama de 81 bits dura 648 µs. A 1 Mbit/s, 81 µs.
  6. En la herramienta 3, con los valores iniciales (0x105, código 0x100, máscara 0x7F0), el filtro acepta: los bits altos coinciden. El filtro acepta 16 identificadores, de 0x100 a 0x10F. Probá 110: se rechaza. Con máscara 7FF solo pasa el 0x100. Con máscara 000 pasa todo.
  7. Código 123, máscara 7FB: acepta 0x123 y 0x127 (difieren en el bit 2, que se ignora), pero no 0x12B.
  8. En la herramienta 4, con los valores iniciales (500 kbit/s, 8 bytes, 1000 tramas por segundo): 111 bits (135 en el peor caso), 222 µs por trama y una carga de 22,2 % (27,0 % en el peor caso). Al 100 % cabrían 4505 tramas por segundo y al 50 %, 2252. Cable de unos 100 m.
  9. Subí a 3000 tramas por segundo: 66,6 % (81 % en el peor caso): «Carga alta». Con 4000, el peor caso pasa de 100 %. A 125 kbit/s las mismas 1000 tramas son el 88,8 %.
  10. En la herramienta 5, con 10 errores de transmisión seguidos (TEC = 80): error activo. Con 16: TEC = 128, error pasivo. Con 32: TEC = 256, bus apagado. Si después hubo 100 tramas correctas con 20 errores, el TEC baja a 60.
Desafío: la latencia del peor caso

En un bus de 500 kbit/s, un mensaje de máxima prioridad quiere transmitir justo cuando acaba de empezar una trama de 8 bytes de baja prioridad. ¿Cuánto espera como máximo? La trama en curso no se interrumpe: hay que esperar a que termine, hasta 135 bits con el peor relleno, o sea 270 µs, más la separación entre tramas (ya incluida). Es un límite superior corto y garantizado, y por eso CAN se usa en control en tiempo real. Para el mensaje de la prioridad más baja el análisis es más complejo, y depende de cuántos más urgentes puedan llegar mientras espera.

13 · Un procedimiento

Diagnóstico de un bus CAN

Un bus CAN que no anda se revisa en este orden, de lo más simple a lo más específico:

  1. Con todo apagado, medir la resistencia entre CANH y CANL. Deben ser unos 60 Ω (dos terminadores de 120 Ω en paralelo). 120 Ω: falta un terminador; 40 Ω: hay tres; abierto: no hay ninguno; unos pocos ohmios: cortocircuito.
  2. Con el bus encendido y sin tráfico, medir las tensiones contra la masa: CANH y CANL deben estar cerca de 2,5 V (recesivo). Si están en 0 V, el transceptor no está alimentado; si una está en cero y otra en 5 V, hay un cortocircuito a masa o a la alimentación.
  3. Igualar la velocidad y el tiempo de bit en todos los nodos. Un nodo a otra velocidad produce tramas de error constantes que perturban a todos.
  4. Mirar el tráfico con un analizador o una interfaz USB–CAN: tramas bien formadas (ID, DLC, datos), con confirmación y sin tramas de error.
  5. Revisar los contadores de error de los nodos: TEC creciendo en un nodo apunta a ese nodo (transceptor, cableado propio); REC creciendo en todos apunta al bus (terminación, ruido, velocidad).
  6. Revisar los identificadores: que cada uno sea transmitido por un solo nodo, y que los filtros dejen pasar lo esperado.
  7. Mirar la carga del bus: una carga alta retrasa los mensajes de baja prioridad.
Síntomas y causa probable.
SíntomaCausa probableQué hacer
Un nodo solo en el bus transmite sin parar, TEC en 127, nadie confirmaFalta otro nodo que dé ACKConectar un segundo nodo, o usar el modo sin ACK para pruebas
Ninguna trama se ve; la resistencia entre CANH y CANL es de 120 ΩFalta un terminador, o un cable rotoAgregar el segundo terminador; revisar continuidad
Muchas tramas de error; todos los nodos suben RECVelocidades distintas, terminación incorrecta, ruidoIgualar velocidad y tiempo de bit; terminar bien; mejorar el cable
Un nodo pasa a bus apagadoTransceptor dañado, cable propio roto, velocidad distintaRevisar ese nodo; mirar el TEC antes de que se apague
Un mensaje de un nodo nunca llega a los demásFiltros mal configurados; máscara invertidaAceptar todo temporalmente y volver a filtrar
Los mensajes de baja prioridad llegan tarde o no lleganBus muy cargadoBajar el tráfico, subir la velocidad, reasignar períodos
Datos incoherentes en un identificadorDos nodos usan el mismo identificadorDar a cada productor sus propios identificadores

14 · Comprensión

Confusiones frecuentes

«El identificador es la dirección del nodo destino»

No: describe el contenido del mensaje, y define la prioridad. El destino lo decide cada receptor con su filtro. Todos los nodos reciben todas las tramas.

«Si dos nodos transmiten a la vez hay una colisión y se pierde todo»

En CAN el arbitraje se resuelve bit a bit sin pérdida: gana el identificador menor y su trama se transmite completa. El que pierde se retira y reintenta después.

«El 1 es el nivel dominante»

Al revés: el dominante es el 0, y prevalece sobre el recesivo (1). Por eso gana el identificador menor: tiene ceros más temprano.

«Un mensaje de identificador alto tiene más prioridad»

Tiene menos. El número menor es el más urgente. Los mensajes críticos reciben identificadores bajos.

«El ACK significa que todos los nodos recibieron la trama»

Significa que al menos uno la recibió bien. Un nodo que no confirma no se entera el emisor.

«Un error en el bus corrompe los datos de la aplicación»

Un error detectado hace que la trama se descarte en todos y se reintente. La aplicación recibe la trama buena. Los datos corruptos solo pasan si el error escapa a los cinco controles (muy improbable por el CRC de 15 bits).

«El bus CAN es lento porque va a 500 kbit/s»

Para control en tiempo real alcanza: una trama de 8 bytes dura unos 222 µs y el mensaje más urgente espera como máximo una trama en curso. Lo que importa es la latencia garantizada, no la velocidad bruta.

«Puedo conectar un nodo solo al CANH y CANL y probar»

Un nodo solo no recibe ACK y reintenta indefinidamente. Además, sin terminadores la señal rebota. Para probar con un solo nodo hay que usar un modo de autoprueba, y para una red real, al menos dos nodos y dos terminadores.

15 · Práctica guiada

Predecí antes de comprobar

1. Quién gana

Los nodos con identificadores 0x0F0 y 0x0F8 empiezan a transmitir a la vez. ¿Quién gana y en qué bit pierde el otro?

Ver solución

0x0F0 = 000 1111 0000 y 0x0F8 = 000 1111 1000. Coinciden en los primeros siete bits y en el octavo el 0x0F0 envía un 0 y el 0x0F8 un 1. Gana 0x0F0 y 0x0F8 pierde en el bit 8.

2. Duración de una trama

Una trama de 5 bytes de datos a 250 kbit/s. ¿Cuántos bits y cuánto tiempo, sin relleno (con la separación entre tramas)? ¿Y en el peor caso?

Ver solución

47 + 8 · 5 = 87 bits: 87 / 250 000 = 348 µs. Peor caso: bits de relleno máximos = ⌊(34 + 40 − 1) / 4⌋ = 18, total 105 bits = 420 µs.

3. Relleno de bits

Los bits a transmitir son 1 0 0 0 0 0 0 1. ¿Cómo salen al cable?

Ver solución

Después de cinco ceros seguidos se inserta un 1: 1 0 0 0 0 0 [1] 0 1 (9 bits). El sexto cero original empieza una nueva cadena después del bit insertado. El receptor, al ver cinco ceros, descarta el 1 siguiente.

4. Un filtro

Querés que un nodo reciba solo los identificadores 0x200 a 0x20F. ¿Qué código y qué máscara usás (convención «1 = se compara»)? ¿Y para recibir solo 0x123 y 0x127?

Ver solución

Para el rango: código 0x200, máscara 0x7F0 (se ignoran los 4 bits bajos). Para 0x123 y 0x127: difieren en el bit 2 (valor 4): código 0x123, máscara 0x7FB (todos los bits salvo el 2). En el ESP32 la máscara va invertida (1 = no importa).

5. Carga

Un bus de 250 kbit/s lleva 300 tramas por segundo de 8 bytes y 500 tramas por segundo de 2 bytes. ¿Qué carga tiene, con el largo mínimo y en el peor caso?

Ver solución

Mínimo: 300 × 111 + 500 × 63 = 33 300 + 31 500 = 64 800 bits por segundo, o sea 25,9 %. Peor caso: 8 bytes → 135 bits; 2 bytes → 63 + ⌊(34 + 16 − 1) / 4⌋ = 75: 300 × 135 + 500 × 75 = 78 000 bits por segundo, 31,2 %.

6. Contadores de error

Un nodo tiene un cable de su transceptor cortado y cada intento de transmisión falla. ¿Cuántos intentos hacen falta para que pase a error pasivo y a bus apagado?

Ver solución

Cada error de transmisión suma 8 al TEC. Error pasivo con TEC ≥ 128: 128 / 8 = 16 errores. Bus apagado con TEC > 255: 256 / 8 = 32 errores. A 500 kbit/s con tramas de 100 µs son menos de 10 ms.

7. Medir un bus

Con el bus apagado, un multímetro entre CANH y CANL marca 120 Ω, y con el bus encendido y sin tráfico CANH y CANL marcan 2,5 V cada una. ¿Qué pasa y qué hacés?

Ver solución

Las tensiones son las correctas para el recesivo, pero con 120 Ω hay un solo terminador: falta el del otro extremo (o un cable cortado antes de él). Sin él habrá reflexiones, sobre todo a velocidades altas. Se agrega la segunda resistencia de 120 Ω y se vuelve a medir: debe dar 60 Ω.

16 · Síntesis

Ideas para recordar

  • CAN es un bus diferencial multimaestro sin direcciones de nodo: cada mensaje lleva un identificador de 11 bits (o 29 en el formato extendido) que dice qué contiene y define su prioridad. Todos los nodos reciben todo y filtran.
  • Los niveles son dominante (bit 0, CANH ≈ 3,5 V y CANL ≈ 1,5 V) y recesivo (bit 1, ambas ≈ 2,5 V). El dominante prevalece: es un AND cableado diferencial. Terminación de 120 Ω en los dos extremos (60 Ω medidos).
  • El arbitraje compara bit a bit lo que se envía con lo que se lee: quien envía un 1 y lee un 0 se retira. Gana el identificador menor, sin perder la trama ni retrasarla. Los identificadores deben ser únicos por productor.
  • Una trama de datos son SOF, identificador, RTR, IDE, r0, DLC, 0 a 8 bytes, CRC de 15 bits, ACK, EOF y separación: 47 + 8·n bits sin relleno, hasta 135 para 8 bytes con el peor relleno (111 a 135 bits, de 222 a 270 µs a 500 kbit/s).
  • El relleno inserta un bit opuesto tras cinco iguales (desde SOF hasta el CRC) para mantener la sincronía; seis iguales seguidos son un error de relleno. El CRC-15 (polinomio 0x4599) deja un resto cero al recorrer mensaje y CRC.
  • Cinco errores posibles (bit, relleno, CRC, forma, ACK) se señalan con tramas de error y la trama se reintenta sola. Los contadores TEC y REC llevan al nodo de error activo a pasivo (≥ 128) y a bus apagado (TEC > 255): un nodo defectuoso se aísla solo.
  • Los filtros de aceptación (código y máscara) descartan por hardware lo que no interesa: aceptar si (id & máscara) == (código & máscara). Un filtro acepta una potencia de 2 de identificadores; el ESP32 usa la máscara invertida.
  • La carga del bus es Σ tramas/s × bits / velocidad, y conviene mantenerla por debajo del 30–50 %. La velocidad y la longitud se compran una a la otra: unos 40 m a 1 Mbit/s, 100 m a 500 kbit/s, 250 m a 250 kbit/s, 500 m a 125 kbit/s.

¿Listo para el siguiente tema?

Antes de avanzar, decidí quién gana entre los identificadores 0x1A0 y 0x190 y en qué bit pierde el otro; calculá la carga de un bus de 500 kbit/s con 500 tramas por segundo de 4 bytes (95 bits como máximo); y explicá por qué un nodo solo en el bus no se apaga pero tampoco logra transmitir. (Para la primera: 0x1A0 = 001 1010 0000 y 0x190 = 001 1001 0000 difieren en el bit 6; gana 0x190.) Si podés justificar las tres respuestas, tenés los fundamentos de CAN.

En el próximo tema pasamos a CAN en la práctica: el tiempo de bit y los puntos de muestreo, el controlador MCP2515 y los transceptores, CAN FD, OBD-II y el uso en sistemas industriales.