Pages: [1] 2   Go Down
Author Topic: Libraries fighting each other?  (Read 1321 times)
0 Members and 1 Guest are viewing this topic.
Chicago
Offline Offline
Jr. Member
**
Karma: 1
Posts: 89
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm trying to use Adafruits libaries for GPS and LCD screen. I can get them to each do exactly what I want in separate programs but once I put them in the same program, shit hits the fan. Does anyone know how or if it is possible to figure out what in them is giving me the issue? Thanks
#include <Adafruit_GPS.h>         GPS LIBRARY
#include <Adafruit_SSD1306.h>   LCD LIBRARY

Logged

Manchester (England England)
Online Online
Brattain Member
*****
Karma: 626
Posts: 34152
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Just look in those header files and see what pins they use. They are defined their.
Logged

Ayer, Massachusetts, USA
Offline Offline
Edison Member
*
Karma: 54
Posts: 1848
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, it might be helpful to go into more detail of exactly is going wrong?  Please quote the entire message that the compiler gives you if it is a compiler message, or what doesn't happen if it fails at runtime.

Given you want to use both GPS and the LCD, do these two devices use any pins that are in common?  For example, do they both want to use pin 10 for completely separate things?  Then you have to figure out whether you can change pins (possibly not, several of the pins in Arduino are specialized, and if you have shields, the pins tend to be fixed), or you can move one of the devices to something like I2C (such as the LCD).

Another possibility is whether you have enough power for your Arduino, GPS, and LCD.  This tends to happen more with motors or lots of LEDs, where you just don't have enough power, and you need to use external power supplies.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18778
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm trying to use Adafruits libaries for GPS and LCD screen. I can get them to each do exactly what I want in separate programs but once I put them in the same program,...

Maybe copy and paste the error messages?

Read this before posting a programming question
Logged


Chicago
Offline Offline
Sr. Member
****
Karma: 5
Posts: 456
With every answer comes more questions.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Complete shot in the dark without having any idea what your error message said, but...

I've noticed that it can be rather picky at times about the order in which the libraries are included. (The list of "#include" at top of sketch.)
Logged

Chicago
Offline Offline
Jr. Member
**
Karma: 1
Posts: 89
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry for being so brief. The two devices do not use the same pins, the LCD uses 9-13 with SPI and the GPS uses 2 and 3 with TTL. What I did to create my program was write two programs, one talking to the GPS and saving variables, the other writing to the LCD to print made up variables to the text in the correct location, ect. Then I tried combining the two programs into one final one. With the GPS saving the data and LCD printing it.

Turns out, it all goes to hell, the LCD screen just displays random pixels, the GPS spits out strange data, even when I comment out all print line statements.

I cant figure out what would be the issue that would cause both to mess up at the same time? Here is my code, but please be nice, my coding isn't the best, but I do try to comment everything. 

Please note, I combined the two programs, where they are in the same program, but the two codes don't interact with each other. The GPS still gets data and prints to serial monitor, and the LCD still prints dummy values. (well they are supposed to)

Code:
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>

//<SCREEN>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//DEFINE LCD PINS and CONST
#define OLED_DC 11
#define OLED_CS 12
#define OLED_CLK 10
#define OLED_MOSI 9
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

//   Connect the GPS TX (transmit) pin to Digital 3
//   Connect the GPS RX (receive) pin to Digital 2
SoftwareSerial mySerial(3, 2);

Adafruit_GPS GPS(&mySerial);
// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
#define GPSECHO  false

int tempF = 0;
int speed = 0;
int NESW = 1;
int hour = 5;
int minute = 15;

void setup() 
{
   
  // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
  Serial.begin(115200);
  // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
  // Set the update rate
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate
 
  //<SCREEN>
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC);
  // init done
  display.clearDisplay();   // clears the screen and buffer
  display.setTextColor(WHITE, BLACK);

  delay(1000);
}

