Módulo CAN BUS Shield MCP2515 para Arduino: Manual Técnico Completo

Módulo CAN BUS Shield MCP2515 para Arduino — manual técnico completo

Introdução

Neste manual, será apresentado como instalar, configurar e utilizar o Módulo CAN BUS Shield MCP2515 para Arduino. Se desejar adquirir este produto, clique aqui.

O Módulo CAN BUS Shield MCP2515 para Arduino (código SKU RB0641) é uma placa de expansão empilhável (stackable shield, 65×53 mm65 \times 53\,\text{mm}) projetada no fator de forma oficial do Arduino Uno R3 para instrumentação veicular OBD-II (On-Board Diagnostics II), redes industriais CANopen / SAE J1939 e sistemas de robótica distribuída. A arquitetura combina o controlador autônomo de protocolo MCP2515 (Microchip Technology) via interface SPI (Serial Peripheral Interface de até 10 MHz10\,\text{MHz}) com um transceptor diferencial de camada física de alta velocidade compatível com a norma ISO 11898-2 (TJA1050 / MCP2551), atingindo taxas de transferência de até 1 Mb/s1\,\text{Mb/s} no padrão CAN 2.0B. Além do conector industrial metálico SUB-D de 9 pinos (DB9) e do borne de parafuso dedicado (CAN_H e CAN_L), o shield disponibiliza 4 LEDs indicadores de estado (PWR, TX, RX, INT), 2 botões táteis embutidos e barramentos auxiliares dedicados para UART e I2C (Inter-Integrated Circuit). Este documento técnico reúne especificações elétricas absolutas, mapeamento completo de pinos, equacionamento de bit timing e firmware pronto para bancada e diagnóstico automotivo.

Especificações técnicas

Principais especificações

As especificações estruturais, de protocolo e de conectividade do Módulo CAN BUS Shield MCP2515 para Arduino estão consolidadas na tabela a seguir:

ParâmetroEspecificação
Modelo ComercialMódulo CAN BUS Shield MCP2515 para Arduino (Formato Uno R3 V1.2)
Código de Referência (SKU)RB0641
Controlador de Protocolo CANMicrochip MCP2515-I/SO (Encapsulamento SMD SOIC-18)
Transceptor de Camada Física (PHY)NXP TJA1050 / Microchip MCP2551 (SOIC-8, alta velocidade ISO 11898-2)
Versão do Protocolo SuportadaCAN V2.0A / V2.0B Ativo (Identificadores Standard de 11 bits11\,\text{bits} e Extended de 29 bits29\,\text{bits})
Taxa Máxima de Transferência CANAté 1 Mb/s1\,\text{Mb/s} (5 kbps5\,\text{kbps} a 1.000 kbps1.000\,\text{kbps}; padrões veiculares típicos: 250 kbps250\,\text{kbps} e 500 kbps500\,\text{kbps})
Interface com o MicrocontroladorSPI (Serial Peripheral Interface) de alta velocidade até 10 MHz10\,\text{MHz} — Modos (0,0) e (1,1)
Oscilador a Cristal na Placa (Y1/X1)Cristal de quartzo metálico HC-49S de 16,000 MHz16{,}000\,\text{MHz} (conferir gravação 16.000 ou 8.000 no invólucro)
Buffers e Filtros em Hardware33 buffers de transmissão (TXB0–TXB2), 22 buffers de recepção (RXB0, RXB1), 66 filtros e 22 máscaras de 29 bits29\,\text{bits}
Conectores de Campo CAN11 conector fêmea padrão SUB-D DB9 (99 pinos) + 11 borne de parafuso duplo (CAN_H / CAN_L)
Terminação de Linha IntegradaResistor de fim de linha de 120 Ω120\,\Omega selecionável na placa (chave/jumper de terminação P1/R3)
Expansões Periféricas AuxiliaresConectores dedicados de 44 pinos (2,54 mm2{,}54\,\text{mm}) para interface serial UART (RX, TX, 5V, GND) e I2C (SDA, SCL, 5V, GND)
** Sinalização Visual (4 LEDs SMD)**Power (PWR), Enviando (TX), Recebendo (RX) e Interrupção (INT)
Interface Tátil Integrada22 botões push-button embutidos na placa (Reset e botão auxiliar / controle)
Dimensões e Massa65×53 mm65 \times 53\,\text{mm} (excluindo projeção frontal do conector DB9) / Peso aproximado: 55 g55\,\text{g}

Características elétricas e operacionais

Os limites elétricos nominais e máximos absolutos do conjunto controlador MCP2515 + transceptor diferencial CAN alimentado pelo barramento do Arduino estão detalhados abaixo:

Parâmetro Elétrico / OperacionalMínimoTípicoMáximoUnidadeCondição / Observação Técnica
Tensão de Operação do Shield (VCCV_{\text{CC}})4,754{,}755,005{,}005,255{,}25VDC\text{VDC}Suprida pelo pino 5V regulado do Arduino (limite absoluto antes de dano: 6,0 V6{,}0\,\text{V})
Consumo Médio Nominal de Corrente15,015{,}030,030{,}045,045{,}0mA\text{mA}Operação típica com tráfego intermitente CAN + LEDs indicadores ativos
Corrente de Pico (Bit Dominante)35,035{,}055,055{,}075,075{,}0mA\text{mA}Transmissão contínua de nível dominante (0) sobre barramento terminado em 60 Ω60\,\Omega
Corrente em Repouso (Recessive Idle)6,06{,}010,010{,}015,015{,}0mA\text{mA}Barramento em estado recessivo (1) com LED PWR energizado
Nível Lógico Alto de Entrada SPI (VIHV_{\text{IH}})3,503{,}505,005{,}00VCC+0,5V_{\text{CC}} + 0{,}5V\text{V}VIH(mıˊn)=0,7⋅VCCV_{\text{IH(mín)}} = 0{,}7 \cdot V_{\text{CC}} nas linhas CS, SCK e MOSI com VCC=5,0 VV_{\text{CC}} = 5{,}0\,\text{V}
Nível Lógico Baixo de Entrada SPI (VILV_{\text{IL}})−0,30-0{,}300,000{,}001,001{,}00V\text{V}VIL(maˊx)=0,2⋅VCCV_{\text{IL(máx)}} = 0{,}2 \cdot V_{\text{CC}} referido ao GND comum
Tensão de Modo Comum Recessiva (CAN_H/CAN_L)2,002{,}002,502{,}503,003{,}00V\text{V}Ambas as linhas polarizadas em VCC/2≈2,5 VV_{\text{CC}}/2 \approx 2{,}5\,\text{V} quando nenhum nó transmite bit 0
Tensão Dominante em CAN_H / CAN_L2,752{,}75 / 0,500{,}503,503{,}50 / 1,501{,}504,504{,}50 / 2,252{,}25V\text{V}CAN_H sobe para ≈3,5 V\approx 3{,}5\,\text{V} e CAN_L desce para ≈1,5 V\approx 1{,}5\,\text{V} sobre carga de 60 Ω60\,\Omega
Tensão Diferencial Dominante (VdiffV_{\text{diff}})1,501{,}502,002{,}003,003{,}00V\text{V}Vdiff=VCANH−VCANLV_{\text{diff}} = V_{\text{CANH}} - V_{\text{CANL}} (limiar diferencial do receptor entre 0,5 V0{,}5\,\text{V} e 0,9 V0{,}9\,\text{V})
Proteção contra Transientes no Barramento−27,0-27{,}0—+40,0+40{,}0V\text{V}Tolerância nos pinos CAN_H e CAN_L contra curtos acidentais à bateria 12 V12\,\text{V} / 24 V24\,\text{V}
Temperatura de Operação Industrial (TAT_A)−40-40+25+25+85+85°C\text{°C}Faixa industrial dos CIs automotivos MCP2515-I/SO e TJA1050/MCP2551

