Sistema Web com Raspberry Pi, Arduino, USB, Lighttpd e PHP

Sistema Web com Raspberry Pi

No presente artigo irei apresentar como podemos criar um sistema Web com Raspberry Pi, que é uma SBC que roda Linux Embarcado e mais uma infinidade de aplicações, para funcionar em conjunto com o Arduino, nossa tão amada plaquinha para projetos eletrônicos. Tudo isso usando nada mais e nada menos do que... a porta USB! Nada de TX/RX, mexer em arquivos do sistema, etc... 

 

Considerando o atual cenário em que tentamos deixar as coisas conectadas, é comum nos depararmos com uma situação em que tentamos deixar um projeto conectado à rede ou internet, propriamente, aliado a funcionalidades de controle de alguma aplicação específica, tal como acender um LED, ligar um relé, ler um sensor, etc. Isso envolve um aumento expressivo na complexidade da aplicação, ainda mais se a mesma for baremetal, ou seja, você está fazendo o código C na raça, lidando com requisições TCP/UDP, tratando eventos diversos e etc. Em suma, isso não fica bonito... E quando você pretende fazer sua página Web, há uma grande mistura de código C, da aplicação, com código HTML, de exibição da página. Menos bonito ainda 🙁

 

Quem já tentou fazer uma simples página do tipo "Apertar um botão e acender um LED" com Arduino e Shield Ethernet sabe do que estou falando..

 

Nada melhor do que... delegar funções! Ou seja, uma parte do sistema trata as coisas mais alto nível, mais complexas, tais como requisições Web, exibição de páginas, demais coisas. E outra parte do sistema trata das atividades de mais baixo nível, tais como leitura de sensores, controle de servos, etc. Mas... Como integrar essas duas partes?

 

Aí que reside a "sacada". O Arduino (tradicional) é energizado e realiza comunicação pela porta USB.

 

Sistema Web com Raspberry Pi: Arduino e porta USB
Figura 1: Vista da porta de conexão USB Tipo-B do Arduino. Fonte: sparkfun.com

 

E as placas da família Raspberry Pi possui uma (Raspberry Pi A+) ou mais portas USB (Raspberry Pi B tem 2 portas, e os modelos Raspberry Pi B+ e Raspberry Pi 2 Model B têm 4 portas).

 

Sistema Web com Raspberry Pi: The Pi board Family
Figura 2: Modelos de Raspberry Pi - com legenda. Fonte: raspi.tv

 

Ou seja, plug-and-play! Porém... Nem tudo são flores... Pois algumas questões surgem:

  1. Como comunicar via USB - principalmente no lado da Raspberry Pi?
  2. Como desenvolver uma interface Web capaz de ler dados do Arduino e enviar comandos para o Arduino?
  3. Quais linguagens e plataformas usar?

 

Pois bem. Vamos responder essas questões e elaborar o artigo:

  1. Ao plugar a USB do Arduino na Raspberry Pi, será criado um device de comunicação serial, normalmente nomeado como ttyACM0. Com isso, basta realizar processo de leitura/escrita em serial com o baudrate configurado no Arduino também;
  2. É preciso ter uma base que seja capaz de realizar comunicação com devices do sistema e que também seja capaz de lidar com requisições Web. É preciso ter um Servidor Web em operação, ou uma aplicação que faça interface com requisições de rede. Em se tratando de servidores Web, temos as opções Apache, Lighttpd e Nginx, dentre os mais difundidos. Para comunicar com o Arduino, existem as seguintes opções:
    • Usar CGI: Você escreve um código no servidor, e o servidor Web faz uma ponte entre a requisição Web e seu código no servidor;
    • Aplicação com interface Web: Você escreve uma aplicação no servidor capaz de responder a requisições Web e gerar respostas específicas.
  3. Com relação às linguagens, temos as seguintes opções:
    • Exibição: HTML  - uma linguagem que formata o conteúdo Web, e CSS dá o "embelezamento" (fonte, cores, ajuste de texto, etc);
    • Código no Servidor Web com CGI: Você pode escrever aplicações nas seguintes linguagens, que irão interagir com o servidor Web quando houver requisições, gerando também respostas aos clientes Web:
    • Aplicação Nativa: É possível escrever uma Aplicação Nativa, capaz de responder a requisições Web, nas linguagens tais como Python, C, C++, JavaScript (Node.JS), dentre outros. Pesquise sobre a linguagem de seu interesse e bibliotecas que tornem possível sua integração com rede, respondendo em requisições TCP/UDP, por exemplo.

 

Para efeito de demonstração, o presente artigo fará uso de Lighttpd com PHP configurado com FastCGI, juntamente com uma biblioteca para PHP para comunicação com Serial TTY, de modo a demonstrar a integração da Raspberry Pi com Arduino na criação de uma interface Web capaz de controlar elementos de hardware.

 

 

