Controlando Arduino com PHP via Serial

O Problema

Apesar de existirem vários posts trazendo informações sobre o assunto, encontrei certa dificuldade em fazer o Arduino funcionar com a serial via PHP ou mesmo o terminal do Linux. Daí a origem deste post.

Para os testes demonstrados neste post, carregue o código do post Lendo uma string com Arduino via serial em seu arduino.

Como enviar dados para o arduino via terminal (Linux)?

De uma forma muito simples, para enviar uma informação para serial, no linux, fazemos assim:

// Define a velocidade de comunicação no dispositivo /dev/ttypACM1
$ /bin/stty -F /dev/ttyACM1 9600

// Envia informação para Arduino
$ echo "LED1:1" > /dev/ttyACM1

Onde /dev/ttyACM1 é a porta serial no linux. LED1:1 significa que o primeiro led configurado será ligado, veja no tutorial acima para entender como isso funciona.

Observação: Apesar dos comandos vistos estarem certos, não irão funcionar, em breve veremos o porquê.

Como enviar dados para o arduino via php?

O PHP é uma linguagem backend, ou seja, roda no servidor. Ele tem acesso à baixo nível no sistema do servidor, e entre outras coisas, podemos acessar diretamente a serial com PHP.

Para ligar uma lâmpada no Arduino diretamente via PHP, podemos fazer algo simples assim:

<?php

// Define porta onde arduino está conectado
$port = "/dev/ttyACM1";

// Configura velocidade de comunicação com a porta serial
exec("stty -F $port raw speed 9600");

// Inicia comunicação serial
$fp = fopen($port, 'c+');

// Escreve na porta
fwrite($fp, "LED1:1");

// Fecha a comunicação serial
fclose($fp);

Para desligá-la, precisamos apenas mudar o fwrite, passando como segundo parâmetro o valor: “LED1:0”

Observação: Apesar do código acima estar certo, não irá funcionar ainda.

Se você manter o terminal do Arduino aberto enquanto envia os comandos, eles funcionam, seja via php ou terminal mesmo. O desafio é fazer ele funcionar de maneira independente em releção a software, ou seja, com um simples comando via serial ou poucas linhas de código em php devem funcionar.

Para Windows, o script php fica levemente diferente:

<?php 
// Define porta onde arduino está conectado
$port = "COM1";
 
// Configura velocidade de comunicação com a porta serial
exec("MODE $port BAUD=9600 PARITY=n DATA=8 XON=on STOP=1");
 
// Inicia comunicação serial
$fp = fopen($port, 'c+');
 
// Escreve na porta
fwrite($fp, "LED1:1");
 
// Fecha a comunicação serial
fclose($fp);

O pulo do gato: Desativando autoreset do arduino na comunicação serial

Pois é, um detalhe muito importante que precisamos resolver para que tudo o que foi visto funcione é desativar o autoreset do arduino.

O autoreset é uma funcionalidade interessante pois permite enviar um novo código ao Arduino sem precisar pressionar o botão de reset, afinal o reset da placa é feito via software, pouco antes de enviar o código.

O problema é que toda vez que iniciamos uma nova comunicação serial ele reseta o Arduino impedindo que nosso comando via terminal ou software via PHP funcione.

Para entender mais sobre o autoreset, recomendo este post.

Como resolver então?
Simples: insira um capacitor de 10uF entre o pino GND e RESET do Arduino. O pino negativo irá no GND claro, e o positivo no RESET.

Veja abaixo:

IMG_20160701_114531545

Só isso?
Isso mesmo, funcionou perfeitamente para mim no Arduino Mega e Uno, mais detalhes você encontra neste link oficial do Arduino informando como desativar esta funcionalidade.

Referências

http://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection
http://playground.arduino.cc/Learning/AutoResetRetrofit
http://forum.arduino.cc/index.php?topic=246169.0
http://php.net/manual/pt_BR/function.fopen.php
http://stackoverflow.com/questions/16860605/communicating-serial-port-on-windows-with-php