Descrição do produto

O que é o Módulo CAN BUS Shield MCP2515 para Arduino?

O Módulo CAN BUS Shield MCP2515 para Arduino é uma interface de rede veicular e industrial completa concebida para encaixe direto (plug-and-play) sobre placas Arduino Uno R3, Arduino Leonardo e Arduino Mega 2560, eliminando fiações soltas em protoboard durante testes em veículos ou painéis elétricos. A placa implementa em hardware dedicado as duas camadas inferiores do modelo OSI para redes CAN 2.0B: o controlador Microchip MCP2515 processa integralmente a camada de enlace de dados (Data Link Layer — enquadramento de mensagens, arbitragem não destrutiva por prioridade de ID, cálculo e validação de CRC de 15 bits, bit stuffing, filtragem por máscaras e retransmissão automática em caso de erro), enquanto o transceptor de alta velocidade TJA1050 / MCP2551 executa a conversão da camada física (Physical Layer — ISO 11898-2) entre níveis lógicos TTL de 5 V5\,\text{V} e sinais diferenciais simétricos imunes a interferência eletromagnética.

Projetado especificamente para instrumentação prática, o shield reúne em uma única PCB de fibra de vidro FR-4 um conector metálico SUB-D de 9 pinos (DB9) já roteado para cabos adaptadores DB9-para-OBD-II, um borne de parafuso lateral de 22 vias para conexão direta de cabos industriais em par trançado, 4 LEDs dedicados de telemetria física (PWR, TX, RX e INT) que permitem diagnosticar visualmente o tráfego de pacotes sem osciloscópio, 2 botões embutidos para reinicialização/interação rápida e conectores header de 44 pinos para acoplar displays I2C (OLED/LCD) ou módulos UART (GPS, Bluetooth ou telemetria LoRa) diretamente sobre o shield.

Para que serve?

  • Scanners automotivos OBD-II, dataloggers de telemetria e painéis digitais (SimRacing / pista): Aquisição em tempo real de grandezas da unidade de controle do motor (ECU — rotação RPM, velocidade veicular, temperatura do líquido de arrefecimento, carga do motor, pressão de admissão e códigos de falha DTC) através de cabo padrão DB9 ↔\leftrightarrow OBD-II (ISO 15765-4).
  • Automação industrial, máquinas agrícolas e supervisão em redes CANopen / SAE J1939: Comunicação multiponto determinística entre controladores, inversores de frequência, sensores industriais remotos e implementos pesados (caminhões, ônibus e tratores a 250 kbps250\,\text{kbps} ou 500 kbps500\,\text{kbps}) por par trançado.
  • Robótica móvel, veículos elétricos e gerenciamento de baterias (BMS): Integração confiável entre o controlador central e controladores de tração BLDC, servoatuadores inteligentes e módulos de proteção de células de lítio em ambientes com intenso ruído de chaveamento PWM.

Por que devo usar?

  • Montagem mecânica empilhável (Shield) com conectividade industrial DB9 e borne de parafuso: Ao encaixar diretamente nos barramentos fêmea do Arduino Uno/Mega e oferecer fixação mecânica parafusada no conector SUB-D DB9, o shield suporta vibrações severas dentro de veículos e máquinas sem mau contato de jumpers.
  • Diagnóstico visual imediato por 4 LEDs de hardware e portas de expansão I2C/UART prontas: Os indicadores independentes de alimentação (PWR), transmissão (TX), recepção (RX) e interrupção ativa (INT) aceleram a depuração de falhas de baud rate ou terminação, enquanto os conectores I2C e UART permitem plugar um display OLED ou módulo GPS em segundos.
  • Desacoplamento total de processamento no controlador MCP2515 via SPI de 10 MHz: Como toda a arbitragem, checagem de CRC e filtragem de identificadores ocorre dentro do silício do MCP2515, o microcontrolador hospedeiro lê apenas os pacotes úteis validados nos buffers RXB0/RXB1, preservando CPU e memória RAM.

Quando devo usar?

Este shield é a solução ideal quando você utiliza placas no formato padrão Arduino (Uno R3, Mega 2560, Leonardo) alimentadas em 5,0 VDC5{,}0\,\text{VDC} e necessita de uma estrutura fisicamente rígida com conector DB9 nativo para cabo OBD-II, LEDs dedicados de monitoramento de tráfego e barramentos prontos para periféricos externos I2C/UART em redes CAN 2.0A/2.0B de até 1 Mb/s1\,\text{Mb/s}.

Em contrapartida, avalie as seguintes alternativas técnicas caso o seu projeto se enquadre nestas restrições:

  • Gabinetes ultracompactos, protoboards ou conexão dedicada a placas miniaturizadas (Arduino Nano / Pro Mini): O formato shield (65×53 mm65 \times 53\,\text{mm}) ocupa toda a área de um Uno. Para espaços reduzidos, utilize o compacto Módulo CAN BUS MCP2515 TJA1050 OBD-II (RB0552) (43×28 mm43 \times 28\,\text{mm}).
  • Barramentos veiculares modernos com protocolo CAN FD (Flexible Data-Rate): Redes automotivas recentes que operam com payloads de até 64 bytes64\,\text{bytes} e taxas de dados de 2 Mbps2\,\text{Mbps} a 8 Mbps8\,\text{Mbps} exigem controladores compatíveis com ISO 11898-1:2015, como o MCP2518FD (o MCP2515 suporta exclusivamente CAN 2.0 clássico até 8 bytes8\,\text{bytes} e 1 Mbps1\,\text{Mbps}).
  • Sistemas nativos de 3,3 V3{,}3\,\text{V} com controlador CAN interno (ex.: ESP32 usando periférico TWAI interno sem fonte de 5 V5\,\text{V}): Como o transceptor TJA1050/MCP2551 do shield requer alimentação estrita de 5,0 V5{,}0\,\text{V}, em circuitos alimentados apenas por bateria 3,3 V3{,}3\,\text{V} com ESP32 prefira um transceptor puro de 3,3 V3{,}3\,\text{V} como o SN65HVD230, ou utilize transceptores isolados (ISO1050) em ambientes industriais sujeitos a ground loops elevados.

Pinout e diagrama de entradas/saídas

O Módulo CAN BUS Shield MCP2515 distribui seus sinais através de quatro grupos funcionais: (1) as barras laterais empilháveis padrão Arduino (incluindo o conector traseiro ICSP/ISP de 66 pinos), (2) o conector frontal SUB-D DB9 em paralelo com o borne lateral de 22 parafusos, (3) os conectores auxiliares de 44 pinos para UART e I2C, e (4) os indicadores luminosos e chaves na superfície da PCB.

