U-blox Neo-7m with the ATSAMD21 Feather M0 and the Feather Wing TFT

Dear Arduino-fellows,

I am trying to connect this GPS (U-blox Neo-7m) module:
Click here for ebay link
With Gnd, VCC, Rx, Tx pin:

To the Feather M0 & Feather Wing TFT:

Most libraries and examples that I found online use the SoftwareSerial library that causes problems with ATSAMD21 processors.
The most useful tutorial that I’ve found seems to be this one:

With the following code. Can I connect the Tx pin of the GPS module to the Rx ping of the Feather M0? Are there better libraries/code examples to use the ATSAMD21 with u-blox modules?

The goal of the project is to track LoRaWAN signal quality and GPS coordinates at the same time. The project without the GPS tracking is described here:
https://github.com/ImprobableStudios/Feather_TFT_LoRa_Sniffer

/*
	Develop by:		Vicente Arturo Zavala Ortiz
	Date:			March 21 2017 1:15:35 PM
	Description:	GPS Test
*/

#include "TFT.h"
#include "TinyGPS.h"

#define TFT_DISPLAY

#define GPSBaud								9600
#define SerialMonitor						SerialUSB
#define gpsPort								Serial

// The TinyGPS object
TinyGPS gps;

void printDateTime(TinyGPSDate &d, TinyGPSTime &t);
void printStr(const char *str, int len);
void printInt(unsigned long val, bool valid, int len);
void printFloat(float val, bool valid, int len, int prec);
bool readGPS(unsigned long ms);

void setup()
{
	// add setup code here
	#ifdef TFT_DISPLAY
		Tft.init();
	#else
		SerialMonitor.begin(GPSBaud);
	#endif

	delay(100);

	gpsPort.begin(GPSBaud);
}

void loop()
{
	// add main program code here 
	readGPS(5000);
	
	#ifdef TFT_DISPLAY
		Tft.set_font_size(3);
		printDateTime(gps.date, gps.time);
		Tft._putchar('\n');
		Tft._puts("LAT: ");
		printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
		Tft._putchar('\n');
		Tft._puts("LNG: ");
		printFloat(gps.location.lng(), gps.location.isValid(), 11, 6);
		Tft._putchar('\n');		
	#else
		printDateTime(gps.date, gps.time);
		SerialMonitor.println();
		SerialMonitor.print("LAT: ");
		printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
		SerialMonitor.print(" LNG: ");
		printFloat(gps.location.lng(), gps.location.isValid(), 11, 6);
		SerialMonitor.println();		
	#endif
 	
	delay(5000);
		
	Tft.clrscr();
	
	if(millis() > 5000 && gps.charsProcessed() < 10)
	{
		#ifdef TFT_DISPLAY
			Tft._puts("No GPS data received: check wiring\n");
		#else
			SerialMonitor.println("No GPS data received: check wiring");
		#endif		
	}
}

bool readGPS(unsigned long ms)
{
	for(unsigned long start = millis(); millis() - start < ms;)
	{
		if(gpsPort.available()) 
		{
			if(gps.encode(gpsPort.read())) 
			{
				if(gps.location.isValid()) {
					return true;
				}
			}
		}
	}
	
	return false;
}

static void printFloat(float val, bool valid, int len, int prec)
{
	if(valid)
	{
		#ifdef TFT_DISPLAY
			Tft.print_float(val);
		#else
			SerialMonitor.print(val, prec);
		#endif
		
		int vi		= abs((int) val);
		int flen	= prec + (val < 0.0 ? 2 : 1);
		
		flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
		
		for(int i=flen; i<len; ++i) {
			#ifdef TFT_DISPLAY
				Tft._putchar(' ');
			#else
				SerialMonitor.print(' ');
			#endif
		}
	}

	readGPS(0);
}

static void printInt(unsigned long val, bool valid, int len)
{
	char sz[32] = "*****************";
	
	if(valid)
		sprintf(sz, "%ld", val);
	
	sz[len] = 0;
	
	for(int i=strlen(sz); i<len; ++i)
		sz[i] = ' ';
	
	if(len > 0)
		sz[len - 1] = ' ';
	
	#ifdef TFT_DISPLAY
		Tft._puts(sz);
	#else
		SerialMonitor.print(sz);
	#endif
	
	readGPS(0);
}

