BASIC ARDUINO WEB SERVER



Esta eh uma copia da pagina
https://pimylifeup.com/arduino-web-server/
Gus AvatarporGus


Este tutorial explica as etapas para criar seu próprio servidor web Arduino.

Servidor Web Arduino

Configurar um servidor web no Arduino é um processo simples que abrange o processo de instalação e execução. Também abordarei alguns conceitos básicos, como usar Ajax para atualizar, em vez de atualizar a página repetidamente.

Você precisará conhecer HTML básico, cujos conceitos são incrivelmente fáceis de entender. Se você nunca estudou HTML, recomendo que visite o w3schools para uma introdução básica .

Este servidor não será capaz de fazer nada muito sofisticado, mas é incrivelmente útil para quem deseja exibir dados de dispositivos conectados aos pinos ou interagir com um circuito de uma página web. O servidor web Raspberry Pi, mais potente, pode lhe interessar se este não for o seu caso.


Todos os exemplos de código podem ser encontrados no meu GitHub e podem ser facilmente baixados (eles também são comentados). Se você notar algum erro, por favor, me avise na seção de comentários no final desta página.


Equipamento

O equipamento que você precisará para este tutorial do servidor web Arduino está listado abaixo.

Recomendado


** O cartão SD precisará ser formatado em FAT16 ou FAT32 .

Noções básicas de código

Se você é novo em codificação ou está interessado em alguns dos conceitos básicos explicados, continue lendo; caso contrário, você pode pular esta seção e ir para a seção sobre como configurar o servidor web com ou sem um cartão SD.

Inicialização

Para começar, primeiro você precisa inicializar o servidor web definindo algumas variáveis ​​e então chamando uma função.

Primeiro, você precisa definir um endereço MAC. O abaixo deve ser suficiente na maioria das redes domésticas. Se você sabe exatamente o que procura, não hesite em alterá-lo.


********************************************************************

IPAddress ip(192, 168, 1, 177);


Em terceiro lugar, você precisará definir o número da porta na qual deseja que o servidor escute. Por padrão, o HTTP simples é executado na porta 80. Se você alterar isso, precisará definir a porta ao acessar a página web no seu navegador. Por exemplo, se a sua porta for 14213 , o endereço ficará assim:192.168.1.177:14213


EthernetServer server(80);

Por fim, na função de configuração, você precisará inicializar o dispositivo Ethernet. Uma vez inicializado, basta fazer uma chamada para server.begin(). Feito isso, você poderá ouvir as conexões e responder com dados quando apropriado.

Ethernet.begin(mac, ip); server.begin();

Detectando uma nova conexão

Na função de loop, precisamos verificar se há uma nova conexão sempre que ela for executada. Se uma nova conexão for detectada, inserimos o código lógico da nossa página web.

O código a seguir detectará quando um novo cliente estiver tentando se conectar ao servidor.

