×

INDI Library v2.0.6 is Released (02 Feb 2024)

Bi-monthly release with minor bug fixes and improvements

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

  • Posts: 6
  • 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 2 months ago by AstroNerd.
3 years 2 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 2 months ago #65373

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

  • Posts: 6
  • 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 2 months ago #65381

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

Time to create page: 1.120 seconds