1. Mapeamento dos pinos entre o Shield e a Placa Base Arduino

Pino no Shield / ArduinoSinal TécnicoDireção (Relativa ao Shield)Nível ElétricoFunção Detalhada na Placa
5V (Power Header)Alimentação Principal VCCV_{\text{CC}}Entrada+5,0 VDC+5{,}0\,\text{VDC} (±5%\pm 5\%)Energiza o controlador MCP2515, o transceptor CAN, o LED PWR e os pinos +5V dos conectores UART e I2C.
GND (Power / Digital)Terra ComumReferência0 V0\,\text{V}Referência elétrica comum da lógica SPI, transceptor CAN e periféricos auxiliares.
RST (Power Header)System ResetBidirecionalAtivo Baixo (0 V0\,\text{V})Conectado ao botão tátil de Reset do shield para reiniciar o conjunto Arduino + Shield com acesso pelo topo.
D10 (ou D9 via jumper)CAN_CS (CS‾\overline{\text{CS}})Entrada Lógica5 V5\,\text{V} TTL/CMOSSeleção de escravo SPI do controlador MCP2515 (ativo em LOW). Padrão de fábrica em D10 na revisão V1.2 EF02037/compatíveis (algumas revisões Seeed usam D9; o código de exemplo testa/configura facilmente).
D11 (e pino 4 ICSP)SPI_MOSI (SI)Entrada Lógica5 V5\,\text{V} TTL/CMOSLinha serial de comandos e dados transmitidos do microcontrolador mestre para a entrada SI do MCP2515.
D12 (e pino 1 ICSP)SPI_MISO (SO)Saída Lógica0 V0\,\text{V} / +5,0 V+5{,}0\,\text{V}Linha serial de dados lidos do pino SO do MCP2515 para o mestre (entra em alta impedância Hi-Z quando CS = HIGH).
D13 (e pino 3 ICSP)SPI_SCK (SCK)Entrada Lógica5 V5\,\text{V} (f≤10 MHzf \le 10\,\text{MHz})Entrada de clock síncrono SPI fornecido pelo microcontrolador hospedeiro.
D2 (INT0)CAN_INT (INT‾\overline{\text{INT}})Saída LógicaAtivo Baixo (5 V5\,\text{V})Saída de interrupção do MCP2515 com pull-up na placa. Cai para LOW (acendendo o LED INT) quando há pacote recebido ou alerta de erro.
D0 / D1 (RX / TX)UART_RX / UART_TXPassagem Direta5 V5\,\text{V} TTLRoteados diretamente para o conector externo de 44 pinos UART (livres caso nenhum módulo serial esteja plugado).
A4 / A5 (SDA / SCL)I2C_SDA / I2C_SCLPassagem Direta5 V5\,\text{V} TTLRoteados diretamente para o conector externo de 44 pinos I2C para displays OLED/LCD e sensores externos.
D3 a D8 e A0 a A3GPIOs Livres (Pass-through)Livre5 V5\,\text{V} TTLPinos preservados nas barras fêmea superiores do shield (em revisões com botão de usuário dedicado, verificar continuidade com D3/D4 ou A0/A1).

2. Pinagem do Conector SUB-D DB9, Borne Lateral e Porta Veicular OBD-II

Na maioria dos cabos adaptadores automotivos OBD-II →\to DB9, o shield utiliza por padrão a pinagem OBD-II Standard nos pinos 3 (CAN_H) e 5 (CAN_L) do conector DB9. Confira a correspondência completa entre o conector DB9 do shield, o conector trapezoidal OBD-II (SAE J1962) do veículo e o padrão industrial CiA-102:

Terminal no ShieldPino Equivalente OBD-II (Carro)Sinal Padrão OBD-II (Default do Shield)Padrão Industrial CiA-102 (Alternativo)Função Técnica
DB9 Pino 2Pino 4 / Pino 5 OBD-IIGND (Terra de Sinal)CAN_L (apenas se jumper CiA alterado)Referência de modo comum entre o veículo e o transceptor do shield.
DB9 Pino 3Pino 6 OBD-IICAN_H (CAN High)GNDLinha diferencial positiva de alta velocidade (ISO 15765-4).
DB9 Pino 5Pino 14 OBD-IICAN_L (CAN Low)Shield / TerraLinha diferencial negativa de alta velocidade (ISO 15765-4).
DB9 Pino 7—Não Conectado (NC)CAN_H (apenas se jumper CiA alterado)Usado somente em cabos industriais padrão CiA DS-102.
DB9 Pino 9Pino 16 OBD-IIV_OBD (+12 V+12\,\text{V} Bateria)CAN_V+Tensão bruta da bateria veicular (desacoplada por padrão por segurança).
Borne CAN_HPino 6 OBD-IICAN_H DiretoCAN_H DiretoEm paralelo direto com a saída CANH do transceptor (independe de cabo DB9).
Borne CAN_LPino 14 OBD-IICAN_L DiretoCAN_L DiretoEm paralelo direto com a saída CANL do transceptor (independe de cabo DB9).

3. Conectores de Expansão Auxiliares (I2C / UART) e LEDs de Diagnóstico

Bloco na PlacaSerigrafiaFunção Operacional
Conector I2C (44 pinos)GND | 5V | SCL | SDAAlimentação +5 V+5\,\text{V} e barramento I2CI^2C conectado a A5 (SCL) e A4 (SDA) para acoplar displays OLED SSD1306 ou LCD I2C.
Conector UART (44 pinos)GND | 5V | TX | RXAlimentação +5 V+5\,\text{V} e porta serial hardware conectada a D1 (TX) e D0 (RX) para módulos GPS, Bluetooth ou conversores seriais.
LED PWRIndicador de EnergiaPermanece aceso continuamente enquanto a malha regulada de +5,0 VDC+5{,}0\,\text{VDC} estiver presente no shield.
LED TXIndicador de TransmissãoPisca em sincronismo com quadros CAN enviados pelo controlador MCP2515 ao barramento físico.
LED RXIndicador de RecepçãoPisca sempre que quadros válidos são recebidos nos buffers de recepção do controlador.
LED INTIndicador de InterrupçãoAcende quando a linha INT‾\overline{\text{INT}} (D2) é levada a nível LOW aguardando leitura via SPI pelo microcontrolador.

Como fazer a ligação

Requisitos de instalação e alimentação

  1. Encaixe empilhado direto (Arduino Uno R3) vs. compatibilidade com Arduino Mega 2560:
    • No Arduino Uno R3, basta alinhar cuidadosamente todas as fileiras de pinos machos inferiores do shield (incluindo o conector traseiro ICSP de 2×32 \times 3 pinos, se presente na revisão) sobre os soquetes fêmea do Arduino e pressionar verticalmente até o assentamento completo. Verifique se a carcaça metálica inferior do conector SUB-D DB9 mantém folga segura em relação ao conector USB tipo B metálico do Arduino Uno (cole uma tira de fita isolante ou Kapton sobre o conector USB do Uno para impedir qualquer curto mecânico com a carcaça).
    • No Arduino Mega 2560, lembre-se de que o barramento SPI em hardware reside nos pinos D50 (MISO), D51 (MOSI), D52 (SCK) e D53 (SS) — ou no conector central ICSP de 6 pinos. Se a sua revisão do shield rotear o SPI pelos pinos laterais D11–D13 sem conectar ao soquete ICSP inferior, interligue com jumpers D11 →\to D51, D12 →\to D50 e D13 →\to D52 (mantendo CS em D10 e INT em D2).
  2. Alimentação estabilizada de 5,0 VDC5{,}0\,\text{VDC} e integração com ESP32 (3,3 V3{,}3\,\text{V}):
    • O transceptor físico de alta velocidade exige alimentação estrita entre 4,75 VDC4{,}75\,\text{VDC} e 5,25 VDC5{,}25\,\text{VDC} no pino 5V, drenando cerca de 30 mA30\,\text{mA} médios (e picos de até 75 mA75\,\text{mA}).
    • Caso deseje operar o shield desacoplado via cabos jumpers junto a um ESP32 (cujos GPIOs operam a 3,3 V3{,}3\,\text{V} e não toleram 5,0 V5{,}0\,\text{V}), alimente o pino 5V do shield com +5,0 VDC+5{,}0\,\text{VDC} (pino VIN / 5V USB) e utilize obrigatoriamente um conversor de nível lógico bidirecional de 4 ou 8 canais (3,3 V↔5,0 V3{,}3\,\text{V} \leftrightarrow 5{,}0\,\text{V}) nas linhas CS (D10), MOSI (D11), MISO (D12), SCK (D13) e INT (D2).
  3. Cabeamento diferencial em par trançado e verificação de continuidade DB9:
    • Para redes industriais conectadas ao borne de parafuso (CAN_H / CAN_L), utilize exclusivamente cabo de par trançado de impedância característica Z0=120 ΩZ_0 = 120\,\Omega (bitola 24 AWG24\,\text{AWG} a 20 AWG20\,\text{AWG}).
    • Ao utilizar um cabo comercial pronto DB9 ↔\leftrightarrow OBD-II, meça sempre com o multímetro em teste de continuidade antes de plugar no veículo se o Pino 6 do OBD-II chega ao Pino 3 do DB9 (CAN_H) e se o Pino 14 do OBD-II chega ao Pino 5 do DB9 (CAN_L), pois existem cabos seriais RS-232 ou cabos padrão CiA no mercado com pinagem diferente. Se preferir evitar qualquer dúvida de pinagem DB9, ligue os fios vindos dos pinos 6 e 14 do conector OBD-II diretamente aos bornes de parafuso CAN_H e CAN_L do shield.

Diagrama de ligação elétrica

A figura abaixo apresenta o diagrama de ligação elétrica em blocos do Módulo CAN BUS Shield MCP2515 para Arduino, evidenciando o acoplamento direto sobre a placa base Arduino Uno R3 (5 V5\,\text{V}), a conexão automotiva via porta OBD-II (SAE J1962), a ligação industrial em par trançado pelo borne dedicado com terminação de 120 Ω120\,\Omega e o uso dos conectores auxiliares I2C / UART:

Diagrama de ligação elétrica do Módulo CAN BUS Shield MCP2515 para Arduino

Conforme ilustrado, toda a comunicação lógica entre o microcontrolador e o controlador MCP2515 trafega internamente pelas barras empilháveis (5V, GND, D10, D11, D12, D13 e D2), deixando os terminais externos do shield livres para o acoplamento simultâneo do barramento diferencial CAN (seja via tomada DB9 automotiva ou via borne de parafuso industrial) e de periféricos de visualização local na porta I2C.

Tabela de conexões dos terminais

O mapeamento completo ponto a ponto (De →\to Para) sincronizado com o diagrama de ligação elétrica para operação com Arduino Uno R3, rede OBD-II / CAN Industrial e periféricos auxiliares encontra-se na tabela abaixo:

Terminal de Origem (Placa Base / Rede / Periférico)Terminal de Destino (CAN BUS Shield RB0641)Cor Sugerida / MeioTipo de SinalObservação Técnica
Pinos +5V e GND (Arduino Uno R3)Pinos 5V e GND (Barra Power do Shield)Encaixe Direto (Vermelho/Preto)Alimentação DC (+5,0 V+5{,}0\,\text{V})Alimenta MCP2515, transceptor CAN e barramentos auxiliares
Pino D10 / SS (Arduino Uno R3)Pino D10 (CS) do ShieldEncaixe DiretoSeleção SPI (CS‾\overline{\text{CS}})Em revisões alternativas com jumper em D9, ajustar pino CS no software
Pinos D11 / D12 / D13 (Arduino Uno R3)Pinos D11 (MOSI) / D12 (MISO) / D13 (SCK)Encaixe DiretoBarramento SPI (10 MHz10\,\text{MHz})No Arduino Mega 2560, garantir conexão ao ICSP ou pinos D51/D50/D52
Pino D2 / INT0 (Arduino Uno R3)Pino D2 (INT) do ShieldEncaixe DiretoInterrupção Ativa BaixaSinaliza quadros recebidos por borda de descida (FALLING)
Pino 6 OBD-II (SAE J1962)DB9 Pino 3 (ou Borne CAN_H)Amarelo / Branco (Par Trançado)Sinal Diferencial CAN_HRede veicular de alta velocidade ISO 15765-4 (500 kbps500\,\text{kbps})
Pino 14 OBD-II (SAE J1962)DB9 Pino 5 (ou Borne CAN_L)Verde / Azul (Par Trançado)Sinal Diferencial CAN_LRede veicular de alta velocidade ISO 15765-4 (500 kbps500\,\text{kbps})
Pino 5 OBD-II (Signal Ground)DB9 Pino 2 (ou Pino GND)PretoTerra de Sinal ComumEqualiza o potencial de modo comum entre ECU e transceptor
Linha CAN_H / CAN_L IndustrialBornes CAN_H e CAN_L (Parafuso)Par Trançado 120 Ω120\,\OmegaBarramento CAN 2.0BHabilitar resistor de 120 Ω120\,\Omega apenas nos 2 extremos físicos da linha
Display OLED / Periférico I2CConector I2C (+5V, GND, SCL/A5, SDA/A4)Chicote 4 ViasAlimentação + I2CI^2CVerificar se o display I2C suporta +5,0 V+5{,}0\,\text{V} nos pinos VCC/SDA/SCL
Módulo GPS / Serial AuxiliarConector UART (+5V, GND, TX/D1, RX/D0)Chicote 4 ViasAlimentação + UART TTLDesconectar D0/D1 durante gravação de código via cabo USB no Uno

Caso deseje ligar o shield por cabos jumpers a um ESP32 (3,3 V3{,}3\,\text{V}) através de um Conversor de Nível Lógico Bidirecional (3,3 V3{,}3\,\text{V} LV ↔\leftrightarrow 5,0 V5{,}0\,\text{V} HV), siga esta correspondência no barramento VSPI:

