×

INDI Library v2.0.7 is Released (01 Apr 2024)

Bi-monthly release with minor bug fixes and improvements

Building a simple GPS 'NMEA server' on an Arduino for INDI?

  • Posts: 7
  • Thank you received: 0
Hello all,

I've been playing around with a few spare 'bits and bobs' and sucessfully made a little GPS receiver using a NEO-8M chip and a spare Arduino I had (plus an ethernet shield). I was just going to use it to set the time on my astroberry / stellarmate when not connected to the network, but then I came across this very interesting driver in the INDI library: www.indilib.org/devices/auxiliary/gps-nmea.html

This seems to do a lot of the hard work for me.... but I cannot fathom how to actually send the data from the GPS chip (using the serial connection, as it were) to generate a web server for the INDI to connect to as client.

So, this is just a shout out to the collective to see if anyone has already tried and come up with a solution, before I spend another day googling! I suspect I have simply miss-understood the syntax/formatting... but so far the detail of how to fix this has eluded me....

Any words of wisdom would be great! (arduno sketch below for those interested...)

Phil


<code>
#include <TinyGPS++.h>
#include <SPI.h>
#include <Ethernet.h>

// The TinyGPS++ object
TinyGPSPlus gps;

// set up the simple web server
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 128);
EthernetServer server(80);

void setup() {
// Open serial communications and wait for port to open:
Serial1.begin(9600);
while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("Ethernet WebServer");

// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}

if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}

// Now, start the server
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());

} //end of setup loop


void loop() {

//Get the GPS data and interpret...
while (Serial1.available() > 0)
gps.encode(Serial1.read());

// 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 you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
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"); // the connection will be closed after completion of the response
client.println("Refresh: 2"); // refresh the page automatically every 2 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");

// Below is the raw output of the GPS chip (NMEA format)... But it doesn't work when added directly to the web server code.
// Formatting/syntax issues? But I wonder what format the GPS NMEA server needs anyway?
//
client.print(F(" Hour=")); // but this is fine... but just goes to the web browser... not the INDI client.
client.print(gps.time.hour());
client.print(F(" Minute="));
client.print(gps.time.minute());
client.print(F(" Second="));
client.println(gps.time.second());

client.println("<br />");

client.print(F(" Lat="));
client.print(gps.location.lat(), 6);
client.print(F(" Long="));
client.println(gps.location.lng(), 6);

client.println("<br />");

client.print(F("#SATS= "));
client.print(gps.satellites.value());
client.print(F(" Meters="));
client.println(gps.altitude.meters());

client.println("<br />");

if (Serial1.available() > 0){
client.println(Serial1.read()); //this works in the serial monotir but in the server only posts two characters...
}

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;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println("client disconnected");
}

// This is the raw output of NMEA ... client wont work when it runs... due to the loop...
//if (Serial1.available() > 0){
//Serial.write(Serial1.read());
//}

// This is the parsed data, using TinyGPS++ to see if it's working - it's fine, in the arduino serial monitor...
//
/* if (gps.location.isUpdated())
{
Serial.print(F("LOCATION Fix Age="));
Serial.print(gps.location.age());
Serial.print(F(" Lat="));
Serial.print(gps.location.lat(), 6);
Serial.print(F(" Long="));
Serial.println(gps.location.lng(), 6);
}
else if (gps.date.isUpdated())
{
Serial.print(F("DATE Fix Age="));
Serial.print(gps.date.age());
Serial.print(F("ms Raw="));
Serial.print(gps.date.value());
Serial.print(F(" Year="));
Serial.print(gps.date.year());
Serial.print(F(" Month="));
Serial.print(gps.date.month());
Serial.print(F(" Day="));
Serial.println(gps.date.day());
}
else if (gps.time.isUpdated())
{
Serial.print(F("TIME Fix Age="));
Serial.print(gps.time.age());
Serial.print(F("ms Raw="));
Serial.print(gps.time.value());
Serial.print(F(" Hour="));
Serial.print(gps.time.hour());
Serial.print(F(" Minute="));
Serial.print(gps.time.minute());
Serial.print(F(" Second="));
Serial.print(gps.time.second());
}
else if (gps.altitude.isUpdated())
{
Serial.print(F("ALTITUDE Fix Age="));
Serial.print(gps.altitude.age());
Serial.print(F("ms Raw="));
Serial.print(gps.altitude.value());
Serial.print(F(" Meters="));
Serial.println(gps.altitude.meters());
}
else if (gps.satellites.isUpdated())
{
Serial.print(F("SATELLITES Fix Age="));
Serial.print(gps.satellites.age());
Serial.print(F("ms Value="));
Serial.println(gps.satellites.value());
}
*/

// the final loop void loop close
}
</code>
Last edit: 3 years 4 months ago by AstroNerd.
3 years 4 months ago #65339

Please Log in or Create an account to join the conversation.

Welcome to INDI forum! So right you'd need to establish a server that write the stream on port 50000 (by default) that is compatible with NMEA streams. Since you have Ethernet shield, I suppose you could use some Arduino library to create such a server? This is a regular TCP/IP server (not web server) that just spits out the stream for someone else (in this case, the INDI driver) to read and parse.
3 years 4 months ago #65373

Please Log in or Create an account to join the conversation.

  • Posts: 7
  • Thank you received: 0
Thanks!

Yes, those were my thought's entirely - looks like my first error (I'm more electronics/mechanics rather than software!) is with the arduino library, which was not set to port 50000 and TCP/IP (now fixed), but still no luck so far. I rather suspect it's how I send the data to the server from the serial that's the issue here: as INDI seems to 'connect' but cannot parse the data, I get the ekos error "[ERROR] Error getting device readings: Connection refused".

Tinkering continues ... at least for today!

Cheers!
3 years 4 months ago #65381

Please Log in or Create an account to join the conversation.

  • Posts: 30
  • Thank you received: 3
I resurrect this old discussion.... maybe it can be useful to someone. I used an ESP8266, connecting a NEO6 GPS module to the TX and RX pins. As firmware, I used the one available on this website: www.forward.com.au/pfod/CheapWifiShield/...fiShield/NMEAbridge/ and everything worked immediately! Be sure to follow the instructions on the website, download all the necessary libraries, etc. There are two versions of the code, one without an HTML configuration page: you have to configure the Wi-Fi access data directly in the file; the second one instead has a configuration page accessible via web browser but works only as a hotspot... so maybe less useful in our case. Now I'll be able to insert the GPS into my allsky weather station and use it to synchronize the position and time with OnStep and Kstars.
Last edit: 1 week 3 days ago by Corrado.
1 week 3 days ago #100670

Please Log in or Create an account to join the conversation.

Time to create page: 0.542 seconds