Nível de complexidade: Mediano. Necessário prévio conhecimento sobre Arduino, redes de computadores e programação em PHP.
Uma funcionalidade muito interessante para o Arduino é a conexão com a rede local ou com a Internet. Isso pode ser realizado de forma relativamente simples com a ajuda do Ethernet Shield oficial, com o chip W5100 e sua respectiva biblioteca "ethernet" presente no Arduino 1.5.4.
No entanto, esta não é a única forma. Neste exemplo vou utilizar o Arduino UNO e um adaptador ethernet ENC28J60 que custa 1/3 do valor da Ethernet Shield oficial, em um exemplo que transmite os dados de um sensor qualquer para um site em PHP na internet ,no meu caso ivair.orgfree.com
Conexões:
A comunicação entre o Arduino e o ENC28J60 utiliza o protocolo SPI e os pinos devem ser conectados da seguinte forma:ARDUINO | ENC28J60 |
GND
|
GND
|
3.3V
|
VCC
|
Pino 2
|
INT
|
Pino 10
|
CS
|
Pino 11
|
SI
|
Pino 12
|
SO
|
Pino 13
|
SCK
|
Um sensor deve ser conectado a entrada A0 do arduino UNO, caso utilize um potenciômetro conecte o terminal central a porta A0 e os terminais laterais um ao positivo e o outro ao negativo.
Código Arduino UNO:
No início do código é definido um MAC para o adaptador ENC28J60, bem como são declaradas as demais variáveis utilizadas pelo programa. Neste exemplo o site PHP "ivair.orgfree.com" receberá e apresentará os dados enviados pelo arduino. O código do site está também logo abaixo.
Função Setup():
O ENC28J60 deve estar conectado a um roteador com DHCP ativado para que possa ser configurado automaticamente (ether.dhcpSetup()) o número IP, a máscara, o gateway e o servidor DNS.
Imediatamente após a gravação abra o monitor serial e será possível observar os resultados da configuração, ou mensagens de erros, caso algo esteja errado. Se tudo correr bem o site responde com um "OK" para cada valor recebido e armazenado na base de dados.
A função Loop():
Esta função envia por GET o valor do sensor conectado a entrada analógica A0. Por exemplo: caso o valor obtido do sensor seja 356, é gerada a seguinte string: "http://ivair.orgfree.com/inserir.php?val=356" que é enviada pela função: ether.browseUrl().
Isso pode ser testado digitando-se essa string diretamente no navegador. Após o recebimento, o site em PHP responde com a sequência de texto padrão do protocolo e a palavra "OK", que é tratado pela função my_callback() e apresentado no monitor serial. Para visualizar a mensagem de retorno completa retire o comentário da segunda linha e comente a terceira.
A biblioteca utilizada é a EtherCard desenvolvida por Jean Claude Wippler. Após descompactá-la na pasta libraries, crie um novo sketch com o código a seguir.
#include <EtherCard.h>
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
byte Ethernet::buffer[700];
static uint32_t timer;
char website[] PROGMEM = "ivair.orgfree.com";
char temp_sensor[150];
int an0 = A0;
int sensor = 0;
static void my_callback (byte status, word off, word len)
{
Ethernet::buffer[off+len] = 0; //mensagem do retorno do servidor
//Serial.print((const char*) Ethernet::buffer + off); //mostra todo o retorno
Serial.print((const char*) Ethernet::buffer + off + 157); //mostra somente ok
}
void setup ()
{
delay(1000);
Serial.begin(57600);
Serial.println("Obtendo IP:");
if (ether.begin(sizeof Ethernet::buffer, mymac,10) == 0)
Serial.println( "Falha ao acessar o controlador Ethernet");
if (!ether.dhcpSetup())
Serial.println( "Falha ao obter o IP");
ether.printIp("IP: ", ether.myip);
ether.printIp("Mascara: ", ether.mymask);
ether.printIp("Gatway: ", ether.gwip);
ether.printIp("Sevidor DNS: ", ether.dnsip);
if (!ether.dnsLookup(website)) //IP do servidor por DNS
Serial.println("Falha no DNS");
//ether.parseIp(ether.hisip, "144.76.99.221"); //IP do servidor manual
ether.printIp("Servidor: ", ether.hisip);
Serial.println(" ");
}
void loop ()
{
ether.packetLoop(ether.packetReceive());
if (millis() > timer)
{
timer = millis() + 5000;
ether.persistTcpConnection(true);
sensor = analogRead(an0);
sprintf(temp_sensor, "?val=%d", sensor);
ether.browseUrl(PSTR("/inserir.php"), temp_sensor, website, my_callback);
}
}
Função Setup():
O ENC28J60 deve estar conectado a um roteador com DHCP ativado para que possa ser configurado automaticamente (ether.dhcpSetup()) o número IP, a máscara, o gateway e o servidor DNS.
Imediatamente após a gravação abra o monitor serial e será possível observar os resultados da configuração, ou mensagens de erros, caso algo esteja errado. Se tudo correr bem o site responde com um "OK" para cada valor recebido e armazenado na base de dados.
A função Loop():
Esta função envia por GET o valor do sensor conectado a entrada analógica A0. Por exemplo: caso o valor obtido do sensor seja 356, é gerada a seguinte string: "http://ivair.orgfree.com/inserir.php?val=356" que é enviada pela função: ether.browseUrl().
Isso pode ser testado digitando-se essa string diretamente no navegador. Após o recebimento, o site em PHP responde com a sequência de texto padrão do protocolo e a palavra "OK", que é tratado pela função my_callback() e apresentado no monitor serial. Para visualizar a mensagem de retorno completa retire o comentário da segunda linha e comente a terceira.
A biblioteca utilizada é a EtherCard desenvolvida por Jean Claude Wippler. Após descompactá-la na pasta libraries, crie um novo sketch com o código a seguir.
#include <EtherCard.h>
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
byte Ethernet::buffer[700];
static uint32_t timer;
char website[] PROGMEM = "ivair.orgfree.com";
char temp_sensor[150];
int an0 = A0;
int sensor = 0;
static void my_callback (byte status, word off, word len)
{
Ethernet::buffer[off+len] = 0; //mensagem do retorno do servidor
//Serial.print((const char*) Ethernet::buffer + off); //mostra todo o retorno
Serial.print((const char*) Ethernet::buffer + off + 157); //mostra somente ok
}
void setup ()
{
delay(1000);
Serial.begin(57600);
Serial.println("Obtendo IP:");
if (ether.begin(sizeof Ethernet::buffer, mymac,10) == 0)
Serial.println( "Falha ao acessar o controlador Ethernet");
if (!ether.dhcpSetup())
Serial.println( "Falha ao obter o IP");
ether.printIp("IP: ", ether.myip);
ether.printIp("Mascara: ", ether.mymask);
ether.printIp("Gatway: ", ether.gwip);
ether.printIp("Sevidor DNS: ", ether.dnsip);
if (!ether.dnsLookup(website)) //IP do servidor por DNS
Serial.println("Falha no DNS");
//ether.parseIp(ether.hisip, "144.76.99.221"); //IP do servidor manual
ether.printIp("Servidor: ", ether.hisip);
Serial.println(" ");
}
void loop ()
{
ether.packetLoop(ether.packetReceive());
if (millis() > timer)
{
timer = millis() + 5000;
ether.persistTcpConnection(true);
sensor = analogRead(an0);
sprintf(temp_sensor, "?val=%d", sensor);
ether.browseUrl(PSTR("/inserir.php"), temp_sensor, website, my_callback);
}
}
Código do site PHP:
O site obrigatoriamente deve estar na Internet, não consegui fazê-lo rodar em um servidor local.
No provedor PHP crie uma base de dados no seguinte formato:
No provedor PHP crie uma base de dados no seguinte formato:
Tabela: leituras
Campos: cod(int auto incremento, chave primária), valor(int) e data (datahora).
O sistema todo é extremamente simples e constituído por três páginas:
index.php - Gera e apresenta uma tabela com os dados armazenados na base.
apagar.php - Limpa a base de dados.
inserir.php - Insere o valor recebido por GET na base de dados
Observe que todas fazem a conexão com os seguintes dados: ("localhost","login","senha","base_de dados"), O primeiro item é o nome do servidor e é definido pelo provedor da página, no meu caso o provedor indicou que utilizasse a palavra "localhost", em outros o nome pode mudar.
O segundo e terceiro itens são o login e a senha escolhidos no momento do cadastro da conta.
O quarto item é o nome da base de dados, que muitas vezes é o próprio login. Faça uma busca no google por "free php host" que você achará alguns gratuítos
Página index.php
<html>
<head>
<meta http-equiv="refresh" content="10">
<title>Arduino</title>
</head>
<body bgcolor="Lightsteelblue">
<table align="center" border="0" width="20%">
<tr><td align="center">
<form method="POST" action="apagar.php">
<input type="submit" value="Apagar">
</form>
</td></tr>
</table>
<table align="center" border="1" width="20%">
<tr><th>Sensor</th><th>Data - Hora</th></tr>
<?php
$con = mysqli_connect("localhost","login","senha","base_de dados") or die("Falha na conexao com o MySQL");
$res = mysqli_query($con,"SELECT * FROM leituras") or die ("Nao foi possivel realizar a consulta");
while($linha = mysqli_fetch_array($res))
{
echo "<tr><td align='center'>".$linha['valor']."</td>";
echo "<td align='center'>".$linha['data']."</td></tr>";
}
mysqli_close($con);
?>
</table>
</body>
</html>
Página apagar.php
<?php
$con = mysqli_connect("localhost","login","senha","base_de dados") or die("Falha na conexao com o MySQL");
mysqli_query($con,"DELETE FROM leituras WHERE cod") or die ("Falha ao apagar os dados");
mysqli_close($con);
header("Location:index.php");
exit(0);
?>
Página inserir.php
<?php
date_default_timezone_set('America/Sao_Paulo');
if (!empty($_GET['val']))
{
$valor = $_GET['val'];
$data = date("d/m/Y H:i:s");
$con = mysqli_connect("localhost","login","senha","base_de dados") or die("Falha na conexao com o MySQL");
mysqli_query($con,"INSERT INTO leituras VALUES ('','$valor','$data')") or die ("Falha ao inserir os dados");
mysqli_close($con);
echo "ok "; //resposta em caso de sucesso
}
else
echo "falha"; //resposta em caso de falha
?>
Boa sorte.
Ivair.
Boa sorte.
Ivair.
ola amigo, estou com dificuldade jogar esses codigos php no orgfree esta dando erro , não tem como vc me enviar por e mail o arquivo dai só inserir com fizella, no orgfree, obrigado
ResponderExcluirEdiy
Ediyfs@gmail.com
Olá Ediy,
ResponderExcluirO código acima é o mesmo que está no orgfree, a diferença é que você tem que atualizar a rotina mysqli_connect("localhost","login","senha","base_de dados"), com seus dados, no meu caso ficou assim:
mysqli_connect("localhost","600962","MINHA_SENHA","600962")
O localhost continua, mas login, base de dados e senha vai depender da sua conta, se você colocar meus arquivos com certeza não funcionarão.
Oi amigo... Gostaria de uma ajuda sua... Reproduzi aqui tudo que vc descreveu acima, só que não consigo obter exito pois o meu projeto não envia os dados para o bd, quando executo o serial monitor não mostra o OK, e sim caracteres expeciais estilo isso (¬°gònP HGÒñ¬pb éZ)... Se puderes me ajudar agradeço...
ResponderExcluirOlá kgpnegro, agora estou usando a biblioteca UIPEthernet que fica mais fácil que a do posto. É uma versão da biblioteca padrão da placa W5100 adaptara para funcionar com a ENC28J60. Intale o pacote USBWebserver, crie o servidos na sua máquina e use este código.
ResponderExcluir#include
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,0,20); //ip estático
IPAddress servDns(201,76,16,58); //ip estático
IPAddress gateway(192,168,0,1); //ip estático
IPAddress subnet(255,255,255,0); //ip estático
IPAddress server(192,168,0,201);
//IPAddress server(144,76,99,221); //sem DNS ivair.orgfree.com
//char server[] = "ivair.orgfree.com"; //com DNS
static uint32_t timer;
EthernetClient client;
void setup()
{
Serial.begin(9600);
Serial.println("Conectando a rede...");
//if(!Ethernet.begin(mac)) //ip dinâmico
// Serial.println("Falha ao conectar a rede"); //ip dinâmico
Ethernet.begin(mac, ip, servDns, gateway, subnet); //ip estático
Serial.println(Ethernet.localIP()); //ip estático
}
void loop()
{
int charRX;
int dados[9];
int cont = 9;
if (millis() > timer)
{
timer = millis() + 5000;
if(client.connect(server,80))
{
client.println("GET /res.php HTTP/1.1");
client.println("Host: 192.168.0.16");
client.println("Connection: close\r\n");
}
else
Serial.println("Falha na conexão");
while(client.connected())
{
while(client.available())
{
charRX = client.read();
Serial.write(charRX);
if(charRX == '*')
cont=0;
if(cont<9)
{
dados[cont] = charRX;
cont++;
}
}
}
Serial.println("\r\nDados Recebidos");
for(int i=0; i<9;i++)
Serial.write(dados[i]);
client.stop();
Serial.println("\r\n");
}
}
Bom dia amigo, tudo bem ?
ResponderExcluirPrimeiramente parabéns pelo post, show de bola mesmo!
Estou querendo fazer um projeto que precisa se comunicar com o banco de dados através do arduino e php... pelo seu post parece que me atenderia.
Estou usando o WAMP para emular um servidor, minha ideia seria fazer meu not conectado no reteador ser o servidor e usar o arduino para se comunicar com ele, por enquanto pode ser só rede local mesmo, não estou preocupado ainda com fazer acesso de fora. Porém estou com algumas dúvidas, espero que possa me ajudar!
Minha dúvida....
Nessa parte:
IPAddress ip(192,168,0,150); //ip estático
IPAddress servDns(201,76,16,58); //ip estático
IPAddress gateway(192,168,0,1); //ip estático
IPAddress subnet(255,255,255,0); //ip estático
IPAddress server(192,168,0,201);
Ip: seria um ip que eu defino para a placa de ethernet no meu caso no roteador está (192.168.0.ESCOLHO1. correto ?
ServDns: oque seria ?
Gateway: seria o gatway que esta no roteador. correto ?
subnet: oque seria ?
server: seria o ip da maquina que contem o servidor WAMP rodando. correto ?
Mano ta funcionando tudo certinho... mas com conexão a internet, pq eu mudo as configurações de ip daí mudo o IP lá nas "propriedades de ethernet -> Protocolo IPv4 e tals", pq n uso dhcp, só que quando eu tiro o cabo de rede que dá acesso a internet do switch não funciona mais =/
ResponderExcluirOlá, parabéns pelo projeto. Pode me passar seu email? Estou precisando tirar umas duvidas referente ao projeto q estou desrnvolvendo. Se puder me ajudar, ficarei grato.
ResponderExcluirOlá.. quando tento compilar, da erro na IDE>.
ResponderExcluirwebClient.cpp:6:23: error: EtherCard.h: No such file or directory
webClient:10: error: 'Ethernet' has not been declared
Sabe o que pode ser:?
Obrigado, consegui fazer ;)
ResponderExcluir