Usando a porta serial em Node.js

A porta serial, também chamada UART, é um dos protocolos de comunicação mais utilizados em sistemas eletrônicos, encontrado em diversas configurações de hardware, desde microcontroladores de 8 bits até microprocessadores complexos de 32/64 bits; além de uma ampla variedade de periféricos, como modems 3G e GPS, dentre outros. Apesar de ser uma tecnologia antiga, sua simplicidade e emprego ainda intenso requerem que os desenvolvedores saibam como usá-la em situações do dia a dia.  

 

No caso dos sistemas embarcados, o uso de sistemas operacionais de alto nível de abstração do hardware, como o Linux - que é possível dado o desenvolvimento de microprocessadores cada vez mais poderosos, menores e mais econômicos - permite aos desenvolvedores utilizar linguagens de programação de alto nível de abstração em suas aplicações - num ramo tradicionalmente dominado pelo bom e velho C.  

 

Node.js é um interpretador de Javascript que roda no servidor, e que tem se tornado cada vez mais popular ao longo dos últimos anos, é um bom exemplo de linguagem de alto nível que pode ser utilizada em sistemas embarcados com elevado poder de processamento. Com essa mudança, às vezes surgem dúvidas sobre como acessar hardware com tal linguagem e, portanto, este artigo é dedicado a pessoas que desejam construir aplicações embarcadas com Node.js em sistemas de Linux Embarcado, integrando as portas de comunicação serial à sua solução.    

 

 

O exemplo prático de porta serial em Node.js

 

A abordagem escolhida para ilustrar o uso da porta serial em Node.js emprega dois computadores em módulo (CoMs) e placas-base de prateleira, que serão usados para a troca de dados entre si. A configuração de hardware escolhida é: Apalis I.MX6Q + Apalis Evaluation Board e Colibri I.MX6S + Iris Carrier Board da Toradex.  

 

O exemplo escolhido é o esboço de um simples jogo por linha de comando, no qual o Colibri envia os dados do usuário para o Apalis (teclas W, A, S, D e espaço), e o Apalis imprime e atualiza constantemente no terminal um retângulo de caracteres, no qual há um elemento que consegue se mover de acordo com a entrada do usuário. A ideia é bem simples e está descrita na figura 1 de maneira mais clara:   

 

Jogo simples de posicionamento com porta serial em Node.js
Figura 1: Jogo simples de posicionamento

 

 

Instalando Node.js e o módulo Node Serialport

 

Para instalar o Node.js e o módulo Node Serialport, o gerenciador de pacotes para a distribuição Angstrom do Linux - OPKG - e o gerenciador de pacotes do Node - NPM - serão utilizados. O procedimento descrito neste capítulo deve ser aplicado a ambos os módulos Apalis e Colibri e, para isto, eles devem estar conectados à internet. Para instalar Node.js e o NPM:

 

 

Uma vez que o Node Serialport não possui binários pré-compilados para a arquitetura ARM, o NPM tentará compilar a partir do código-fonte, então precisamos de alguns pacotes adicionais que não estão instalados na imagem padrão:  

 

 

Se o seu módulo não possui a última imagem pre-built disponibilizada pela Toradex, a instalação de alguns pacotes pode falhar. Você pode fazer o update da imagem para a última versão ou simplesmente usar a flag "--force-downgrade" com o OPKG:

 

 

Agora é possível instalar o Node Serialport. Observe que – enquanto este artigo é escrito - o OPKG instala a versão 0.12 do Node.js, que só é suportada pelo Node Serialport v4 - e isto é importante na hora de consultar a documentação do módulo:

 

 

Nota: na hora de finalizar um produto, é recomendado criar uma imagem personalizada, e portanto o Node.js e o Node Serialport podem ser incluídos direto nesta imagem, ao invés de usar gerenciadores de pacotes. Isto pode ser conseguido gerando uma distribuição do OpenEmbedded/Yocto - você pode usar a camada meta-nodejs, por exemplo. Um passo a passo de como gerar uma imagem pode ser encontrado neste artigo.

 

 

Entendendo o hardware

 

O Apalis iMX6 possui 5 interfaces UART, sendo 4 destas disponíveis por padrão (seção 5.9 do datasheet) e o Colibri iMX6 também possui 5 UART, mas somente 3 delas estão disponíveis sem precisar mudar as configurações do sistema (seção 5.11 do datasheet). O nível de tensão de ambos os módulos é TTL 3,3V.

 

Tanto a Apalis Evaluation Board (seção 3.13.1.2 do datasheet) quanto a Iris Carrier Board (seções 3.9.1 e 3.9.2 do datasheet) possuem conversores para o padrão elétrico RS-232 se necessário, mas como o sinal é disponibilizado num conector DB9 na Apalis Evaluation Board e na barra de pinos para a Iris Carrier Board, foi escolhido não usar o padrão RS-232 mas sim os pinos de nível lógico TTL 3,3V, para que não fosse preciso confeccionar um cabo adaptador.

 

Para a Apalis Evaluation board, consultando a seção 3.16 do datasheet, escolhemos os pinos 38 (UART3-Tx) e 39 (UART3-Rx) do conector x3, enquanto para a Iris Carrier Board, consultamos a seção 3.9.3 do datasheet para escolher os pinos 31 (UART_C-Rx) e 32 (UART_C-Tx). As figuras 2, 3, 4 e 5 ilustram a conexão dos jumpers aos pinos.

 

