Out of RAM? Or is my code not acceptable

I am attempting to make a gps in a mint tin, much like this guy and his smalls tin. (See Link Below) Though my project will consist of a standard size Altoids tin, and an Arduino uno. The other two parts I will be interfacing with are Adafruit's 128x64 oled 1.3" display and Adafruit's Ultimate GPS breakout board. The code uploads fine, but the program doesn't run as I expected. It seems to hang up where it initializes the i2c interface to the display. Though I don't know what changed, it used to go beyond that boundary.

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include "bitmaps.h"

// If you're using a GPS module:
// Connect the GPS Power pin to 5V
// Connect the GPS Ground pin to ground
// If using software serial (sketch example default):
//   Connect the GPS TX (transmit) pin to Digital 3
//   Connect the GPS RX (receive) pin to Digital 2
// 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

// If you're using the Adafruit GPS shield, change 
// SoftwareSerial mySerial(3, 2); -> SoftwareSerial mySerial(8, 7);
// and make sure the switch is set to SoftSerial

// If using software serial, keep these lines enabled
// (you can change the pin numbers to match your wiring):

int freeRam () 
{
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}


SoftwareSerial mySerial(3, 2);

Adafruit_GPS GPS(&mySerial);
// If using hardware serial (e.g. Arduino Mega), comment
// out the above six lines and enable this line instead:
//Adafruit_GPS GPS(&Serial1);


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

// this keeps track of whether we're using the interrupt
// off by default!
boolean usingInterrupt = false;
void useInterrupt(boolean); // Func prototype keeps Arduino 0023 happy

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
int dispClear = 0;
int sw1 = 5;
int sw2 = 6;


#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2


#define splash_GLCD_HEIGHT 64
#define splash_GLCD_WIDTH  128


void setup()  
{
  pinMode(sw1,INPUT);//Mode Switch 1
  pinMode(sw2,INPUT);//Mode Switch 2
  // connect at 115200 so we can read the GPS fast enough and echo without dropping chars
  // also spit it out

  Serial.begin(115200);
  Serial.println(F("Serial Started"));

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  Serial.println(F("Start Display"));
  Serial.println(freeRam());
  display.begin(SSD1306_SWITCHCAPVCC, 0x3D);  // initialize with the I2C addr 0x3D (for the 128x64)
  Serial.println(F("Display Started"));

  display.println(F("Serial Started"));
  display.println(F("Display Started"));

  // init done
  //display.clearDisplay();
  // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800

  GPS.begin(9600);
  Serial.println(F("GPS.begin(9600)"));
  display.println(F("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);


  // Ask for firmware version
  mySerial.println(PMTK_Q_RELEASE);
  display.setCursor(0,0);
  display.clearDisplay();
  display.drawBitmap(0, 0,  splash_glcd_bmp, 128, 64, 1);
  Serial.println(F("Splash Screen Start"));
  delay(1000);
  display.display();
}


// 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 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;
  }
  Serial.println(F("End Setup"));
}

uint32_t timer = millis();
void loop()                     // run over and over again
{


  #include "mode1.h"//displays all gps info -----------------------both switches off
  //#include "mode2.h"//Displays only time and date info-------------Switch 1 on
  //#include "mode3.h"//displays only lat, lon, and altitude---------Switch 2 on
  //#include "mode4.h"//Displays the about information. -------------both switches on

}

Are the bit maps all in RAM too?

where does it stop ?

And what does all the other missing code, which you have bizarrely hidden in a .h file, do ?

Okay here is the entire Arduino folder only including the sketch and it's libraries.
https://drive.google.com/file/d/0B-xbQ5Nkmz-UT0xNREV1bFI1UnM/edit?usp=sharing

AWOL:
Are the bit maps all in RAM too?

No, it's using PROGMEM.

michinyon:
where does it stop ?
And what does all the other missing code, which you have bizarrely hidden in a .h file, do ?

It tents to stop around the display.begin line, but after about 15 seconds it continues on not operating properly, or loops one or more of the Serial.println(); lines

The End project is supposed to operate upon two switches depending on their states, to determine the mode, which is where the .h files come into play. Instead of having all the code in one big line I put it in .h files to make the editing of specific modes more organized.

I left out one important part, I do not have the screen, or GPS module in my hands yet. So if this is in the formula working against me, please let me know.

it is quite likely that display.begin( ) actually attempts to communicate with the display. It doesn't surprise me at all that it doesn't work.

You are also trying to send messages to the GPS that isn't there. That is likely to not work, also.

michinyon:
it is quite likely that display.begin( ) actually attempts to communicate with the display. It doesn't surprise me at all that it doesn't work.

You are also trying to send messages to the GPS that isn't there. That is likely to not work, also.

I thought that might be the case, I guess I'll just have to wait till I get the devices before I can rule this out.

I now have all these items, and they work individually, but through some trouble shooting I found that just the libraries themselves take up too much sram, how can I minimize this, and fix the problem, I am about 190 bytes in the hole.

I now have all these items, and they work individually, but through some trouble shooting I found that just the libraries themselves take up too much sram, how can I minimize this, and fix the problem, I am about 190 bytes in the hole.

Ladyada's GPS lib is double-buffered. This is probably not necessary for your implementation, so I would suggest bringing her .h into your project as a tab (to isolate the code from your library code) and put the .cpp file in the project directory, too. Then make your edits to the code and remove the duplicate SRAM usage.

If you are unfamiliar with encapsulating a library into your project, I had a download you can inspect here:
http://forum.arduino.cc/index.php?PHPSESSID=9oq91pm4065sripgha2bsfo9e1&topic=199216.msg1498362#msg1498362

Ray

I'm not sure what you mean when you say double buffered in the gps library. Here is the code I got now.

https://drive.google.com/file/d/0B-xbQ5Nkmz-UbVgzbWJjOGJHMTA/edit?usp=sharing

I could not get to your zip on Google Drive, however
https://github.com/adafruit/Adafruit-GPS-Library/blob/master/Adafruit_GPS.cpp

#include <Adafruit_GPS.h>

// how long are max NMEA lines to parse?
#define MAXLINELENGTH 120

// we double buffer: read one line in and leave one for the main program
volatile char line1[MAXLINELENGTH];
volatile char line2[MAXLINELENGTH];

So, char line1[] and line2[] are both buffers @ length of 120 characters.... so that is a significant part of your 190 shortage and you could regain 120 bytes by rewriting this to use a single buffer.

Ray

THANK YOU SOO MUCH!
I just changed the buffer size to a much smaller length, and it works.

THANK YOU SOO MUCH!
I just changed the buffer size to a much smaller length, and it works.

“Without deviation from the norm, progress is not possible.”
? Frank Zappa

legendlcox:
THANK YOU SOO MUCH!
I just changed the buffer size to a much smaller length, and it works.

Hi i think i have the same problem with my try to build a GPS-Kit.

Which buffer size to you use?

hat happens when de buffer size is to small?

hat happens when de buffer size is to small?

It overflows sooner.