uint32_t timer = millis();
void loop()                     // run over and over again
{
  // 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();
 
  // approximately every 2 seconds or so, print out the current stats
  if (millis() - timer > 2000) {
    timer = millis(); // reset the timer
   
    Serial.print("\nTime: ");
    Serial.print(GPS.hour, DEC); Serial.print(':');
    Serial.print(GPS.minute, DEC); Serial.print(':');
    Serial.println(GPS.seconds, DEC);
    Serial.print("Fix: "); Serial.print((int)GPS.fix);
    Serial.print(" quality: "); Serial.println((int)GPS.fixquality);
    if (GPS.fix) {
     
       
      UpdateTime(hour, minute); 
      UpdateSpeed(speed);
     
      // print the display
      display.display();

     
           
      Serial.print("Location: ");
      Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
      Serial.print(", ");
      Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
     
      Serial.print("Speed (knots): "); Serial.println(GPS.speed);
      Serial.print("Angle: "); Serial.println(GPS.angle);
      Serial.print("Altitude: "); Serial.println(GPS.altitude);
      Serial.print("Satellites: "); Serial.println((int)GPS.satellites);
    }
   
  }
}

void UpdateTime(int hour, int minute){
  // display the time
  display.setTextSize(2);
  if (hour < 10)
    display.setCursor(80,0);
  else
    display.setCursor(68,0);
   
  display.print(hour,DEC);
  display.print(":");
  if(minute < 10)
    display.print("0");
  display.print(minute,DEC);   
}

 
void UpdateSpeed(int Speed){
  // display speed
  if(speed > 99)
  display.setCursor(28,17);
  else if(speed > 9){
  display.setCursor(42,17);
  display.fillRect(28, 17, 14, 28,BLACK);
  }
  else{
  display.setCursor(54,17);
  display.fillRect(28, 17, 26, 28,BLACK);
  }
  display.setTextSize(4);
  display.print(speed);display.print(" ");
 
  // write MPH below the speed
  display.setCursor(55,47);
  display.setTextSize(1);
  display.print("MPH");
}



Logged

Ayer, Massachusetts, USA
Offline Offline
Edison Member
*
Karma: 54
Posts: 1848
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Then I suspect your problem is either you are running out of memory and things are being overwritten.  Or possibly each is trying to use one of the hardware resources (like the timers), and not working together.  For the later, you will need to do a deep dive to see what resources are being used.
Logged

UK
Offline Offline
God Member
*****
Karma: 17
Posts: 568
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So, it compiles and runs but strange things happen?

If both libraries are adafruit then you'd think they probably don't clash with any public variables etc.

Memory is another area to look, as stated.

You can try running a freeram sketch to see what SRAM usage is like.

You have quite a few serial.print statements with string literals so the first thing to do is wrap them up in the F() macro to move them into PROGMEM. Every character is using a byte and you only have 2kB. Your NMEA sentences are all strings, being buffered over serial, so I'd suspect SRAM in the first instance.

Get those string literals into PROGMEM then report back.
Logged

Chicago
Offline Offline
Sr. Member
****
Karma: 5
Posts: 456
With every answer comes more questions.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It does sound like either memory, timing...or both. How many pixels is your display?

I was using the same Adafruit GPS module & library with a small Nokia GLCD display. After a while the display would just stop updating on me. I switched to an I2C character LCD & it's much more reliable now. Though, the screen still flickers a bit when new NMEA sentences come in.

Have you tried using hardware serial ports?

Also....I don't see you you ever clearing the display in loop(). Typically, that will cause the display just keep writing the new data (pixels, letters, etc...) over the old. Which, eventually just looks like 'random pixels' changing.
Logged

Chicago
Offline Offline
Jr. Member
**
Karma: 1
Posts: 89
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can try running a freeram sketch to see what SRAM usage is like.

You have quite a few serial.print statements with string literals so the first thing to do is wrap them up in the F() macro to move them into PROGMEM. Every character is using a byte and you only have 2kB. Your NMEA sentences are all strings, being buffered over serial, so I'd suspect SRAM in the first instance.

Get those string literals into PROGMEM then report back.

I'm a hardware guy, so programming is not my strong suit. Could you please explain what freeram is?

Also, what is F() macro? I've used macros in assembly programming, but never in arduino.

And again, what is PROGMEM?

It does sound like either memory, timing...or both. How many pixels is your display?

I was using the same Adafruit GPS module & library with a small Nokia GLCD display. After a while the display would just stop updating on me. I switched to an I2C character LCD & it's much more reliable now. Though, the screen still flickers a bit when new NMEA sentences come in.

Have you tried using hardware serial ports?

Also....I don't see you you ever clearing the display in loop(). Typically, that will cause the display just keep writing the new data (pixels, letters, etc...) over the old. Which, eventually just looks like 'random pixels' changing.
Screen is 128x64. I have no tried using hardware serial. I don't clear the display because I have the text background color set as black, so if I write a number over another number it will black out what was there. I know exactly what you're talking about though, I have that issue with another LCD I've used.

Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18778
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


I'm a hardware guy, so programming is not my strong suit. Could you please explain what freeram is?
...
And again, what is PROGMEM?


http://arduino.cc/en/Tutorial/Memory

Quote
Also, what is F() macro? I've used macros in assembly programming, but never in arduino.

Change:

Code:
Serial.print(" quality: ");

to:

Code:
Serial.print(F(" quality: "));

That keeps the literal in PROGMEM (of which you have quite a bit) and stops it being copied into RAM.
Logged


Chicago
Offline Offline
Sr. Member
****
Karma: 5
Posts: 456
With every answer comes more questions.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
And again, what is PROGMEM?

http://arduino.cc/en/Reference/PROGMEM

Quote
I don't clear the display because I have the text background color set as black, so if I write a number over another number it will black out what was there.
Ah.

I haven't played with OLEDs too much. Could you post a photo of what it looks like while in-use?

Also, this hints that if too much else is going on, the Arduino might not fully 'capture' all the GPS output.
Code:
  // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
When using serial monitor (with your posted version of code), does it still display all the updated GPS information?
Logged

Chicago
Offline Offline
Jr. Member
**
Karma: 1
Posts: 89
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah.

I haven't played with OLEDs too much. Could you post a photo of what it looks like while in-use?

Also, this hints that if too much else is going on, the Arduino might not fully 'capture' all the GPS output.
Code:
  // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
When using serial monitor (with your posted version of code), does it still display all the updated GPS information?

I don't have one of it showing actual variables, but it looks the exact same with numbers.

It displays some GPS information, but its all broken up into unintelligible data.

I'm trying to mod the code now to put my text into PROGMEM now, will update in a few.
Logged

Chicago
Offline Offline
Jr. Member
**
Karma: 1
Posts: 89
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've made some progress, but I still think I'm running out of RAM. I stopped getting jumbled up BS and now I'm getting SOME real data back, but not everything. What else can I do to save RAM? If I go into the GPS library, and only pull out the parts that I NEED (Speed, time, direction) and cut out all the shit I dont need (a lot) will that cut down on my ram usage? I only use the library for 10% of it's use.

Here is my most up to date code:
Code:
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>

//<SCREEN>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//DEFINE LCD PINS and CONST
#define OLED_DC 11
#define OLED_CS 12
#define OLED_CLK 10
#define OLED_MOSI 9
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

//   Connect the GPS TX (transmit) pin to Digital 3
//   Connect the GPS RX (receive) pin to Digital 2
SoftwareSerial mySerial(3, 2);

Adafruit_GPS GPS(&mySerial);
// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
#define GPSECHO  false

byte tempF = 0;
byte speed = 0;
byte NESW = 1;
byte hour = 5;
byte minute = 15;

