0

Mega 2560 with GPS and TFT TS compatibility
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Mega 2560 with GPS and TFT TS compatibility

by raidoh on Sun Feb 17, 2019 3:53 pm

I'm trying to use a Mega 2560 with the Adafruit Ultimate GPS Shield and Adafruit 2.8" TFT Touch Shield v2 - Resistive shield. I can use each shield individually but together the TFT just displays a white screen, though it does appear to write to the microSD. I've wired the GPS 8 -> Mega Tx1 and GPS 7 -> Mega Rx1. My code is below, and it's based just on examples while I try to get these all working together.

Code: Select all | TOGGLE FULL SIZE

#include <SD.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <avr/sleep.h>
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"

// Set the shield pins, RST and DC can be shared by shields
#define DC 9
#define MISO 50   // UNO MISO = 12
#define MOSI 51   // UNO MOSI = 11
#define SCLK 52   // UNO SCK = 13
#define TS_CS 8   // Resistive touchscreen chipSelect
#define TFT_CS 10 // TFT display chipSelect
#define SD_CS 4   // microSD card on the TFT shield chipSelect
#define GPS_CS 53  // GPS chipSelect

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
//Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, DC);
// If using the breakout, change pins as desired
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, DC, MOSI, SCLK);

// Using the Adafruit Ultimate GPS module shield
// If using hardware serial (e.g. Arduino Mega):
//   Connect the GPS TX (transmit) pin to Arduino RX1, RX2 or RX3
//   Connect the GPS RX (receive) pin to matching TX1, TX2 or TX3
//SoftwareSerial mySerial(8, 7);
#define mySerial Serial1
Adafruit_GPS GPS(&mySerial);
// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences.
#define GPSECHO  false
/* set to true to only log to SD when GPS has a fix, for debugging, keep it false */
#define LOG_FIXONLY true
// this keeps track of whether we're using the interrupt; off by default!
boolean usingInterrupt = true;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy
File logfile;
unsigned long logLast = 20;
uint32_t timer = millis();
char filename[] = "GPSLOG00.TXT";

#define ECHO_TO_SERIAL   1 // echo data to serial port
#define DEBUG 1 // output debugging Serial prints
 
void setup() {
  // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
  // also spit it out
  tft.begin();
  Serial.begin(115200);
  tft.fillScreen(ILI9341_BLACK);
  tft.setCursor(0, 0);
  tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
  tft.println("Adafruit GPS library basic test!");
  tft.println("Ultimate GPSlogger Shield");
  //pinMode(ledPin, OUTPUT);

  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(GPS_CS, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(SD_CS, MOSI, MISO, SCLK)) {
  //if (!SD.begin(SD_CS)) {      // if you're using an UNO, you can use this line instead
    Serial.println("Card init. failed!");
    error(2);
  }

  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = '0' + i/10;
    filename[7] = '0' + i%10;
    // create if does not exist, do not open existing, write, sync after write
    if (! SD.exists(filename)) {
      logfile = SD.open(filename, FILE_WRITE);
    }
  }

  if( ! logfile ) {
    Serial.print("Could not create ");
    Serial.println(filename);
    error(3);
  }
  Serial.print("Writing to ");
  Serial.println(filename);
 
  // Initialize variables and one-time Output
  logfile.println("Time,Date,Fix,Quality,Lat,Long,LatDeg,LonDeg,Angle,Altitude,Satellites,SW1B,SW1R,SW2B,SW2R,SW3B,SW3R,SW4B,SW4R,SW5B,SW5R");
  logfile.close();
  #if ECHO_TO_SERIAL
    Serial.println("Echo to Serial");
  #endif
  #if DEBUG
    Serial.println(F("Debugging")); // printing stuff to Serial for debugging
  #endif
 
  // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
  GPS.begin(9600);
 
  // uncomment this line to turn on RMC (recommended minimum) and GGA (fix data) including altitude
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  // uncomment this line to turn on only the "minimum recommended" data
  //GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
  // For parsing data, we don't suggest using anything but either RMC only or RMC+GGA since
  // the parser doesn't care about other sentences at this time
 
  // Set the update rate
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate
  // For the parsing code to work nicely and have time to sort thru the data, and
  // print it out we don't suggest using anything higher than 1 Hz

  // Request updates on antenna status, comment out to keep quiet
  GPS.sendCommand(PGCMD_ANTENNA);

  // the nice thing about this code is you can have a timer0 interrupt go off
  // every 1 millisecond, and read data from the GPS for you. that makes the
  // loop code a heck of a lot easier!
  useInterrupt(true);

  delay(1000);
  // Ask for firmware version
  mySerial.println(PMTK_Q_RELEASE);
}

