Go Down

Topic: TV-Out and TinyGPS+ (Read 3110 times) previous topic - next topic

TLS3

Hello.

I'd like to add a small GPS data device on an existing rear view camera (the LCD screen has 2 NTSC inputs).
Using an Arduino Mega 2560, no data is extracted from the GPS module (Neo6M) when TV-out library is called. When a regular 2x16 LCD is used, lcd.print(gpsData) works like a charm.
Listening to the GPS port (Serial1.read) displays the NMEA string, 1 character per second; the TV library should definitly slow down the process.
How can I define the following:
Fixed data on screen
Get NMEA during 10 seconds and extract the parameters thanks to TinyGPS
Flush the average data on the TV screen.

The «blink without delay» method to acquire data failed in my case, it is basically just a simple prog problem I cannot resolve with so few knoledge.
Thank you

-dev

#1
Jul 15, 2016, 04:58 pm Last Edit: Jul 15, 2016, 10:55 pm by /dev
Well, nobody else replied, so I'll give it a shot.

This is an advanced project, because the TV signal generation takes up so much of the MCU's time.  You really can't use Serial.  Instead, you have to use the provided pollSerial, and use it as shown in the NTSCserialTerm.pde. 

It uses the horizontal blanking interval (HBI) to watch the UART for received characters.  If one is ready, it is put into the input buffer.  Then you can read them in loop and, in your case, feed them to the GPS parser.

I would also suggest using NeoGPS, a smaller faster GPS library.  You can also configure it to skip GPS fields and messages that you don't use.  Every little thing helps when the MCU is so busy.

If you put your code in a code block, I can help you convert it pretty quickly.  Either attach the INO file, or put it in line with the "</>" button in the upper left-hand corner of the post editor or insert code tags like this:

[code]// my program
// goes here, between these
//  tags
  .
  .
  .
[/code]

Then it will look like this:

Code: [Select]
// my program
// goes here, between these
//  tags
  .
  .
  .

Be sure to follow the NeoGPS Installation Instructions, because it goes in your sketch subdirectory, not the Libraries folder.

The NeoGPS version of your sketch will look something like this:

Code: [Select]
#include <TVout.h>
#include <pollserial.h>
#include <fontALL.h>
#include "NMEAGPS.h"

NMEAGPS gps;
TVout TV;
pollserial pserial;

void setup()  {
  TV.begin(_NTSC,184,72);
  TV.select_font(font6x8);
  TV.println("GPS Display");
  TV.println("-- Version 1.0 --");
  TV.set_hbi_hook(pserial.begin(9600));
}

void loop() {
  // Check for GPS characters on the pserial port and parse them.
  while (gps.available( pserial )) { // <-- must use new pollserial from reply #7 below!

    //  When enough characters have been parsed,
    //    a complete GPS fix structure is ready to use.
    gps_fix fix = gps.read();

    //  Display some of the fix members
    TV.print( "Lat/Lon: " );
    TV.print( fix.latitude() );
    TV.print( '/' );
    TV.print( fix.longitude() );
    TV.println();
  }
}

There are several ways to optimize this further, and I can suggest a minimal NeoGPS config when you say what pieces you want to display.  (EDIT - attached to reply #7 below)

Cheers,
/dev
Really, I used to be /dev.  :(

-dev

Quote
I had a similar issue...
Thanks for that.  J-M-L had some good suggestions.

Quote
I couldn't even get the pollserial example to compile
Well, that needs to be fixed, for sure.  There's no way the built-in Serial will work.  I'll take a look...

BTW, you *really* need to get rid of String.  There's just no room or time for that here, and it will cause long-term instability.  You've already seen some improvement by reducing your use of String.

Cheers,
/dev
Really, I used to be /dev.  :(

-dev

Ok, I have attached a NTSCserialTerm.ino and pollserial modifications.  Naturally, I can't test the video output, but the serial read and write appears to work on my Mega.

I had to reduce the baud rate, because at 57600, more than two characters are being received before the hbi_hook (USART_receive) is getting called.  At 9600, no characters are lost.  Other bauds might work, too.

Have fun with code I can't test,
/dev

;)
Really, I used to be /dev.  :(

-dev

Quote from: travis_farmer
Hey, cool, it compiles, and works! :D
No. Way.

Say, could you update that other thread, maybe point back to this one, too?  Thanks.

@TLS3, here is the NTSCserialTerm example modified into a NeoGPS example.  I have also modified pollSerial so it can be used on other serial ports, like Serial1 on a Mega, and a little clean-up to bring it in line with HardwareSerial, and a way to select different serial ports.  Hmm... maybe I'll turn this into NeoPolledSerial...

To select the serial port you want to use for the GPS device, modify this line in the attached pollserial.CPP:

Code: [Select]
// set this to 0, 1, 2, 3 or nothing to select a USART
#define PS_PORT_NUMBER 1

@travis_farmer, if you take these files, you would set this line to 0 for your sketch.

These three files use Serial1 for the GPS and Serial for debug prints to the Serial Monitor window.  It will output the current date/time and GPS checksum errors to the Serial Monitor, and it will print the current GPS second to the TV.

Cheers,
/dev
Really, I used to be /dev.  :(

TLS3

Hello folks,
Thank you very much for this guidance, i'll try everything this week end.
I was affraid of this memory/speed concern and thought of dealing with 2 arduinos: one for the sensors/buffer and one just for TV signal generation.
Thank you again, I'll come with updates.

TLS3

Hi again;
Very promising, image is stable, NMEA string is recovered, but for some reason, the TV keeps displaying ASCII characters while the serial monitor is ok:

-dev

That looks like the current GPS second. Does it cycle through 0 to 59?  That's what it's supposed to do, I think.
Really, I used to be /dev.  :(

TLS3

#8
Jul 16, 2016, 07:28 pm Last Edit: Jul 16, 2016, 07:37 pm by TLS3
Well, actually not, it starts as following, then shows the previous screen and loops indefinitely.



*update*
Displaying the satellite number (more or less constant) shows it looks more like a conversion error of the characters

TLS3

Yes it does.
Asking for fix.altitude() gives decent data, with 2 decimal, updated once a second.
Asking for altitude_cm gives rubish

Project is the following: on the TV LCD a rear camera is running
Pressing a button switch to the other TV input, linked to the Arduino Mega.
The Arduino Mega displays GPS data (position, time, altitude, cape, speed, etc) every 10 seconds in block.

TLS3

I'm speaking about what /dev posted, as a beginning for my work.
It looks like a character conversion error in the NeoGPS Library I never used before. Some data are rubbish (like a wrong baud rate), some other displays normally on the TV screen.

-dev

#11
Jul 16, 2016, 09:58 pm Last Edit: Jul 16, 2016, 10:25 pm by /dev
Quote from: TLS3
it starts as following, then shows the previous screen and loops indefinitely.
Please attach your code.  Is suspect you might be calling write instead of print.

(EDIT - TVout is doing this!  Grrr... see next reply.)

Cheers,
/dev
Really, I used to be /dev.  :(

-dev

#12
Jul 16, 2016, 10:06 pm Last Edit: Jul 16, 2016, 10:24 pm by /dev
Quote from: TLS3
It looks like a character conversion error
Doh!  The TVOut library defaults to doing a write for an unsigned char.  That's what printing dateTime.seconds will use.

Ok, try this instead:

      TV.print( fix.dateTime.seconds, DEC );

That should force it to print the integer value of the current second, not the character with that value.  :-/

Cheers,
/dev

Really, I used to be /dev.  :(

-dev

#13
Jul 16, 2016, 10:22 pm Last Edit: Jul 16, 2016, 10:23 pm by /dev
Quote from: travis_farmer
In the example you posted (NTSCneogps.ino), I see...
    if (gps.available( pserial )) {
But I haven't found how NeoGPS handles pserial.
gps.available is a method of the NMEAGPS class (that's the gps variable type).  See line 112 of NMEAGPS.h

As you can see, the first argument to gps.available is the GPS serial port object, pserial.  Actually, you can pass in anything that is derived from the Stream class.  HardwareSerial, AltSoftSerial, Neo**Serial, and pollserial are all derived from Stream, so you can pass any of those in.

The code in NMEAGPS.h calls port.available to see if any characters are available to be read.  If there are, it reads them and parses them with the decode method... which does all the rest of the NeoGPS magic.

The gps.available returns the number of fix structures that are available, not the number of characters on the port.  After hundreds of calls to pollserial.read(), one fix structure has been filled out from all those NMEA sentences.  Finally, one fix structure is available, and calling gps.read will fetch it for you.  Then you can do whatever you need to with the pieces... like

    TV.print( fix.altitude_cm(), DEC );

The problem you ran into is that the TVout class doesn't quite behave like Serial.  That's a mistake, IMHO, but you can make it do what you want with that second argument, DEC.

Cheers,
/dev

Really, I used to be /dev.  :(

TLS3

/dev I owe you a good beer. It works like a charm:


Code: [Select]
#include <TVout.h>
#include "NMEAGPS.h"
#include "pollserial/pollserial.cpp"
#include "TVoutfonts/font6x8.cpp"

NMEAGPS gps;
TVout TV;
pollserial pserial;

const char *banner = "NTSC NeoGPS\n-- Version 0.1 --";

void setup()  {
  Serial.begin( 9600 );
  Serial.println( banner );
  Serial.println( F("Date/Time,CS errors") );
  Serial.flush();

  TV.begin(_NTSC,184,72);
  TV.select_font(font6x8);
  TV.println( banner );
  TV.set_hbi_hook(pserial.begin(9600));
}

void loop() {
  if (gps.available( pserial )) {
    gps_fix fix = gps.read();

    // For debugging, print some things to the Serial Monitor window
    Serial << fix.dateTime;
    Serial.print( ',' );
    Serial.print( fix.satellites );
    Serial.println();
    TV.clear_screen();
    TV.print("HEURE GMT: ");
    TV.print( fix.dateTime.hours, DEC );    //DEC to turn into integer
    TV.print(" : ");
    TV.println( fix.dateTime.minutes, DEC );
    TV.print("Satellites: ");
    TV.print( fix.satellites, DEC );
    TV.println("\n\n\n");
//    TV.delay(500);
  }
}


Now how can I reduce the refresh rate of the GPS, the TV screen blinks at each new frame (1/sec) and i'm afraid it could disturb while driving, TV.delay freeze the incoming data.

~Travis: you are absolutely right about the 4800 bauds, but the new ones from ebay are now 9600 bauds.

Go Up