quarta-feira, 16 de janeiro de 2013

Controle de Relé via Internet com Arduino e PHP

Palavras-chave: Arduino, PHP, Controle de Relé, Auto-Reset.

Nota: todos os  links para sites e ferramentas encontram-se no final do post.

Resolvi escrever este pequeno tutorial depois de conversar com um amigo que estava interessado em controlar dispositivos via internet.

Embora eu tenha o EtherShield (ENC28J60 - não recomendo!), os testes foram realizados em localhost.

CONSIDERAÇÕES INICIAIS

Para que a página PHP funcione, será necessário ter instalado na máquina o servidor Apache e o PHP.

A instalação não será tratada aqui, mas pode-se adiantar que usuários do Windows podem utilizar o XAMPP (possui versão Linux, Mac OS X e Solaris) ou o WAMP. Já usuários Linux devem baixar e instalar os pacotes caso não o tenham. Para verificar, no Slackware, se os pacotes estão instalados, digite:

# pkgtool

Selecione a opção "View" e procure por httpd e php.

COMPONENTES

1 Arduino Uno R2;
1 Protoboard;
1 Diodo 1N4148;
1 Transistor BC548;
1 Resistor de 2.2 kΩ;
1 Relé 5 Vcc (bobina) e 250 V / 7A;
1  bloco de terminal;
1 Lâmpada de mini abajur;
Fios.

MONTAGEM

A Figura 1 mostra como o relé foi ligado ao Arduino.

Figura 1 - Montagem.

ARDUINO

/*---------------------------------------------------
# Autor: Cleber Moretti
# Data: 10/01/2013
# www.binarycodec.blogspot.com
# CONTROLE DE RELE VIA INTERNET COM ARDUINO E PHP
----------------------------------------------------*/

int Rele = 13; /** rele no pino 13 */
int digito = 0; /** guarda retorno da porta serial */

void setup () {
  Serial.begin(9600);
  pinMode(Rele, OUTPUT);
  }

void loop () {
  if (Serial.available()>0)
  {
    digito = Serial.read();
  }
 
/** Acionar rele "1" */

  if (digito == '1')
  {
    digitalWrite(Rele, HIGH);
    Serial.println("ligado");
  }
  
else

/** Desligar rele "0" */

  if (digito == '0')
  {
    digitalWrite(Rele, LOW);
    Serial.println("desligado");
  }
 
digito = 0;
 
}

PHP

Copie o código abaixo (substituindo o /dev/ttyACM0 pela sua porta serial) em um arquivo chamado "controlerele.php" e salve na pasta htdocs. No Slackware o caminho é /var/www/htdocs (automaticamente é criado uma cópia em /srv/httpd/htdocs e /srv/www/htdocs).

<!-- O conteudo deste blog (binarycodec.blogspot.com) esta sob licenca Creative Commons 2.5 -->

<?php

    $port = fopen("/dev/ttyACM0", "w");

      if ($_POST['situacao']=="Acionar")
      {
      fwrite($port, "1");
      }

    //header ("Location: http://localhost/controlerele.php");

      if ($_POST['situacao']=="Desativar")
      {
      fwrite($port, "0");
      }

    //header ("Location: http://localhost/controlerele.php");

fclose($port);

?>

<html>
    <head>
        <meta http-equiv="Content-Language" content="pt-br" />
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="http://www.binarycodec.blogspot.com" />
        <title>..::: CONTROLE DE RELE VIA INTERNET COM ARDUINO E PHP :::..</title>
    </head>
    <body>
        <body bgcolor="#D4D2D2">
        
        <h1>CONTROLE DE RELE VIA INTERNET COM ARDUINO E PHP</h1>

<table border="0" cellpadding="0" cellspacing="0" style="width: 12%;">
<tbody>
    <tr>
        <td>

<!-- ACIONAR RELE -->

<form method="POST" action="controlerele.php">

        <input type="hidden" value="Acionar" name="situacao">
        <input type="submit" value="Ligar" name="acionado" style="border-color:black; border-style: solid; border-width: 1; background-color: green; color: white">

</form>
        </td>    

    <td>

<!-- DESATIVA RELE -->

<form method="POST" action="controlerele.php">

        <input type="hidden" value="Desativar" name="situacao">
        <input type="submit" value="Desligar" name="desativado" style="border-color:black; border-style: solid; border-width: 1; background-color: red; color: white">
    
</form>
        </td>
    </tr>
</tbody>
</table>

        <p>OBS: Rodando em localhost.</p>
        <p><a href="http://www.binarycodec.blogspot.com" target="_blank">http://www.binarycodec.blogspot.com</a></p>
        <p>v.1.2</p>
    </body>
</html>


TESTES

Através do Serial Monitor (IDE Arduino), digite 1 para acionar o relé e 0 para desligar.

Abra seu navegador (o código foi testado no Firefox) e escreva localhost/controlerele.php. Deverá abrir uma página como mostra a Figura 2.

Figura 2 - Interface via navegador.
Ainda com o Serial Monitor aberto clique nos botões "Ligar" e "Desligar".

Note que tanto pelo Serial Monitor, quanto pelo navegador, mensagens surgem indicando a situação do relé.

Como último teste, feche o Serial Monitor e clique nos botões "Ligar" e "Desligar". Verifique se o relé se mantém na condição desejada.
 
PROBLEMA


Pode ocorrer, ao fechar o Serial Monitor, do relé oscilar e não permanecer ligado devido ao Auto-Reset. Para corrigir este problema pode-se utilizar um capacitor de 10μF entre o pino Reset e o Gnd do Arduino, Figura 3.

Figura 3 - Desabilitando o Auto-Reset.

Maiores informações podem ser obtidas na página "Arduino Playground -  Disabling Auto Reset On Serial Connection".

MATERIAIS/LINKS RELACIONADOS

WampServer - http://www.wampserver.com/en/

XAMPP - http://www.apachefriends.org/pt_br/xampp.html

Apache - http://www.apache.org/

PHP - http://php.net/

PKGS.ORG - http://pkgs.org/


35 comentários:

Thiago Ponder disse...

Sou iniciante no arduino+PHP e tenho encontrado uma pequena dificuldade para poder acionar o rele via PHP. Quando abro o Monitor Serial funciona bem, mas nao tenho o mesmo exito quando via PHP. Poderia fazer um tutorial de o que fazer com o comando PHP passo a passo. Tem um pessoal aqui comigo esperando sua ajuda.

Binary Codec disse...

Olá, Posso sim, mas me qual o erro que efetivamente está acontecendo? Ainda, qual o modelo do seu arduino?

Helcio santos disse...

Boa tarde

fiz tudo como escrito , mas quando abro no navegador aparece essa mensagem abaixo , e as tecla , quando aciono as mesma dá erro e não acontece nada no arduino , 1280

Poderia me ajudar??




Warning: fopen(/dev/ttyACM0): failed to open stream: No such file or directory in C:\xampp\htdocs\TESTE3.php on line 4

Notice: Undefined index: situacao in C:\xampp\htdocs\TESTE3.php on line 6

Notice: Undefined index: situacao in C:\xampp\htdocs\TESTE3.php on line 13

Warning: fclose() expects parameter 1 to be resource, boolean given in C:\xampp\htdocs\TESTE3.php on line 20
CONTROLE DE RELE VIA INTERNET COM ARDUINO E PHP



OBS: Rodando em localhost.

http://www.binarycodec.blogspot.com

v.1.2

?>

Binary Codec disse...

Olá Helcio, o erro ocorre devido ao caminho da porta serial utilizada.
/dev/ttyACM0 é o caminho no meu sistema (slackware linux). Notei que está usando Windows e será algo como COM4. Para ver abra a IDE do arduino, clique em tools e depois em serial port. Acredito que este procedimento resolverá o problema. Caso contrário estou a disposição.
Vou acrescentar isso no meu código.

fabiano andrade disse...

Olá a todos do blog,
para terminar meu projeto usando o arduino e programação PHP como o exemplo do Bruno, estou precisando fazer com que no arduino eu envie bits de retorno para o PHP e no PHP receba esses bits para que possa determina-los para qual pagina vai ser mandado, ex: enviando o bit 0001 ou 0010 etc… do arduino para o PHP o PHP identifica qual bit recebeu e executa a função determinada, pq fazendo assim irei consegui dizer qual led esta aceso ou apagado.

abraço.

Binary Codec disse...

Olá Fabiano, neste caso a melhor rota é atravez de classes em PHP.

Samuel disse...

Olá, gostei muito do site e do projeto, só que estou com problemas na hora de compilar no IDE, aparece as seguintes mensagens:

