ÍNDICE DE CONTEÚDO
Computadores e sistemas embarcados estão cada vez mais populares e presentes em nosso dia a dia. No ambiente acadêmico não é diferente. Com tecnologias compactas e de performance considerável, as opções de escolha para o hardware que fará parte de cada projeto são inúmeras, bastando apenas escolher a que mais se alinha com a aplicação do projeto.
A rede CAN, muito conhecida por sua aplicação na indústria automobilística, é uma rede versátil, usada atualmente nos mais diversos projetos. Sua segurança e confiabilidade são definitivamente fatores que pesam na sua escolha pelos projetistas.
Nesse tutorial em forma de artigo focaremos na BeagleBone Black, mostrando como habilitar os dois controladores CAN nativos da placa, estabelecendo uma rede entre eles e trocando mensagens via terminal. Além disso, será mostrado como utilizar a programação em Python para enviar e receber mensagens na rede.
Como um conteúdo adicional, mostraremos também outra aplicação. Será feita a comunicação entre a Beaglebone Black e um microcontrolador LPC1768 NXP presente no kit Mbed.
O conteúdo desenvolvido aqui faz parte do meu Trabalho de Conclusão de Curso, que tem por objetivo implementar uma rede CAN no projeto de uma versão compacta móvel de um relógio de átomos frios, projeto do Centro de Pesquisa em Óptica e Fotônica – CePOF.
Toda a arquitetura deste projeto foi projetada pelo Rodrigo, e a rede CAN é a rede que fará a comunicação entre os diversos subsistemas do relógio.
Confesso que não sou um expert em redes CAN, e devido ao desafio desse projeto, tanto pela quantidade de informações (muitas vezes desatualizadas) quanto por todos os problemas encontrados, decidi fazer esse tutorial, e assim contribuir um pouco com toda a comunidade Open Source, que me ajudou muito no projeto.
Parto do princípio aqui que o leitor está minimamente familiarizado com a BeagleBone e também com os conceitos de rede CAN, mesmo que nunca tenha implementado uma. Assim, poderei ser mais direto e específico no artigo, evitando o prolongamento do mesmo.
Esclarecimentos feitos, vamos começar.
Setup BeagleBone Black
Neste tutorial, será utilizado os seguintes hardwares:
- BeagleBone Black Rev C
- 2 Transceivers CAN MCP2551 – Datasheet
- Conversor bidirecional de nível lógico (4 canais) – Exemplo nesse link
- Fonte [email protected] – conector P4 (A fonte é opcional, poderá ser utilizada a alimentação USB)
- Protoboard e cabos macho-macho
- 2 resistores 120Ohm
- Cartão SD de no mínimo 4Gb
Sistema operacional
Debian (wheezy) versão 7.9. Pode ser baixada aqui.
Tão importante quanto a distribuição do Linux, é necessário verificar também a versão do Kernel usada. Você poderá verificar através do comando:
1 |
$ uname –r |
Utilizo aqui a versão 3.8.13 (Não foi necessário alterar o Kernel, pois esta imagem do Debian já utiliza essa versão).
Recomendo utilizar o sistema operacional no cartão de memória, evitando assim que caso alguma coisa seja feita erroneamente, basta apenas regravar a imagem no cartão e recomeçar os procedimentos. Posteriormente você pode passar o conteúdo do cartão para a memória flash conforme este tutorial
Configurando os controladores CAN
Apesar da placa possuir 2 controladores CAN, por padrão eles não estão habilitados. Isso porque eles compartilham os mesmos pinos que outras funções da placa, como i2c e GPIO.
É necessário então a criação de overlays, que irão alterar a função dos pinos, possibilitando que sejam usados para a CAN.
O controlador can0 utiliza os pinos P9_19(rx) e P9_20(tx), enquanto o can1 utiliza os pinos P9_24(rx) e P9_26(tx).
Por questão de preferência, usaremos a interface do cloud9 para a conexão com a Beaglebone (digite no navegador 192.168.7.2:3000 , quando conectado ao cabo USB), por ser um pouco mais user-friendly, quando comparada aos terminais do Putty por exemplo. Além disso, no cloud9 posso gerenciar arquivos e terminais mais facilmente quando necessário. É apenas uma questão de preferência e não afetará em nada caso o usuário opte por outra opção.
Os overlays foram retirados do blog Embedded Things. Nesse site é possível encontrar um tutorial (com alguns passos desatualizados e em inglês) sobre CAN e Beaglebone Black. Utilizei ele como ponto de partida na minha busca por informações do assunto.
Os overlays são scripts que são compilados e colocados no diretório de arquivo do sistema. Eles modificam as funções de cada pino, assim, um pino que antes seria uma GPIO passará a ser utilizado para o controlador CAN.
Vamos começar pelo can1, pois seu processo é mais simples.
Configurando o can1
Abra um editor de texto de sua preferência (utilizado aqui o nano) e cole o código abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
/dts-v1/; /plugin/; / { compatible = "ti,beaglebone", "ti,beaglebone-black"; /* identification */ part-number = "dcan1pinmux"; fragment@0 { target = <&am33xx_pinmux>; __overlay__ { dcan1_pins_s0: dcan1_pins_s0 { pinctrl-single,pins = < 0x180 0x12 /* d_can1_tx, SLEWCTRL_FAST | INPUT_PULLUP | MODE2 */ 0x184 0x32 /* d_can1_rx, SLEWCTRL_FAST | RECV_ENABLE | INPUT_PULLUP | MODE2 */ >; }; }; }; fragment@1 { target = <&dcan1>; __overlay__ { #address-cells = <1>; #size-cells = <0>; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dcan1_pins_s0>; }; }; }; |
Salve o arquivo como BB-DCAN1-00A0.dts
Agora vamos compilar o overlay, gerando um arquivo binário, através do comando:
1 |
$ dtc -O dtb -o BB-DCAN1-00A0.dtbo -b 0 -@ BB-DCAN1-00A0.dts |
O arquivo gerado deverá ser copiado para a pasta lib/firmware. Use o comando:
1 |
$ sudo cp BB-DCAN1-00A0.dtbo /lib/firmware |
Feito isso, já temos o necessário para habilitar o controlador can1.
Configurando o controlador can0
O processo é similar ao can1, com a diferença de que haverá um passo adicional.
Novamente, abre-se um editor de texto e copia-se o código abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
/dts-v1/; /plugin/; / { compatible = "ti,beaglebone", "ti,beaglebone-black"; /* identification */ part-number = "dcan0pinmux"; fragment@0 { target = <&am33xx_pinmux>; __overlay__ { dcan0_pins_s0: dcan0_pins_s0 { pinctrl-single,pins = < 0x178 0x12 /* d_can0_tx, SLEWCTRL_FAST | INPUT_PULLUP | MODE2 */ 0x17C 0x32 /* d_can0_rx, SLEWCTRL_FAST | RECV_ENABLE | INPUT_PULLUP | MODE2 */ >; }; }; }; fragment@1 { target = <&dcan0>; __overlay__ { #address-cells = <1>; #size-cells = <0>; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&dcan0_pins_s0>; }; }; }; |
Salve o arquivo como BB-DCAN0-00A0.dts . Depois, compile-o e mova o binário gerado para a pasta /lib/firmware:
1 2 |
$ dtc -O dtb -o BB-DCAN0-00A0.dtbo -b 0 -@ BB-DCAN0-00A0.dts $ sudo cp BB-DCAN0-00A0.dtbo /lib/firmware |
Até aqui, o processo foi semelhante. O que precisamos fazer agora é uma modificação no “default device tree” do kernel, para que ele permita a mudança da função dos pinos.
O problema que surge é o fato de que o can0 utiliza os mesmos pinos do i2c, e esse módulo tem prioridade no carregamento sobre qualquer outro módulo. Então mesmo que feito o overlay, como foi feito acima, ele não será usado pela prioridade do i2c.
Por isso, essa modificação que faremos irá mascarar essa prioridade permitindo assim carregar o can0 ao invés do i2c.
É por isso que a versão do Kernel é importante, pois para cada versão a modificação é feita de uma maneira, utilizando arquivos diferentes. Lembrando: Versão a utilizada aqui é 3.8.13. Isso não significa que só é possível trabalhar com essa versão de Kernel. Apenas significa que o script a seguir é aplicado a ela. Acredito que até haja conteúdo para a versão 4.x, porém não pesquisei a fundo então decidi restringir nosso tutorial a esta versão particular.
É necessário baixar os arquivos fonte (source files) originais dessa versão, para isso, use os comandos a seguir para copia-los do repositório do Derek Molloy:
1 2 |
$ git clone https://github.com/derekmolloy/boneDeviceTree.git $ cd boneDeviceTree/DTSource3.8.13/ |
Vamos abrir o seguinte arquivo, utilizando o comando nano com o parâmetro ‘–c ‘, que permite visualizar o número da linha atual do cursor:
1 |
$ nano -c am335x-bone-common.dtsi |
Vá até a linha 404 e a comente (usando // no começo da linha), salve e saia do arquivo:
1 |
// pinctrl-0 = <&i2c2_pins>; |
Vamos então compilar o binário:
1 |
$ dtc -O dtb -o am335x-boneblack.dtb -b 0 -@ am335x-boneblack.dts |
Moveremos o arquivo criado para a pasta /boot/dtbs/3.8.13-bone79 . Note que no blog do ‘embedded things’ o diretório indicado é diferente. Porém, para a versão do sistema que estamos usando, o caminho é esse indicado no comando acima.
Antes de mover o arquivo, vamos fazer um backup do arquivo que ele irá substituir, salvando ele com a terminação ‘.orig’ somente para referência:
1 |
$ sudo mv /boot/dtbs/3.8.13-bone79/am335x-boneblack.dtb /boot/dtbs/3.8.13-bone79/am335x-boneblack.orig.dtb |
Então, movemos o arquivo que criamos:
1 |
$ sudo mv am335x-boneblack.dtb /boot/dtbs/3.8.13-bone79 |
Pronto, o procedimento para a can0 está feito. Reinicie a BeagleBone para utilizarmos os controladores.
Com os procedimentos acima, temos os dois controladores configurados. Para usá-los precisamos instalar o pacote can-utils, que contém o SocketCAN, uma espécie de pacote de utilidades para podermos interagir com a rede CAN e os controladores mais facilmente.
Instalando o can-utils
Digite os comandos abaixo:
1 2 3 4 5 6 |
$ git clone https://github.com/linux-can/can-utils.git $ cd can-utils $ ./autogen.sh $ ./configure $ sudo make $ sudo make install |
Assim, feita a instalação, podemos habilitar os controladores.
Habilitando os controladores CAN
Essa sequência de comandos deverá ser seguida toda vez que a placa for ligada:
1 2 3 4 5 6 7 8 9 |
$ echo BB-DCAN0 > /sys/devices/bone_capemgr.*/slots $ echo BB-DCAN1 > /sys/devices/bone_capemgr.*/slots $ sudo modprobe can $ sudo modprobe can-dev $ sudo modprobe can-raw $ sudo ip link set can0 up type can bitrate 500000 $ sudo ifconfig can0 up $ sudo ip link set can1 up type can bitrate 500000 $ sudo ifconfig can1 up |
As duas primeiras linhas são os comandos que habilitam os controladores.
A terceira, quarta e quinta carregam o módulo CAN.
A sexta e sétima configura a velocidade do barramento para o controlador can0 e também o ativa, da mesma forma que as duas últimas fazem para o can1.
Como são vários comandos, aconselho a colocá-los em um script simples, e assim evitamos ter que digitar toda vez (Colocarei meu script em meu repositório). Na próxima seção mostrarei como criar e adicionar esse script ao PATH.
Para verificar se a instalação e ativação foi concluída com êxito, digite o comando:
1 |
$ ifconfig |
Seu output deverá ser semelhante ao da imagem abaixo. Esse comando listará seus controladores ativos.
Vale ressaltar que se você optou por usar apenas o controlador can1 (pinos 24 e 26), a sequência de comandos é parecida:
1 2 3 4 5 6 |
$ echo BB-DCAN1 > /sys/devices/bone_capemgr.*/slots $ sudo modprobe can $ sudo modprobe can-dev $ sudo modprobe can-raw $ sudo ip link set can0 up type can bitrate 500000 $ sudo ifconfig can0 up |
Note que mesmo utilizando o controlador can1, ele está agora referenciado como can0 pois a Beaglebone nomeia os controladores conforme a ordem que você os habilita.
Agora que os controladores estão configurados e habilitados, podemos testar na rede física.
Criando um script
Antes do teste da rede física, irei rapidamente mostrar como criar o script e adicioná-lo ao PATH, e dessa forma o usuário apenas precisará digitar o nome do script no terminal que todos aqueles comandos da seção anterior serão carregados.
Crie um arquivo, que será o nosso script (meu arquivo está disponibilizado em meu repositório no Github)
1 |
$ nano can_exec |
Adicione todos os comandos anteriores. Nesse caso, está sendo feito para os dois controladores CAN:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#!/bin/bash # Enable Can0 and Can1 echo "Ligando can........." echo BB-DCAN0 > /sys/devices/bone_capemgr.*/slots echo BB-DCAN1 > /sys/devices/bone_capemgr.*/slots echo "Done" echo "Habilitando Modprobe........." modprobe can modprobe can-dev modprobe can-raw echo "Done" echo "Setando parametros can..........." sudo ip link set can0 up type can bitrate 500000 sudo ifconfig can0 up sudo ip link set can1 up type can bitrate 500000 sudo ifconfig can1 up echo "Done" |
Feito isso, salve o arquivo e saia do editor.
Adicione permissões de execução do script:
1 |
$ chmod 777 can_exec |
Para executá-lo, é necessário estar no diretório em que ele se encontra e digitar
1 |
./can_exec. |
Como queremos que seja possível executá-lo em qualquer diretório, vamos adicioná-lo ao PATH. É necessário alterar o arquivo /etc/profile:
1 |
$ nano /etc/profile |
Nesse arquivo, procure a linha do PATH, que deve ser similar a isso:
1 |
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" |
Então basta adicionar o caminho do diretório em que se encontra seu script. Em meu exemplo, o script se encontra no meu diretório do cloud9 (/var/lib/cloud9), então modificando a linha teremos:
1 |
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/var/lib/cloud9/Bruno/bin" |
Reinicie sua BBB. Feito isso, basta abrir um terminal e digitar o nome do seu script (nesse caso can_exec) que ele executará todos os comandos de uma vez:
1 |
$ can_exec |
Testando a CAN
O primeiro passo é montar todo o circuito, conforme a figura abaixo. Note que não se deve conectar o controlador direto a rede CAN. É necessário o uso de transceivers entre o controlador e a rede.
Considerações importantes:
- Faça isso com a placa desligada (caso algum seja desconectado/conectado com a placa ligada, é necessário desativar e ativar os controladores, através do comando sudo ifconfig can0 down e sudo infconfig can0 up. O mesmo vale para o can1)
- Aqui eu usei um transceiver 5V. Porém, o nível logico da beaglebone é de 3V3. Por isso usamos o conversor de nível lógico. Usamos ele apenas no RX dos transceivers, pois para o TX, a tensão 3V3 dos pinos da BBB é suficiente para ser reconhecido como nível logico alto pelo transceiver.
- Como alternativa a esse transceiver, poderia ser usado um de 3V3 como o SN65HVD233.
- Se você estiver utilizando a fonte externa, use os pinos P9_5 ou P9_6 ao invés do pino P9_7 (confira o pinout abaixo):
Além disso, da forma que os controladores foram configurados, não é possível testar a rede se ela não possuir pelo menos 2 controladores conectados a ela. Quando é verificado a ausência do número mínimo, as mensagens que deveriam ser enviadas ficam armazenadas no buffer. Caso muitas mensagens sejam armazenadas e não enviadas, surgirá um erro de buffer cheio.
Para contornar esse problema e testar os controladores individualmente, podemos adicionar o parâmetro ‘loopback on’ ao setup deles. Com o parâmetro habilitado, pode-se testar normalmente usando os comandos cangen/candump/cansend. Segue exemplo para o can0:
1 2 3 |
$ sudo ifconfig can0 down $ sudo ip link set can0 up type can bitrate 500000 loopback on $ ifconfig can0 up |
Feito o teste, repita os comandos acima para desabilitar o parâmetro, substituindo para ‘loopback off’ na segunda linha.
Por curiosidade, seguem imagens do meu circuito protótipo:
Devido a quantidade de fios no circuito, estamos desenvolvendo paralelamente uma espécie de cape que agrupe os componentes e as conexões, otimizando o espaço. O protótipo dela é mostrado na figura a seguir:
Ainda é necessário fazer algumas correções e otimizações na placa, mas pode-se notar que temos um circuito muito melhor que o da figura anterior.
Com o circuito montado, ligue a placa e espere que ela se inicialize. Depois, habilite os controladores CAN usando o script ou todos os comandos da seção anterior.
Existem basicamente 3 comandos que podemos usar no terminal para interagir com a rede:
candump: Mostra as mensagens recebidas ou enviadas pelo controlador.
cansend: Envia uma única mensagem na rede
cangen: Envia mensagens aleatórias na rede
Para ficar mais fácil a visualização, abra 2 terminais.
No primeiro, vamos digitar:
1 |
$ candump any –x |
Usando essa linha de comando significa que será mostrado as mensagens de todos os controladores. O parâmetro –x dará os detalhes de qual controlador enviou o recebeu a mensagem.
Em outro terminal, digite:
1 |
$ cangen can1 |
Dessa forma, o controlador can1 passará a enviar mensagens na rede.
O resultado deverá ser semelhante a imagem abaixo:
Pode ser feito o mesmo processo para o can0, verificando sua funcionalidade
1 |
$ cangen can0 |
Caso não apareçam as mensagens no terminal do candump, sugiro verificar alguns pontos:
- Cheque as conexões, e os componentes. São muitos fios, com isso existe a chance de alguma ligação estar errada e/ou solta.
- Tive muito problema com transceiver queimando. Troque por outros transceivers e veja se o problema continua. (Troque um por um, intercale-os também).
- Confira os sinais com um osciloscópio. Abaixo segue uma medida feita durante o cangen. Mais importante que medir o valor da tensão, é verificar a presença das oscilações. Elas indicam que algum conteúdo está sendo transmitido.
- Não se esqueça de desligar e ligar os controladores (ou até mesmo reiniciar a BBB) toda vez que conectar e desconectar os fios.
- Deixe o cangen rodando durante alguns minutos para ver se ele apresenta o erro de buffer cheio (isso é um indicativo que a CAN funciona, mas algum componente ou fio está errado)
Sugiro que os leitores explorem esses três comandos, com todos os parâmetros e etc. Para isso use o comando seguido de ‘ –help’ ou até mesmo utilize o comando sem parâmetro algum, assim o sistema indicará um erro, mas também dará exemplos de uso, e listará os parâmetros possíveis.
Com os controladores funcionando na forma mais crua, vamos então implementar a rede programando em python.
Instalando a python-can
A instalação do python-can, biblioteca do Python que permite a programação e interação com os drivers CAN, é bem simples. Basta fazer seu download e instalação através do comando:
1 |
$ pip install python-can |
Feito a instalação, podemos checar se funciona abrindo a interface do python no terminal, e digitando no terminal os comandos a seguir:
1 2 |
$ python #abre a interface python no terminal $ import can |
ou
1 |
$ help(can) |
Como a programação nessa interface python é dinâmica, ou seja, ela é processada na medida que o usuário escreve as linhas, se a biblioteca não estiver instalada corretamente, o sistema fornece um erro ao digitar os dois últimos comandos acima.
Exemplos em Python utilizando CAN
Feita a instalação da biblioteca, mostrarei 2 programas simples, mas que utilizam dos dois recursos principais da rede CAN, enviar e receber mensagens.
Também disponibilizarei os programas em meu repositório no github.
Antes de analisarmos os códigos, algumas considerações importantes:
- As mensagens que são enviadas para a rede contêm 2 partes importantes: O id da mensagem e seu conteúdo(também chamada de Data). São esses os campos que nós modificamos para criar as mensagens enviadas na rede.
- O id, em sua forma não estendida varia de 0 a 2047(ou 0 a 7FF hexadecimal) enquanto o conteúdo é composto por um vetor de no máximo 8 elementos(chamados de frames), cada frame possuindo 8 bits, ou seja, cada um deles varia de 0 a 255 (ou 0 a FF hexadecimal).
- Tome como exemplo as mensagens na figura 7, onde é mostrado o id, o DLC(contagem do número de frames) e o campo de data com seus respectivos frames de conteúdo.
- Os programas mostrados aqui consideram que a can já está habilitada e ativa (todos os comandos daquele script foram executados).
Vamos começar com o programa rx_simples.
Programa rx_simples
Ele praticamente simularia o comando candump que vimos anteriormente. Tentei deixar comentado ao máximo para que fique tudo melhor explicado.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#!/usr/bin/python # coding=UTF-8 ### Esse programa monitorará a rede CAN, mostrando todas as mensagens recebidas. ### Também verificará se a mensagem possuem um id conhecido ou não #Importando bibliotecas import can #Biblioteca do python-can #Definir qual controlador vamos usar bus = can.interface.Bus(channel='can0', bustype='socketcan_ctypes') #Selecionamos o can0 como o controlador que monitorará as mensagens #Definindo um id conhecido id = 0x123 #Main while True: message = bus.recv() ##Fica esperando receber mensagem no barramento CAN print("Recebemos uma mensagem") if message.arbitration_id == id: #verifica se o id da mensagem é o mesmo que o id definido print("A mensagem possui um id conhecido!") else: print("A mensagem possui um id desconhecido!") #O loop a seguir irá formatar o conteudo do vetor para que possa ser apresentado na tela da forma de hexadecimal s=[] for i in range(len(message.data)): #loop que percorrerá todo o vetor message.data s.append(hex(message.data[i])) #Convertendo o valor em hexadecimal e adicionando ao fim do vetor s print s |
Gostaria de ressaltar alguns pontos do código:
O primeiro é em relação a linha 15. O parâmetro passado para o bustype, para o python2.x, deverá ser ‘socketcan_ctypes’. Se você usa a partir da versão 3.0, o parâmetro deverá ser ‘socketcan_native’.
O programa roda em loop. Ele fica esperando as mensagens no barramento CAN, e quando as recebe, analisa o identificador da mensagem, processa o conteúdo (faz uma formatação simples para ficar melhor apresentável) e o mostra na tela.
Programa tx_simples
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# coding=UTF-8 ### Esse programa enviará periodicamente uma mensagem para a rede can #Importando bibliotecas import can import time #Definir qual controlador vamos usar bus = can.interface.Bus(channel='can1', bustype='socketcan_ctypes') #Selecionamos o can0 como o controlador que monitorará as mensagens #Definindo um id para nossas mensagens id = 0x123 #Definindo o conteudo das mensagens cont = [0xf5,0x23,0x1A] #Main while True: msg = can.Message(arbitration_id = id,data=cont) #Criando a mensagem que será enviada na rede bus.send(msg) #Enviado para a rede print "Mensagem enviada" time.sleep(5) #espera 5 segundos antes de enviar a mesma mensagem |
O programa tx simularia o comando cansend, enviando uma mensagem ao barramento. Essa ação se repete a cada 5 segundos.
Da mesma forma que o programa anterior, primeiramente é selecionado o barramento. Depois, definimos os dois elementos chaves da mensagem a ser transmitida, o id e o conteúdo.
Utilizamos as funções da biblioteca para criar a mensagem no formato da rede CAN e posteriormente a enviamos.
Aqui podemos ver os dois programas funcionando simultaneamente:
Esses dois programas ilustram realmente o básico de python+can. Com isso já é possível expandir as possibilidades do que pode ser feito. Como exemplo, com id’s diferentes é possível fazer um filtro, sendo que cada módulo conectado à rede responderá de uma maneira. E com o conteúdo das mensagens podemos enviar de tudo, desde que os módulos da rede saibam trabalhar com a mensagem que você enviou. E lógico, todo o conteúdo é apenas um monte números sendo enviados, deixando seu sistema mais seguro, caso alguém decida se conectar à rede e monitorar as mensagens.
Recomendo também olhar estes exemplos. São ligeiramente mais complexos e possuem mais conteúdo, e podem te ajudar a entender ainda mais o assunto. A descrição e todos os documentos relacionados à biblioteca python-can podem ser encontrados aqui.
Conteúdo adicional – BeagleBone Black e Mbed
O kit de desenvolvimento Mbed possui como núcleo um microcontrolador LPC1768, esse kit foi desenvolvido principalmente para projetos de prototipagem rápida voltadas para aplicações que exploram o uso de interfaces de rede e internet das coisas.
Esse kit mostra-se como uma boa alternativa para prototipagem e programação dos microcontroladores, pois oferece como plataforma de software um SDK (software development kit) open source online, dispensando a instalação de compiladores, que possui bibliotecas em linguagem C para o core e periféricos disponíveis no LPC1768, suporte, e compartilhamento pela comunidade de desenvolvedores.
O intuito aqui não é mostrar a programação detalhada da Mbed, mas sim mostrar que os dois hardwares, mesmo com arquiteturas distintas podem trocar informações entre si através da rede CAN. E lógico, com a rede estabelecida, é possível conectar outros hardwares à rede, bastando apenas que eles também possuam uma interface CAN.
O Mbed possui duas interfaces de controlador CAN nos pinos P9 (RX)-P10 (TX) e P30 (RX)-P29(TX). Como iremos realizar a comunicação com a Beaglebone, vamos utilizar os controladores dos pinos P29 e P30. O esquema do circuito completo pode ser visto abaixo:
Como qualquer outro controlador CAN, também é necessário o uso de um transceiver entre a Mbed e a rede. A diferença está no fato de que não precisamos usar um conversor de nível lógico pois este microcontrolador trabalha com 5V.
Nos limitamos aqui a mostrar apenas uma troca de mensagens simples utilizando o Putty para a BeagleBone e RcomSerial para a comunicação com o Mbed. Mais informações e exemplos sobre esse assunto podem ser encontradas no handbook sobre CAN para Mbed.
O resultado da comunicação inicial pode ser visto nas figuras a seguir. Utilizamos os comandos cansend e candump na Beaglebone para enviar e receber dados na rede, realizando assim a comunicação com o Mbed.
Considerações finais
Espero que esse tutorial sirva para qualquer pessoa que esteja começando nessa área de implementar uma rede CAN. O conteúdo disponível na internet é gigantesco. Fóruns, blogs me ajudaram muito, mas sinto que perdi muito tempo procurando e tentando entender as informações que muitas vezes eram demasiadamente complexas, e por não ter um mínimo conhecimento básico desse assunto, senti muita dificuldade tentando entender as discussões que aconteciam.
Dessa forma, se esse texto servir de ponto de partida para o leitor ou leitora, a missão aqui está cumprida. Espero que muitos projetos bons sejam criados a partir dele.
Deixo aqui o blog do laboratório em que fiz meu TCC, o LIEPO. Tem muito conteúdo interessante, sobre sistemas embarcados e muito mais. Os membros estão constantemente postando sobre os trabalhos desenvolvidos lá.
Agradeço pelo tempo dispensado para ler o artigo
Este texto teve como Co-autor o Rodrigo Pechoneri.
Referências
- Beaglebone for dummies – Rui Santos e Luís Perestrelo
- Python programming for the absolute beginner – Michael Dawson
- Introduction to the Controller Area Network (CAN) – Texas instruments – Disponível aqui
- Documentação Python-can: Disponível aqui
- AM335X DCAN Driver Guide: Disponível aqui
- Readme file for SocketCAN: Disponível aqui
Felicitações pelo artigo, Bruno e Rodrigo. Em um cenário em que há mais dispositivos para serem ligados na CAN, como ficaria essa ligação física com um único Beaglebone Black? Grata.
Oi Jordana! Muito obrigado pelo elogio! Pela própria estrutura da rede CAN a adição de um novo dispositivo é simples, basta apenas você conectá-lo em “paralelo” com a rede (dê uma olhada na figura anexa a este comentário). No artigo utilizamos 2 controladores CAN da BBB, e depois um controlador da placa e outro da mBed. Poderíamos ter apenas adicionado a mBed na mesma rede que conectava os dois controladores CAN nativos da beagle, e assim os 3 dispositivos se comunicariam através do barramento. Se ficou alguma dúvida ou se eu puder ajudar em algo mais é só perguntar. Abraços!… Leia mais »
Obriga, Bruno! Entendi sim. Montando o circuito da CAN é mais claro para visualizar isso. A questão agora é que ao reproduzir seu artigo com um Debian 9 LXQT, kernel 4.4 (adaptei, pois você usou o 3.8) e conferir as conexões, não tenho resposta de rede. Envio um comando para ela, não há nada de modificação no osciloscópio e não dá erro de buffer. Vi as suas recomendações quando há erros, sem sucesso para mim. Alguma ideia? Desde já agradeço.
Eu lembro que na época tentei utilizar o kernel em versões superiores e não consegui, mas não quer dizer que seja impossível. Você está com dois controladores conectados a rede ou apenas um só? Eu tentaria primeiramente testar os controladores individualmente, através do parâmetro “loopback on”, pra ver se realmente tudo está funcionando como deveria, se os controladores CAN estão configurados corretamente, gerando as mensagens e etc. Se isso funcionar, já é um bom sinal. Em caso negativo, talvez seja alguma configuração incorreta, principalmente na questão dos arquivos binários pela diferença de versão do kernel. Ai a sugestão seria fazer… Leia mais »
Bruno, novidades! O Beaglebone Black funciona a CAN com o kernel 4.4. A solução que resolveu para economizar tempo, foi reinstalar a imagem no BBB, utilizando as mesmas configurações. Feito isto, a CAN funciou. =D
Bruno, o link do repositório para o Github está sendo direcionado para o datasheet do SN65HVD233-HT 3.3-V CAN Transceiver.
Estranho :S
Mas realmente vi aqui, e um deles está sim, o hyperlink deve estar mal configurado…falarei com o pessoal.
De qualquer maneira, o mesmo link é citado um pouco para cima (pelo menos ameniza um pouco).
O link do meu repositório para esse trabalho é https://github.com/brunohuffenbaecher/bbb-can
Valeu pelo toque!
Oi Jordana! Que bom que no fim deu certo! As vezes a solução de reinstalar tudo resolve mesmo hahaha.
O importante é que funcionou. Agora vem a parte mais legal(trabalhosa, mas legal), de definir o seu protocolo, dicionário e etc.
Enfim, boa sorte nas próximas etapas! Recomendo escrever um artigo aqui para o embarcados falando sobre seu trabalho. Temos pouco conteúdo sobre BBB e rede CAN, com certeza seria um artigo bem vindo.
Precisando de alguma coisa é só mandar!
Abraços!
Obrigada pelo apoio e incentivo, Bruno! Você tem material sobre a criação do protocolo? Aproveitando, a execução do arquivo de recebimento (Rx) não dá erro mas também não imprime nada na tela. O arquivo de transmissão executa de 5 em 5 segundos, e imprime a mensagem na tela.
Obs.: Penso que o mais legal será eu relatar os erros que podem dar no projeto, pois cada a etapa é cada um que aparece … (risos)
Bruno, quanto ao código: só funciona com loopback on. Quando dou loopback off, geralmente ele retorna com a mensagem de buffer cheio. Sabe o motivo? Obrigada!
Isso aconteceu comigo quando eu só estava usando um controlador conectado a rede, e quando um dos meus transceivers estava queimado (quando passei a utilizar os 2 controladores da BBB). Para que a CAN na rede física funcione é importante ter ao menos 2 controladores conectados. Com o loopback on, ele faz uma “rede virtual” com 1 controlador só, por isso ele envia as mensagens sem erro nenhum. No momento que você desativa o loopback, ele passa a tentar enviar as mensagens na rede, e quando não consegue, vai acumulando em um buffer até ele ficar cheio e começar a… Leia mais »
Oi Jordana! Muito estranho isso.. Você está rodando os dois programas em paralelo? É importante também dizer que nesses códigos, eu utilizo os dois controladores CAN. Eles precisam ser acionados/configurados previamente, e com os dois programas rodando simultaneamente é possível ver um deles enviando mensagens e o outro indicando que recebeu. Eu disponibilizarei temporariamente a monografia do meu TCC no mesmo repositório do github citado anteriormente. Lá tem todo o trabalho que eu fiz de uma forma mais detalhada, com mais alguns exemplos de código também. Dá uma olhada, vê se te ajuda em alguma coisa. O arquivo do rx_simples… Leia mais »
Olá, Bruno! Muito obrigada pela explicação!
Vou ter que que colocar mais componentes físicos na CAN, o que falou vai ser fundamental nesse acréscimo. Ainda estou com somente um controlador, e por isso o lookback on faz sentido. Quando habilito a CAN de forma correta (como você fez) e abro dois terminais e coloco “python3 nomeDoArquivoEmPython.py” em cada um com o Rx e TX separadamente, funciona.
—-Muito—- obrigada pelo apoio!
Vi hj seu trabalho, parabéns. agradeço ao Bruno por ter te dado uma mão. Abraços Che. Vc pode verificar os overlays tbm.
Excelente artigo! Está de parabéns!
Ficou muito bom Brunão parabéns pelo trabalho.
Excelente artigo. Muito didático!