Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Componentes e Materiais

1× Kit Estação Meteorológica DFRobot com Anemômetro/Biruta/Balde de Chuva
1× Placa NodeMCU ESP8266 Breakout Board (ESP-12E)
1× Shield DFRobot SIM808 GPS/GPRS/GSM para Arduino
1× Arduino UNO
1× Raspberry Pi 3 Model B+ Raspberry Pi 3B+ ou 4
1× Raspberry Pi 4 Model B Raspberry Pi 3B+ ou 4
2× Protoboard Soldável SparkFun - Mini

Ferramentas Necessárias

Aplicativos e Serviços Online

Sobre o Projeto

Especialmente em 2020, chuvas instantâneas, fortes e violentas causaram efeitos prejudiciais em estufas e rendimentos de colheitas no meu país. Infelizmente, hoje em dia chuvas inesperadas e excessivas ocorrem mais frequentemente e tornaram-se relativamente comuns devido às mudanças climáticas em algumas áreas. Enquanto isso, outras regiões sofrem com secas. À medida que 2020 passa, mais de trinta e cinco incidentes que causaram perda de colheitas e gado devido a chuvas fortes e violentas são registrados na minha região. Para contribuir com a solução para prevenir e evitar problemas instigados por chuvas excessivas como perda de produtividade agrícola, contemplei este projeto como um ponto de partida.

Primariamente, foquei nos efeitos de chuvas excessivas na agricultura neste projeto. No entanto, chuvas excessivas podem levar a numerosos perigos, por exemplo [1]:

Como mostrado nos estudos mais recentes, chuvas excessivas podem afetar a produtividade das culturas de várias formas, incluindo dano físico direto, plantio e colheita atrasados, crescimento radicular restrito, deficiência de oxigênio e perda de nutrientes. Assim, muita chuva pode ser tão perigosa quanto seca para a agricultura: "Dados das últimas três décadas sugerem que chuvas excessivas podem afetar o rendimento das culturas tanto quanto calor excessivo e seca. Em um novo estudo, uma equipe interdisciplinar da Universidade de Illinois vinculou dados de seguro de culturas, clima, solo e rendimento de milho de 1981 a 2016. O estudo descobriu que, durante alguns anos, chuvas excessivas reduziram o rendimento de milho dos EUA em até 34% em relação ao rendimento esperado. Dados sugerem que seca e calor excessivo causaram perda de rendimento de até 37% durante alguns anos [2]".

Infelizmente, sistemas de alerta precoce não são suficientes para prevenir totalmente os efeitos exacerbantes de chuvas excessivas em produtos e processos agrícolas sem dados meteorológicos locais adequados e preliminares para cada estufa ou fazenda. Portanto, na esperança de evitar os efeitos prejudiciais de chuvas excessivas na agricultura, decidi criar este projeto como uma estação meteorológica remota econômica para coletar e interpretar informações meteorológicas locais para fazer previsões mais precisas sobre a intensidade da chuva.

Após fazer algumas pesquisas sobre deep learning e redes neurais, decidi construir uma rede neural artificial (ANN) baseada no modelo de classificação para interpretar os dados meteorológicos locais acumulados para prever a intensidade da chuva de acordo com as classes dadas. Como o seguinte estudo indica, pesquisadores aplicaram diferentes modelos e tipos de redes neurais para prever não apenas chuvas mas também fenômenos meteorológicos: "Muitos experimentos usaram redes neurais para prever quantidades quantitativas de chuva em vários locais e alcances de previsão. Por exemplo, pesquisadores na Tailândia conseguiram previsões altamente precisas usando redes neurais feed-forward para prever quantidades quantitativas de chuva no alcance de previsão de uma a três horas para prever possíveis perigos de inundação. Redes neurais também foram usadas para prever fenômenos meteorológicos além dos valores de previsão tradicionais, como probabilidade/quantidade de chuva, velocidade do vento, pressão barométrica, etc. Foram usadas com muito sucesso para prever tornados. Além disso, pesquisadores na Austrália usaram com sucesso uma rede neural para identificar nevoeiro em vários alcances de previsão variando de 3 a 18 horas ao redor do Aeroporto Internacional de Canberra [3]."

Antes de construir e testar meu modelo de rede neural, coletei dados meteorológicos na minha varanda e quintal num raio de três quilômetros por mais de três meses para criar um dataset meteorológico local mostrando informações climáticas na minha vizinhança. Para conseguir obter informações meteorológicas mesmo em condições extremas, usei um Kit de Estação Meteorológica com Anemômetro, Biruta e Balde de Chuva da DFRobot com duas placas de desenvolvimento diferentes:

Assim, pude transferir dados meteorológicos via WiFi na minha varanda ou GPRS se a distância entre meu roteador e a estação meteorológica for muito grande.