sketch_oct19a.cpp: In function 'void loop()':
sketch_oct19a:15: error: 'gt' was not declared in this scope
sketch_oct19a:15: error: expected `)' before ';' token
sketch_oct19a:15: error: expected `;' before ')' token

Aparentemente o problema parece ser nessas linhas:

void loop () {
if (Serial.available()>0)
{
digito = Serial.read();
}

Se puder me ajudar, agradeço!

Binary Codec disse...

Olá Samuel, já corrigi o problema.
Compilei aqui e está tudo ok.
Obrigado pelo aviso!
Abs.

Anônimo disse...

Ola, bom dia. Tbm sou iniciante e estou tentando usar seu código, arduino uno r3, consegui fazer que ele executasse na placa e consegui hospedar pagina e abril, mas não estou conseguindo fazer com q o clique do botão da pagina acenda a luz do arduino, ja fiz a substituição para com3.

Binary Codec disse...

Olá anônimo, vamos por partes...
Pelo que entendi ao digitar 1 ou 0 no serial monitor ele funcionou e vc alterou o caminho da porta no PHP, correto? Ainda, a página está abrindo sem apresentar erros.
Você tentou deixar o serial monitor aberto e na sequência clicar através da página? Tive um problema parecido devido ao auto-reset (meu arduino é o R2). Se o problema continuar me avise para tentarmos corrigir.

andrerds disse...

Olá a amigo ... primeiramente parabens .. muito bom...
Queria tirar um duvida fiz conforme esta no blog.. passo a passo .. porem no codigo php .. recebo o seguinte erro (
Notice: Undefined index: situacao in C:\xampp\htdocs\arduino\controlerele.php on line 7

Notice: Undefined index: situacao in C:\xampp\htdocs\arduino\controlerele.php on line 14

)

.. mais funciona consigo desligar e ligar.. normalmente.. o problema e que toda vez que atualizo da esse erro

Binary Codec disse...

Olá Andrerds,
Tente usar o código abaixo no lugar do php que estou usando:



Binary Codec disse...

?php
if(isset($_POST['situacao'])) {

$port = fopen("/dev/ttyACM0", "w");

if ($_POST['situacao']=="Acionar")
{
fwrite($port, "1");
}

//header ("Location: http://localhost/controlerele.php");

if ($_POST['situacao']=="Desativar")
{
fwrite($port, "0");
}

//header ("Location: http://localhost/controlerele.php");

fclose($port);


}
?

Heyron Cn. disse...

Muito bom!!!

Eu estou seguindo outro tutorial para fazer um localizador para o meu carro e gostaria de colocar esse seu modulo relé para ele acionar a buzina ou cortar a energia da bomba de combustivel, poderia adaptador o codigo para mim acrescentando esse seu esquema, pois eu vou fazer com sms. Me manda um email "heyron.cn@live.com"

Heyron Cn. disse...

Muito bom!!!

Eu estou montando um localizador gps ativado por sms, gostaria de acrescentar o seu esquema no que estou fazendo porem ativando ele com sms, pode me ajudar acrescentando o código? me envia um email para heyron.cn@live.com, preciso muito de ajuda. Obrigado!

Anônimo disse...

Ola Meu nome ~e Mario e sou iniciante.
Cara liguei o serv de php, en fim tudo funcionando como deve. só tem 1 problema...
para funcionar a pagina php depois de um reset no arduino, tenho que abrir o serial monitor, e fechalo.
dai en diante funciona a php. ligando e desligando.
percebo que quando ligo serial monitor, ele começa a fazer leitura... antes disso noto que o arduino recebe o sinal mas não responde, pois vejo o led interno oscilar quando mando comando. mas não faz nada. tenho que ligar o serial monitor para que ele responda. meu email é kin.mario@yahoo.com.br
nossa fico muito grato pela explicação aki contida... deu certinho. des de já muito obrigado.

Binary Codec disse...

Olá Mario, ao que tudo indica deve ser o auto-reset do seu arduino. Boa sorte e obrigado pela visita.

Sidalto Pereira disse...

Gostei do seu tutorial, no entanto no meu caso não queria utilizar essa estrutura: cliente -> internet -> servidor -> arduino
Pois nesse modelo entre o servidor e o arduino você utilizou a serial, eu estou a procura de algo que funcione na minha estrutura, mas sem comunicação serial:
cliente -> internet -> arduino. Onde a requisição do cliente passa por um roteador local (TPLink) e redireciona para a porta do arduino, nada de serial. Se você puder me ajudar agradeço.

Sidalto Pereira disse...

Gostei do seu tutorial, no entanto no meu caso não queria utilizar essa estrutura: cliente -> internet -> servidor -> arduino
Pois nesse modelo entre o servidor e o arduino você utilizou a serial, eu estou a procura de algo que funcione na minha estrutura, mas sem comunicação serial:
cliente -> internet -> arduino. Onde a requisição do cliente passa por um roteador local (TPLink) e redireciona para a porta do arduino, nada de serial. Se você puder me ajudar agradeço.

Binary Codec disse...

Olá Sidalto,
Se entendi seu problema, vc deve utilizar ethershield (ou equivalente wi-fi). No caso do ethershield não recomendo os que utilizam o ENC28J60.

Binary Codec disse...

Olá Sidalto,
Se entendi seu problema, vc deve utilizar ethershield (ou equivalente wi-fi). No caso do ethershield não recomendo os que utilizam o ENC28J60.

Sidalto Pereira disse...

Pois é, já tenho o ethernet shield (W5100) , estava querendo mesmo era pensar como fazer para enviar uma requisição de servidor web na nuvem para o arduino e depois fazer ele responder ao server na web.

Binary Codec disse...

Olá Sidalto, não cheguei a fazer este tipo de aplicação, mas sei que há possibilidade de enviar comandos do twitter para o arduino e, por exemplo, acender uma lâmpada. Então acho que este pode ser um ponto de partida para seu projeto.

Sidalto Pereira disse...

Ok, vou dar mais uma pesquisa. Obrigado

Anônimo disse...

estou tendo problema que quando reinicio a maquina tenho recompilar o arduino e abri serial monitor para a pagina php voltar a funcionar
alguem ja vio o problema

Tiko disse...

quando reinicio o computardor tenho q recompilar o Arduino e abrir o serial monitor, para q a paginha php volte a funcionar alguem ja teve este problema

Binary Codec disse...

Anonimo/Tiko, parece que o problema está relacionado ao caminho/porta que está sendo utilizado e auto-reset. Se estiver no linux e dependendo da distribuição, é normal ter que habillitar a interface novamente. Mas não há necessidade de ficar recompilando. Quanto ao serial monitor, normalmente a necessidade de deixa-lo aberto está relacionado ao auto-reset do seu arduino.

Anônimo disse...

tiko
ok deu certo Obrigado

como colocaria no site uma indicação de quanto a lampada esta liga e desliga, quando fecho o site e depois ao abrir saber saber se esta liga ou desligado

Binary Codec disse...

tiko

Para ter está indicação você deve utilizar classes em PHP.

Anônimo disse...

Amigo, não conheço bem do arduíno, mas no código que postou parece-me um erro no código, isto explica o porque que ele ficar armando e desligando o tempo todo como comentou, eu modifiquei o código, experimente usar este abaixo, removendo a linha que setá o dígito como 0 ao final:

int Rele = 13; /** rele no pino 13 */
int digito = 0; /** guarda retorno da porta serial */

/** setup*/
void setup () {
Serial.begin(9600);
pinMode(Rele, OUTPUT);
}

void loop () {/** loop */
if (Serial.available()>0){
digito = Serial.read();
}

if (digito == '1'){
/** Acionar rele "1" */
digitalWrite(Rele, HIGH);
Serial.println("ligado");
}else if (digito == '0'){
/** Desligar rele "0" */
digitalWrite(Rele, LOW);
Serial.println("desligado");
}

/** a linha abaixo desligará o relê a cada fim de loop, remova esta linha! */
/** digito = 0; */

}/** loop */

Binary Codec disse...

Olá Anonimo,
Irei testar seu código assim que possível.
Obrigado pelas observações.

Anônimo disse...

tem como eu fazer a conexão do arduino ao mysql,ultilizando o php?

Binary Codec disse...

Olá anônimo, acho que tem sim, mas nunca fiz e não sei te dizer qual o procedimento.

Unknown disse...

Isso roda em localhost. Eu preciso que rode no meu site que esta online. Como faço isso? Precisa mudar algo no codigo???

Binary Codec disse...

@Unknown
Sim, precisa mudar o código. Do lado arduino vai depender se será via cabo ethernet ou wifi. Além de configurá-lo como server e um IP fixo (ou um serviço do tipo no-ip). Do lado web, apenas o link para acesso à página.