void setup() 
{
   
  // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
  Serial.begin(115200);
  // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCONLY);
  // Set the update rate
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate
 
  //<SCREEN>
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC);
  // init done
  display.clearDisplay();   // clears the screen and buffer
  display.setTextColor(WHITE, BLACK);

  delay(1000);
}

uint32_t timer = millis();
void loop()                     // run over and over again
{
  // 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();
 
  // approximately every 2 seconds or so, print out the current stats
  if (millis() - timer > 2000) {
    timer = millis(); // reset the timer
   
    Serial.print(F("\nTime: "));
    Serial.print(GPS.hour, DEC); Serial.print(F(":"));
    Serial.print(GPS.minute, DEC); Serial.print(F(":"));
    Serial.print(F("Fix: ")); Serial.print((boolean)GPS.fix);
    Serial.print(F("Quality: ")); Serial.println((byte)GPS.fixquality);
    if (GPS.fix) {
     
       /*
      UpdateTime(hour, minute); 
      UpdateTemp(tempF);
      UpdateSpeed(speed);
      UpdateDirection(NESW);
     
      // print the display
      display.display();

      */
           
      Serial.print(F("Location: "));
      Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
      Serial.print(F(", "));
      Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
     
      Serial.print(F("Speed (knots): ")); Serial.println(GPS.speed);
      Serial.print(F("Angle: ")); Serial.println(GPS.angle);
      Serial.print(F("Altitude: ")); Serial.println(GPS.altitude);
      Serial.print(F("Satellites: ")); Serial.println((int)GPS.satellites);
    }
   
  }
}

void UpdateTime(byte hour, byte minute){
  // display the time
  display.setTextSize(2);
  if (hour < 10)
    display.setCursor(80,0);
  else
    display.setCursor(68,0);
   
  display.print(hour,DEC);
  display.print(F(":"));
  if(minute < 10)
    display.print(F("0"));
  display.print(minute,DEC);   
}

void UpdateTemp(byte Temp){
    // display the temperature
  display.setCursor(0,0);
  display.setTextSize(2);
  display.print(Temp);display.print(F("F  "));
}
 
void UpdateSpeed(byte Speed){
  // display speed
  if(speed > 99)
  display.setCursor(28,17);
  else if(speed > 9){
  display.setCursor(42,17);
  display.fillRect(28, 17, 14, 28,BLACK);
  }
  else{
  display.setCursor(54,17);
  display.fillRect(28, 17, 26, 28,BLACK);
  }
  display.setTextSize(4);
  display.print(speed);display.print(" ");
 
  // write MPH below the speed
  display.setCursor(55,47);
  display.setTextSize(1);
  display.print(F("MPH"));
}

void UpdateDirection(byte NESW){
  // write direction (NESW)
  display.setCursor(0,50);
  display.setTextSize(2);
      switch (NESW) {
    case 1:
      display.print(F("N"));
      break;
    case 2:
      display.print(F("E"));
      break;
    case 3:
      display.print(F("S"));
      break;
    case 4:
      display.print(F("W"));
      break;
    }
}

Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I can see two ways to tackle this. Firstly, use the freeMemory() function from the playground to see how close you are to running out of RAM. If necessary, simplify your sketch until it runs reliably to ensure that freeMemory() is giving you a valid answer before you trust it. (If you have run out of memory then freeMemory() itself, or the mechanisms used to show you the result, might not work correctly.) This will tell you whether you actually have a memory problem.

Secondly, disable everything that writes to the Serial port and only echo the characters received from the GPS port. Unless/until you get sensible data from that, nothing else will work. If you're getting garbage, try simplifying the sketch until you produce something that does produce sensible output. Then reinstate the remaining functionality piece by piece. If it stops working, you can assume it's due to the last thing you changed. By monitoring the amount of free memory at the same time, you can get a clue whether this is simple memory exhaustion, or a logic fault or memory corruption in your code or a library you're using.

Logged

I only provide help via the forum - please do not contact me for private consultancy.

Pages: [1] 2   Go Up
Jump to: