I’m here, where are you?

I started to work with a ESP8266 NodeMCU module to connect to Internet and perform continuous ping commands to random IP numbers. After a few trials and errors I was successful. I then moved to include a repository for finding the IP geolocation. I then hit a wall with the library for this module. It seems that the Adafruit version of the ESP8266 has better documentation for creating the geolocation so I ordered one.
My idea originally was to create a laser projector that points to the IP coordinates. After an intensive search I’m not sure this would be possible using a ESP8266 module. I’m still asking around to see if there’s a way of doing it but also thinking of alternative ways to display the information.
I’m using the following repositories:

https://github.com/esp8266/Arduino
https://github.com/dancol90/ESP8266Ping
https://github.com/m0xpd/ESP8266-GeoLocation/blob/master/ESP8266_GeoLocate_1.ino

I will also have to deal that I cannot connect the module to the New School wifi nor to my phone but just to a regular wifi. In order to exhibit the piece in my finals in my studio I need it to be connected to the internet.

I was receiving help from a DT tutor to incorporate the geolocation library and according to them this is what makes the code not to work with our module:

if (client.connect(server, 80)) {
Serial.println(“connected to server”);
client.println(“GET /json/ HTTP/1.1\r\nHost: freegeoip.net\r\n\r\n”);
Serial.print(“\r\nReading response…”);
country[0] = region[0] = city[0] = 0; // Clear data
jsonParse(0, 0);

all the code here:

/*
* With this library an ESP8266 can ping a remote machine and know if it’s reachable.
* It provides some basic measurements on ping messages (avg response time).
*/

#include <ESP8266WiFi.h>
#include <ESP8266Ping.h>

#include <ArduinoJson.h>
// variables for location service…

char
country[20],
region[20],
city[20],
name[13], // Temp space for name:value parsing
value[64]; // Temp space for name:value parsing
float
longitude, latitude;
char server[] = “freegeoip.net”; // (using DNS)

char ssid[] = “iotf17class”; // your network SSID (name)
char password[] = “iotf17class”; // your network password

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
WiFiClient client;

//const char* ssid = “iotf17class”;
//const char* password = “iotf17class”;

int A;
int B;
int C;
int D;

void setup() {
DynamicJsonBuffer jsonBuffer;
Serial.begin(115200);
delay(10);
// We start by connecting to a WiFi network

Serial.println();
Serial.println(“Connecting to WiFi”);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(“.”);
}

}

void loop() {

uint32_t ip = 0L;

A = random (255);
B = random (255);
C = random (255);
D = random (255);

const IPAddress remote_ip(A,B,C,D);

Serial.println();
Serial.print(“WiFi connected with ip “);
Serial.println(WiFi.localIP());

Serial.print(“Pinging ip “);
Serial.println(remote_ip);

if(Ping.ping(remote_ip,10)) {
Serial.println(“Success!!”);

delay(100);

Serial.println(“IP address: “);
ip=WiFi.localIP();
Serial.println(ip);
Serial.println(“\nStarting connection to server…”);
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println(“connected to server”);
// Make a HTTP request:
client.println(“GET /json/ HTTP/1.1\r\nHost: freegeoip.net\r\n\r\n”);
Serial.print(“\r\nReading response…”);
country[0] = region[0] = city[0] = 0; // Clear data
jsonParse(0, 0);
client.println(“Connection: close”);
Serial.println(F(“OK”));
Serial.println(F(“\nDisconnecting”));
client.stop();
}
Serial.print(F(“\r\nRESULTS:\r\n Country: “));
Serial.println(country);
Serial.print(F(” Region: “));
Serial.println(region);
Serial.print(F(” City: “));
Serial.println(city);
Serial.print(F(” Longitude: “));
Serial.println(longitude);
Serial.print(F(” Latitude: “));
Serial.println(latitude);

} else {
Serial.println(“Error :(“);
}

}

