Need some insight

Good evening folks,

So I'm trying to marry two programs that work just fine on their own, trimmed down to just what I need. Problem is that I can't get BOTH my GPS AND my display to work at the same time and I've narrowed it down to one particular line.

Using a Huzzah32 from Adafruit utilizing the ESP32 chip. Using the SSD1351 display, from here. Most current version of Arduino IDE. OS is Linux Mint 18.2. Programs have been slimmed down from the Adafruit GPS Library, GPS_HardwareSerial_Parsing sample, and the ESP32_graphictest from here.

#include <Adafruit_GPS.h>
#include <SPI.h>
#include <SSD_13XX.h>

// For the ESP32
#define _cs   23  // goes to TFT CS
#define _dc   22  // goes to TFT DC
#define _mosi 18  // goes to TFT MOSI
#define _sclk 5   // goes to TFT SCK/CLK
#define _rst  12  // ESP RST to TFT RESET
#define _miso     // Not connected
//       3.3V     // Goes to TFT LED
//       5v       // Goes to TFT Vcc
//       Gnd      // Goes to TFT Gnd
uint8_t errorCode = 0;

SSD_13XX tft = SSD_13XX(_cs, _dc);

//not sure this is needed in IDF
#if defined(ESP32)
HardwareSerial Serial1(2);
#endif

#define GPSSerial Serial1

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

// 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

uint32_t timer = millis();


void setup()
{
  Serial.begin(115200);

  // 9600 NMEA is default baud rate, alternate 4800
  GPS.begin(9600);

  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);

  // Set the update rate
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_10HZ);

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

  // Ask for firmware version
  GPSSerial.println(PMTK_Q_RELEASE);

  tft.begin(true);
}

void loop()
{

  // 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 (millis() - timer > 100) {
    timer = millis(); // reset the timer
    Serial.print("\nTime: ");
    if (GPS.hour <= 0){
      Serial.print(GPS.hour +7, DEC);
    } else {
      Serial.print(GPS.hour -5, DEC);
    }
    if (GPS.minute <=0){
      Serial.print(':0');
    } else {
      Serial.print(':');
    }
    Serial.print(GPS.minute, DEC); Serial.print(':');Serial.println(GPS.seconds, DEC);
    Serial.print("Date: ");
    Serial.print(GPS.month, DEC); Serial.print('/');
    Serial.print(GPS.day, DEC); Serial.print("/20"); Serial.println(GPS.year, DEC);
    if (GPS.fix) {
      Serial.print("Speed (MPH): "); Serial.println(GPS.speed * 1.15078);
      Serial.print("Satellites: "); Serial.println((int)GPS.satellites);
    }
}
  tft.setCursor(0, 0);
  tft.setTextColor(WHITE);  tft.setTextScale(1);
  if (GPS.hour<=0){
    tft.print(GPS.hour +7);
  } else {
    tft.print(GPS.hour -5);
  }
  if (GPS.minute <=10){
    tft.print(':0');tft.println(GPS.minute);
  } else {
    tft.print(':');tft.println(GPS.minute);
  }
  tft.setTextScale(5);
  tft.println(GPS.speed);
  tft.setTextScale(1);
  tft.print("Satelites ");tft.print(GPS.satellites);
  tft.setCursor(0, 0);
  tft.setTextColor(BLACK);  tft.setTextScale(1);
  if (GPS.hour<=0){
    tft.print(GPS.hour +7);
  } else {
    tft.print(GPS.hour -5);
  }
  if (GPS.minute <=10){
    tft.print(':0');tft.println(GPS.minute);
  } else {
    tft.print(':');tft.println(GPS.minute);
  }
  tft.setTextScale(5);
  tft.println(GPS.speed);
  tft.setTextScale(1);
  tft.print("Satelites ");tft.print(GPS.satellites);
}

The line causing the bug up is..

tft.begin();

If I put it to false, the display works as supposed to, receiving time and date from GPS only. Put it to true and the GPS reads like it should, but no display. Leave it empty, and it seems to be just like false.

Can someone explain this conundrum to me?

Which exact display do you have? (Does it have a separate driver, if so, tell us exactly which one.)

What does the documentation for that display say that true/false does?

Which Arduino?

MorganS:
Which exact display do you have? (Does it have a separate driver, if so, tell us exactly which one.)

What does the documentation for that display say that true/false does?

Which Arduino?

SSD1351, found here.

Documentation attached, I didn't see anything in it for coding, simply the hardware side of things. I could have been reading it wrong, but I still didn't see any kind of code.

If you look at the top of the program, you'll see "For the ESP32"... Huzzah32 made by Adafruit, utilizing the ESP32 chip.

Also to note, when it is commented out, the board crashes and restarts over and over. I will post what that says in the serial blotter when I get home from work today.

As promised, here is the serial monitor read out when the line is commented out.

mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:956
load:0x40078000,len:0
load:0x40078000,len:13076
entry 0x40078a58
Guru Meditation Error: Core  1 panic'ed (LoadProhibited)
. Exception was unhandled.
Register dump:
PC      : 0x400e8c2d  PS      : 0x00060330  A0      : 0x800d1dc4  A1      : 0x3ffca600  
A2      : 0x00000000  A3      : 0x00000037  A4      : 0x00000000  A5      : 0x00000001  
A6      : 0x00000000  A7      : 0x00000000  A8      : 0x00000000  A9      : 0x00000000  
A10     : 0x3ffc2280  A11     : 0x00000007  A12     : 0x0000000a  A13     : 0x00000000  
A14     : 0x00000001  A15     : 0x00000000  SAR     : 0x00000009  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffff  

Backtrace: 0x400e8c2d:0x3ffca600 0x400d1dc1:0x3ffca620 0x400d2245:0x3ffca660 0x400d0a34:0x3ffca680 0x400d2706:0x3ffca6a0 0x400d279d:0x3ffca6c0 0x400d284c:0x3ffca710 0x400d285d:0x3ffca730 0x400d0bf3:0x3ffca750 0x400e6a4d:0x3ffca770

Rebooting...

As promised, here is the serial monitor read out when the line is commented out.

It would appear that you failed to mention that you are NOT using an Arduino. No Arduino or library produces that output.

I failed to mention it in the first post, however I did in the 3rd response.

I've updated the first post to include everything I can think of that is pertinent. Normally I don't leave that stuff out, not sure why I did this time.

And that's even worse. Now the responses above this point won't make any sense as they're complaining about lacking information which obviously is in the first post.

New information should go in new posts. You can quote an older post if it's so old that it's off the screen.

I responded rashly and I apologize for that.

I have attempted to fix the one thing I didn't do at the start and what information I did add is already in other comments.

Please, just stop commenting unless you are trying to help, badgering me about forum etiquette isn't helping anybody at this point. This is the one time I've posted stuff out of order and I'd appreciate not getting lectured instead of receiving help.

No one seems to either have the desire to help or perhaps the experience to know why.

My guess is that it might be the SoftwareSerial library, as I was reading a bit ago that it is very limiting and only allows one serial transmission at a time. I'm stabbing in the dark, but this sounds like it might be closer to the issue than I've seen on anything else.

Any thoughts anyone?

If I understand correctly:

  1. Commenting out the tft.begin() line causes the Huzzah to reset when you call any other method on the tft object.

  2. Without it commented out, and with true as the argument, the display works, but the GPS doesn't return all the data that it should.

  3. Without it commented out, and with false as the argument, the display doesn't work, but the GPS does return all the data that it should.

Is that a correct summary? If not, please explain what does happen.

Commenting out the tft.begin() method leading to crashes is not surprising. If the display worked without having tft.begin() called, that would be surprising.

All we have seen for the display you are using is that stupid link to a retailer's site. No link to a manufacturer's site, where some real information might be found. No link to the library you are using, so we can't see what true or false means to the begin() method. No links to the other libraries you are using.

PaulS:
If I understand correctly:

  1. Commenting out the tft.begin() line causes the Huzzah to reset when you call any other method on the tft object.

  2. Without it commented out, and with true as the argument, the display works, but the GPS doesn't return all the data that it should.

  3. Without it commented out, and with false as the argument, the display doesn't work, but the GPS does return all the data that it should.

Is that a correct summary? If not, please explain what does happen.

Commenting out the tft.begin() method leading to crashes is not surprising. If the display worked without having tft.begin() called, that would be surprising.

All we have seen for the display you are using is that stupid link to a retailer's site. No link to a manufacturer's site, where some real information might be found. No link to the library you are using, so we can't see what true or false means to the begin() method. No links to the other libraries you are using.

#1 you have correct.

You have #2 and #3 backwards, I mentioned these in the first post the first time I posted these.

Commented to true allows all GPS data but no display.

Commented to false allows the display to work, but only receive time and date GPS data.

I already posted the link to display library I am using, but here it is again.

I currently have no information on the manufacturer other than what I thought I had already uploaded. I had attempted to upload a zip supplied from the retailer on Amazon with my initial post but it does not appear there and I don't know why. I'll make sure to get that up after I get home from work.

I already posted the link to display library I am using, but here it is again.

That is NOT the link to the library, but there is a link there to the library.

Interestingly, on the library page, there are comments "works with ESP8266", but nothing about working with the ESP32. Makes me wonder why you think that it will.

	void     	begin(bool avoidSPIinit=false);

So, the argument to begin() controls whether SPI initialization is avoided, or not.

We've already concluded that the call to the begin() method is required, so omitting it, resulting an a crash is expected behavior, so we don't have to go there again.

You need to summarize, as we are a long way from where we started. What value passed to begin causes what problems? You said my summary was wrong, so correct it.

Then, think about what doing, or not doing SPI initialization means. What pins, on the ESP32 are you using for the display? What pins are the SPI pins? What other pins are you using, for the GPS and any other stuff?