Decidi usar o Google Sheets, um programa de planilha baseado na nuvem, para reunir dados meteorológicos gerados pela estação meteorológica porque criar grandes datasets e adicionar novas informações são simples com a API do Google Sheets. Por isso, desenvolvi uma aplicação web em PHP para obter dados meteorológicos transferidos pelas placas de desenvolvimento e anexá-los a uma planilha no Google Sheets.

Após completar a coleta de dados meteorológicos por mais de três meses a cada cinco minutos, construí um modelo de rede neural artificial (ANN) com TensorFlow para fazer previsões sobre a intensidade da chuva. Teoricamente, atribuí uma classe de intensidade de chuva para cada leitura após escalar e normalizar o dataset. Então, treinei o modelo de rede neural para classificar estas classes:

Então, este é meu projeto em poucas palavras 😃

Nos passos a seguir, você encontra informações mais detalhadas sobre codificação, coleta de dados meteorológicos locais e construção de um modelo de rede neural artificial (ANN) com TensorFlow.

Muito obrigado à DFRobot por patrocinar este projeto.

Produtos patrocinados pela DFRobot:

⭐ Kit Estação Meteorológica com Anemômetro/Biruta/Balde de Chuva | Inspecionar

⭐ Shield SIM808 GPS/GPRS/GSM para Arduino | Inspecionar

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Passo 1: Montando o kit da estação meteorológica com anemômetro, biruta e balde de chuva

Este kit de estação meteorológica inclui anemômetro, biruta, balde de chuva e uma placa sensora para enviar dados meteorológicos via protocolo de comunicação serial. Assim, é fácil de usar com placas de desenvolvimento para coletar dados meteorológicos locais.

Ele gera 37 bytes por segundo, incluindo o final CR/LF.

c000s000g000t086r000p000h53b10020

Parser de Dados:

⭐ Primeiro, prenda o anemômetro e a biruta na ponte usando parafusos e porcas.

⭐ Conecte a biruta ao anemômetro usando o cabo telefônico RJ11 e aperte sob a ponte.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Então, monte o bastão de aço inoxidável na ponte com parafusos.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Instale a junta do balde de chuva sob o balde com parafusos.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Por fim, coloque o balde de chuva no bastão de aço inoxidável usando parafusos e porcas.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Agora, está pronto para coletar dados meteorológicos mesmo em condições extremas. No entanto, a placa sensora (conversora) não é à prova d'água, então adicionei uma caixa plástica à estação meteorológica para proteger a placa sensora e o shield SIM808 ao ar livre.

Passo 2: Coletando dados meteorológicos no Google Sheets

Para poder enviar informações para uma planilha no Google Sheets, você precisa criar uma nova aplicação no Google Developer Console e obter credenciais de verificação para utilizar a API do Google Sheets. Se você é novato em criar aplicações com o Google Developer Console, siga as instruções abaixo.

⭐ Acesse o Google Developer Console e clique no botão 'NOVO PROJETO'. Insira o nome do projeto como Remote Weather Station (Estação Meteorológica Remota).

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Vá em APIs & Services e clique na biblioteca de API para habilitar a Google Sheets API.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Passo 2.1: Obtendo credenciais para usar a API do Google Sheets

⭐ Abra o painel do projeto e clique no botão Credenciais. Então, preencha o formulário como mostrado abaixo para criar a conta de serviço e chave.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Clique no botão CREATE CREDENTIALS e configure a tela de consentimento para poder criar um OAuth client ID.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Então, crie um novo OAuth client ID chamado Client sob Desktop app (tipo de aplicação).

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Após criar o OAuth client ID (Client), baixe as credenciais (ID e Secret) e nomeie o arquivo como credentials.json.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Passo 2.2: Criando uma planilha no Google Sheets

⭐ Acesse o Google Sheets e selecione Pessoal.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Crie uma planilha Em branco e nomeie-a Remote Weather Station.

⭐ Então, defina os nomes das colunas como a primeira linha:

⭐ Se necessário, modifique um gráfico para inspecionar os dados coletados, como fiz.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Passo 3: Desenvolvendo uma aplicação web em PHP para anexar dados meteorológicos à planilha

Esta aplicação web PHP é para obter dados meteorológicos transferidos pelas placas de desenvolvimento (ESP8266 e SIM808) via requisição HTTP GET e anexar esses dados a uma planilha dada (por ID) no Google Sheets com credenciais e token verificados.

A aplicação web requer a Google Client Library for PHP para anexar dados meteorológicos a uma planilha dada no Google Sheets.

⭐ Primeiro, crie uma pasta chamada remote_weather_station no seu servidor e instale a Google Client Library for PHP nela.

A pasta remote_weather_station deve incluir estes quatro arquivos além da Google Client Library para funcionar:

Neste passo, discutirei os dois primeiros arquivos - index.php e account_verification_token.php:

💻 index.php

⭐ Obtenha dados meteorológicos locais da estação meteorológica via requisição GET:


