Este tutorial que dei na Embedded Linux Conference tenta responder às perguntas, fornecendo links para uma descrição mais detalhada dos tópicos abordados e usando o exemplo prático de dirigir um drone 4WD, onde um Arduino Mini Pro atua como escravo e controla as 4 rodas independentes . O documento original pode ser encontrado aqui .
Nota: Atualmente, esta resposta está em andamento, pois adapto os destaques do link.
Aplicações típicas do barramento I2C
- Interface com periféricos relativamente lentos. Ex: sensores, atuadores mecânicos.
Controlando periféricos "rápidos", que usam outros canais para troca de dados. Ex: codecs.
Em um PC, o sistema operacional geralmente interage pelo I2C com:
- medidores de temperatura e voltagem da bateria;
- controladores de velocidade do ventilador;
- codecs de áudio.
No caso de vários controladores de barramento, os periféricos são agrupados por velocidade, para que os mais rápidos não sejam penalizados pelos mais lentos.
Uma rápida introdução ao barramento I2C - principais recursos
- Barramento serial.
- Apenas 2 linhas: Relógio Serial e Data Serial (mais terra).
- 4 velocidades: 100kHz, 400kHz, 1MHz, 3.2MHz.
- Normalmente, 1 dispositivo mestre e 1 ou mais escravos.
- As comunicações são sempre iniciadas por um dispositivo mestre.
- Vários mestres podem coexistir no mesmo barramento (multimestre).
- Dreno aberto: o SDA e o SCL precisam de resistores de pull-up.
- “Alongamento do relógio”
- O mestre controla o SCL, mas um escravo pode pressioná-lo (por exemplo, dreno aberto), se precisar ajustar a velocidade.
- O mestre deve verificar esse cenário.
- Um escravo pode ficar preso e congestionar o barramento: necessidade de redefinir linhas do mestre para o escravo.
- Normalmente, o endereçamento de 7 bits, mas também 10 bits, é suportado.
- Protocolo lógico: os níveis reais de tensão não são especificados e dependem de implementações individuais. Ex: 1.8V / 3.3V / 5.0V
URLs de referência:
Exemplo de configuração de barramento
Características do protocolo (simplificado)
- 2 tipos de mensagens: leitura e gravação
- Bit Start / Stop - representado como "[" e "]" no restante da resposta
- Endereço: 7 ou 10 bits
- Bit R / W: R = 1 / W = 0 Usado para discriminar o tipo de mensagem enviada.
- Dados no ônibus: (Endereço << 1 | R / W)
- Registra como manipuladores de informações, dentro do dispositivo selecionado.
Exemplo de tráfego de ônibus
Escravos personalizados
Por que criar um escravo I2C personalizado?
- Sensor / atuador desejado indisponível com interface I2C.
- Endereços menos exclusivos disponíveis do que os escravos necessários.
- Funcionalidade personalizada desejada no escravo:
- Reações semi-autônomas a estímulos.
- Filtragem / pré-processamento de dados de entrada.
- Otimização de energia: o “hub do sensor” personalizado faz a limpeza enquanto o processador principal está ocioso.
- Resposta em tempo real às entradas.
- [sua imaginação aqui]
Como projetar um escravo I2C personalizado?
- Defina os requisitos (veja o slide anterior).
- Escolha microcontrolador ou microprocessador.
- Escolha Agendador ou Sistema operacional (se houver).
- Defina o subprotocolo de comunicação:
- Defina parâmetros e comandos a serem trocados.
- Organize-os em “registros” e escolha um endereço gratuito.
Projeto do mestre I2C
Critérios de design chave:
- Peso / dimensões.
- Potência computacional necessária e latência média.
- Dispositivo semelhante a um PC
- Dispositivo incorporado, normalmente sem cabeça.
- Linguagem de programação preferida: interpretada versus compilada.
- Disponibilidade de ônibus / gpios para dirigir o (s) escravo (s):
- Apenas GPIOs: bitbang o protocolo
- I2C: aplicativo de espaço do usuário x driver do kernel.
- Não há interfaces GPIOs / I2C disponíveis: adaptador USB para I2C.
Depuração: Divida e Conquiste
Assuma o controle direto do barramento com um dispositivo ad-hoc. Exemplos:
BUS Pirate
- Principalmente para fins de desenvolvimento.
- Os dois podem cheirar o ônibus e dirigi-lo.
- Porta da interface do console pela porta serial (ttyACM), incluindo macros ou acesso programático a várias linguagens de programação.
- Resistores de pull-up e fontes de tensão incorporados (5V / 3.3V)
- Suporta muitos outros protocolos.
- Referências: Wikipedia , página principal
Adaptador USB para I2C
- Pequena pegada.
- Adequado para instalações permanentes.
- Não há necessidade de conexões especiais no host: ele pode ser usado para interagir com um PC típico.
- Variante disponível que também é compatível com SPI.
- Sem interface de console, apenas protocolo binário serial.
- Requer wrapper de protocolo .
- Referência: protocol
sigrok e pulseview
Logomarca do sigrok (componente bakend)
exemplo pulseview (visualizador)
Exemplo de analisador lógico low-end
- Padrão de fato para medições controladas por PC no Linux (mas também disponível em outros sistemas operacionais).
- Suporte para uma vasta gama de analisadores lógicos, escopos e medidores.
- Vários decodificadores de protocolo, incluindo I2C.
- Útil para visualizar os sinais lógicos e erros de protocolo de depuração.
- Mesmo na extremidade mais baixa, o HW barato pode fornecer uma nova dimensão à depuração.
- Referências: sigrok , pulseview , hardware suportado
Exemplo: dirigir um drone 4WD
Protótipo construído usando 2 Arduino Mini Pro.
O que o escravo faz no exemplo?
O escravo I2C:
- Controla a quantidade de torque aplicado a cada roda.
- Controla a direção em que cada roda gira.
- Mede a velocidade de rotação de cada roda através de um codificador óptico (odômetro).
- Expõe os parâmetros acima ao mestre I2C.
Diagrama de blocos de alto nível do escravo I2C.
- Pinos / funções suficientes para fornecer a cada roda:
- 1 saída PWM com configuração independente do ciclo de trabalho.
- 1 GPIO para registrar a entrada do odômetro como IRQ.
- 2 GPIOs para selecionar:
- frente
- Marcha ré
- Ocioso
- Bloquear
- Bloco I2C HW para trocas i2c acionadas por interrupção.
- Pinos dedicados para programação baseada em SPI.
- Pequena pegada.
- Baixo custo.
- O layout da placa do clone representado na imagem é otimizado para montagem em um soquete DIL.
CID específico do escravo: AVR Dragon
Selecionando o SO: ChibiOS
- RTOS: preempção, tarefas, semáforos, sistema dinâmico de tiques, etc.
- Tamanho reduzido: vincule apenas código / dados usados.
- Distinção entre RTOS e BSP através do HAL.
- GPLv3 para uso não comercial.
- Ativamente desenvolvido, mas já maduro.
- Suporta AVR de 8 bits.
No entanto, havia suporte BSP limitado ao AVR, falta de: - interrompe o driver dos GPIOs do AVR (adicionado). - Suporte I2C para o modo escravo AVR (personalizado). O qual teve que ser desenvolvido separadamente como parte do Drone SW para o AVR .
Definindo os parâmetros de comunicação
Para cada roda:
Ciclo de trabalho do sinal PWM usado para acioná-lo - 1 byte. 0xFF = torque máximo / 0x00 = sem torque.
Sentido de rotação - 1 byte.
- 0x00 = inativo
- 0x01 = reverso
- 0x02 = encaminhar
- 0x03 = bloqueado
Período médio entre os slots do codificador óptico - 2 bytes.
- Escrever qualquer coisa redefine a medida.
Índice de Parâmetros - 1 mordidela:
- 0 = Ciclo de Trabalho
- 1 = Direção
- 2 = Período médio
Índices das rodas - 1 mordidela:
- 0 = traseira esquerda
- 1 = Traseira Direita
- 2 = Frente Direita
- 3 = Frente Esquerda
- 4 = Todos
Subprotocolo: Definindo os Registros
Formato de registro: 0xαβ
- α = Índice de Parâmetros - β = Índice de Rodas
Endereço (escolhido arbitrariamente): 0x10
Formato Bus Pirate:
- [= bit inicial -] = bit final - r = byte lido - tempos de endereço 2 (shift esquerdo 1), para bit R / W
Exemplo - no formato Bus Pirate
[i2c_addr reg_addr = (parm, roda) reg_value]
[0x20 0x20 0x02] Left Rear Forward
[0x20 0x21 0x01] Right Rear Backward
[0x20 0x22 0x01] Right Front Backward
[0x20 0x23 0x02] Left Front Forward
[0x20 0x14 0xFF] Wheels set to max torque
O carro gira no sentido horário.