Pino no ESP32 (Lado LV 3,3 V3{,}3\,\text{V})Pino no CAN BUS Shield (Lado HV 5,0 V5{,}0\,\text{V})Função Técnica
Pino 5V / VIN (USB) + GNDPinos 5V (Alimentação HV) e GNDAlimentação +5,0 VDC+5{,}0\,\text{VDC} obrigatória para o transceptor CAN
GPIO 5 (VSPI SS) ↔\leftrightarrow LV1/HV1Pino D10 (CS)Seleção do controlador MCP2515
GPIO 23 (VSPI MOSI) ↔\leftrightarrow LV2/HV2Pino D11 (MOSI / SI)Transmissão SPI Mestre →\to Shield
GPIO 19 (VSPI MISO) ↔\leftrightarrow LV3/HV3Pino D12 (MISO / SO)Recepção SPI protegida contra os 5,0 V5{,}0\,\text{V} de saída do MCP2515
GPIO 18 (VSPI SCK) ↔\leftrightarrow LV4/HV4Pino D13 (SCK)Clock síncrono SPI
GPIO 4 (IRQ) ↔\leftrightarrow LV5/HV5Pino D2 (INT)Interrupção externa protegida em 3,3 V3{,}3\,\text{V}

Cuidados e observações de segurança

⛔ Perigo: Nunca realize testes de injeção aleatória de pacotes CAN (fuzzing) ou escrita em identificadores proprietários na porta OBD-II com o veículo em movimento! Os barramentos CAN de automóveis interligam módulos críticos de segurança ativa, incluindo direção elétrica (EPS), controle de estabilidade e freios (ABS/ESC), câmbio automático e gerenciamento de torque da ECU. Transmitir quadros com IDs conflitantes ou na taxa de bits incorreta gera contadores de erro (Error Frames / Bus-Off) capazes de acionar modos de falha de emergência no painel. Em veículos, inicie sempre em modo passivo (Listen-Only) e efetue requisições padronizadas OBD-II (0x7DF) apenas com o veículo estacionado e freio de estacionamento acionado.

⚠️ Atenção: Isole eletricamente o topo da carcaça metálica do conector USB-B do Arduino Uno R3 antes de empilhar o shield e jamais aplique +12 V+12\,\text{V} do pino 16 do OBD-II diretamente no pino 5V! Nos modelos Arduino Uno com conector USB tipo B grande (quadrado metálico), os terminais soldados sob o conector DB9 do shield ficam muito próximos do topo metálico do USB; aplique uma camada de fita isolante sobre a blindagem do USB do Uno. Além disso, se alimentar o conjunto pela tomada OBD-II do carro (12 V12\,\text{V} a 14,4 V14{,}4\,\text{V} com alternador ativo), conecte essa linha exclusivamente através de um regulador automotivo protegido ou entrada VIN com proteção contra picos (load dump), nunca na malha lógica de 5 V5\,\text{V}.

💡 Dica: Antes de ligar a alimentação, meça com um multímetro na escala de resistência (Ω\Omega) entre os parafusos CAN_H e CAN_L do barramento desenergizado. Uma rede CAN física íntegra exige dois resistores de 120 Ω120\,\Omega nas duas extremidades opostas do cabo, resultando em 60 Ω60\,\Omega (±5 Ω\pm 5\,\Omega) equivalentes. Ao conectar o shield na tomada OBD-II de um automóvel, mantenha a terminação interna de 120 Ω120\,\Omega do shield desativada/aberta, pois o chicote original do carro já possui 60 Ω60\,\Omega internos; já em uma bancada ligando dois shields entre si, habilite os 120 Ω120\,\Omega em ambas as placas.

Como usar

Guia de operação passo a passo

  1. Inspecione o cristal oscilador e o pino CS na placa antes de compilar: Localize o componente oval prateado ao lado do CI MCP2515. Em shields completos de formato Uno (como o RB0641), o cristal padrão é de 16,000 MHz16{,}000\,\text{MHz} (MCP_16MHZ), diferentemente dos mini-módulos azuis compactos que costumam usar 8,000 MHz8{,}000\,\text{MHz} (MCP_8MHZ). Verifique também se a trilha/jumper CS está no padrão D10 (o firmware da próxima seção detecta automaticamente D10 e D9, facilitando a partida imediata).
  2. Acompanhe o comportamento dos 4 LEDs de diagnóstico ao energizar: Conecte o Arduino empilhado com o shield ao computador via USB. O LED PWR deve acender imediatamente com brilho firme. Os LEDs TX, RX e INT devem permanecer apagados ou estabilizar logo após a inicialização do setup().
  3. Instale a biblioteca oficial na Arduino IDE: Acesse Sketch →\to Include Library →\to Manage Libraries..., procure por MCP_CAN_lib (desenvolvida por Cory J. Fowler) e instale a versão mais atual. Alternativamente, a biblioteca autowp-mcp2515 também é integralmente compatível.
  4. Execute primeiro o Autoteste Interno (Loopback) pelo Monitor Serial: Sem precisar conectar nenhum veículo ou segundo módulo CAN, abra o Monitor Serial em 115200 bps115200\,\text{bps} e envie a letra L. O controlador MCP2515 transmitirá e receberá internamente um quadro de teste validando toda a comunicação SPI, o cristal de 16 MHz16\,\text{MHz} e a interrupção no pino D2.
  5. Conecte ao barramento físico em modo Listen-Only (S) ou Scanner OBD-II (O): Ligue o cabo DB9-OBD-II (ou os bornes CAN_H e CAN_L) ao veículo com a ignição ligada na posição de acessórios/motor em marcha lenta (500 kbps500\,\text{kbps} para veículos leves modernos ISO 15765-4). Observe o LED RX piscando conforme os pacotes chegam e acione O para decodificar grandezas reais da ECU.

Modos de operação e ajustes

Equacionamento diferencial ISO 11898-2, impedância de barramento e Bit Timing em 16 MHz

O transceptor do shield codifica os bits sobre o par trançado pela tensão diferencial (VdiffV_{\text{diff}}) medida entre as linhas CAN_H e CAN_L:

Vdiff=VCANH−VCANLV_{\text{diff}} = V_{\text{CANH}} - V_{\text{CANL}}

Em estado recessivo (bit lógico 1), os estágios de saída permanecem em alta impedância polarizados a ≈2,5 V\approx 2{,}5\,\text{V}, resultando em Vdiff≈0 VV_{\text{diff}} \approx 0\,\text{V} (<0,5 V< 0{,}5\,\text{V}). Em estado dominante (bit lógico 0), o transceptor eleva CAN_H para ≈3,5 V\approx 3{,}5\,\text{V} e reduz CAN_L para ≈1,5 V\approx 1{,}5\,\text{V}, impondo Vdiff≈2,0 VV_{\text{diff}} \approx 2{,}0\,\text{V} (≥0,9 V\ge 0{,}9\,\text{V}) sobre a carga equivalente formada pelos dois resistores terminadores de fim de linha (RT1=RT2=120 ΩR_{T1} = R_{T2} = 120\,\Omega):

Rbus=RT1⋅RT2RT1+RT2=120 Ω×120 Ω120 Ω+120 Ω=60 ΩR_{\text{bus}} = \frac{R_{T1} \cdot R_{T2}}{R_{T1} + R_{T2}} = \frac{120\,\Omega \times 120\,\Omega}{120\,\Omega + 120\,\Omega} = 60\,\Omega