30 Comments

  1. Olá, Paulo, gostaria de perguntar se vc sabe se existe alguma maneira de enviar a informação via serial de um módulo rfid conectado ao Arduino para o computador, ou para algum software que faça o controle dessa informação?Tenho interesse em saber pois estou fazendo um projeto e estou com esta grande dúvida.
    Obrigada, e aguardo sua resposta !

    1. Oi Isadora,
      sim, existe como fazer isso. O segredo está em receber a informação vinda do Arduino. O script abaixo faz isso usando php. No Arduino basta fazer um Serial.println e enviar o que precisa, sempre seguido de um “sair” ou outro caractere que desejar. Você pode mudar o script abaixo para ler linhas se avaliar o caractere \n:

      1. Paulo, muito obrigada por me responder. Porém tenho dúvidas. Não consegui entender a parte que vc falou de dar um “sair” entre um caracter do outro que for desejado.E vc sabe para onde vai a informação que eu mando da serial no computador, ou se tem como transformar a informação que eu enviar em texto (.txt)?
        Obrigada mais uma vez !

  2. Meu caro, ótimo tutorial, mas tenho um problema. Quando mando o echo via CMD, caso o serial do arduíno esteja fechado, rxtx piscam, mas nada acontece. Caso eu abra o serial no arduino, o CMD dá acesso negado ao tentar mandar o echo. Enfim, desabilitei o autoreset, e mesmo assim a falha persiste. O mesmo ocorre com o script php.

  3. ola cara, parabens pelo post primeiramente. entao queria uma ajuda aqui… estou conseguindo fazer funcionar pelo codigo mas ele acende depois apaga.. sera o auto-reset fazendo isso? se sim, tem alguma forma de desabilita-lo no Uno sem o capacitor.. (estou sem e sem possibilidade de ir atras esses dias) valeu

  4. bom dia

    agradeço pelo seu trabalho

    porem fiquei com uma pequena duvida vi q o php e uma linguagem de baixo nivel e que pode ser
    entendida pelo arduino porem gostaria de saber se a informação e mandada direto para o arduino
    e se e necessário escrever algum codigo no proprio arduino ??

    ou eu apenas gero o php e clico no botao com o caminho feito via serial para o arduino colocando porta com e velocidade??

  5. oi Paulo, a minha questão é a seguinte, gostaria de saber se existe algum programa que crie uma interface para comunicar com o arduino, preciso fazer um projeto de acionamento de motores pelo PC usando o arduino.

  6. Bom dia Paulo, parabéns pelo seu trabalho. Você tem algum contato que possamos nos falar? Estou com um problema numa placa da maquina de lavar eletrolux lt60.ja mexi nela e nao acho o problema.desde ja agradeco

  7. Amigo muito bom seu post mas estou com um problema que ainda não consigo entender. Eu embarco o software no arduino e executo os dois comandos no shell do linux porem apenas os leds tx e rx acendem o porque disso? Deixe eu te dizer qual é o meu problema eu preciso mandar inicialmente dois char para o arduino e ele deve fazer um servo motor digital funcionar entendeu?

  8. oi tudo bom? já uso o Arduíno faz um tempo e agora estou com projetos de interação web, e gostaria de umas dicas sobre qual linguagem de programação web usar no meu projeto(php ou javascript),

    Na pagina web eu entraria com um tempo(ano,mês,dia e hora) para ascender um LED no arduino quando o tempo escolhido batesse com o tempo atual.

    Funcionaria como um alarme.

    por favor qualquer opinião é bem vinda, ja sei fazer interações de ascender e imprimir com html usando o Arduíno.

    1. Olá Mateus,
      é sempre complicado indicar uma linguagem ou outra para fazer algo, pois isso depende de muitos fatores. No seu caso eu diria que as duas são ótimas. Adoro PHP, ele é incrível. O problema é que javascript é mais incrível ainda hehe.
      Recomendo que teste scripts em backend com PHP e NodeJS, faça vários testes e tire sua conclusão. Na empresa usamos muito PHP e Javascript, ambas as linguagens são incríveis!

  9. Parabéns Paulo Marcos.
    Só tenho uma dúvida, o capacitor de 10μF deve ter qual voltagem?
    Tem o link da foto de um para eu comparar?
    Obrigado.

  10. Parabéns pela maneira que você explicou. Fiquei um tempo sem conseguir realizar a comunicação entre o PHP e o Arduino, mas ainda bem que esse seu tutorial caiu como uma luva. No caso do autoreset, como eu não tinha um capacitor (e não possuo muito conhecimento na área da eleetrônica), coloquei um de 2.2uf. Creio que não haja problema, pois consegui executar o projeto normalmente. Muito obrigado.

  11. Você me salvou, amigo. Estava com problema de comunicação serial PHP x Arduino e utilizei sua configuração para velocidade. Funcionou perfeitamente. Só uma observação, para o meu teste simples de acender e apagar um Led, não foi necessário colocar o capacitor para desativar o autoreset. Mais uma vez obrigado por compartilhar informações.

  12. Paulo estou realizando um projeto de faculdade e preciso saber se tem como fazer o processo inverso.
    Pegar informações no serial e mandar pro PHP. Ótimo post e obrigado desde já.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *