Em alguns projetos, especialmente na domótica, é interessante poder controlar uma placa Arduino pela Internet. Isso é possível com um shield Ethernet.
O shield usado neste tutorial é o VMA04, da Velleman. Você também pode utilizar outro shield, com configuração, pinos e biblioteca diferentes.
Atenção: o Shield VMA04 também existe na versão em kit para soldar KA04. Verifique qual versão deseja comprar.
Pré-requisitos: Conhecimento de HTML/CSS
Material
- Computador
- Arduino UNO
- Cabo USB para ligar o Arduino ao computador
- Cabo Ethernet
- Shield Ethernet VMA04
Obs: Escrever uma página web pode tomar muito espaço de memória para uma placa Arduino. Nós usamos o Ethernet Shield VMA04 e uma placa Arduino UNO, mas se achar que a sua página tomará muita memória, opte por um shield W5100.
Visão geral do Ethernet Shield VMA04
O Ethernet Shield VMA04 utiliza o Microchip ENC28J60. Ele usa:
- os pinos 10 e 2 numa placa Arduino UNO.
- para o conector ICSP: pinos 11, 12 e 13 numa placa Arduino UNO.
As ligações no caso de um shield são pré-definidas. Verifique a documentação técnica do componente para saber como utilizá-lo (VMA04 datasheet).
Configuração de rede
Para acessar a placa Arduino sem precisar conectá-la ao roteador de Internet, é necessário criar uma ponte entre a conexão WiFi e a conexão Ethernet no seu computador. Para isso, é preciso:
- Conectar o shield VMA04 ao Arduino
- Conectar o shield Ethernet ao computador (RJ45).
- Abrir a Central de Rede e Compartilhamento.
- Ir para “Alterar configurações da placa”.
- Selecionar Ethernet(Arduino) e Wifi /(Internet source) e clicar com o botão direito do mouse.
- Clicar em “Criar ponte”.
Exemplo de código para o Ethernet Shield VMA04
Para interagir com o Ethernet Shield VMA04, utilizamos a biblioteca UIPEthernet.h
- Ethernet.begin() para iniciar uma conexão de rede.
- server.begin() para inicializar um servidor.
- EthernetClient client = server.available() para inicializar um cliente.
- client.read() para ler dados do cliente.
- client.print() para enviar dados para o cliente.
UIPEthernet.h
// Enter ip address http://192.168.1.179:80 in your browser // Based on WMA04 ethernet shield #include <UIPEthernet.h> //Ethernet byte mac[]={0x54, 0x34, 0x41, 0x30, 0x30, 0x31}; IPAddress ip(192, 168, 1, 179); EthernetServer server(80); void setup() { Serial.begin(57600); // start the Ethernet connection and the server: Ethernet.begin(mac, ip); server.begin(); Serial.print("IP Address: "); Serial.println(Ethernet.localIP()); } void loop() { // listen for incoming clients EthernetClient client = server.available(); if (client){ Serial.println("-> New Connection"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()){ if (client.available()){ char c = client.read(); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply if (c == '\n' && currentLineIsBlank){ client.println("<html><title>Hello World!</title><body><h3>Hello World!</h3></body>"); break; } if (c == '\n'){ // you're starting a new line currentLineIsBlank = true; } else if (c != '\r'){ // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(10); // close the connection: client.stop(); Serial.println("Disconnected\n"); } }
Ao digitar o endereço https://192.168.1.179, uma página com as palavras “Hello Word! ” irá aparecer.
Código para visualizar os dados provenientes da placa Arduino
Vamos criar uma função generatePage() para escrever a página HTML. Ela tomará como entrada o cliente que abre e fecha durante o loop infinito loop().
void generatePage(EthernetClient client){ if(x==0){ //output HTML data header client.println(F("HTTP/1.1 200 OK")); client.println(F("Content-Type: text/html")); client.println(); }else{ //header client.print(F("<html><head><title>Arduino</title>")); //meta-refresh page every x seconds client.print(F("<meta http-equiv='refresh' content='1'>")); client.print(F("</head><body bgcolor='black'><br>")); client.print(F("<h1 style='color:green;'>Arduino data</h1>")); client.println("<p style='color:white;'>"); client.print(F("<br><br>Arduino analog input data :<br>")); client.print(F("<br>Page refresh number: ")); client.print(x); //current refresh count client.print("<br><br>"); //output analog input pin for(int i=0;i<6;i++){ client.print("<b>Input A"); client.print(i); client.print(" : </b>"); client.print(analogRead(14+i)); //A0=14, A1=15 ,etc. client.print("<br>"); } client.println("</p>"); client.println(F("<br></body></html>")); } x=x+1; }
O truque na função generatePage é adicionar uma meta tag para que a página recarregue automaticamente [meta http-equiv=”refresh” content=”1″]
Este é o código completo:
// Enter ip address http://192.168.1.179:80 in your browser // Based on WMA04 ethernet shield #include <UIPEthernet.h> //Ethernet byte mac[]={0x54, 0x34, 0x41, 0x30, 0x30, 0x31}; IPAddress ip(192, 168, 1, 179); EthernetServer server(80); //server port //Page unsigned long int x=0; //set refresh counter to 0 String readString; ////////////////////// void setup(){ Serial.begin(9600); Ethernet.begin(mac, ip); server.begin(); Serial.println("System initialized"); Serial.print("IP Address: "); Serial.println(Ethernet.localIP()); } void loop(){ EthernetClient client = server.available(); if (client) { while (client.connected()) { if (client.available()) { char c = client.read(); if (readString.length() < 100) { readString += c; } //check if HTTP request has ended if (c == '\n') { //check get atring received Serial.println(readString); generatePage(client); delay(1); //stopping client client.stop(); //clearing string for next read readString=""; } } } } } void generatePage(EthernetClient client){ if(x==0){ //output HTML data header client.println(F("HTTP/1.1 200 OK")); client.println(F("Content-Type: text/html")); client.println(); }else{ //header client.print(F("<html><head><title>Arduino</title>")); //meta-refresh page every x seconds client.print(F("<meta http-equiv='refresh' content='1'>")); client.print(F("</head><body bgcolor='black'><br>")); client.print(F("<h1 style='color:green;'>Arduino data</h1>")); client.println("<p style='color:white;'>"); client.print(F("<br><br>Arduino analog input data :<br>")); client.print(F("<br>Page refresh number: ")); client.print(x); //current refresh count client.print("<br><br>"); //output analog input pin for(int i=0;i<6;i++){ client.print("<b>Input A"); client.print(i); client.print(" : </b>"); client.print(analogRead(14+i)); //A0=14, A1=15 ,etc. client.print("<br>"); } client.println("</p>"); client.println(F("<br></body></html>")); } x=x+1; }
Ao digitar o endereço IP do seu Arduino, será exibida uma página com os valores de entrada analógicos atualizados automaticamente.
Código para enviar dados da página web para o Arduino
Veremos agora como controlar as saídas do Arduino a partir da página web. Isso pode ser muito prático para ativar relés para acender luzes, por exemplo.
A ideia aqui é criar botões para cada saída e enviar um comando string (“/?On+pin number”) para o Arduino.
client.print(F("<input type=button value=ON onmousedown=location.href='/?On4;'>"));
client.print(F("<input type=button value=OFF onmousedown=location.href='/?Off4;'>"));
Estes comandos são depois recuperados pelo Arduino na variável readString. Notamos bem a quantidade de pinos e o comando On/Off associado.
if (readString.indexOf("4") > 0) { if (readString.indexOf("?On") > 0) { digitalWrite(4, HIGH); Serial.println("LED 4 On"); } if (readString.indexOf("?Off") > 0) { digitalWrite(4, LOW); Serial.println("LED 4 Off"); } }
Este é o código completo com as três saídas digitais disponíveis:
// Enter ip address http://192.168.1.179:80 in your browser // Based on WMA04 ethernet shield #include <UIPEthernet.h> //Ethernet byte mac[] = {0x54, 0x34, 0x41, 0x30, 0x30, 0x31}; IPAddress ip(192, 168, 1, 179); EthernetServer server(80); //server port //Page unsigned long int x = 0; //set refresh counter to 0 String readString; // int digPin[3] = {4, 7, 8}; int anaPin[4] = {3, 5, 6, 9}; ////////////////////// void setup() { Serial.begin(9600); Ethernet.begin(mac, ip); server.begin(); Serial.println("System initialized"); Serial.print("IP Address: "); Serial.println(Ethernet.localIP()); } void loop() { EthernetClient client = server.available(); if (client) { while (client.connected()) { if (client.available()) { char c = client.read(); if (readString.length() < 100) { readString += c; } //check if HTTP request has ended if (c == '\n') { //check get atring received Serial.println(readString); processCommand(); generatePage(client); delay(1); //stopping client client.stop(); //clearing string for next read readString = ""; } } } } } void processCommand() { if (readString.indexOf("4") > 0) { if (readString.indexOf("?On") > 0) { digitalWrite(4, HIGH); Serial.println("LED 4 On"); } if (readString.indexOf("?Off") > 0) { digitalWrite(4, LOW); Serial.println("LED 4 Off"); } } if (readString.indexOf("7") > 0) { if (readString.indexOf("?On") > 0) { digitalWrite(7, HIGH); Serial.println("LED 7 On"); } if (readString.indexOf("?Off") > 0) { digitalWrite(7, LOW); Serial.println("LED 7 Off"); } } if (readString.indexOf("8") > 0) { if (readString.indexOf("?On") > 0) { digitalWrite(8, HIGH); Serial.println("LED 8 On"); } if (readString.indexOf("?Off") > 0) { digitalWrite(8, LOW); Serial.println("LED 8 Off"); } } } void generatePage(EthernetClient client) { if (x == 0) { //output HTML data header client.println(F("HTTP/1.1 200 OK")); client.println(F("Content-Type: text/html")); client.println(); } else { //header client.print(F("<html><head><title>Arduino</title>")); //meta-refresh page every x seconds client.print(F("<meta http-equiv='refresh' content='2'>")); client.print(F("</head><body bgcolor='black'><br>")); client.print(F("<h1 style='color:green;'>Arduino Inputs</h1>")); client.println("<p style='color:white;'>"); client.print(F("<br><br>Arduino analog input data :<br>")); client.print(F("<br>Page refresh number: ")); client.print(x); //current refresh count client.print("<br><br>"); //output analog input pin for (int i = 0; i < 6; i++) { client.print("<b>Input A"); client.print(i); client.print(" : </b>"); client.print(analogRead(14 + i)); //A0=14, A1=15 ,etc. client.print(F("<br>")); } client.print(F("</p><br>")); client.print(F("<h1 style='color:green;'>Arduino Outputs</h1>")); client.print(F("<p style='color:white;'>")); //digital output client.print(F("<br><br>Arduino digital outputs :<br><br>")); for (int j = 0; j < 3; j++) { client.print(F("<b>Digital output ")); client.print(digPin[j]); client.print(" : </b>"); client.print(F("<input type=button value=ON onmousedown=location.href='/?On4;'>")); client.print(F("<input type=button value=ON onmousedown=location.href='/?On")); client.print(digPin[j]); client.print(F(";'>")); client.print(F("<input type=button value=OFF onmousedown=location.href='/?Off")); client.print(digPin[j]); client.print(F(";'>")); client.print(F("<br>")); } client.print(F("</p><br>")); //file end client.print(F("<br></body></html>")); } x = x + 1; }
Teste e combine estes exemplos para obter as funcionalidades que deseja. Se tiver algum problema para usar o seu shield Ethernet com o microcontrolador Arduino, sinta-se à vontade para nos deixar um comentário ou mandar uma mensagem.
Aplicação
- Controlar o seu projeto Arduino via Internet
Referências
- Um bom tutorial sobre o assunto em inglês
- Velleman VM04 Shield
- Tutoriais HTML W3School
- Tutoriais HTML Mozilla
Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie