X

ESP8266 e Bancos de Dados – Requisições WEB com PHP

Neste artigo vamos mostrar como enviar dados coletados de sensores e armazená-los em um banco de dados usando ESP8266 através da conexão WI-FI e requisições HTTP com PHP


Nosso projeto de exemplo, vai funcionar da seguinte maneira:

  • A cada 30 segundos o ESP8266 vai ler os dados do sensor e enviá-los através da conexão Wi-Fi a um servidor WEB via requisição HTTP  (GET ou POST);
  • No servidor um script PHP vai receber os dados enviados e gravá-los no banco de dados .

Supõe-se que o leitor tenha conhecimentos básicos sobre a teoria de Bancos de Dados Relacionais e MySQL, bem como sobre requisições HTTP.
No final do artigo relaciono alguns links úteis nesse sentido.

Passo 1: Criação do Banco de Dados

Vamos criar um banco de dados que será usado futuramente para armazenar os dados de uma estação meteorológica. Por isso nossa tabela receberá o nome de weather

Para criar o banco e a tabela, utilizei a ferramenta phpMyAdmin que vem com o uWamp – pacote de instalação do Apache + PHP + MySQL

Crie o banco de dados maker no MySQL e a tabela weather que receberá os dados dos sensores com a seguinte estrutura:

CREATE TABLE `weather` (
  `wea_id` int(11) NOT NULL AUTO_INCREMENT,
  `wea_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `wea_temp` float NOT NULL,
  `wea_humid` float NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Obs:

  1. O campo wea_id (chave primária) será incrementado automaticamente a cada inserção;
  2. A mesma coisa acontecerá o campo wea_date que guardará a data e hora em que o sinal foi enviado
  3. Os campos wea_temp e wea_humid vão armazenar os dados de temperatura e umidade enviados pelo ESP,

Passo 2: Script PHP

O script PHP ficará encarregado de ler os dados dos sensores enviados pelo ESP por uma requisição GET, fazer a conexão com o banco e gravar os dados através de um comando INSERT.

Vejamos:

<?php
$temp = filter_input(INPUT_GET, 'temp', FILTER_SANITIZE_NUMBER_FLOAT);
$humid = filter_input(INPUT_GET, 'humid', FILTER_SANITIZE_NUMBER_FLOAT);
if (is_null($temp) || is_null($humid) ) {
  //Gravar log de erros
  die("Dados inválidos");
} 
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "maker";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
  //Gravar log de erros
  die("Não foi possível estabelecer conexão com o BD: " . $conn->connect_error);
} 
$sql = "INSERT INTO weather (wea_temp, wea_humid) VALUES ($temp,$humid)";

if (!$conn->query($sql)) {
  //Gravar log de erros
  die("Erro na gravação dos dados no BD");
}
$conn->close();
?>

Obs: Crie uma pasta weather dentro da pasta www do servidor e coloque esse script com o nome insert_weather.php.

Passo 3: Protótipo ESP8266

Para nosso teste vamos usar o sensor de temperatura e umidade DHT11 e a placa de desenvolvimento NodeMCU, mas você pode usar qualquer placa compatível com a IDE do Arduino como a WEMOS ou a Adafruit Huzzah.

Montagem:

Nodemcu e DHT11

O sketch comentado ficou da seguinte forma:

/* ESP8266 e Banco de Dados - Requisições HTTP
 * 2016 por José Cintra
 * www.josecintra.com/blog
 */ 

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <SimpleDHT.h>

// WiFi - Coloque aqui suas configurações de WI-FI
const char ssid[] = "login";
const char psw[] = "senha";

// Site remoto - Coloque aqui os dados do site que vai receber a requisição GET
const char http_site[] = "http://mycomputer";
const int http_port = 8080;

// Variáveis globais
WiFiClient client;
IPAddress server(192,168,0,23); //Endereço IP do servidor - http_site
int pinDHT11 = D2;
SimpleDHT11 dht11;

void setup() {
  delay(30000); Aguarda 30 segundos 
  Serial.begin(9600);
  Serial.println("NodeMCU - Gravando dadios no BD via GET");
  Serial.println("Aguardando conexão");
  
  // Tenta conexão com Wi-fi
  WiFi.begin(ssid, psw);
  while ( WiFi.status() != WL_CONNECTED ) {
    delay(100);
    Serial.print(".");
  }
  Serial.print("\nWI-FI conectado com sucesso: ");
  Serial.println(ssid);

}

void loop() {
  
  //Leitura do sensor DHT11
  delay(3000); //delay entre as leituras
  byte temp = 0;
  byte humid = 0;
  if (dht11.read(pinDHT11, &temp, &humid, NULL)) {
    Serial.print("Falha na leitura do sensor.");
    return;
  }
  
  Serial.println("Gravando dados no BD: ");
  Serial.print((int)temp); Serial.print(" *C, "); 
  Serial.print((int)humid); Serial.println(" %");

  // Envio dos dados do sensor para o servidor via GET
  if ( !getPage((int)temp,(int)humid) ) {
    Serial.println("GET request failed");
  }
}

// Executa o HTTP GET request no site remoto
bool getPage(int temp, int humid) {
  if ( !client.connect(server, http_port) ) {
    Serial.println("Falha na conexao com o site ");
    return false;
  }
  String param = "?temp=" + String(temp) + "&humid=" + String(humid); //Parâmetros com as leituras
  Serial.println(param);
  client.println("GET /weather/insert_weather.php" + param + " HTTP/1.1");
  client.println("Host: ");
  client.println(http_site);
  client.println("Connection: close");
  client.println();
  client.println();

    // Informações de retorno do servidor para debug
  while(client.available()){
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  return true;
}

Obs:

  1. Repare que usamos library SimpleDHT para controlar o sensor DHT11, mas você pode usar a library de sua preferência. Veja aqui as instruções para usar essa biblioteca.
  2. Neste exemplo usamos o servidor de teste da máquina local Windows, o localhost. No entanto, para acesso remoto não deve ser usado o IP 127.0.0.1. Para saber o IP da máquina local para a variável server use o comando ipconfig e observe o valor do ipv4.

Passo 4: Ação

Depois de criar o banco e upar o sketch para o ESP, realize a seguinte sequência de passos para ver tudo funcionando:

  • Startar o servidor através da ferramenta uWamp. O Apache deve ser startado no modo ONLINE;
  • Startar o sketch do ESP8266 e abra o Monitor Serial da IDE para acompanhar as mensagens de log.

Pronto! Para ver o resultado abra o phpMyAdmin e execute o seguinte comando SQL:

SELECT * FROM WEATHER

E então você verá os dados chegando a cada 30 segundos.
Até a próxima!

Referências

José Cintra:
Related Post