Comunicação entre PHP e Arduino via USB

Fazem uns 6 meses desde que tive meu primeiro contato com o Arduino, desde então eu sempre tive curiosidade de como seria fazer ele “conversar” com um script em PHP. Hoje, finalmente, eu botei a mão na massa e, depois de algumas pesquisas no Google, fiz algumas experiências de comunicação básica. A seguir deixo os dois experimentos que fiz.

Detalhe para a variável $ttyPath usada nos dois exemplos que contém o caminho do dispositivo, no meu caso, no Mac. No Linux e outros Unixes(-like) esse caminho deve ser algo parecido, é o mesmo caminho que aparece na IDE do Arduino. Não cheguei a testar no Windows, mas acredito que não seja complicado encontrar algum exemplo no Google.

Não vou explicar todo o código porque acredito que o próprio código e os comentários já dão uma boa noção do funcionamento, mas caso tenha qualquer dúvida, fique a vontade para usar o espaço para comentários.

Do Arduino para o script PHP

O primeiro experimento consiste em ler o que o Arduino escreve na porta serial.

to_php.cpp

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  Serial.println('Hello!');
  delay(1000);
}

Esse script PHP basicamente escreve na saída padrão o conteúdo enviado pelo Arduino.

conn_a.php

<?php
$ttyPath = '/dev/tty.usbmodem1a21';
$ttyHandler = fopen($ttyPath, 'r'); // Abrindo a conexão serial
while (true) { // Loop infinto, para testarmos a leitura como acontece no Serial Monitor
  $bytes = fread($ttyHandler, 1024); // Lendo uma linha da conexão, até 1024 bytes
  if (strlen($bytes) > 0) { // Se o Arduino enviou algo ...
    echo $bytes; // Imprimimos
  }
}
fclose($ttyHandler); // Fechando a conexão. De fato, o script nunca vai chegar aqui

Do script PHP para o Arduino

O segundo experimento faz o caminho inverso, de comunicação, do primeiro: envia a quantidade de vezes que o LED deve piscar.

from_php.cpp

int ledPin = 13; // Porta do LED embutido no Arduino UNO
int times = 0; // Por padrão, não deve piscar nenhuma vez

void setup()
{
  Serial.begin(9600); // Iniciando a porta serial
  pinMode(ledPin, OUTPUT); // Iniciando a porta do LED
}

void loop()
{
  if (Serial.available() > 0) { // Se a porta estiver disponível ...
    times = Serial.read() - '0'; // Lemos o conteúdo recebido como inteiro
    if (times < 0 || times > 9) { // Validando o valor lido
      times = 0;
    }
  }
  while (times > 0) { // Piscando até que o número de "piscadas" faltantes seja zerado
    digitalWrite(ledPin, HIGH); // Acende ...
    delay(500); // Espera 1/2 segundo
    digitalWrite(ledPin, LOW); // Apaga ...
    delay(500); // Espera 1/2 segundo
    times--; // Diminui uma "piscada"
  }
}

Nesse script PHP vamos passar o número de “piscadas” do LED como parâmetro. Por padrão, sempre que um script PHP é executado diretamente pelo cliente o primeiro argumento ($argv[0]) é o nome do próprio script ('conn_b.php', por exemplo), sendo assim precisamos capturar o segundo argumento para identificar o número de “piscadas”.

conn_b.php

<?php
$ttyPath = '/dev/tty.usbmodem1a21';
if (count($argv) < 2) { // Esperamos que o número de "piscadas" seja passado como parâmetro
  exit(1);
}
$blinkTimes = (int) $argv[1]; // Lendo o parâmetro com a quantidade de "piscadas"
$ttyHandler = fopen($ttyPath, 'r+'); // Abrindo a conexão serial
fwrite($ttyHandler, (string) $blinkTimes); // Escrevendo a quantidade na conexão
fclose($ttyHandler); // Fechando a conexão

Exemplo de execução (com o Arduino conectado à porta USB):

$ php conn_b.php 5

UPDATE: Infelizmente, notei que esse modelo de comunicação, funciona apenas se o Serial Monitor da IDE do Arduino estiver aberta. Isso acontece porque é necessário abrir a conexão COM e na velocidade correta – normalmente 9600 baud. Assim que conseguir uma solução independente da IDE, atualizo os scripts.

UPDATE 2: O Paulo Trentin colocou um link nos comentários para um artigo que ele escreveu. Eu ainda não tive oportunidade de testar, mas a princípio ele teria resolvido essa questão da comunicação com o hardware exigir a IDE do Arduino aberta durante a execução: http://www.paulotrentin.com.br/eletronica/controlando-arduino-com-php-via-serial/

Referências:

Advertisements