static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
{
	if(d.isValid()) 
	{
		char sz[32];

		sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
		
		#ifdef TFT_DISPLAY
			Tft._puts(sz);
			Tft._putchar('\n');
		#else
			SerialMonitor.print(sz);
		#endif
	}
	
	if(t.isValid()) 
	{
		char sz[32];
		
		sprintf(sz, "%02d:%02d:%02d ", (t.hour() + gps.timeZone()), t.minute(), t.second());
		
		#ifdef TFT_DISPLAY
			Tft._puts(sz);
			Tft._putchar('\n');
		#else
			SerialMonitor.print(sz);
		#endif
	}

	//printInt(d.age(), d.isValid(), 5);
	readGPS(0);
}

static void printStr(const char *str, int len)
{
	int slen = strlen(str);
	
	for(int i=0; i<len; ++i) 
	{
		#ifdef TFT_DISPLAY
			Tft._putchar(i < slen ? str[i] : ' ');
		#else
			SerialMonitor.print(i < slen ? str[i] : ' ');
		#endif
	}
	
	readGPS(0);
}

Hi.

I've had three very similar modules, but using the neo-6M.

I use Mikal Hart's TinyGPS++ library. It is worth exploring all the examples he provides. While he uses software serial for the GPS input, it is not hard to switch to hardware serial.

Have you been able to see any NMEA sentences output from the module so far?

John.

mbobinger:
The goal of the project is to track LoRaWAN signal quality

As well as scanning the typical 8 frequencies in use by LoRaWAN you will need to scan 6 spreading factors on each frequency.

srnet:
As well as scanning the typical 8 frequencies in use by LoRaWAN you will need to scan 6 spreading factors on each frequency.

Thank you for your comment! I am following this project:
https://github.com/ImprobableStudios/Feather_TFT_LoRa_Sniffer/blob/master/Feather_TFT_LoRa_Sniffer.ino

My code for the frequency scanning is:

// How long should a frequency be monitored
#define FREQ_TIME_MS            5000

// Used to track how many packets we have seen on each frequency above
uint16_t _packetCounts[FREQ_COUNT] = { 0 };

// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT);

Adafruit_ILI9341 _tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

uint8_t  _rxBuffer[RH_RF95_MAX_MESSAGE_LEN];                // receive buffer
uint8_t  _rxRecvLen;                                        // number of bytes actually received
char     _printBuffer[512]  = "\0";                         // to send output to the PC
uint32_t _freqExpire        = 0;                            // Millisecond at which frequency should change
uint32_t _freqIndex         = 0;                            // Which frequency is currently monitored
bool     _sdReady           = false;                        // Is a file open and ready for writing?
File     _logfile;                                          // Log file on SD card

How can I also scan the different spreading factors? My LoRaWAN sniffer only reports 0 values.

Thank you!

mbobinger:
How can I also scan the different spreading factors? My LoRaWAN sniffer only reports 0 values.

Thank you!

Read the library documentation and work out how to change spreading factors, SF7 to SF12 are used.

NissanCedric:
Hi.

I’ve had three very similar modules, but using the neo-6M.

I use Mikal Hart’s TinyGPS++ library. It is worth exploring all the examples he provides. While he uses software serial for the GPS input, it is not hard to switch to hardware serial.

Have you been able to see any NMEA sentences output from the module so far?

John.

Hi John,

Thank you for your help. Using TinyGPS library I’ve received some NMEA sentences already:

17:05:13.630 -> Time: 15:05:15.000
17:05:13.630 -> Date: 8/8/2019
17:05:13.630 -> Fix: 0 quality: 0
17:05:13.667 -> $GPRMC,150516.00,V,,,,,,,080819,,,N*73
17:05:13.667 -> 
17:05:13.667 -> $GPVTG,,,,,,,,,N*30
17:05:13.667 -> 
17:05:13.733 -> $GPGGA,150516.00,,,,,0,00,99.99,,,,,,*60
17:05:13.733 -> 
17:05:13.767 -> $GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
17:05:13.767 -> 
17:05:13.801 -> $GPGSV,1,1,01,32,,,19*71
17:05:13.801 -> 
17:05:13.834 -> $GPGLL,,,,,150516.00,V,N*4C
17:05:13.834 -> 
17:05:14.648 -> $GPRMC,150517.00,V,,,,,,,080819,,,N*72
17:05:14.648 -> 
17:05:14.682 -> $GPVTG,,,,,,,,,N*30
17:05:14.682 -> 
17:05:14.717 -> $GPGGA,150517.00,,,,,0,00,99.99,,,,,,*61
17:05:14.717 -> 
17:05:14.785 -> $GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
17:05:14.785 -> 
17:05:14.785 -> $GPGSV,1,1,01,32,,,19*71
17:05:14.785 -> 
17:05:14.819 -> $GPGLL,,,,,150517.00,V,N*4D
17:05:14.819 ->