// Wind Direction (wd), Average Wind Speed (a_ws), Max Wind Speed (m_ws), 1hr Rainfall (1_rf), 24hr Rainfall (24_rf), Temperature (tem), Humidity (hum), Barometric Pressure (b_pr).
$variables_from_module;
if(isset($_GET['wd']) && isset($_GET['a_ws']) && isset($_GET['m_ws']) && isset($_GET['1_rf']) && isset($_GET['24_rf']) && isset($_GET['tem']) && isset($_GET['hum']) && isset($_GET['b_pr'])){
  $variables_from_module = [
    "wd" => (int)$_GET['wd'],
    "a_ws" => (float)$_GET['a_ws'],
    "m_ws" => (float)$_GET['m_ws'],
    "1_rf" => (float)$_GET['1_rf'],
    "24_rf" => (float)$_GET['24_rf'],
    "tem" => (float)$_GET['tem'],
    "hum" => (int)$_GET['hum'],
    "b_pr" => (float)$_GET['b_pr']
  ];
}else{
  $variables_from_module = [
    "wd" => "err",
    "a_ws" => "err",
    "m_ws" => "err",
    "1_rf" => "err",
    "24_rf" => "err",
    "tem" => "err",
    "hum" => "err",
    "b_pr" => "err"
  ];
}

⭐ Conecte ao aplicativo do Google Developer Console chamado Remote Weather Station usando o arquivo credentials.json (Passo 2.1).


$client = new Google_Client();
$client->setApplicationName('Remote Weather Station'); // Insira o nome da sua aplicação.
$client->setScopes('https://www.googleapis.com/auth/spreadsheets');
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');

⭐ Carregue token autorizado anteriormente de um arquivo (token.json), se existir.


$tokenPath = 'token.json';
if (file_exists($tokenPath)) {
  $accessToken = json_decode(file_get_contents($tokenPath), true);
  $client->setAccessToken($accessToken);
  print("Token Found!");
}

⭐ Se não há token anterior ou expirou, solicite autorização do usuário e defina o código de verificação para criar o arquivo token.json com a função file_put_contents().


if ($client->isAccessTokenExpired()) {
  // Atualize o token se possível, senão busque um novo.
  if ($client->getRefreshToken()) {
    $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
  } else {
    // Solicite autorização do usuário.
    $authUrl = $client->createAuthUrl();
    
    ...
    
    // Defina o código de verificação para criar o token.json.
    $authCode = trim($GLOBALS['account_verification_token']);
    
    ...
    
    // Verifique se houve erro e o account_verification_token foi inserido.
    if (array_key_exists('error', $accessToken)) {
      throw new Exception(join(', ', $accessToken));
    }else{
      print("Successful! Refresh the page.");
    }
  }
  // Salve o token em um arquivo.
  if (!file_exists(dirname($tokenPath))) {
    mkdir(dirname($tokenPath), 0700, true);
  }
  file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}

⭐ Insira o ID da planilha e intervalo para anexar descobertas recentes da estação meteorológica à planilha.

https://docs.google.com/spreadsheets/d/spreadsheetId/edit#gid=0


// Insira seu spreadsheetId:
$spreadsheetId = '';
// Insira o intervalo (a primeira linha) sob o qual novos valores serão anexados (8 linhas):
$range = 'A1:H1';
// Anexe descobertas recentes da estação meteorológica à planilha.
$values = [
  [$variables_from_module["wd"], $variables_from_module["a_ws"], $variables_from_module["m_ws"], $variables_from_module["1_rf"], $variables_from_module["24_rf"], $variables_from_module["tem"], $variables_from_module["hum"], $variables_from_module["b_pr"]]
];
$body = new Google_Service_Sheets_ValueRange([
  'values' => $values
]);
$params = [
  'valueInputOption' => "RAW"
];

...