I'm suspecting a pin conflict.

PaulS:
That is NOT the link to the library, but there is a link there to the library.

Interestingly, on the library page, there are comments "works with ESP8266", but nothing about working with the ESP32. Makes me wonder why you think that it will.

 void     begin(bool avoidSPIinit=false);

So, the argument to begin() controls whether SPI initialization is avoided, or not.

We've already concluded that the call to the begin() method is required, so omitting it, resulting an a crash is expected behavior, so we don't have to go there again.

You need to summarize, as we are a long way from where we started. What value passed to begin causes what problems? You said my summary was wrong, so correct it.

Then, think about what doing, or not doing SPI initialization means. What pins, on the ESP32 are you using for the display? What pins are the SPI pins? What other pins are you using, for the GPS and any other stuff?

I'm suspecting a pin conflict.

I apologize, I thought that was the library. I need to relabel my bookmarks then.

I have not delved into the SSD_13XX, but I felt confident that it would work with the ESP32 beause of the sample code in the link that I did supply. I was able to get the graphictest.ino to work just fine once I pinned it properly. I was not able to get the other two programs working because I do not have WiFi in my home and I haven't figured why it won't connect to my phones HotSpot connection even with no password enabled.

I have the ESP32 pinned out as follows:

TX/17 to GPS RX;
RX/16 to GPS TX;
SCK/5 to Display SCL
MOSI/18 to Display SDA
SCA/23 to Display CS
SCL/22 to Display DC
with power and ground split to both.

Here is the link to Adafruits pinout guide for the ESP32, in case you're not familiar with their board. The display is hooked up to 4 of the 5 I2C/SPI pins. Without the GPS hooked up, I had the Display DC and CS connected to the TX and RX pins. Either way, it shows the graphictest.ino exactly as it should be.

I didn't realize I needed to number my corrections to your summary, but I had laid them out exactly as you had..

#1 When tft.begin(true); is called, GPS is receives full NMEA data and not just time and date, but display is dead.

2# When tft.begin(false); is called, GPS receives only time and date data, but display is fully functional.

The void begin line tells the chip not to avoid SPI transmission, and I'm guessing that tft.begin() is a shorthand of that. Based off of that, calling false is telling the chip to once again not avoid initialization of SPI chatter. Conversely, giving a true value gives the chip a thumbs up for avoiding it. Specifically to the display.

I still don't quite see how it conflicts with the GPS, but it is obvious calling false is seen by the GPS as well as the display.

I'm thinking, hopefully correctly, that the line from the SSD_13XX library:

void begin(bool avoidSPIinit=false);

is conflicting with the line from the Adafruit_GPS library:

void begin(uint32_t baud);

because they are both public classes. And because the #include for SSD13XX comes after the #include for the GPS.

Am I on the right trail?

#1 When tft.begin(true); is called, GPS is receives full NMEA data and not just time and date, but display is dead.

The true value tells the tft instance to avoid initializing the SPI pins/software. If the display is an SPI device, the isn't a good thing to do.

I really don't understand why you have the display connected to the SPI and I2C pins. Either it is an I2C device, and should be connected to the I2C pins, or it is an SPI device and should be connected to the SPI pins, or it is neither and doesn't need to be connected to the pins that are specific to SPI or to I2C.

If it IS an SPI device, then you need to call tft.begin() with false, so that is doesn't avoid initializing the SPI pins and software.

What a stupid way to do things. tft.begin() should take an argument, initSPI, where true means do it, and false means don't do it, not avoidSPIInit, where true means don't initialize SPI and false means do initialize SPI.

But, it is what it is, so you need to call begin() with false if the display IS an SPI device.

// 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

I would suggest that you change false to true, so you can see, on the Serial Monitor, just what the ESP32 is getting from the GPS. That might give us a clue. If the data that is received looks OK, except that stuff is obviously missing, we've learned one thing. If the data is just random garbage, we've learned something else.

The Huzzah32 has 5 pins specifically stated as being I2C AND SPI.

The display IS an SPI Communications device, hence why I corrected to false to make it work.

The Huzzah32 has 5 pins specifically stated as being I2C AND SPI.

I understand that.

The display IS an SPI Communications device

So, why are any of its pins connected to the I2C pins?

I'm not quite understanding the logic behind the question..

According to Adafruit, their board does not have any SPI only pins. It has a bunch of analog pins, a few power pins that I don't really know what to do with, the SPI/I2C shared pins we've talked about, and the RX/TX pins.

The two begin() methods are on different objects. It cannot call the wrong one. The only conflict is if they use the same physical pins.

SDA/SCL is not relevant here. If you are. Ot using any Wire methods then those two pins are available as general purpose input or output.

I think it would be very useful to see what the raw GPS data is received when the display is working. I think that perhaps some display methods are taking too much time and the incoming Serial buffer is overflowing.