No gerador de baud rate interno do MCP2515 (registradores CNF1, CNF2 e CNF3), cada período de bit é construído por múltiplos inteiros da unidade fundamental de tempo Time Quantum (TQT_Q), derivada da frequência do cristal oscilador (fOSCf_{\text{OSC}}) e do Baud Rate Prescaler (BRP∈[0..63]\text{BRP} \in [0..63]):

TQ=2⋅(BRP+1)fOSCT_Q = \frac{2 \cdot (\text{BRP} + 1)}{f_{\text{OSC}}}

Somando os quatro segmentos que compõem um bit CAN — sincronismo fixo (1 TQ1\,T_Q), propagação (tPropSegt_{\text{PropSeg}}), segmento de fase 1 (tPS1t_{\text{PS1}}, onde ocorre a amostragem do nível lógico) e segmento de fase 2 (tPS2t_{\text{PS2}}) — obtém-se a taxa exata de transferência no barramento (fBITf_{\text{BIT}}):

fBIT=fOSC2⋅(BRP+1)⋅(1+tPropSeg+tPS1+tPS2)f_{\text{BIT}} = \frac{f_{\text{OSC}}}{2 \cdot (\text{BRP} + 1) \cdot \left(1 + t_{\text{PropSeg}} + t_{\text{PS1}} + t_{\text{PS2}}\right)}

Considerando o cristal padrão do shield de fOSC=16 MHzf_{\text{OSC}} = 16\,\text{MHz} (16.000), ao configurar BRP=0\text{BRP} = 0 e NTQ=16 TQN_{\text{TQ}} = 16\,T_Q por bit (ex.: 1+5+6+4=16 TQ1 + 5 + 6 + 4 = 16\,T_Q, posicionando o ponto de amostragem em 75%75\% do bit conforme recomendação automotiva SAE/CIA), atinge-se com resolução temporal superior a velocidade padrão OBD-II de 500 kbps500\,\text{kbps}:

fBIT=16×106 Hz2⋅(0+1)⋅16=500.000 bps=500 kbpsf_{\text{BIT}} = \frac{16 \times 10^6\,\text{Hz}}{2 \cdot (0 + 1) \cdot 16} = 500.000\,\text{bps} = 500\,\text{kbps}

⚠️ Atenção: Se o seu lote específico do shield possuir um cristal gravado com 8.000 (8 MHz8\,\text{MHz}) e o código estiver configurado para MCP_16MHZ, a equação acima dividirá a frequência real pela metade (250 kbps250\,\text{kbps} em vez de 500 kbps500\,\text{kbps}), gerando erros imediatos de barramento ao conectar no carro! Sempre confira a inscrição numérica gravada na cápsula metálica do cristal.

Modos de operação do controlador MCP2515 e regras de terminação física

Modo Interno (MCP2515)Constante MCP_CAN_libEfeito nos Pinos CAN_H / CAN_L e LEDsUso Recomendado
Normal (Active)MCP_NORMALTransmite pacotes, confirma recepção enviando bit dominante ACK e aciona LEDs TX / RXRede CAN industrial ativa e scanner OBD-II com requisição de PIDs
Somente Escuta (Listen-Only)MCP_LISTENONLYDesabilita TXCAN; escuta 100% do tráfego silenciosamente sem enviar ACK nem quadros de erroSniffer seguro para engenharia reversa automotiva
Autoteste (Loopback)MCP_LOOPBACKDesconecta do barramento externo e realimenta TXB →\to RXB dentro do próprio chipTeste isolado de bancada (valida SPI, CS, cristal e INT)
Hibernação (Sleep)MCP_SLEEPParalisa o oscilador interno para economia de corrente até detecção de atividade CAN ou comando SPIDispositivos embarcados alimentados continuamente em veículos estacionados
Topologia de InstalaçãoConexão Física UsadaTerminação de 120 Ω120\,\Omega no Shield
Bancada ponto a ponto (2 Shields / Módulos CAN)Par trançado entre bornes CAN_H e CAN_LATIVADA (Fechada) nas duas placas (60 Ω60\,\Omega totais)
Rede industrial linear (33 ou mais nós)Cabo tronco entrando e saindo pelos bornesATIVADA apenas nos 2 nós extremos; DESATIVADA nos nós intermediários
Porta de diagnóstico veicular OBD-IICabo DB9 ↔\leftrightarrow OBD-II (pinos 6 e 14)DESATIVADA (Aberta) — o veículo já contém os dois resistores de 120 Ω120\,\Omega

Exemplos práticos de uso

Console de Diagnóstico Completo: Autodetecção CS (D10/D9), Loopback, Sniffer e Scanner OBD-II (Arduino e ESP32)

O código-fonte C++ completo abaixo compila diretamente na Arduino IDE ou PlatformIO para Arduino Uno R3, Arduino Mega 2560 e ESP32 (com conversor de nível lógico). O firmware realiza a autodetecção automática do pino CS (D10 ou D9) em placas Arduino, libera a porta UART ao desligar o cabo USB ou permite expansão futura no barramento I2C (A4/A5), e disponibiliza no Monitor Serial (115200 bps115200\,\text{bps}) quatro modos operacionais em tempo real, incluindo decodificação matemática de RPM (0x0C), Velocidade (0x0D), Temperatura do Motor (0x05) e Posição da Borboleta/Acelerador (0x11):

/**
 * ============================================================================
 * Projeto: Console Tecnico CAN 2.0B (Loopback / Sniffer) e Scanner OBD-II
 * Hardware: Modulo CAN BUS Shield MCP2515 para Arduino (SKU: RB0641)
 * Biblioteca Requerida: "MCP_CAN_lib" por Cory J. Fowler (Arduino Library Manager)
 * Plataformas: Arduino Uno R3 / Mega 2560 (5V nativo) e ESP32 (com Level Shifter)
 * Nota de Clock: Ajuste CRISTAL_SHIELD conforme gravacao no cristal (16MHz padrao)
 * ============================================================================
 */

#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>
#include <mcp_can.h>

// Mapeamento de pinos conforme a arquitetura selecionada na IDE
#if defined(ESP32)
  const uint8_t PIN_CS_PRIMARIO   = 5;   // GPIO 5 (VSPI SS via Level Shifter)
  const uint8_t PIN_CS_ALTERNATIVO = 5;
  const uint8_t PIN_CAN_INT       = 4;   // GPIO 4 (IRQ via Level Shifter)
#else
  const uint8_t PIN_CS_PRIMARIO   = 10;  // Padrao CAN BUS Shield V1.2 (D10)
  const uint8_t PIN_CS_ALTERNATIVO = 9;  // Alternativa revisoes Seeed (D9)
  const uint8_t PIN_CAN_INT       = 2;   // Interrupcao externa INT0 (D2)
#endif

// Confira o topo metalico do cristal na placa: MCP_16MHZ (16.000) ou MCP_8MHZ (8.000)
#define CRISTAL_SHIELD     MCP_16MHZ
#define VELOCIDADE_CAN     CAN_500KBPS

