
ÍNDICE DE CONTEÚDO
- Localização aproximada via IP com ESP8266 - Parte 1
- Localização aproximada via IP com ESP8266 - Parte 2
Introdução
Essa é a parte 1 da série Localização aproximada via IP com ESP8266. Na parte 1 será desenvolvido um Web Client com ESP8266 onde o mesmo será capaz de fazer requisições HTTP GET e POST, recebendo sua localização aproximada e posteriormente enviando esses dados a um Web Server. Na parte 2 será desenvolvido um Web Server em Node.js que recebe a localização aproximada do ESP8266 e exibe em uma página do Google Maps.
O módulo ESP8266 é atualmente uma das plataformas mais populares entre makers para desenvolvimento de projetos conectados à Internet. Podemos encontrá-lo em projetos desde Acionamento de Eletrodomésticos via Web até Dispositivos de Assistência Médica Pessoal. Essa popularidade é devida ao seu baixo custo e facilidade de desenvolvimento, podendo ser integrado e programado usando a IDE Arduino. Neste artigo utilizaremos a versão ESP-01 da família ESP8266.

Em um mundo IoT onde hoje existem diversos desses dispositivos conectados à internet gerando uma quantidade inimaginável de dados, uma coisa interessante a se saber é a localização e origem desses dispositivos.
Neste artigo iremos mostrar como obter a geolocalização aproximada de um módulo ESP8266 conectado à Internet e enviar esses dados para um servidor que exibe uma página Web com Google Maps e um marcador na localização aproximada.
Recomenda-se fortemente a leitura do artigo escrito por Pedro Bertoleti, BeagleBone Black - Localização aproximada via IP, onde o autor obtém a geolocalização aproximada de uma Beaglebone Black via IP usando a linguagem Python.
Pré Requisitos
Para a reprodução deste artigo, é necessário ter:
- Um módulo WiFi ESP8266 ESP-01;
- Um roteador WiFi conectado à Internet;
- Noções de programação usando a IDE Arduino e suas bibliotecas;
- Noções do protocolo HTTP e seus métodos de requisição GET e POST;
- Noções de JSON.
Programando ESP8266 com IDE Arduino
Para possibilitar a programação do módulo ESP8266 usando a IDE Arduino, execute os seguintes passos:
- Abra a IDE Arduino
- Clique em File -> Preferences
- Adicione a seguinte URL no campo Additional Boards Manager URLs e clique OK
http://arduino.esp8266.com/stable/package_esp8266com_index.json
- Clique em Tools -> Board -> Bards Manager
- Encontre a placa esp8266 by ESP8266 Community e clique em instalar.
Assim teremos disponíveis as placas da linha ESP8266, suas bibliotecas e exemplos incluídos.
Funcionamento da API de Geolocalização via IP
Dentre alguns serviços da web que fornecem uma API de Geolocalização via IP, temos o ip-api.com. Além de ser free, é bem fácil de usar. Basta apenas enviarmos uma requisição HTTP GET (para testes pode-se usar cURL) para o link http://ip-api.com/json e receberemos o seguinte JSON como resposta:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | $ curl -X GET http://ip-api.com/json { "as": "CLARO S.A.", "city": "Artur Nogueira", "country": "Brazil", "countryCode": "BR", "isp": "Virtua", "lat": -22.5833, "lon": -47.15, "org": "Virtua", "query": "177.194.xx.xxx", "region": "SP", "regionName": "Sao Paulo", "status": "success", "timezone": "America/Sao_Paulo", "zip": "13160" } |
Usando o selecionador de itens, podemos especificar quais itens desejamos receber como resposta.

Selecionando apenas country,region,city,lat,lon,query, podemos fazer uma requisição GET no seguinte link:
http://ip-api.com/json/?fields=country,region,city,lat,lon,query
Ou também usar a forma numérica para economizar largura de banda:
http://ip-api.com/json/?fields=8405
E receberemos do servidor o seguinte JSON:
1 2 3 4 5 6 7 8 | { "city": "Artur Nogueira", "country": "Brazil", "lat": -22.5833, "lon": -47.15, "query": "177.194.xx.xxx", "region": "SP" } |
Implementando requisições HTTP no ESP8266
A biblioteca que possibilita ao ESP8266 se portar como um Web Client e fazer requisições HTTP é a ESP8266WiFi que pode ser incluída no código com ‘#include <ESP8266WiFi.h>’.
A função que faz a requisição HTTP GET para receber os dados de gelolocalização é a seguinte:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | String makeGETlocation() { if ( !client.connect(IpApiHost, 80) ) { Serial.println("connection ao ip-api.com falhou"); return "connection failed"; } // Realiza HTTP GET request client.println("GET /json/?fields=8405 HTTP/1.1"); client.print("Host: "); client.println(IpApiHost); client.println("Connection: close"); client.println(); // recebe o Header de resposta, // cada linha do header termina com "\r\n", a última linha é vazia (“\r\n”) while (client.connected()) { String data = client.readStringUntil('\n'); Serial.println(data); if (data == "\r") { break; } } // recebe os dados de geolocalização em formato JSON e guarda na variável data String data = client.readStringUntil('\n'); Serial.println("Dados de geolocalização recebidos\n"); //Serial.println(data); return data; } |
Primeiramente, tentamos conectar ao Host ip-api.com na porta 80, então fazemos uma requisição GET da seguinte maneira:
1 2 3 4 | GET /json/?fields=8405 HTTP/1.1 Host: ip-api.com Conection: close <linha vazia> |
Logo após, o servidor ip-api retorna com um Header (Cabeçalho). Lemos o Header até chegarmos na linha vazia “\r\n”.
1 2 3 4 5 6 7 | HTTP/1.1 200 OK Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 Date: Wed, 11 Jan 2017 13:10:22 GMT Content-Length: 111 Connection: close <linha vazia “\r\n”> |
Após o Header lemos o JSON com os dados de geolocalização e imprimimos no console serial.
1 2 3 4 5 6 7 8 9 10 11 12 | Requisitando Geolocalização via IP HTTP/1.1 200 OK Access-Control-Allow-Origin: * Content-Type: application/json; charset=utf-8 Date: Wed, 11 Jan 2017 13:10:22 GMT Content-Length: 111 Connection: close Dados de geolocalização recebidos {"city":"Artur Nogueira","country":"Brazil","lat":-22.5833,"lon":-47.15,"query":"177.194.26.233","region":"SP"} |
Para enviarmos o JSON recebido ao servidor, fazemos uma requisição POST no link ‘/location’ indicando o endereço e porta do servidor. A função que realiza essa tarefa é a seguinte:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | void makePOSTlocation() { String location = makeGETlocation(); // guarda o JSON de geolocalização na variável location if(!client.connect(rpiHost, 3000)) // aqui conectamos ao servidor { Serial.print("Could not connect to host: \n"); Serial.print(rpiHost); } else { // realiza HTTP POST request client.println("POST /location HTTP/1.1"); client.println("Host: 192.168.0.24"); client.println("Content-Type: application/json"); client.print("Content-Length: "); client.println(location.length()); client.println(); client.println(location); // enviamos o JSON ao servidor } } |
Código Completo
O código completo pode ser visto e analisado abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | #include <ESP8266WiFi.h> #include <ArduinoJson.h> // Definições da rede Wifi const char* SSID = "nome da rede"; const char* PASSWORD = "senha da rede"; // endereço IP local do Servidor Web instalado na Raspberry Pi 3 // onde será exibida a página web const char* rpiHost = "192.168.0.24"; // servidor que disponibiliza serviço de geolocalização via IP const char* IpApiHost = "ip-api.com"; WiFiClient client; /* * função que conecta o NodeMCU na rede Wifi * SSID e PASSWORD devem ser indicados nas variáveis */ void reconnectWiFi() { if(WiFi.status() == WL_CONNECTED) return; WiFi.begin(SSID, PASSWORD); while(WiFi.status() != WL_CONNECTED) { delay(100); Serial.print("."); } Serial.println(); Serial.print("Conectado com sucesso na rede: "); Serial.println(SSID); Serial.print("IP obtido: "); Serial.println(WiFi.localIP()); } void initWiFi() { Serial.println("\nIniciando configuração WiFi\n"); delay(10); Serial.print("Conectando-se na rede: "); Serial.println(SSID); Serial.println("Aguarde"); reconnectWiFi(); } /* * Função que realiza GET request no site ip-api.com * Esse site disponibiliza uma API de geolocalização via IP * A função retorna um JSON com dados de geolocalização * Os dados de geolocalização são exibidos na pagina web em um Google Maps */ String makeGETlocation() { Serial.println("\nRequisitando Geolocalização via IP\n"); if ( !client.connect(IpApiHost, 80) ) { Serial.println("connection ao ip-api.com falhou"); return "connection failed"; } // Realiza HTTP GET request client.println("GET /json/?fields=8405 HTTP/1.1"); client.print("Host: "); client.println(IpApiHost); client.println("Connection: close"); client.println(); // recebe o Header de resposta, // cada linha do header termina com "\r\n", a ultima linha é fazia, ou seja, "\r\n" apenas while (client.connected()) { String data = client.readStringUntil('\n'); // lê uma linha até o "\n" Serial.println(data); if (data == "\r") { // a ultima linha do header é vazia, ou seja apenas "\r\n", se lermos até "\n", temos apenas "\r" break; } } // recebe os dados de geolocalização em formato JSON e guarda na variável data String data = client.readStringUntil('\n'); Serial.println("Dados de geolocalização recebidos\n"); Serial.println(data); return data; } /* * Função que envia ao servidor a localização do NodeMCU * função realiza um POST request ao servidor no link /location * o servidor por sua vez exibe a localização do NodeMCU no Google Maps */ void makePOSTlocation() { String location = makeGETlocation(); // guarda o JSON de geolocalização na variável location Serial.println("\nEnviando geolocalização ao servidor\n"); if(!client.connect(rpiHost, 3000)) // aqui conectamos ao servidor { Serial.print("Could not connect to host: \n"); Serial.print(rpiHost); } else { // realiza HTTP POST request client.println("POST /location HTTP/1.1"); client.println("Host: 192.168.0.24"); client.println("Content-Type: application/json"); client.print("Content-Length: "); client.println(location.length()); client.println(); client.println(location); // enviamos o JSON ao servidor Serial.println("\nLocalização enviada com sucesso!"); } } void setup() { Serial.begin(115200); initWiFi(); makePOSTlocation(); } void loop() { } |
Conclusão
Neste artigo foi desenvolvido um Web Client usando o módulo WiFi ESP8266 ESP-01 que utiliza da API do site ip-api.com para receber sua geolocalização aproximada via IP. Esse tipo de aplicação pode ser usada quando é necessário identificar a localização de um determinado dispositivo e quando não há possibilidade de usar um GPS no projeto.
Não deixe de ler a parte 2 desse artigo! Iremos mostrar os dados de geolocalização em um Google Maps!
Referências
https://www.embarcados.com.br/modulo-esp8266/
https://www.embarcados.com.br/esp8266-com-arduino/
http://www.whatimade.today/esp8266-easiest-way-to-program-so-far/
https://github.com/esp8266/Arduino
http://ip-api.com/docs/api:json
http://www.w3schools.com/tags/ref_httpmethods.asp
https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
- Localização aproximada via IP com ESP8266 - Parte 1
- Localização aproximada via IP com ESP8266 - Parte 2
NEWSLETTER
Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Localização aproximada via IP com ESP8266 - Parte 1 por Giovanni Bauermeister. Esta obra está licenciado com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Deixe um comentário
6 Comentários em "Localização aproximada via IP com ESP8266 - Parte 1"
Hi, I've written a library to get position from Wi-Fi networks around using Google maps location API. You may have a look to it in https://github.com/gmag11/ESPWifiLocation
Hi Germán. Thanks! I will have a look and test your library.
Boa tarde,
Primeiramente parabéns pelo Blog, conteúdo muito interessante e de simples compreensão. Porém, eu trabalho com programação e não intendo muito de eletrônica, e gostaria de programar alguns sensores do esp8266 nodemcu. Eu vi que alguns você pode conectar direto na placa sem o protoboard.
Segue um que eu vi na internet (RGB SMD LED Module 5050): http://www.ebay.com/itm/181307916806?_trksid=p2060353.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT
Gostaria de saber, o que eu deveria levar em consideração, quando for comprar algum sensor pra conectar direto no esp8266 nodemcu? Somente sensores com 3.3V para a alimentação são possíveis?
Olá Fábio. Obrigado pela leitura do artigo!
O NodeMCU e a família ESP em geral aceitam apenas níveis de 3,3V. Se não estou enganado os GPIOs suportam corrente máxima de 12mA.
Creio que esse modulo de LED SMD que vc indicou poderia ser usado com ESP sem problemas.
Muito bom esse artigo Giovanni Bauermeister, aguardando a segunda parte
Muito obrigado pela leitura Marcelo! Já saiu a segunda parte!