// Interrupt is called once a millisecond, looks for any new GPS data, and stores it
SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();
  // if you want to debug, this is a good time to do it!
  #ifdef UDR0
    if (GPSECHO)
      if (c) UDR0 = c; 
      // writing direct to UDR0 is much much faster than Serial.print
      // but only one character can be written at a time.
  #endif
}

void loop() {
  const unsigned int logInterval = 10000; // milliseconds for recording data
  const unsigned int serialInterval = 2000; // milliseconds for viewing data
  const char* COMMA = ","; // adding a comma after text in the logfile
   
  // in case you are not using the interrupt above, you'll
  // need to 'hand query' the GPS, not suggested :(
  if (! usingInterrupt) {
    // read data from the GPS in the 'main loop'
    char c = GPS.read();
    // if you want to debug, this is a good time to do it!
    if (GPSECHO)
      if (c) Serial.print(c);
  }
 
  // if a sentence is received, we can check the checksum, parse it...
  if (GPS.newNMEAreceived()) {
    // a tricky thing here is if we print the NMEA sentence, or data
    // we end up not listening and catching other sentences!
    // so be very wary if using OUTPUT_ALLDATA and trytng to print out data
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
 
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
  }

  // if millis() or timer wraps around, we'll just reset it
  if (timer > millis())  timer = millis();
  if (LOG_FIXONLY && !GPS.fix) {
    // No GPS Fix
  }
  else if (millis() - logLast > logInterval) { // see when the log was last written
    // Data logging
    logfile = SD.open(filename, FILE_WRITE);
    logfile.print(GPS.hour, DEC); logfile.print(':');
    logfile.print(GPS.minute, DEC); logfile.print(':');
    logfile.print(GPS.seconds, DEC); logfile.print('.');
    logfile.print(GPS.milliseconds);
    logfile.print(COMMA);
    logfile.print(GPS.day, DEC); logfile.print('/');
    logfile.print(GPS.month, DEC); logfile.print("/20");
    logfile.print(GPS.year, DEC);
    logfile.print(COMMA);
    logfile.print((int)GPS.fix); logfile.print(COMMA);
    logfile.print((int)GPS.fixquality); logfile.print(COMMA);
    logfile.print(GPS.latitude, 4); logfile.print(GPS.lat); logfile.print(COMMA);
    logfile.print(GPS.longitude, 4); logfile.print(GPS.lon); logfile.print(COMMA);
    // Location (in degrees, works with Google Maps)
    logfile.print(GPS.latitudeDegrees, 4); logfile.print(COMMA);
    logfile.println(GPS.longitudeDegrees, 4); logfile.print(COMMA);
    logfile.print(GPS.angle); logfile.print(COMMA);
    logfile.print(GPS.altitude); logfile.print(COMMA);
    logfile.print((int)GPS.satellites); logfile.print(COMMA);
    logfile.println(); // Go to New Line
    logfile.close();
    logLast = millis();          // update the last time the log was written
    #if DEBUG
      Serial.println(F("Log written"));
    #endif
  }

  // approximately every 2 seconds or so, print out the current stats
  #if ECHO_TO_SERIAL
    if (millis() - timer > serialInterval) {
      timer = millis(); // reset the timer
      Serial.print("Time: ");
      Serial.print(GPS.hour, DEC); Serial.print(':');
      Serial.print(GPS.minute, DEC); Serial.print(':');
      Serial.print(GPS.seconds, DEC); Serial.print('.');
      Serial.print(GPS.milliseconds);
      Serial.print("\tDate: ");
      Serial.print(GPS.day, DEC); Serial.print('/');
      Serial.print(GPS.month, DEC); Serial.print("/20");
      Serial.print(GPS.year, DEC);
      Serial.print("\tFix: "); Serial.print((int)GPS.fix);
      Serial.print("\tQuality: "); Serial.print((int)GPS.fixquality);
      if (LOG_FIXONLY && !GPS.fix) {
        Serial.println("\tNo GPS Fix");
      }
      else {
        Serial.print("\tLoc: ");
        Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
        Serial.print(", ");
        Serial.print(GPS.longitude, 4); Serial.print(GPS.lon);
  //      Serial.print("Location (in degrees, works with Google Maps): ");
  //      Serial.print(GPS.latitudeDegrees, 4);
  //      Serial.print(", ");
  //      Serial.println(GPS.longitudeDegrees, 4);
  //      Serial.print("Speed (knots): "); Serial.println(GPS.speed);
  //      Serial.print("Angle: "); Serial.println(GPS.angle);
  //      Serial.print("Altitude: "); Serial.println(GPS.altitude);
        Serial.print("\tSats: "); Serial.print((int)GPS.satellites);
        Serial.println(); // Go to New Line
      }
   #endif
  }
}

