Interação com Hardware usando JavaScript
É isso mesmo que você leu!
Já ouvimos falar que o JavaScript "roda em tudo", certo? Existem diversos exemplos que provam que tal afirmação está correta, e hoje irei mostrar um deles. Inclusive, se contássemos o que anda acontecendo atualmente, faríamos alguém dos anos 90 rir muito. Primeiramente, existem frameworks e plataformas diferentes:
O Cylon.js, por exemplo, suporta 43 plataformas desde Arduino, passando por alguns drones até Leap Motion.
Já o Tessel.js, é uma placa que roda Node.js e tem módulos plugáveis que permitem conexão WiFi, câmera, 3G e etc.
A diferença entre os dois acima é: No Cylon.js, rodamos o código em um computador que irá enviar dados via uma interface para a plataforma (vamos usar Arduino como exemplo para facilitar). Uma interface bem comum e barata é o cabo USB! Logo, iniciamos um processo Node.js que envia comandos ou recebe informações para o Arduino. Se paramos o processo ou removermos o cabo, encerramos essa comunicação. Isso porque o software estava rodando no computador e o Arduino não funciona stand-alone.
Já no Tessel, a implementação vai no chip da placa, eliminando a necessidade de uma conexão constante. Quem está acostumado a usar a linguagem C para fazer isso pode achar estranho, mas seria difícil ter todo o ambiente dentro do microprocessador. Nesse caso, o computador é usado para gravar e enviar o programa que escrevemos para a placa via USB. Uma vez que o cabo é removido, o código já está salvo e pode rodar sem ter um computador conectado.
No artigo "JavaScript Beyond the Web", o autor fala sobre o JavaScript fora da web e apresenta diferentes plataformas e soluções.
Como temos várias opções para brincar, talvez seja difícil escolher uma para começar. Nesse post eu usarei um framework bem popular, com uma API clara e que oferece suporte a várias plataformas: o Johnny Five!
Baseado no protocolo Firmata, o Johnny Five suporta plataformas como Arduino, Intel Galileo, Raspberry Pi (isso mesmo) e muito mais. Dependendo da plataforma escolhida, a comunicação com um computador pode ou não ser necessária. Os exemplos demonstrados aqui usam um Arduino Uno!
Instalação
Teoricamente, basta instalar o módulo para que a mágica aconteça:
npm install johnny-five
mas algumas dependências que lidam com compilação de módulos nativos de baixo nível, como o serial-port, podem causar um pouco de dor de cabeça dependendo do sistema operacional utilizado ou em versões mais novas do Node.js.
O "Hello World" do hardware
Como nem sempre a plataforma que estamos usando tem um monitor, o "Hello World" costuma ser um led piscando! Então vamos seguir a tradição e começar por ele. Para isso, vamos precisar de:
O Arduino Uno (e o cabo de conexão USB)
Um led
Um resistor de 220 ohm
Na própria documentação do Johnny Five o exemplo não mostra esse resistor, mas para evitar que ele queime, seremos prudentes e o adicionaremos ao circuito como na imagem.
Se você nunca mexeu com circuitos eletrônicos fique tranquilo, pois o resistor funciona independente da maneira como é ligado (não tem um lado certo). Já o led tem que ser ligado de forma que a corrente elétrica circule de forma que aquela "seta" em seu interior fique apontando do pino onde está o resistor para o pino "gnd".
Para permitir que o Node.js envie os comandos para o Arduino você deve fazer upload do protocolo Firmata para o microcontrolador:
Baixe a IDE do Arduino
Plugue o Arduino na USB do computador
Abra a IDE, depois abra o arquivo no caminho
File > Examples > Firmata > StandardFirmata
Clique em upload!
Se não houve qualquer erro no upload, você conseguiu gravar o protocolo no microcontrolador e estamos prontos para usar o nosso amigo JavaScript! Vamos criar um arquivo blink.js na pasta onde instalamos o módulo Johnny Five:
// Como o johnny five é um módulo Node.js, // ele é carregado como qualquer outro var five = require('johnny-five'); // Instanciamos uma placa, que neste caso // será a do Arduino que se comunicará com o computador var board = new five.Board(); // O evento de ready é disparado quando a comunicação // é estabelecida entre o processo Node.js e o Arduino board.on('ready', function() { // Instanciamos um led no pino 13 var led = new five.Led(13); // Chamamos o método blink do led que recebe // a duração da fase que piscará em milissegundos led.blink(500); });
Basta rodarmos o script no terminal: node blink.js
E pronto! Temos nosso "Hello World". Podemos ver o exemplo rodando no vídeo abaixo: https://www.youtube.com/watch?v=3qzi0VqCFqo "Socorro, tem um led no meu servidor" Agora que sabemos como fazer um led piscar e considerando que temos um computador que é responsável pelo processo Node que envia os comandos, podemos imaginar todas as aplicações que já escrevemos se comunicando com hardware! Neste próximo exemplo vamos criar um servidor http que liga e desliga um led. Vamos usar a mesma configuração de hardware. A ideia é que através de uma url, o servidor mude o estado do led e assim toda vez que ele for acessado ligue ou desligue. Ou seja, com poucas linhas vamos conseguir acessar o hardware pela rede. Talvez isso explique porque algumas empresas estão usando JavaScript para seus dispositivos e frameworks ligados a essa tal "Internet das Coisas". // Vamos carregar os módulos johnny five e http var five = require('johnny-five'); var http = require('http'); // Instanciaremos uma placa var board = new five.Board(); // isReady vai ser verdadeira quando a placa // disparar o evento 'ready' var isReady = false; // isOn guarda o estado do led para sabermos // se está aceso ou apagado var isOn = false; // Vamos criar uma variável global para o led // dessa forma podemos acessá-lo de forma global // sem precisar de muita complexidade var led; // quando a placa se conecta e está pronta... board.on('ready', function() { // instanciamos um led no pino 13 led = new five.Led(13); // certificamos que o led estará desligado led.off(); // setamos a variável que usamos para // saber o estado atual da placa isReady = true; }); // Vamos criar um servidor http extremamente simples // que escuta a porta 3000 http.createServer(function (req, res) { // Em toda a requisição checamos a url // acessada verificando se ela foi feita // para a raiz do servidor... if (req.url == '/') { // chamamos a função que muda o estado do led toggleLed(); // encerramos a requisição com a variável isOn // informando se o led está aceso ou não // a concatenação com uma string se dá porque // o método end precisa de uma string ou um buffer res.end(isOn + ''); } else { // caso a requisição não seja para a raiz // encerramos a conexão sem fazer mais nada res.end(); } }).listen(3000); console.log('listening at 3000'); // Função responsável por ligar e desligar o led function toggleLed () { // Se a placa não estiver pronta // a execução não prossegue if (!isReady) { return; } // Se o led estiver ligado... if (isOn) { // o método off é chamado, desligando-o led.off(); // a variável recebe false isOn = false; } else { // se o led estiver desligado, o método on // é chamado, ligando-o led.on(); // a variável recebe true isOn = true; } }
Veja este exemplo rodando no vídeo abaixo: https://www.youtube.com/watch?v=EkvAYIBcyuA Isso pode parecer banal e fácil, mas essa é a beleza de tudo isso. Usar conhecimentos prévios para criar um servidor e poder acender coisas na sua casa! Esse post foi introdutório e espero poder abordar mais sobre hardware aqui no portal BrazilJS. A documentação do Johnny Five contém muitos exemplos legais e espero que eles inspirem a descobrir mais usos. Imagine tocar uma sirene sempre que houver um erro no build ou piscar uma luz do escritório quando um merge para a branch master for feito. Espero ter mostrado algo novo para alguns e ficarei feliz em ajudar com qualquer dúvida :) Até a próxima!