The serial connection is set as follows:

#include <Adafruit_GPS.h>

// what's the name of the hardware serial port?
#define GPSSerial Serial1

// Connect to the GPS on the hardware port
Adafruit_GPS GPS(&GPSSerial);

The serial connection seems to work but I haven’t been able to get a fix so far (yesterday i got one using u-center but today it took longer than 10 minutes again, even though I was on the roof). I have also tested it with u-center. Thus, I have purchased an active amplifier.

Is there any more efficient library than the one from Adafruit. You suggested the TinyGPS++ that uses following serial connection:

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

How can i adapt it for my case? Using the HardwareSerial library?
To give you a better idea of what I am doing, I have attached two images of the Hardware.

Thank you!

srnet:
Read the library documentation and work out how to change spreading factors, SF7 to SF12 are used.

Hi srnet, thank you for your help!
Obviously, the radiohead library and in particular #include <RH_RF95.h> is used:
http://www.airspayce.com/mikem/arduino/RadioHead/classRH__RF95.html#ade668dcd0730fef266c8d94c7e6e7085

However, in these projects no spreading factor is defined:
https://github.com/ImprobableStudios/Feather_TFT_LoRa_Sniffer
https://github.com/LooUQ/Arduino-LoRa-Sniffer/blob/master/Arduino-LoRa-Sniffer.ino

and the sniffers are probably still working. How does that come?

mbobinger:
the sniffers are probably still working. How does that come?

Working on one spreading factor only I suspect, and thus potentially only seeing one in six packets.

The Radio Head library is maybe not a good choice for such a scanner, there does not appear to be a direct way of changing spreading factor, without a resonable inderstanding of how to set the registers directly on the SX127x.

You are tackling several technologies at once. It might be a good idea to master them separately before putting them all together in one package. The GPS is I think the easiest to master.

Your sentences show you have the correct pin connections and baud rate setting. You are getting some satellite signals, enough to provide time and date (15:05:17.00 and 08/08/2019 in the RMC sentence). But no navigational data, hence all those commas with nothing between them.

I always use u-center to prove I have a fix before using an Arduino to do something with the data.

I do this: connect the module to laptop via a USB cable (one that handles data, not just a charging cable). Don’t connect the GPS to anything else. Windows Device Manager shows me which COM port has been allocated to the GPS. Connect u-center to that port and monitor the sat signals and NMEA sentences. I don’t see sense in struggling with sketches until you are confident you can reliably get a fix.

I use this type of antenna, that has a 3m cable; makes a big difference; it can go on roof of house or car:

GPS puck style antenna

The short stick like antenna that screws directly to the GPS socket works too.

The pundits warn of interference from Arduino boards & laptops. In your image you have it very close to the scanner; I don’t know, but perhaps their is a possibility of RF interference between them.

It helps to have a ground plane – this is formed by placing the antenna on a sheet of metal, like car roof.

Good luck. It’s a thrill when you see the blue sat signals suddenly change to green. I’ve attached a screen shot showing great reception.

John.

mbobinger:

// The TinyGPS++ object

TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);




How can i adapt it for my case? Using the HardwareSerial library?
To give you a better idea of what I am doing, I have attached two images of the Hardware.

You don't need a "HardwareSerial" library. You use the functions defined in Arduino's Reference section, sub heading "Serial".

I'm not familiar with Adafruit boards -- do you know how many h/w serial ports it has?

John.

NissanCedric:
You don't need a "HardwareSerial" library. You use the functions defined in Arduino's Reference section, sub heading "Serial".

I'm not familiar with Adafruit boards -- do you know how many h/w serial ports it has?

John.

Dear John,

I would just like to thank you for your friendly and helpful comments. I will first troubleshoot a bit more on my own and then eventually get back to the forum :).