Configuração da Raspberry Pi

 

Com relação à Raspberry Pi, vou tratar os seguintes itens tendo como base o sistema operacional Raspbian instalado. Caso você tenha a sua Raspberry Pi ou outro sistema, use os itens como referência para o seu modelo ou caso.

 

Aviso: Os seguintes passos demandam o acesso ao terminal (shell) do sistema Raspbian, o que pode ser feito tanto via SSH, como feito nativamente, caso você esteja usando sua Raspberry Pi ligada a um monitor, com teclado e mouse, ou até mesmo se você ligou um conector USB-TTL na UART da Raspberry Pi para acesso direto ao seu terminal. Além disso, tomarei por base que os comandos são realizados pelo usuário pi.

 

Tendo por base que a Raspberry Pi é um sistema embarcado, com recursos mais limitados de processamento e memória, é um tiro no pé a instalação tradicional do servidor Web Apache2, por mais intuitivo que seja. Ele consome muita memória, e isso vai deixar seu sistema pesado.

 

Dito isso, proceda com a instalação do Lighttpd e do PHP com o seguinte comando:

 

 

Muito provavelmente o comando também incorrerá na instalação do Apache2. Como não o queremos na Raspberry Pi, podemos desinstalá-lo com o seguinte comando:

 

 

Mesmo tendo instalado o Lighttpd e o PHP, a "ponte" entre os dois ainda não foi estabelecida. Ela é feita por meio do módulo FastCGI, e este módulo pode ser habilitado para o PHP com o seguinte comando:

 

 

O que também pode ser feito com o comando abreviado "lighty-enable-mod", já que Lighttpd é pronunciado como "lighty":

 

 

Feito isso, é preciso reiniciar o serviço do Lighttpd:

 

 

Se tudo correu certo até aqui, estamos com Lighttpd funcionando e PHP funcionando. Para ter certeza disso, vá até o diretório /var/www/, crie um arquivo PHP chamado teste.php e coloque o seguinte código neste arquivo:

 

 

Feche o arquivo. Veja qual é o endereço IP da sua Raspberry Pi por meio do comando "ifconfig" no console, tal como mostrado na figura adiante:

 

Sistema Web com Raspberry Pi: saída do ifconfig
Figura 3: Exibição do comando ifconfig em console na Raspberry Pi

 

Agora, abra uma janela do seu navegador de preferência (Chrome, Firefox, etc), e digite como endereço de página web uma URL composta pelo endereço IP retornado pelo comando ifconfig, acrescido de "/teste.php". No meu caso, ficou  assim: http://192.168.1.18/teste.php. Se tudo correr bem, você verá no seu navegador uma tela parecida com a mostrada abaixo, indicando todo um relatório sobre o PHP instalado na Raspberry Pi, além de outras informações de sistema.

 

Sistema Web com Raspberry Pi: Tela de informações sobre o PHP em Execução
Figura 4: Tela de informações sobre o PHP em Execução.

 

Se você teve algum problema, ou seja, não apareceu a tela esperada, podem ser duas coisas: 

  1. Os pacotes não foram apropriadamente instalados;
  2. Problemas de permissão no diretório www.

 

Caso algum pacote não tenha sido apropriadamente instalado, reinstale. Caso tenha problemas de permissão, realize os seguintes comandos abaixo:

 

 

Estes comandos irão adicionar o usuário pi ao grupo www-data, que é o grupo que possui permissão no diretório /var/www/, onde devem ficar os arquivos da nossa interface Web. Além disso, é colocada a permissão 755 no diretório, além da permissão g+s, que garante a associação de permissão de grupo em futuros arquivos e subdiretórios.

 

Além disso, para que a nossa interface Web, executada pelo grupo www-data, consiga acessar devices do sistema Linux que façam comunicação via Serial TTY, é preciso adicionar o usuário dialout ao grupo www-data, pois este usuário é que possui permissão de acesso ao dispositivos /dev/tty* do Linux. O comando para realizar isso é mostrado adiante:

 

 

Apenas para garantir, reinicie o sistema da Raspberry Pi.

 

 

Estruturação do Modelo

 

Para o nosso presente caso, iremos tratar uma comunicação realizada entre o Arduino e a Raspberry Pi via USB. O Arduino irá tratar das tarefas de baixo nível, e a Raspberry Pi, das tarefas de alto nível, tais como interface com a Rede e Internet.

 

Sistema Web com Raspberry Pi e Arduino: Estruturação do Modelo Arduino + Raspberry Pi
Figura 5: Estruturação do Modelo Arduino + Raspberry Pi

 

No nosso humilde exemplo, iremos conectar um LED ao Arduino, o qual será controlado pela nossa página Web armazenada na Raspberry Pi. E no Arduino também iremos conectar um botão do tipo "pushbutton", cujo estado será mostrado na mesma página armazenada na Raspberry Pi.

 