Conexão com a UART3 da Apalis Evaluation Board
Figura 2: Conexão com a UART3 da Apalis Evaluation Board (observe o conector de rede na parte inferior da imagem, para localizar os pinos com mais facilidade)

 

Conexão com a UART_C da Iris Carrier Board. Os fios na parte de baixo da imagem estão desconectados.
Figura 3: Conexão com a UART_C da Iris Carrier Board. Os fios na parte de baixo da imagem estão desconectados.
Vista de cima da Apalis Evaluation Board (à esquerda) e Iris Carrier Board (à direita) lado a lado, já conectadas pelos fios branco e roxo.
Figura 4: Vista de cima da Apalis Evaluation Board (à esquerda) e Iris Carrier Board (à direita) lado a lado, já conectadas pelos fios branco e roxo.
Ambos os sistemas conectados, em outra perspectiva
Figura 5: Ambos os sistemas conectados, em outra perspectiva

 

Quanto ao acesso das interfaces UART pelo Linux, a UART_3 do Apalis corresponde à interface /dev/ttymxc3 e a UART_C do Colibri corresponde à /dev/ttymxc2. Esta e outras informações sobre a UART no Linux podem ser encontradas neste artigo do Toradex Developer Center.

 

 

A aplicação

 

Nesta seção, primeiro será abordado o código-fonte do Colibri e depois o código-fonte do Apalis.

 

Colibri i.MX6

 

O primeiro passo para fazer os módulos se comunicarem é conseguir usar o Node Serialport. Você pode encontrar informações detalhadas de uso dele aqui. Para configurar a UART, nós precisamos adicionar o módulo e criar um objeto contendo as informações da UART – para isto usamos o caminho descrito no final da última seção, uma taxa de transferência (baud-rate) arbitrária de 57600 bps e vamos definir uma mensagem por tamanho, que será de um byte no nosso caso. Alternativamente poderíamos usar um caractere para determinar fim de mensagem (por exemplo o newline, ou \n), se o tamanho da mensagem fosse variável.  

 

 

Em seguida, fazemos o tratamento de possíveis erros da serial e também criamos uma função que envia dados:

 

 

É preciso tratar também dos dados recebidos. No nosso projeto, os únicos dados recebidos que importam para o Colibri são a conexão inicial entre módulos. Vamos usar o caractere '0' para o handshake – o Colibri espera até receber um '0' e responde com outro '0':

 

 

No final do handshake a função enableStdin é chamada. Ela habilita a leitura de dados do terminal (teclado) e a cada tecla apertada este dado é enviado para o módulo Apalis:

 

 

Você pode encontrar o código completo aqui.

 

Apalis i.MX6

 

A configuração da porta serial, tratamento de erros e envio de dados serão omitidas desta seção, pois são iguais aos do Colibri - só é preciso mudar o path da serial. Quando a porta UART é aberta, é realizada uma tentativa de handshake com o módulo Colibri e um timer programado para tentar reconectar a cada 15 segundos, caso a primeira tentativa falhe. Para isto é usado o caractere '0', conforme convencionado no código-fonte do Colibri:

 

 

Quando o Apalis recebe dados, estes são tratados da seguinte forma: se receber um '0' a tentativa de reconexão é desligada e a área inicial é impressa na tela; se ' ' (espaço), a área é resetada e se outro caractere for recebido, é chamada uma função para cuidar do movimento do personagem na tela:

 

 

A função de gerenciamento de movimento faz o posicionamento baseada na recepção de 'w', 'a', 's' e 'd' e então atualiza a tela. Deixei alguns bugs e funcionalidades não implementadas de presente 🙂 para que você possa fazer do seu jeito, mas o básico está pronto:

 

 

Você pode encontrar o código completo aqui.

 

 

Executando a aplicação

 

Para rodar a aplicação no Apalis e Colibri:

 

 

Observe que, se você iniciar o código no Apalis primeiro, ele irá enviar uma tentativa de conexão que não será recebida, fazendo outra tentativa somente 15 segundos depois. Se você começar com o Colibri, não haverá delay de conexão. É claro que você também pode mudar o modo/tempo como o handshake funciona, ou até removê-lo.

 

Aplicação rodando no Apalis
Figura 6: Aplicação rodando no Apalis
Aplicação rodando no Colibri
Figura 7: Aplicação rodando no Colibri

 

 

Conclusão

 

Este artigo começou com a instalação do Node.js e do Node Serialport em uma imagem pre-built; identificou as UARTs disponíveis nos módulos e sua correspondência com o Linux; e demonstrou o uso do Node Serialport para conectar dois computadores em módulo de diferentes famílias. O processo de instalação do software foi a parte mais crítica, uma vez que foi necessário instalar bibliotecas e compilar código-fonte no sistema embarcado – embora também tenha sido indicado o caminho para executar estes passos em uma máquina de desenvolvimento.

 

No fim, usar a porta serial com Node.js se mostrou uma solução simples do ponto de vista de software, para aqueles que estão interessados em usar esta linguagem em sistemas embarcados, onde utilizar interfaces de hardware de baixo nível é uma necessidade. Espero que este artigo tenha sido útil e nos vemos em breve!

NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

1
Deixe um comentário

avatar
 
1 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Rodrigo Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Rodrigo
Visitante
Rodrigo

Boa tarde. Qual o limite do nodejs? Dá para desenvolver sistema supervisório com ele?