$result = $service->spreadsheets_values->append($spreadsheetId, $range, $body, $params);
printf("

%d cells appended.", $result->getUpdates()->getUpdatedCells());

💻 account_verification_token.php

⭐ Após autorizar a aplicação web pelo AuthUrl criado, insira o código de verificação dado para definir um token de acesso.


$account_verification_token = ""; // Insira o código de verificação após autorização.
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Passo 3.1: Configurando a aplicação web no Raspberry Pi (ou qualquer servidor)

Após criar a aplicação web PHP, decidi rodá-la no meu Raspberry Pi, mas você pode rodar a aplicação em qualquer servidor desde que seja um servidor PHP.

Se quiser usar Raspberry Pi mas não sabe como configurar um servidor web LAMP no Raspberry Pi, pode consultar este tutorial.

⭐ Primeiro, mova a pasta da aplicação (remote_weather_station) para o servidor apache (/var/www/html) usando o terminal já que o servidor apache é um local protegido.

sudo mv /home/pi/Downloads/remote_weather_station /var/www/html/

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ A aplicação web lança um erro quando aberta pela primeira vez devido ao código de verificação ausente. Para obter o código de verificação, acesse o link de autorização gerado pela aplicação.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Então, clique em Go to Remote Weather Station (unsafe).

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Conceda à aplicação as permissões necessárias.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Agora, copie o código de verificação e cole no account_verification_token.php.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Volte para a aplicação web. Deve exibir a mensagem de confirmação: Successful! Refresh the page.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Após atualizar a página, a aplicação web usa o código de verificação para obter um token de acesso e salva o token de acesso em um arquivo chamado token.json. Assim, não lança erro novamente.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Para testar se a aplicação web PHP está anexando novos dados à planilha dada com precisão:

https://localhost/remote_weather_station/?wd=12&a_ws=8&m_ws=11&1_rf=14&24_rf=84&tem=24&hum=32&b_pr=57

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Passo 4: Lendo e enviando dados meteorológicos com ESP8266 (WiFi)

Para coletar dados meteorológicos na minha varanda, usei uma placa de desenvolvimento NodeMCU ESP-12E (ESP8266) com a estação meteorológica.

Programei para enviar dados meteorológicos para a aplicação web PHP a cada cinco minutos.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Inclua bibliotecas necessárias e defina configurações WiFi.


#include 
#include 
#include 
#include 
#include 

// Defina suas configurações WiFi.
const char *ssid = "";
const char *password = "";

⭐ Defina configurações da estação meteorológica e pinos de conexão serial - D6, D5.


// Defina configurações da estação meteorológica:
char databuffer[35];
double temp;
int transferring = 0;

// Defina os pinos de conexão serial - RX e TX.
SoftwareSerial Serial_1(D6, D5); // (Rx, Tx)

⭐ Na função getBuffer(), obtenha dados da estação meteorológica.


void getBuffer(){
  int index;
  for (index = 0; index < 35; index++){
    if(Serial_1.available()){
      databuffer[index] = Serial_1.read();
      if (databuffer[0] != 'c'){
        index = -1;
      }
    } else {
      index--;
    }
  }
}

⭐ Depure os dados meteorológicos e crie o link.


String weather_data = "wd=" + String(WindDirection()) + "&a_ws=" + String(WindSpeedAverage()) + "&m_ws=" + String(WindSpeedMax()) + "&1_rf=" + String(RainfallOneHour()) + "&24_rf=" + String(RainfallOneDay()) + "&tem=" + String(Temperature()) + "&hum=" + String(Humidity()) + "&b_pr=" + String(BarPressure());
String server = "https://192.168.1.24/remote_weather_station/?";

...

int WindDirection(){ return transCharToInt(databuffer,1,3); } // Direção do Vento (graus)

float WindSpeedAverage(){ temp = 0.44704 * transCharToInt(databuffer,5,7); return temp; } // Velocidade Média do Ar (1 minuto)

float WindSpeedMax(){ temp = 0.44704 * transCharToInt(databuffer,9,11); return temp; } // Velocidade Máxima do Ar (5 minutos)

float Temperature(){ temp = (transCharToInt(databuffer,13,15) - 32.00) * 5.00 / 9.00; return temp; } // Temperatura ("C")

float RainfallOneHour(){ temp = transCharToInt(databuffer,17,19) * 25.40 * 0.01; return temp; } // Chuva (1 hora)

float RainfallOneDay(){ temp = transCharToInt(databuffer,21,23) * 25.40 * 0.01; return temp; } // Chuva (24 horas)

int Humidity(){ return transCharToInt(databuffer,25,26); } // Umidade (%)

float BarPressure(){ temp = transCharToInt(databuffer,28,32); return temp / 10.00; } // Pressão Barométrica (hPA)

⭐ Envie pacotes de dados a cada 5 minutos para Raspberry Pi (ou qualquer servidor).


transferring++; Serial.println("Time => " + String(transferring) + "s / " + String(int(5*60)) + "s\n\n");
if(transferring == 5*60){
  // Crie o objeto HTTP para fazer uma requisição ao servidor.
  HTTPClient http;
  http.begin(server + weather_data);
  int httpCode = http.GET();
  String payload = http.getString();
  Serial.println("Data Send...\nHTTP Code => " + String(httpCode) + "\nServer Response => " + payload + "\n\n");
  http.end();
  transferring = 0;
}
// Espere 1 segundo...
delay(1000);
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Após fazer upload do código para a placa de desenvolvimento NodeMCU ESP-12E (ESP8266), ele exibe dados meteorológicos a cada segundo no monitor serial e envia pacotes de dados a cada cinco minutos (300 segundos) para a aplicação web PHP.


Connection is successful!

...

Weather Data => wd=0&a_ws=0.00&m_ws=0.00&1_rf=0.00&24_rf=0.00&tem=21.67&hum=29&b_pr=1016.70
Buffer => c000s000g000t071r000p000h29b10167*3
Time => 299s / 300s


Weather Data => wd=0&a_ws=0.00&m_ws=0.00&1_rf=0.00&24_rf=0.00&tem=21.67&hum=29&b_pr=1016.70
Buffer => c000s000g000t071r000p000h29b10167*3
Time => 300s / 300s

...

⭐ Então, mostra a resposta do servidor.


...

Data Send...
HTTP Code => 200
Server Response => Token Found!

8 cells appended.

...
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Passo 4.1: Lendo e enviando dados meteorológicos com SIM808 (GPRS)

Para coletar dados meteorológicos no meu quintal, usei um shield SIM808 para Arduino Uno se a distância entre a estação meteorológica e meu roteador for muito grande.

A maior parte do código é a mesma e coberta no passo anterior, exceto as partes abaixo.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Inclua bibliotecas necessárias e defina o objeto sim808.

Para Shield SIM808 GPS/GPRS/GSM | Download


#include 
#include 

// Defina o sim808.
DFRobot_SIM808 sim808(&Serial);

⭐ Inicialize o módulo SIM808 e continue se estiver funcionando corretamente.


//******** Inicialize módulo sim808 *************
while(!sim808.init()) {
  delay(1000);
  Serial.print("Sim808 init error\r\n");
}
delay(2000);
// Continue se o Módulo SIM808 estiver funcionando corretamente.
Serial.println("Sim808 init success");
delay(5000);

⭐ Envie pacotes de dados a cada 5 minutos para o servidor estabelecendo uma conexão TCP para fazer uma requisição GET.


transferring++; Serial.println("Time => " + String(transferring) + "s / " + String(int(5*60)) + "s\n\n");
if(transferring == 5*60){
  //*********** Attempt DHCP *******************
  while(!sim808.join(F("cmnet"))) {
    Serial.println("Sim808 join network error!");
    delay(2000);
  }
  //************ Successful DHCP ***************
  delay(5000);
  Serial.println("Successful DHCP");
  //*********** Establish a TCP connection ************
  if(!sim808.connect(TCP,"192.168.1.24", 80)) { // Altere com seu servidor.
    Serial.println("Connection Error");
  }else{
    Serial.println("Connection OK");
  }
  delay(2000);
  
  ...

⭐ Após criar a string da linha, converta de string para array char para fazer uma requisição HTTP GET com o SIM808.


...
String line = "GET /remote_weather_station/?" + weather_data_1 + weather_data_2 + weather_data_3 + " HTTP/1.0\r\n\r\n";
Serial.println(line);
char buffer[512];
// Converta a linha de string para array char para fazer requisição HTTP GET com SIM808.
char web_hook[110];
String_to_Char(line, 110, web_hook);
sim808.send(web_hook, sizeof(web_hook)-1);
while (true) {
  int ret = sim808.recv(buffer, sizeof(buffer)-1);
  if (ret <= 0){
    Serial.println("Fetch Over...");
    break;
  }
  ...
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

⭐ Após fazer upload do código para o shield SIM808, ele exibe dados meteorológicos a cada segundo no monitor serial e envia pacotes de dados a cada cinco minutos (300 segundos) para a aplicação web PHP.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Passo 4.2: Criando o dataset meteorológico por mais de três meses

Após terminar a codificação, comecei a reunir dados meteorológicos no Google Sheets a cada cinco minutos por mais de três meses para construir meu modelo de rede neural e fazer previsões sobre a intensidade da chuva.

Dados Meteorológicos Coletados:

Então, baixei a planilha como Remote Weather Station.csv, consistindo de 32219 linhas como meu dataset meteorológico local preliminar. Ainda estou coletando dados meteorológicos para melhorar meu dataset e modelo :)

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Passo 5: Construindo uma Rede Neural Artificial (ANN) com TensorFlow

Quando completei a coleta do meu dataset meteorológico local preliminar, comecei a trabalhar no meu modelo de rede neural artificial (ANN) para fazer previsões sobre a intensidade da chuva.

Decidi criar meu modelo de rede neural com TensorFlow em Python. Então, primeiro, segui os passos abaixo para obter melhor compreensão dos dados meteorológicos:

Após aplicar estes passos, decidi usar meu modelo de rede neural para classificar diferentes classes de intensidade de chuva teoricamente atribuídas como labels (saídas) para cada entrada (linha). Criei minhas classes de acordo com a taxa de precipitação, que depende do tempo considerado.

As seguintes categorias são usadas para classificar intensidade de chuva pela taxa de precipitação:

De acordo com as taxas de precipitação (chuva), pré-processei os dados meteorológicos para atribuir uma destas cinco classes para cada entrada como seu label:

Após escalar (normalizar) e pré-processar os dados meteorológicos, obtive sete variáveis de entrada e um label para cada leitura, classificadas com as cinco classes mencionadas. Então, construí um modelo de rede neural artificial com TensorFlow para obter os melhores resultados e previsões possíveis com meu dataset preliminar.

Camadas:

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Para executar todos os passos acima, criei uma classe chamada Weather_Station em Python após incluir as bibliotecas necessárias:


import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

Subsequentemente, discutirei a codificação em Python para cada passo mencionado acima.

Também, você pode baixar IoT_weather_station_neural_network.py para inspecionar a codificação.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Passo 5.1: Visualizando e escalando (normalizando) os dados meteorológicos

Antes de mergulhar na construção de um modelo, é importante entender os dados meteorológicos para passar dados apropriadamente formatados ao modelo.

Então, neste passo, mostrarei como visualizar dados meteorológicos e escalar (normalizar) em Python.

⭐ Primeiro, leia os dados meteorológicos de Remote Weather Station.csv.


csv_path = "E:\PYTHON\Remote Weather Station.csv"
df = pd.read_csv(csv_path)

⭐ Na função graphics(), visualize as colunas solicitadas do dataset meteorológico usando a biblioteca Matplotlib.


def graphics(self, column_1, column_2, xlabel, ylabel):
  # Mostre colunas solicitadas do dataset:
  plt.style.use("dark_background")
  plt.gcf().canvas.set_window_title('IoT Weather Station')
  plt.hist2d(self.df[column_1], self.df[column_2])
  plt.colorbar()
  plt.xlabel(xlabel)
  plt.ylabel(ylabel)
  plt.title(xlabel)
  plt.show()

⭐ Na função data_visualization(), inspecione todas as colunas antes de escalar dados meteorológicos para construir um modelo com dados apropriadamente formatados.


def data_visualization(self):
  # Inspecione colunas solicitadas para construir um modelo com dados apropriadamente formatados:
  self.graphics('WD', '1h_RF', 'Wind Direction (deg)', 'One-Hour Rainfall (mm)')
  self.graphics('Av_WS', '1h_RF', 'Average Wind Speed (m/s)', 'One-Hour Rainfall (mm)')
  self.graphics('Mx_WS', '1h_RF', 'Maximum Wind Speed (m/s)', 'One-Hour Rainfall (mm)')
  self.graphics('24h_RF', '1h_RF', '24-Hour Rainfall (mm)', 'One-Hour Rainfall (mm)')
  self.graphics('Tem', '1h_RF', 'Temperature (°C)', 'One-Hour Rainfall (mm)')
  self.graphics('Hum', '1h_RF', 'Humidity (%)', 'One-Hour Rainfall (mm)')
  self.graphics('b_PR', '1h_RF', 'Barometric Pressure (hPA)', 'One-Hour Rainfall (mm)')
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Após visualizar dados meteorológicos, escalei (normalizei) cada coluna para formatá-la adequadamente.

Normalmente, cada linha (leitura) parecia assim antes de escalar:

⭐ Na função scale_data():

⭐ A direção do vento em unidades de graus e ângulos não são boas entradas para o modelo. 360° e 0° devem estar próximos um do outro e transicionar suavemente. A direção não deve importar se o vento não estiver soprando. Assim, converta as colunas de direção e velocidade do vento para um vetor de vento para interpretá-las facilmente com um modelo de rede neural.


def scale_data(self):
  # Direção e Velocidade do Vento:
  wv = self.df.pop('Av_WS')
  max_wv = self.df.pop('Mx_WS')
  # Converter para radianos.
  wd_rad = self.df.pop('WD')*np.pi / 180
  # Calcule os componentes x e y do vento.
  self.df['scaled_WX'] = wv*np.cos(wd_rad)
  self.df['scaled_WY'] = wv*np.sin(wd_rad)
  # Calcule os componentes máximos x e y do vento.
  self.df['scaled_max_WX'] = max_wv*np.cos(wd_rad)
  self.df['scaled_max_WY'] = max_wv*np.sin(wd_rad)
  
  ...

⭐ Para as colunas restantes exceto 1h_RF, divida-as pelos valores médios de leitura para escalar (normalizar) e formatar.


...

# Temperatura:
tem = self.df.pop('Tem')
self.df['scaled_Tem'] = tem / 25
# Umidade:
hum = self.df.pop('Hum')
self.df['scaled_Hum'] = hum / 70
# Pressão Barométrica:
bPR = self.df.pop('b_PR')
self.df["scaled_bPR"] = bPR / 1013
# Chuva de 24 Horas (Aprox.)
rain_24 = self.df.pop('24h_RF')
self.df['scaled_24h_RF'] = rain_24 / 24

Após completar o escalonamento (normalização), extraí estas novas colunas do dataset meteorológico:

Passo 5.2: Treinando o modelo (ANN) nas classes de intensidade de chuva

Antes de construir e treinar um modelo de rede neural em TensorFlow, precisei criar o array de entrada e o array de label pré-processando o dataset meteorológico escalado e normalizado.

⭐ Na função create_input_and_label():

⭐ Primeiro, anexe cada elemento de entrada como array NumPy ao array de entrada e converta para array NumPy usando a função asarray().

⭐ Cada elemento de entrada inclui sete variáveis [shape=(7, )]:


def create_input_and_label(self):
  n = len(self.df)
  # Crie o array de entrada usando as variáveis escaladas:
  for i in range(n):
    self.input.append(np.array([self.df['scaled_WX'][i], self.df['scaled_WY'][i], self.df['scaled_max_WX'][i], self.df['scaled_max_WY'][i], self.df['scaled_Tem'][i], self.df['scaled_Hum'][i], self.df['scaled_bPR'][i]]))
  self.input = np.asarray(self.input)
  
  ...

⭐ Então, avalie a taxa aproximada de chuva (precipitação) para cada leitura (linha).

approx_RF_rate = (1h_RF + scaled_24h_RF) * 100

⭐ De acordo com a taxa de chuva, atribua uma classe [0-4] para cada elemento de entrada e anexe-as ao array de label.


...
for i in range(n):
  _class = 0
  # Avalie a taxa aproximada de chuva:
  approx_RF_rate = (self.df['1h_RF'][i] + self.df['scaled_24h_RF'][i]) * 100
  // Como labels, atribua classes de intensidade de chuva de acordo com a taxa aproximada de chuva (mm):
  if approx_RF_rate == 0:
    _class = 0
  elif approx_RF_rate < 2.5:
    _class = 1
  elif 2.5 < approx_RF_rate and approx_RF_rate < 7.6:
    _class = 2
  elif 7.6 < approx_RF_rate and approx_RF_rate < 50:
    _class = 3
  else:
    _class = 4
  self.label.append(_class)
  self.label = np.asarray(self.label)

Após pré-processar os dados meteorológicos escalados para criar arrays de entrada e label, dividi-os como dados de treino (60%) e teste (40%):


def split_data(self):
  n = len(self.df)
  // (60%, 40%) - (treino, teste)
  self.train_input = self.input[0:int(n*0.6)]
  self.test_input = self.input[int(n*0.6):]
  self.train_label = self.label[0:int(n*0.6)]
  self.test_label = self.label[int(n*0.6):]

Então, construí meu modelo de rede neural artificial (ANN) usando Keras e o treinei com o dataset de treino por dezenove épocas.

Você pode consultar estes tutoriais para aprender sobre funções de ativação, funções de perda, épocas, etc.


def build_and_train_model(self):
  // Construa a rede neural:
  self.model = keras.Sequential([
    keras.Input(shape=(7,)),
    keras.layers.Dense(16, activation='relu'),
    keras.layers.Dense(32, activation='relu'),
    keras.layers.Dense(64, activation='relu'),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(5, activation='softmax')
  ])
  // Compile:
  self.model.compile(optimizer='adam', loss="sparse_categorical_crossentropy", metrics=['accuracy'])
  // Treine:
  self.model.fit(self.train_input, self.train_label, epochs=19)
  
  ...

Após treinar com o dataset de treino preliminar, a precisão do modelo está entre 0.83 e 0.85.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Passo 5.3: Avaliando o modelo e fazendo previsões sobre a intensidade da chuva

Após construir e treinar meu modelo de rede neural artificial, testei sua precisão usando o dataset de teste preliminar.

Por enquanto, a precisão avaliada do modelo está entre 0.72 e 0.73 devido a dataset de teste inadequado fazendo overfit no modelo. No entanto, ainda estou coletando dados meteorológicos para melhorar a precisão do modelo.


...
// Teste a precisão:
print("\n\nModel Evaluation:")
test_loss, test_acc = self.model.evaluate(self.test_input, self.test_label)
print("Evaluated Accuracy: ", test_acc)

Então, usei meu modelo de rede neural para fazer previsões sobre a intensidade da chuva com um array de previsão dado consistindo de leituras da estação meteorológica após o treino do modelo. Como ponto de partida, o modelo funciona bem :)

O modelo prevê possibilidades de labels para cada elemento de entrada como um array de 5 números. Eles representam a "confiança" do modelo que o elemento de entrada dado corresponde a cada uma das cinco diferentes classes de intensidade de chuva [0-4].

⭐ Na função make_prediction(), faça uma previsão para cada elemento de entrada em um array dado e obtenha o label mais preciso [0-4] usando a função argmax() para exibir seu nome de classe.


def make_prediction(self, pre_array):
  print("\n\nModel Predictions:\n")
  prediction = self.model.predict(pre_array)
  for i in range(len(pre_array)):
    print("Prediction => ", self.class_names[np.argmax(prediction[i])])

Entradas de Previsão:

Saídas de Previsão:

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Conexões e Ajustes (ESP8266)


// Conexões
// NodeMCU ESP-12E (ESP8266) : 
// Estação Meteorológica
// VV --------------------------- 5V
// D5 --------------------------- RX
// D6 --------------------------- TX
// G --------------------------- GND

Conectei a placa sensora (conversora) ao NodeMCU ESP-12E (ESP8266) e os prendi a uma caixa plástica enquanto coletava dados meteorológicos na minha varanda.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Conexões e Ajustes (SIM808)


// Conexões
// Arduino Uno: 
// SIM808 GPS/GPRS/GSM Shield para Arduino
// D0 --------------------------- RX
// D1 --------------------------- TX
// D12 --------------------------- POWER
// Estação Meteorológica
// 5V --------------------------- 5V
// D5 --------------------------- RX
// D6 --------------------------- TX
// GND --------------------------- GND

⭐ Nota: Pinos D0, D1, D12 são ocupados pelo Shield SIM808 GPS/GPRS/GSM.

⭐ Conecte uma bateria externa (7-23V) para o módulo SIM808 funcionar corretamente.

⭐ Anexe a antena GPS e a antena GSM ao shield SIM808.

⭐ Insira um cartão SIM no slot SIM no shield SIM808.

⭐ Antes de fazer upload do código, defina a chave de função no shield para None (1).

⭐ Faça upload do código.

⭐ Então, defina a chave de função para Arduino (3).

⭐ Pressione o botão Boot no shield até ver o LED indicador Net piscando a cada 1 segundo e espere o cartão SIM registrar a rede - o LED indicador Net piscará lentamente a cada 3 segundos.

⭐ Clique aqui para obter mais informações sobre o Shield SIM808 GSM/GPS/GPRS.

Após configurar o shield SIM808 com Arduino Uno, conectei a placa sensora (conversora) a ele.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Coloquei todos os componentes em uma caixa plástica para coletar dados meteorológicos ao ar livre, mesmo em condições extremas, já que a placa sensora não é à prova d'água.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Então, prendi a caixa plástica à estação meteorológica.

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Vídeos e Conclusão

Após completar a codificação e montar a estação meteorológica, reuni dados meteorológicos locais por mais de três meses a cada cinco minutos para construir meu modelo de rede neural com sucesso.

Ainda estou coletando dados meteorológicos na minha varanda e quintal para melhorar meu modelo de rede neural e sua precisão :)

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Discussões Adicionais