// Identificadores funcionais OBD-II (ISO 15765-4 CAN 11 bits)
const uint32_t OBD2_ID_BROADCAST    = 0x7DF; // Requisicao funcional para ECUs
const uint32_t OBD2_ID_ECU_MIN      = 0x7E8; // Resposta ECU Motor (ECM)
const uint32_t OBD2_ID_ECU_MAX      = 0x7EF;

// PIDs padronizados SAE J1979 - Servico 0x01 (Dados Atuais)
const uint8_t PID_TEMP_MOTOR        = 0x05; // A - 40 (°C)
const uint8_t PID_RPM_MOTOR         = 0x0C; // ((256 * A) + B) / 4 (RPM)
const uint8_t PID_VELOCIDADE_VEIC   = 0x0D; // A (km/h)
const uint8_t PID_POSICAO_BORBOLETA = 0x11; // (100 * A) / 255 (%)

// Ponteiro dinamico para permitir autodetecao entre D10 e D9 no setup()
MCP_CAN *canBus = nullptr;
uint8_t pinoCsAtivo = PIN_CS_PRIMARIO;

bool scannerObdAtivo = false;
uint32_t instanteUltimaReqMs = 0;
uint8_t indicePid = 0;

/**
 * Transmite um quadro de requisicao OBD-II (Single Frame ISO-TP de 8 bytes)
 */
bool enviarRequisicaoPidObd2(uint8_t pid) {
  if (canBus == nullptr) return false;
  byte req[8] = {0x02, 0x01, pid, 0x55, 0x55, 0x55, 0x55, 0x55};
  return (canBus->sendMsgBuf(OBD2_ID_BROADCAST, 0, 8, req) == CAN_OK);
}

/**
 * Decodifica respostas positivas do Servico 0x01 (Byte 1 == 0x41) vindas da ECU
 */
void interpretarPacoteObd2(uint32_t canId, uint8_t dlc, const uint8_t *dados) {
  if (dlc < 4 || dados[1] != 0x41) {
    return;
  }

  uint8_t pid = dados[2];
  uint8_t A   = dados[3];
  uint8_t B   = (dlc >= 5) ? dados[4] : 0;

  Serial.print(F("  -> [ECU 0x"));
  Serial.print(canId, HEX);
  Serial.print(F("] "));

  switch (pid) {
    case PID_TEMP_MOTOR: {
      int16_t tempC = (int16_t)A - 40;
      Serial.print(F("Temp. Arrefecimento: "));
      Serial.print(tempC);
      Serial.println(F(" °C"));
      break;
    }
    case PID_RPM_MOTOR: {
      float rpm = ((256.0f * (float)A) + (float)B) / 4.0f;
      Serial.print(F("Rotacao do Motor: "));
      Serial.print(rpm, 0);
      Serial.println(F(" RPM"));
      break;
    }
    case PID_VELOCIDADE_VEIC: {
      Serial.print(F("Velocidade: "));
      Serial.print(A);
      Serial.println(F(" km/h"));
      break;
    }
    case PID_POSICAO_BORBOLETA: {
      float tps = (100.0f * (float)A) / 255.0f;
      Serial.print(F("Posicao Acelerador (TPS): "));
      Serial.print(tps, 1);
      Serial.println(F(" %"));
      break;
    }
    default:
      Serial.print(F("PID 0x"));
      Serial.print(pid, HEX);
      Serial.print(F(" Bruto A=0x"));
      Serial.println(A, HEX);
      break;
  }
}

/**
 * Esvazia os buffers RXB0 e RXB1 do MCP2515 enquanto o pino INT estiver em LOW
 */
void lerMensagensRecebidas() {
  if (canBus == nullptr) return;

  while (digitalRead(PIN_CAN_INT) == LOW) {
    long unsigned int rxId = 0;
    unsigned char dlc = 0;
    unsigned char rxBuf[8];

    if (canBus->readMsgBuf(&rxId, &dlc, rxBuf) == CAN_OK) {
      bool estendido = ((rxId & 0x80000000UL) != 0);
      bool remoto    = ((rxId & 0x40000000UL) != 0);
      uint32_t idReal = estendido ? (rxId & 0x1FFFFFFFUL) : (rxId & 0x7FFUL);

      Serial.print(estendido ? F("[RX 29b] ID: 0x") : F("[RX 11b] ID: 0x"));
      Serial.print(idReal, HEX);
      Serial.print(F(" | DLC: "));
      Serial.print(dlc);
      Serial.print(F(" | Payload:"));

      if (remoto) {
        Serial.println(F(" [RTR - REMOTE REQUEST]"));
      } else {
        for (uint8_t i = 0; i < dlc; i++) {
          Serial.print(rxBuf[i] < 0x10 ? F(" 0") : F(" "));
          Serial.print(rxBuf[i], HEX);
        }
        Serial.println();

        if (!estendido && idReal >= OBD2_ID_ECU_MIN && idReal <= OBD2_ID_ECU_MAX) {
          interpretarPacoteObd2(idReal, dlc, rxBuf);
        }
      }
    } else {
      break;
    }
  }
}

/**
 * Executa autoteste interno em modo Loopback (sem depender de rede externa)
 */
void testarLoopbackInterno() {
  scannerObdAtivo = false;
  Serial.println(F("\n[AUTOTESTE] Ativando modo LOOPBACK interno no MCP2515..."));
  canBus->setMode(MCP_LOOPBACK);
  delay(20);

  // Quadro de assinatura SKU RB0641
  byte quadroTeste[8] = {0x52, 0x42, 0x06, 0x41, 0xCA, 0xFE, 0x16, 0x00};
  byte res = canBus->sendMsgBuf(0x321, 0, 8, quadroTeste);

  if (res == CAN_OK) {
    Serial.println(F("[OK] Quadro ID 0x321 transmitido internamente. Lendo buffer RX..."));
    delay(20);
    lerMensagensRecebidas();
    Serial.println(F("[APROVADO] Barramento SPI, pino CS, cristal e pino INT (D2) operacionais!"));
  } else {
    Serial.print(F("[ERRO] Falha no envio em Loopback. Codigo retorno: "));
    Serial.println(res);
  }
}

void exibirMenuConsole() {
  Serial.println(F("\n======================================================================"));
  Serial.println(F("  CAN BUS SHIELD MCP2515 ARDUINO (SKU: RB0641) - CONSOLE DE BANCADA"));
  Serial.print(F("  Pino CS ativo: D"));
  Serial.print(pinoCsAtivo);
  Serial.println(F(" | Interrupcao: D2 | Barramento I2C (A4/A5) pronto"));
  Serial.println(F("  [L] Autoteste em LOOPBACK (testa o Shield isolado sem cabo CAN)"));
  Serial.println(F("  [S] Modo SNIFFER Passivo (Listen-Only 500 kbps - seguro em carros)"));
  Serial.println(F("  [N] Modo NORMAL Ativo (500 kbps - transmite pacote teste ID 0x150)"));
  Serial.println(F("  [O] Ativar/Pausar Scanner OBD-II (RPM, Km/h, Temp, Borboleta TPS)"));
  Serial.println(F("======================================================================"));
}