EthernetClient client = server.available(); if (client) { while (client.connected()) { if (client.available()) {


Depois de determinar que há um cliente disponível, passamos a gerar a saída HTML do servidor web Arduino.

Retornando o cabeçalho de resposta HTML

Para que um navegador exiba a página corretamente, primeiro precisamos responder com um cabeçalho HTML. Não precisa ser nada complicado; o exemplo abaixo é mais do que suficiente para que tudo funcione corretamente.

Se você estiver procurando mais informações sobre os campos de cabeçalho, esta página wiki incrivelmente útil explica tudo muito bem.


client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println();

Saída de HTML

A saída de HTML pode ser feita simplesmente chamando client.println()ou client.print()passando o texto/HTML como parâmetro. Isso é simples, mas, como você pode ver nos exemplos mais abaixo nesta página, realmente sobrecarrega o código.

Abaixo está um exemplo básico de saída de HTML.

client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.print("<h1>Analogue Values</h1>");


A outra opção é armazenar os arquivos HTML em um cartão SD, que você pode acessar e carregar. Você pode então executar solicitações AJAX para atualizar elementos na página web para que eles exibam os dados corretos.

Você também pode fazer isso para que o Arduino execute ações como ligar e desligar um LED.


Fechando a conexão

Após concluir o processamento da página web, aguarde um breve período para garantir que o cliente receba os dados. Após cerca de um segundo, basta encerrar a conexão com o cliente.


delay(1); client.stop();


Servidor Web Arduino sem cartão SD

Se você não estiver usando o cartão SD, será muito simples colocar um servidor web em funcionamento.

É importante observar que, se você tiver um cartão SD inserido, mas ele não estiver em uso, isso pode causar problemas na comunicação do sketch com o Arduino. Para evitar que isso aconteça, adicione as duas linhas a seguir na função de configuração.


pinMode(4, OUTPUT); digitalWrite(4, HIGH);

Depois de adicioná-los, você pode adicionar o cartão SD novamente ao dispositivo.

Para colocar um servidor web Arduino em funcionamento rapidamente, basta abrir o Sketch, copiar e colar o código abaixo. Ele também pode ser encontrado na minha página do GitHub, juntamente com o código completo de todos os exemplos deste tutorial.


*******************************************************************

#include <SPI.h> #include <Ethernet.h> byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 1, 177); EthernetServer server(80); void setup() { Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } Ethernet.begin(mac, ip); server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); } void loop() { // listen for incoming clients EthernetClient client = server.available(); if (client) { Serial.println("new client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c); if (c == '\n' && currentLineIsBlank) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println("Refresh: 5"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.print("<h1>Analogue Values</h1>"); for (int analogChannel = 0; analogChannel < 6; analogChannel++) { int sensorReading = analogRead(analogChannel); client.print("analog input "); client.print(analogChannel); client.print(" is "); client.print(sensorReading); client.println("<br />"); } client.println("</html>"); break; } if (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') { currentLineIsBlank = false; } } } delay(1); // close the connection: client.stop(); Serial.println("client disconnected"); } }


Depois de enviar esse código para o Arduino, você terá um servidor web muito básico instalado e funcionando.

Ele será atualizado a cada 5 segundos, atualizando os valores dos pinos analógicos do Arduino (serão apenas valores aleatórios, a menos que você tenha um dispositivo ou sensor real conectado a eles).

Você também pode monitorar o monitor serial para quaisquer linhas de depuração localizadas no código.





Servidor Web Arduino com um cartão SD

Se você decidir usar o cartão SD para o servidor web Arduino, os arquivos HTML precisarão ser criados no seu computador e depois copiados para o cartão SD antes de ele ser inserido no Arduino.

Uma vantagem de carregar a página web do cartão SD é que você pode ter páginas mais complexas/pesadas sem precisar escrever centenas de linhas client.write . Isso também ajuda a evitar situações de falta de memória que geralmente ocorrem quando há muito código em execução no Arduino.

Inicializando o cartão SD

Antes de poder acessar o cartão SD, você precisará importar o pacote SD e inicializá-lo na função de configuração. A verificação na função de configuração verificará se ele consegue acessar o cartão, caso contrário, gerará um erro no monitor serial.

Serial.println("Checking SD card is accessible..."); if (!SD.begin(4)) { Serial.println("ERROR - SD card initialization failed!"); return; // init failed } Serial.println("SUCCESS - SD card initialized.");


Carregando o arquivo

Quando estiver pronto para carregar o arquivo, basta usar sd.open(filename)para abri-lo. Use uma instrução if para garantir que o arquivo exista e, em seguida, percorra o conteúdo do arquivo até chegar ao fim.

webPage = SD.open("index.htm"); // open web page file if (webPage) { while (webPage.available()) { client.write(webPage.read()); // send web page to client } webPage.close();

Abaixo está um exemplo da página da web que é carregada via cartão SD com Ajax (explicado abaixo) atualizando os elementos na página.


Executar ações através da página web (AJAX)

Pode haver momentos em que você queira controlar um dispositivo ou sensor por meio de uma página web. Nesta seção, abordarei a execução de solicitações e atualizações usando AJAX. Isso significa que você não verá a página carregando repetidamente, mas ela ainda será atualizada quando necessário.

AJAX, ou JavaScript e XML assíncronos, é um pouco complicado demais para ser abordado completamente neste tutorial, mas abordarei os conceitos básicos de uso no Arduino. Você conseguirá adaptar os exemplos às suas necessidades sem muitos problemas.

Exemplo de AJAX

O AJAX funciona enviando uma solicitação ao servidor, que então verifica se a string ajaxrefresh  ou ledstatus  existe no cabeçalho (neste exemplo). Se existir, ele gera os dados relevantes e os retorna.

O JavaScript então encontra o elemento HTML relevante com o ID correto e substitui o innerHTML pela resposta da solicitação AJAX.

O exemplo abaixo envia uma requisição ao servidor web em execução no Arduino com a variável GET ajaxrefresh . Se o servidor retornar dados, ele substituirá o innerHTML do elemento que possui o id analog_data .

Este script é executado a cada 5 segundos, mas pode ser ajustado para atender melhor às suas necessidades.


<script>window.setInterval(function(){ nocache = "&nocache=" + Math.random() * 10; var request = new XMLHttpRequest(); request.onreadystatechange = function() { if (this.readyState == 4) { if (this.status == 200) { if (this.responseText != null) { document.getElementById("analoge_data").innerHTML = this.responseText; } } } } request.open("GET", "ajaxrefresh" + nocache, true); request.send(null); }, 5000); </script>


Funções Ajax do Arduino

As duas funções abaixo são chamadas sempre que a requisição AJAX relevante chega ao servidor. Elas são muito simples: a primeira lê os pinos analógicos e retorna os dados relevantes.

A segunda função ligará ou desligará o LED VERMELHO dependendo do seu status atual. Ela também retornará o status do LED para que o AJAX possa atualizar o valor na página da web.


void ajaxRequest(EthernetClient client) { for (int analogChannel = 0; analogChannel < 6; analogChannel++) { int sensorReading = analogRead(analogChannel); client.print("analog input "); client.print(analogChannel); client.print(" is "); client.print(sensorReading); client.println("<br />"); } } void ledChangeStatus(EthernetClient client) { int state = digitalRead(RED); Serial.println(state); if (state == 1) { digitalWrite(RED, LOW); client.print("OFF"); } else { digitalWrite(RED, HIGH); client.print("ON"); } }

AJAX com HTML gerado pelo Arduino

O exemplo abaixo contém todo o HTML e JavaScript gerados completamente pelo Arduino. O JavaScript faz requisições AJAX ao servidor Arduino, que atualiza a página com base nos resultados fornecidos.

Um problema que notei ao gerar todo o código no Arduino é que ele começou a ficar com pouco espaço e a exibir avisos de estabilidade. Isso pode ser um problema se você quiser muitos sensores e opções na página. Talvez seja uma boa ideia armazenar o HTML em um cartão SD e baixá-lo de lá.


void loop() { EthernetClient client = server.available(); if (client) { Serial.println("new client"); boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); if( HTTP_req.length() < 120) HTTP_req += c; // save the HTTP request 1 char at a time Serial.write(c); if (c == '\n' && currentLineIsBlank) { // send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); Serial.println(HTTP_req); if (HTTP_req.indexOf("ajaxrefresh") >= 0 ) { // read switch state and analog input ajaxRequest(client); break; } else if (HTTP_req.indexOf("ledstatus") >= 0 ) { // read switch state and analog input ledChangeStatus(client); break; } else { client.println("<!DOCTYPE HTML>"); client.println("<html lang=\"en\">"); client.println("<script>window.setInterval(function(){"); client.println("nocache = \"&nocache=\" + Math.random() * 10;"); client.println("var request = new XMLHttpRequest();"); client.println("request.onreadystatechange = function() {"); client.println("if (this.readyState == 4) {"); client.println("if (this.status == 200) {"); client.println("if (this.responseText != null) {"); client.println("document.getElementById(\"analoge_data\").innerHTML = this.responseText;"); client.println("}}}}"); client.println("request.open(\"GET\", \"ajaxrefresh\" + nocache, true);"); client.println("request.send(null);"); client.println("}, 5000);"); client.println("function changeLEDStatus() {"); client.println("nocache = \"&nocache=\" + Math.random() * 10;"); client.println("var request = new XMLHttpRequest();"); client.println("request.onreadystatechange = function() {"); client.println("if (this.readyState == 4) {"); client.println("if (this.status == 200) {"); client.println("if (this.responseText != null) {"); client.println("document.getElementById(\"led_status\").innerHTML = this.responseText;"); client.println("}}}}"); client.println("request.open(\"GET\", \"?ledstatus=1\" + nocache, true);"); client.println("request.send(null);"); client.println("}"); client.println("</script></head>"); // output the value of each analog input pin client.print("<h1>Analogue Values</h1>"); client.println("<div id=\"analoge_data\">Arduino analog input values loading.....</div>"); client.println("<h1>Arduino LED Status</h1>"); client.println("<div><span id=\"led_status\">"); if(digitalRead(RED) == 1) client.println("On"); else client.println("Off"); client.println("</span> | <button onclick=\"changeLEDStatus()\">Change Status</button> </div>"); client.println("</html>"); 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; } } } delay(1); client.stop(); HTTP_req = ""; Serial.println("client disconnected"); } }


AJAX com arquivos HTML no cartão SD

Como você pode ver abaixo, o resultado é muito mais limpo ao simplesmente armazenar o HTML em um arquivo no cartão SD. Isso deve ajudar a manter seu script processando principalmente código, especialmente se você fizer tudo via AJAX e carregar o HTML do cartão SD.

Tenha em mente que esta é apenas a parte do loop do código. Se você quiser a versão completa, acesse minha página do Github .


void loop() { EthernetClient client = server.available(); if (client) { Serial.println("new client"); boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); if ( HTTP_req.length() < 80) HTTP_req += c; if (c == '\n' && currentLineIsBlank) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); if (HTTP_req.indexOf("ajaxrefresh") >= 0 ) { ajaxRequest(client); break; } else if (HTTP_req.indexOf("ledstatus") >= 0 ) { ledChangeStatus(client); break; } else { webPage = SD.open("index.htm"); if (webPage) { while (webPage.available()) { client.write(webPage.read()); } webPage.close(); } break; } if (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') { currentLineIsBlank = false; } } } } delay(1); client.stop(); HTTP_req = ""; Serial.println("client disconnected"); } }

Solução de problemas

Como em qualquer projeto Arduino , você pode encontrar alguns problemas. Os problemas a seguir são apenas alguns que encontrei ao montar este tutorial.

  • Não consigo acessar minha página web: Verifique novamente o endereço IP e certifique-se de que não esteja em conflito com outro dispositivo na rede. Além disso, tente executar um ping no endereço IP e veja se obtém uma resposta.
  • Meu cartão SD diz que está inacessível: Mantenha pressionado o botão de desligar e insira o cartão SD. Descobri que isso geralmente resolve o problema.
  • CSS: Você pode incluir CSS em suas páginas web, seja em linha ou localizado no cabeçalho, entre as tags de estilo. Talvez você queira se aprofundar mais nisso se não tiver muita experiência com CSS. Não é realmente necessário, a menos que você queira que suas páginas tenham uma boa aparência.

Implementações adicionais

Existem muitas outras maneiras de usar um servidor web que aumentariam a funcionalidade do seu circuito. Listarei rapidamente alguns projetos nos quais você pode querer implementar uma interface web.

  • Controle de Ventilador/Temperatura – Monitore uma sala de servidores, estufa ou algo semelhante onde o calor e o fluxo de ar sejam importantes. Você pode adicionar controles para ligar e desligar aquecedores e ventiladores.
  • Contador – Use um sensor de movimento para detectar movimento e contar cada vez que o sensor é acionado. Você pode aplicar essa mesma lógica a quase qualquer tipo de sensor.

Espero que este tutorial sobre o servidor web Arduino tenha ajudado você a criar um site onde você possa visualizar e interagir com os dados. Se você tiver alguma recomendação, dica ou perceber que algo está errado, não hesite em deixar um comentário abaixo.









































Comentários

Postagens mais visitadas deste blog

GPS NEO 6M NO ARDUINO PAGINA ELETROGATE

ESQUEMA DE ARDUINO DIY BÁSICO

Endereços Barramento I2C