boolean jsonParse(int depth, byte endChar) {
int c, i;
boolean readName = true;
for(;;) {
while(isspace(c = timedRead())); // Scan past whitespace
if(c < 0) return false; // Timeout
if(c == endChar) return true; // EOD

if(c == ‘{‘) { // Object follows
if(!jsonParse(depth + 1, ‘}’)) return false;
if(!depth) return true; // End of file
} else if(c == ‘[‘) { // Array follows
if(!jsonParse(depth + 1,’]’)) return false;
} else if((c == ‘”‘) || (c == ‘\”)) { // String follows
if(readName) { // Name-reading mode
if(!readString(name, sizeof(name)-1, c)) return false;
} else { // Value-reading mode
if(!readString(value, sizeof(value)-1, c)) return false;
// Process name and value strings:
if (!strcasecmp(name, “country_name”)) {
strncpy(country, value, sizeof(country)-1);
} else if(!strcasecmp(name, “region_name”)) {
strncpy(region, value, sizeof(region)-1);
} else if(!strcasecmp(name, “city”)) {
strncpy(city, value, sizeof(city)-1);
}
}
} else if(c == ‘:’) { // Separator between name:value
readName = false; // Now in value-reading mode
value[0] = 0; // Clear existing value data
} else if(c == ‘,’) { // Separator between name/value pairs
readName = true; // Now in name-reading mode
name[0] = 0; // Clear existing name data
} else {
// Else true/false/null or a number follows.
value[0] = c;
if(!strcasecmp(name, “longitude”)) {
if(!readString(value+1, sizeof(value)-1, ‘,’)) return false;
longitude = atof(value);
} else if(!strcasecmp(name, “latitude”)) {
if(!readString(value+1, sizeof(value)-1, ‘,’)) return false;
latitude = atof(value);
}
readName = true; // Now in name-reading mode
name[0] = 0; // Clear existing name data
}
}
}

// Read from client stream with a 5 second timeout. Although an
// essentially identical method already exists in the Stream() class,
// it’s declared private there…so this is a local copy.
int timedRead(void) {
unsigned long start = millis();
while((!client.available()) && ((millis() – start) < 5000L));
return client.read(); // -1 on timeout
}

// Read string from client stream into destination buffer, up to a maximum
// requested length. Buffer should be at least 1 byte larger than this to
// accommodate NUL terminator. Opening quote is assumed already read,
// closing quote will be discarded, and stream will be positioned
// immediately following the closing quote (regardless whether max length
// is reached — excess chars are discarded). Returns true on success
// (including zero-length string), false on timeout/read error.
boolean readString(char *dest, int maxLen, char quote) {
int c, len = 0;

while((c = timedRead()) != quote) { // Read until closing quote
if(c == ‘\\’) { // Escaped char follows
c = timedRead(); // Read it
// Certain escaped values are for cursor control —
// there might be more suitable printer codes for each.
if (c == ‘b’) c = ‘\b’; // Backspace
else if(c == ‘f’) c = ‘\f’; // Form feed
else if(c == ‘n’) c = ‘\n’; // Newline
else if(c == ‘r’) c = ‘\r’; // Carriage return
else if(c == ‘t’) c = ‘\t’; // Tab
else if(c == ‘u’) c = unidecode(4);
else if(c == ‘U’) c = unidecode(8);
// else c is unaltered — an escaped char such as \ or ”
} // else c is a normal unescaped char

if(c < 0) return false; // Timeout

// In order to properly position the client stream at the end of
// the string, characters are read to the end quote, even if the max
// string length is reached…the extra chars are simply discarded.
if(len < maxLen) dest[len++] = c;
}

dest[len] = 0;
return true; // Success (even if empty string)
}

// Read a given number of hexadecimal characters from client stream,
// representing a Unicode symbol. Return -1 on error, else return nearest
// equivalent glyph in printer’s charset. (See notes below — for now,
// always returns ‘-‘ or -1.)
int unidecode(byte len) {
int c, v, result = 0;
while(len–) {
if((c = timedRead()) < 0) return -1; // Stream timeout
if ((c >= ‘0’) && (c <= ‘9’)) v = c – ‘0’;
else if((c >= ‘A’) && (c <= ‘F’)) v = 10 + c – ‘A’;
else if((c >= ‘a’) && (c <= ‘f’)) v = 10 + c – ‘a’;
else return ‘-‘; // garbage
result = (result << 4) | v;
}

return ‘?’;
}

Leave a Reply

Your email address will not be published. Required fields are marked *