void setup() {
  Serial.begin(115200);
  delay(400);

  // Inicializa barramento I2C (conector de 4 pinos do Shield pronto para display OLED)
  Wire.begin();
  pinMode(PIN_CAN_INT, INPUT_PULLUP);

  // No Arduino Uno/Mega, garante que D10 (SS hardware) seja saida para o mestre SPI
#if !defined(ESP32)
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
#endif

  Serial.println(F("Inicializando Modulo CAN BUS Shield MCP2515 (RB0641)..."));

  // Tenta inicializar no pino CS primario (D10)
  canBus = new MCP_CAN(PIN_CS_PRIMARIO);
  if (canBus->begin(MCP_ANY, VELOCIDADE_CAN, CRISTAL_SHIELD) == CAN_OK) {
    pinoCsAtivo = PIN_CS_PRIMARIO;
  }
  else if (PIN_CS_ALTERNATIVO != PIN_CS_PRIMARIO) {
    // Fallback automatico para D9 caso o jumper CS da placa esteja na posicao D9
    delete canBus;
    canBus = new MCP_CAN(PIN_CS_ALTERNATIVO);
    if (canBus->begin(MCP_ANY, VELOCIDADE_CAN, CRISTAL_SHIELD) == CAN_OK) {
      pinoCsAtivo = PIN_CS_ALTERNATIVO;
    } else {
      Serial.println(F("[FALHA CRITICA] Controlador MCP2515 nao respondeu em D10 nem em D9!"));
      Serial.println(F(" -> Verifique o encaixe do Shield (inclusive conector ICSP no Mega)."));
      while (true) {
        delay(1000);
      }
    }
  } else {
    Serial.println(F("[FALHA CRITICA] Controlador MCP2515 nao respondeu no barramento SPI!"));
    while (true) {
      delay(1000);
    }
  }

  Serial.println(F("[OK] MCP2515 configurado com sucesso a 500 kbps!"));
  canBus->setMode(MCP_LISTENONLY);
  Serial.println(F("[INFO] Shield iniciado em modo passivo seguro (LISTEN-ONLY)."));
  exibirMenuConsole();
}

void loop() {
  // 1. Verifica recepcao por interrupcao em tempo real (LED RX / INT)
  lerMensagensRecebidas();

  // 2. Comandos interativos pelo Monitor Serial
  if (Serial.available() > 0) {
    char c = toupper(Serial.read());

    if (c == 'L') {
      testarLoopbackInterno();
    }
    else if (c == 'S') {
      scannerObdAtivo = false;
      canBus->setMode(MCP_LISTENONLY);
      Serial.println(F("\n[MODO] Shield em LISTEN-ONLY (escuta passiva de rede 500 kbps)."));
    }
    else if (c == 'N') {
      scannerObdAtivo = false;
      canBus->setMode(MCP_NORMAL);
      delay(10);
      byte dados[4] = {0xAA, 0x55, 0x06, 0x41};
      byte st = canBus->sendMsgBuf(0x150, 0, 4, dados);
      Serial.print(F("\n[MODO NORMAL] Transmissao ID 0x150 -> "));
      Serial.println(st == CAN_OK
        ? F("ACK confirmado no barramento (CAN_OK)!")
        : F("Sem ACK (verifique 2o modulo e resistores de 120 Ohms)."));
    }
    else if (c == 'O') {
      canBus->setMode(MCP_NORMAL);
      scannerObdAtivo = !scannerObdAtivo;
      Serial.println(scannerObdAtivo
        ? F("\n[OBD-II] Leitura ciclica ATIVADA (500 kbps - mantenha terminacao 120R aberta no carro).")
        : F("\n[OBD-II] Leitura ciclica PAUSADA."));
    }
  }

  // 3. Requisicao periodica nao-bloqueante de 4 PIDs OBD-II a cada 250 ms
  if (scannerObdAtivo && (millis() - instanteUltimaReqMs >= 250)) {
    instanteUltimaReqMs = millis();
    const uint8_t tabelaPids[4] = {
      PID_RPM_MOTOR,
      PID_VELOCIDADE_VEIC,
      PID_TEMP_MOTOR,
      PID_POSICAO_BORBOLETA
    };

    enviarRequisicaoPidObd2(tabelaPids[indicePid]);
    indicePid = (indicePid + 1) % 4;
  }
}

Projetos

Para integrar o Módulo CAN BUS Shield MCP2515 a sistemas de telemetria web em tempo real, automação de potência em chão de fábrica ou redes mistas com módulos compactos, consulte os projetos práticos e guias complementares publicados no blog da RoboBuilders:

Conclusão

Neste manual técnico do Módulo CAN BUS Shield MCP2515 para Arduino (RB0641), foram abordados todos os fundamentos de hardware, cabeamento diferencial e desenvolvimento de firmware necessários para operação segura e determinística:

  • Arquitetura e especificações elétricas: Operação compatível com CAN V2.0B / ISO 11898-2 até 1 Mb/s1\,\text{Mb/s}, alimentada em +5,0 VDC+5{,}0\,\text{VDC} (≈30 mA\approx 30\,\text{mA} nominais), aliando o controlador SPI MCP2515 (até 10 MHz10\,\text{MHz}, cristal típico de 16,000 MHz16{,}000\,\text{MHz}) a conectores industriais robustos (SUB-D DB9 e borne de parafuso) no formato empilhável 65×53 mm65 \times 53\,\text{mm}.
  • Pinout completo e recursos de expansão: Identificação precisa dos pinos de controle (D10/D9 para CS, D11–D13/ICSP para SPI e D2 para INT), correspondência entre o conector DB9 e a tomada veicular OBD-II (pinos 3 e 5 no DB9 ↔\leftrightarrow pinos 6 e 14 no OBD-II), além dos 4 LEDs de status (PWR, TX, RX, INT), 2 botões embutidos e portas dedicadas I2C e UART.
  • Instalação segura e casamento de impedância: Isolamento preventivo sobre o conector USB metálico do Arduino Uno, uso de conversor de nível lógico bidirecional em sistemas de 3,3 V3{,}3\,\text{V} (ESP32) e aplicação correta da terminação de 120 Ω120\,\Omega (60 Ω60\,\Omega equivalentes na rede industrial vs. terminação aberta em portas OBD-II).
  • Validação de bancada e diagnóstico veicular: Equacionamento de Time Quanta (TQT_Q) para 16 MHz16\,\text{MHz} e firmware C++ pronto com autodetecção de pino CS, teste interno de Loopback, escuta passiva (Sniffer) e leitura de parâmetros reais da ECU via protocolo OBD-II.

Com a correta configuração da frequência do cristal oscilador e o respeito às normas de terminação e segurança automotiva detalhadas neste documento, o Módulo CAN BUS Shield MCP2515 transforma qualquer placa Arduino em um analisador de protocolos e controlador de rede industrial de alta confiabilidade.

Solução de problemas

Olá! Sou o assistente técnico da RoboBuilders. Descreva seu problema com o Módulo CAN BUS Shield MCP2515 para Arduino: Manual Técnico Completo e eu ajudarei a encontrar a solução.

O assistente usa IA e pode errar. Confirme informações críticas no datasheet oficial do fabricante.