☔ 💧 Como precisamos de datasets meteorológicos locais para obter previsões mais precisas sobre fenômenos meteorológicos, estações meteorológicas econômicas habilitadas para NN como esta podem ser colocadas em fazendas e estufas para evitar os efeitos prejudiciais de chuvas excessivas na agricultura.

☔ 💧 Como sistemas de alerta precoce trabalhando com redes neurais, podemos usá-los simultaneamente para criar um enxame de estações meteorológicas se comunicando e alimentando umas às outras para prever a intensidade da chuva precisamente em áreas locais.

☔ 💧 Também podemos utilizar essa informação para avaliar:

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão
Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Referências

[1] Extreme weather - heavy rainfall, NIWA, NIWA

[2] University of Illinois at Urbana-Champaign, News Bureau. "Excessive rainfall as damaging to corn yield as extreme heat, drought." ScienceDaily. ScienceDaily, 30 April 2019. ScienceDaily.

[3] Andrew Culclasure, Using Neural Networks to Provide Local Weather Forecasts, Georgia Southern University, Spring 2013, Digital Commons.

Código

O projeto inclui múltiplos arquivos de código:

Peças Personalizadas e Caixas

remote_weather_station_OobOCQNPSW.csv (Dataset de exemplo)

Esquemáticos

Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão Estação Meteorológica IoT com TensorFlow Prevê Intensidade de Chuva com Precisão

Processo de manufatura

  1. Estação Meteorológica Solar DIY com Raspberry Pi
  2. Construindo Estação Meteorológica Externa com Raspberry Pi 2 e ADS‑WS1
  3. Construa Estação Meteorológica Raspberry Pi que Envia Dados Diários por Email
  4. Tutorial IoT Iniciante: Streaming de Dados de Temperatura de um Raspberry Pi
  5. Monitoramento Remoto do Tempo com Raspberry Pi 3 e PubNub
  6. Integre sua Estação Meteorológica ao CWOP: Guia Prático
  7. Construindo IoT com Java ME 8 no Raspberry Pi: Parte 1 – Integração de Sensores GPIO
  8. Conecte Raspberry Pi 3 a Sensor DHT11 e Envie Dados para Nuvem ThingsIo.ai
  9. Enviando Dados do IMU Adafruit 10DOF do Raspberry Pi 2 ao Azure Event Hubs com Windows 10 IoT Core
  10. Estação Meteorológica Avançada v2.0: Monitoramento em Tempo Real de Temperatura, Pressão, Umidade e Altitude