Basic Arduino Web Server

 

Basic Arduino Web Server



COPIA DA PAGINA
https://pimylifeup.com/arduino-web-server/


Servidor Web básico do Arduino

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

Servidor Web Arduino

A configuração de um servidor web no Arduino é um processo direto que abrange o processo de colocá-lo em funcionamento. Também abordarei alguns conceitos principais, como usar o Ajax para atualizar, em vez de atualizar a página repetidamente.

Você precisará conhecer um pouco de HTML básico, que é incrivelmente fácil de entender os conceitos. Se você nunca fez HTML, então eu recomendo acessar w3schools para uma introdução básica .

Este servidor não poderá fazer nada muito sofisticado, mas é incrivelmente útil para quem deseja exibir dados de dispositivos conectados aos pinos ou gostaria de interagir com um circuito de uma página da web. servidor web Raspberry Pi mais poderoso pode lhe interessar se isso não cobrir realmente o que você procura.

0 seconds of 6 minutes, 15 secondsVolume 0%
 

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, não se esqueça de me informar na seção de comentários na parte inferior 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 na codificação ou está interessado em alguns dos conceitos básicos que estão sendo explicados, continue lendo, caso contrário, você pode pular esta seção e descer para configurar o servidor da Web com ou sem uma seção de cartão SD.

Inicialização

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

Em primeiro lugar, você precisa definir um endereço mac, o abaixo deve funcionar bem na maioria das redes domésticas. Se você sabe exatamente o que está procurando, não hesite em mudá-lo.

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};cópia de

Em segundo lugar, você precisará definir um endereço IP, isso é feito simplesmente chamando a IPAddressclasse com o IP escolhido. Certifique-se de atualizar isso para um endereço IP que não entre em conflito em sua rede.

IPAddress ip(192, 168, 1, 177);cópia de

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 da Web em seu navegador. Por exemplo, se sua porta for 14213 , o endereço ficará assim:192.168.1.177:14213

EthernetServer server(80);cópia de

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

Ethernet.begin(mac, ip);
  server.begin();cópia de

Detectando uma nova conexão

Na função de loop, precisamos verificar se há uma nova conexão toda vez que ela faz um loop. Se uma nova conexão for detectada, inserimos nosso código lógico da página da 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()) {cópia de

Uma vez determinado que há um cliente disponível, passamos para a saída do HTML do servidor web do Arduino.

Retornando o cabeçalho de resposta HTML

Para que um navegador exiba a página da Web corretamente, primeiro precisamos responder com um cabeçalho de resposta HTML. Não precisa ser nada complicado, o exemplo abaixo é mais que suficiente para que as coisas funcionem corretamente.

Se você procura 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();cópia de

Saída de HTML

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

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


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

A outra opção é ter os arquivos HTML armazenados 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 da Web para que eles mostrem 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

Depois de concluir o processamento da página da Web, você deve esperar um pouco para garantir que o cliente obtenha os dados. Após um segundo ou mais, basta fechar a conexão com o cliente.

delay(1);
    client.stop();cópia de

Servidor Web Arduino sem cartão SD

Se você não estiver usando o cartão SD, é incrivelmente simples colocar um servidor web em funcionamento.

É importante observar que, se você tiver um cartão SD inserido, mas não estiver em uso, poderá causar problemas com a 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);cópia de

Depois de adicionados, você pode adicionar o cartão SD de volta ao dispositivo.

Para colocar rapidamente um servidor web Arduino em funcionamento, basta abrir o sketch e copiar e colar o código abaixo. Ele também pode ser encontrado na minha página do Github junto com o código completo para todos os exemplos neste 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");
  }
}cópia de

Depois de ter carregado este código para o Arduino, você deve 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 em todo o código.

Página da web do Arduino exibindo entradas analógicas

Servidor Web Arduino com um cartão SD

Se você decidir seguir a rota do cartão SD para o servidor web do Arduino, os arquivos HTML precisarão ser criados em seu computador e depois copiados para o cartão SD antes de serem inseridos no Arduino.

Um profissional em carregar a página da web a partir do cartão SD é que você pode ter páginas mais complexas/pesadas sem precisar escrever centenas de linhas client.write . Também ajuda a evitar situações de pouca memória que geralmente ocorrem quando você acaba tendo 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 verá se ele pode 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.");cópia de

Carregando o arquivo

Quando estiver pronto para carregar o arquivo, basta usar sd.open(filename)para abrir o arquivo. Use uma instrução if para certificar-se de que o arquivo existe e, em seguida, faça um loop pelo conteúdo do arquivo até chegar ao final.

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();cópia de

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.

Página da Web do Arduino

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

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

AJAX ou JavaScript e XML assíncrono é um pouco complicado demais para cobrir completamente neste tutorial, mas vou passar pelo básico de como usá-lo no Arduino. Você deve ser capaz de ajustar os exemplos para atender às suas necessidades sem muitos problemas.

Exemplo AJAX

AJAX funciona enviando uma solicitação ao servidor, o servidor verificará se a string ajaxrefresh  ou ledstatus  existe no cabeçalho (para este exemplo). Se isso acontecer, ele gerará os dados relevantes e os retornará.

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 para o servidor web rodando no Arduino com a variável GET ajaxrefresh . Se o servidor retornar dados, ele substituirá o innerHTML do elemento que possui o id analogue_data .

Este script é executado a cada 5 segundos, mas pode ser ajustado para melhor atender à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>
cópia de

Funções do Arduino Ajax

As duas funções abaixo são chamadas sempre que a solicitação AJAX relevante chega ao servidor. Eles são muito simples com o primeiro lendo os pinos analógicos e retornando os dados relevantes.

A segunda função ligará ou desligará o LED VERMELHO dependendo de seu status atual. Ele 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");
  }
}
cópia de

AJAX com HTML gerado pelo Arduino

O exemplo abaixo tem todo o HTML e JavaScript completamente gerado pelo Arduino. O JavaScript faz solicitações AJAX ao servidor Arduino que atualiza a página dependendo dos resultados que fornece.

Um problema que notei ao gerar todo o código no Arduino é que ele começou a ficar com pouco espaço e a dar avisos de estabilidade. Isso pode ser um problema se você quiser vários sensores e opções na página. Você pode querer olhar para armazenar o HTML em um cartão SD e pegá-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");
  }
}cópia de

AJAX com arquivos HTML no cartão SD

Como você pode ver abaixo, o resultado é muito mais limpo simplesmente armazenando o HTML dentro de um arquivo no cartão SD. Isso deve ajudar a manter seu script principalmente processando 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, vá para 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");
  }
}cópia de

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 da web: verifique o endereço IP e certifique-se de que não esteja em conflito com outro dispositivo na rede. Além disso, tente pingar o endereço IP e veja se você 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 corrigia o problema.
  • CSS: Você pode incluir CSS em suas páginas da web, você pode fazer isso inline ou localizado no cabeçalho entre as tags de estilo. Isso é algo que você pode querer ler mais se não tiver feito muito CSS. Não é realmente necessário, a menos que você queira que suas páginas tenham uma boa aparência.

Outras implementações

Há muito mais maneiras de usar um servidor da Web que aumentaria a funcionalidade do seu circuito. Vou listar rapidamente alguns projetos onde 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 são importantes. Você pode adicionar controles para ligar e desligar aquecedores e ventiladores.
  • Contador – Use um sensor de movimento para detectar movimento e contar toda vez que o sensor for acionado. Você pode aplicar essa mesma lógica com quase qualquer tipo de sensor.

Espero que este tutorial do servidor web do 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 notou 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