Porém... Como iremos tratar a comunicação entre ambos, via USB? Temos que bolar um PROTOCOLO!

 

Um protocolo é uma regra que estabelece como a comunicação deverá ser realizada entre ambas as partes, para que ambos consigam se entender. De certa forma, você e eu usamos o "protocolo" que é a língua portuguesa para nos entendermos.

 

Dentre os vários modelos que existem, nos quais podemos nos basear, o meu favorito é o NMEA. Ele foi criado como base para os receptores de GPS, e, em suma, consiste em sentenças ASCII cujas informações são separadas por vírgula.

 

O fato de você separar as informações por vírgula facilita muito o processo, pois quem irá receber a informação precisará separas as informações pelas vírgulas, e saber precisamente a ordem com que estas informações foram enviadas.

 

Para o nosso modelo, vamos trabalhar da seguinte forma:

  • Arduino: Irá enviar mensagens com a seguinte forma: "$STS,botaoStatus,ledStatus,\n" - Ou seja, a primeira informação pode indicar do que se trata a mensagem, no caso, eu uso $STS como mnemônico para Status, e depois manda-se a informação de botaoStatus (que pode ser 0 ou 1) e ledStatus (que pode ser 0 ou 1). Ou seja, sabemos o que virá em cada campo separado por vírgula;
  • Raspberry Pi: Irá enviar o caractere 'a' para acender um LED ligado no Arduino, e 'd' para apagar o LED ligado no Arduino. E receberá as respostas geradas pelo Arduino.

 

 

Código Arduino e Configuração do Arduino

 

Com base no que foi projetado anteriormente, vamos partir para a codificação do Arduino, de modo que o mesmo faça o controle do LED e a leitura do botão, assim como também receber comandos da Raspberry Pi pela Serial e informar o status dos componentes pela Serial. Segue adiante o código desenvolvido para esta atividade.

 

 

Como exemplo de como fiz as ligações dos componentes em protoboard, segue o esquemático da minha montagem em Fritzing

 

Sistema Web com Raspberry Pi: Esquema de conexões com Arduino - Ligações com LED e Botão
Figura 6: Esquema de conexões com Arduino - Ligações com LED e Botão.

 

Após programado, é necessário colocar um capacitor de 10uF entre os sinais GND e Reset do Arduino para evitar que o mesmo seja reiniciado a cada conexão USB. Caso contrário, a cada vez que a Raspberry Pi for iniciar uma comunicação, todo o programa em execução no Arduino entrará em reset. Veja na figura abaixo como ficará a ligação do capacitor, tendo como base o Arduino UNO:

 

Sistema Web com Raspberry Pi: Arduino schematic + capacitor
Figura 7: Arduino com Capacitor de 10uF entre GND e Reset. Fonte: CreativeApplications.net

 

 

Código PHP

 

Para fazer o código PHP de controle da Serial, foi usada a Biblioteca PhpSerial. Para usar essa biblioteca, basta realizar o download do arquivo "PhpSerial.php" no diretório /var/www, de modo que o mesmo seja encontrado pelo nosso próprio arquivo PHP.

 

Há um pequeno problema nessa biblioteca, na parte em que trata se há uma serial no ambiente Linux, precisamente na linha 50:

 

 

Este código não vai funcionar, e gerará uma mensagem de erro quando você tentar usar. Troque para:

 

 

Feita a modificação, salve e feche o arquivo PHP da biblioteca PhpSerial.php.

 

Após isso, vamos então escrever o código da nossa página de controle. Para o meu exemplo, chamei a minha página de serial.php, e coloquei o código no arquivo da página. Observe que está precisamente comentado, incluindo as partes que lidam com comunicação Serial usando a biblioteca PHP citada.

 

 

 

Execução

 

Para a boa execução da Serial pelo PHP, ainda fica faltando mais uma coisa. É preciso digitar o seguinte comando abaixo para garantir que o dispositivo serial /dev/ttyACM0, usado pelo Arduino, opere corretamente.

 

 

Feito isso, digite o caminho da sua página PHP em seu navegador de preferência, e veja o resultado da página. Clique no botão "Acende LED", e verá o LED acender. Clique no botão "Apaga LED", e verá o LED apagar.  E no momento em que você apertar nos botões, a resposta que virá da Raspberry Pi também informará o status do botão. Mas isso é porque este modelo foi arquitetado assim.

 

Veja como ficou o meu exemplo abaixo. Eu cliquei no botão "Acende LED", e no mesmo momento eu também estava pressionando o botão conectado ao Arduino.

 

Sistema Web com Raspberry Pi: página web
Figura 8: Página Web da Integração Raspberry Pi com Arduino
Sistema Web com Raspberry Pi: Sistema running!
Figura 9: Foto da correspondente ação no mundo real 🙂

 

É normal ocorrer alguns problemas, chegarem alguns caracteres "zoados". Quer resolver? Trabalhe em cima da "temporização" da comunicação. Trate o recebimento de caracteres até a quebra de linha, dentre outras coisas.

 

Achou super interessante? Veja mais sobre a linguagem PHP no CodeAcademy, e estude mais sobre HTML também no CodeAcademy, assim você pode ficar craque na parte de Web, aprender como fazer uma página Web ser atualizada automaticamente, usar recursos JavaScript e embelezar a página com CSS. Além, é claro, de toda a funcionalidade por trás dos bastidores!

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.

André Curvello
Graduado em Engenharia de Computação com ênfase em Sistemas Embarcados pela USP, campus São Carlos, possui MBA em gestão de TI pela UNIFRAN e Mestrado em Ciências pela EESC-USP. Atua como Analista de Tecnologia para Sistemas Embarcados na Padtec S/A, sendo também professor de pós-graduação e instrutor de cursos na área de sistemas embarcados. Como hobby, gosta de programar tudo que pode ser programado, escovando bits sempre ao lado de um bom café. Gosta de compartilhar seu conhecimento por meio de palestras, e publicando artigos como colaborador dos sites Embarcados e FilipeFlop.

20
Deixe um comentário

avatar
 
17 Comment threads
3 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
16 Comment authors
Breno MendonçaDanilo Renato De AssisSamuel CassianoFabricio OliveiraFernando França Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
wellington costa
Visitante
wellington costa

Tem como conectar mais de um Arduino, no Raspberry?
Se sim, como?

Andre Valderes Vieira
Visitante
Andre Valderes Vieira

André meu xara´. Gostei da matéria, tenho uma pergunta. Estamos desenvolvendo aqui na UFSC-SC, um sistema parecido com o seu com o Arduíno uno e nele conectado sensores como o de temperatura e corrente, onde o mesmo Arduíno se comunica com o Raspberry. Só que estamos querendo enviar os dados dos sensores tipo:
equipamento a ser monitorado>sensor>Arduíno>Raspberry>servidor>programa gerador de ordem de serviços. Aqui usamos o Lotus Notes, nossa ideia é desenvolver um protótipo para monitorar equipamentos de longa distancia e enviar alertas a uma central para que o técnico possa receber esse alerta, afim de executar uma manutenção preventiva no equipamento se que o cliente precise informar o defeito. Fico grato se poder me dar uma luz.

Mateus Silva
Visitante
Mateus Silva

Ótimo artigo parabéns

Hudson Alesse
Visitante
Hudson Alesse

Cara meus parabéns! resolveu minha vida! kkkkk. Abraco

Luciano Braun
Visitante
Luciano Braun

Voce tem que dar a permissão pra porta do arduino se comunicar com as demais.Tenta dar "sudo chmod a+rw /dev/ttyACM0" sem as aspas e ve se funciona

Luciano Braun
Visitante
Luciano Braun

Voce tem que dar a permissão pra porta do arduino se comunicar com as demais.Tenta dar "sudo chmod a+rw /dev/ttyACM0" sem as aspas e ve se funciona
• Edit• Reply•Share ›

Alex
Visitante
Alex

Tambem estou com o mesmo problema. Tentei dar "sudo chmod a+rw /dev/ttyACM0" e deu a mensagem: "não é possível acessar “/dev/ttyACM0”: Arquivo ou diretório não encontrado"

Tarcísio Marinho
Visitante
Tarcísio Marinho

Olá André, gostaria de saber se eu executar esse comando da página por um smartfone ele também retorna a página ?

Quantos clientes solicitando a página ele aguente simultaneamente ?

Breno Mendonça
Visitante
Breno Mendonça

Bom dia. Mando o comando para o Arduíno via web . O mesmo chega mas não liga nem desliga o led. O que pode ser?

Danilo Renato De Assis
Visitante
Danilo Renato De Assis

Boa tarde

Estou seguindo tutorial mas tenho algumas dúvidas:

1) Minha conexao com o raspberry e arduino aparece em ttyUSB0 e se eu conectar um modulo wifi usb ele usa memo ttyUSB0. Como arrumar isso?

2) O codigo não escuta por parte do php mesmo cm as permissões. O arduino fica escutando mas o comando não é enviado pela serial para o arduino. Tem alguma permissao especial?. Fiz um echo "a" > /dev/ttyUSB0 e não chega nada para o arduino

Pode me ajudar?

trackback
Desenvolvendo Sistema Web com Raspberry Pi, Arduino, USB, Lighttpd e PHP | Portalfisica

[…] http://embarcados.com por André Curvello em terça-feira, 20 de outubro de 2015. No presente artigo irei apresentar […]