void error(const char *str)
{
  Serial.print(F("error: "));
  Serial.println(str);
//  while(1); //Stop
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
}

// read a Hex value and return the decimal equivalent
uint8_t parseHex(char c) {
  if (c < '0')
    return 0;
  if (c <= '9')
    return c - '0';
  if (c < 'A')
    return 0;
  if (c <= 'F')
    return (c - 'A')+10;
}

// blink out an error code
void error(uint8_t errno) {
//  /*
//  if (SD.errorCode()) {
//   putstring("SD error: ");
//   Serial.print(card.errorCode(), HEX);
//   Serial.print(',');
//   Serial.println(card.errorData(), HEX);
//   }
//   */
//  while(1) {
//    uint8_t i;
//    for (i=0; i<errno; i++) {
//      digitalWrite(ledPin, HIGH);
//      delay(100);
//      digitalWrite(ledPin, LOW);
//      delay(100);
//    }
//    for (i=errno; i<10; i++) {
//      delay(200);
//    }
//  }
}
raidoh
 
Posts: 9
Joined: Mon Oct 08, 2012 9:59 pm

Re: Mega 2560 with GPS and TFT TS compatibility

by franklin97355 on Sun Feb 17, 2019 4:58 pm

The TFT shield uses the ICSP port for communications and the GPS shield does not pass that through. You could add one (I think) or wire the jumpers around the shield.

franklin97355
 
Posts: 21081
Joined: Mon Apr 21, 2008 2:33 pm
Location: Lacomb, OR.

Re: Mega 2560 with GPS and TFT TS compatibility

by raidoh on Sun Feb 17, 2019 5:20 pm

When I soldered the stacking headers on the GPS shield, I included the 6-pin ICSP header, so it should get passed through.
raidoh
 
Posts: 9
Joined: Mon Oct 08, 2012 9:59 pm

Re: Mega 2560 with GPS and TFT TS compatibility

by franklin97355 on Sun Feb 17, 2019 6:06 pm

Have you read through the tutorial and does any of that apply?

franklin97355
 
Posts: 21081
Joined: Mon Apr 21, 2008 2:33 pm
Location: Lacomb, OR.

Re: Mega 2560 with GPS and TFT TS compatibility

by raidoh on Sun Feb 17, 2019 6:10 pm

Yes, I've been examining the tutorial for two days... :-/
raidoh
 
Posts: 9
Joined: Mon Oct 08, 2012 9:59 pm

Re: Mega 2560 with GPS and TFT TS compatibility

by franklin97355 on Sun Feb 17, 2019 8:37 pm

I'll see if anyone else has an idea of what is going on. Was that the actual program you are running? Could you try running the code to test each board separately but with both boards attached?

franklin97355
 
Posts: 21081
Joined: Mon Apr 21, 2008 2:33 pm
Location: Lacomb, OR.

Re: Mega 2560 with GPS and TFT TS compatibility

by adafruit_support_carter on Mon Feb 18, 2019 2:21 pm

Can you clarify what you mean by they work individually. Is that hardware-wise or software-wise? Your code is trying to use both. But what if you just run the basic GFX test demo with everything connected. Does that work?
https://learn.adafruit.com/adafruit-2-8 ... ibrary-3-4

Can you post a photo of your setup showing how you have everything connected.

I've wired the GPS 8 -> Mega Tx1 and GPS 7 -> Mega Rx1.

8 is also the touchscreen chip select.

adafruit_support_carter
 
Posts: 12970
Joined: Tue Nov 29, 2016 2:45 pm

Re: Mega 2560 with GPS and TFT TS compatibility

by adafruit2 on Mon Feb 18, 2019 11:24 pm

also try running the TFT software without any GPS *code* but the GPS hardware in place, so you can see if its the GPS library causing problems, or the GPS hardware

adafruit2
Site Admin
 
Posts: 18659
Joined: Fri Mar 11, 2005 7:36 pm

Please be positive and constructive with your questions and comments.