I have connected up my GPS, accelerometer and tft display to my Arduino nano.
In the Serial COM port I notice that all the NMEA sentences are printing out nicely and correctly. An RMC sentence followed by a GGA sentence.
However, when I check to see what was logged on the SD card I notice that the RMC sentences contain strange characters and symbols.
After some researching I discovered that this may be due to a low SRAM availaibility problem. Upon compilation, I received the warning "Low memory available, stability problems may occur" and:
Sketch uses 29036 bytes (94%) of program storage space. Maximum is 30720 bytes.
Global variables use 1592 bytes (77%) of dynamic memory, leaving 456 bytes for local variables
As a result I tried to free up memory. Having read that STRINGS take up a lot of SRAM, I removed one of the NMEA sentences I was storing on the SD card. This resulted in good NMEA sentences being stored on the SD card. However, This means I am unable to capture all the good NMEA sentences coming through.
My Question: How can I send both NMEA sentences to the SD card.
my guesses: 1) Using an alternate data type to string. Maybe a character array? I am not sure how to implement this...
2) Storing the string temporarily in EEPROM - again I am not sure how to implement this.
I was hoping someone could take a look at my code below and aid me in finding a solution.
Many thanks in advance for your time!
Laurence
p,s It may have nothing to do with Strings and Memory. If anyone can think of any other problems (Most like to do with the code) please let me know.
//Make sure to install the adafruit GPS library from https://github.com/adafruit/Adafruit-GPS-Library
#include <Adafruit_GPS.h> //Load the GPS Library. Make sure you have installed the library form the adafruit site above
#include <SoftwareSerial.h> //Load the Software Serial Library. This library in effect gives the arduino additional serial ports
SoftwareSerial mySerial(3, 2); //Initialize SoftwareSerial, and tell it you will be connecting through pins 2 and 3
Adafruit_GPS GPS(&mySerial); //Create GPS object
#include "Adafruit_ILI9341.h"
#include <Adafruit_GFX.h>
#include <SD.h>
#include <SPI.h>
#define TFT_DC 9
#define TFT_CS 8
int chipSelect = 4;
File gpsData; //Variable for SD cards Object
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
String NMEA1; //We will use this variable to hold our first NMEA sentence
String NMEA2; //We will use this variable to hold our second NMEA sentence
char c; //Used to read the characters spewing from the GPS module
void setup()
{
tft.begin();
tft.setRotation(3);
tft.setTextSize(2);
tft.fillScreen(ILI9341_BLACK);
Serial.begin(115200); //Turn on the Serial Monitor
GPS.begin(9600); //Turn GPS on at baud rate of 9600
pinMode(10,OUTPUT);
SD.begin(chipSelect); //Initialise SD card and say it is connected to chipSelect (4)
if (SD.exists("NMEA.txt")) //Checks to see if the files exists (if it does and we don't remove it, we append it. We don't want old data)
{
SD.remove("NMEA.txt");
}
if (SD.exists("GPSdata.txt")) //Same as above. Get rid of old data so we can obtain new data
{
SD.remove("GPSdata.txt");
}
GPS.sendCommand("$PGCMD,33,0*6D"); // Turn Off GPS Antenna Update
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); //Tell GPS we want only $GPRMC and $GPGGA NMEA sentences
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
delay(1000); //Pause
}
void loop() // run over and over again
{
readGPS();//This is a function we define below which reads two NMEA sentences from GPS
if (GPS.fix == 1) //only log data after we have a fix
{
gpsData = SD.open("NMEA.txt",FILE_WRITE); //open NMEA.txt to write to it.
gpsData.println(NMEA1); //Write first sentence to file
gpsData.println(NMEA2); //Write second sentence to file
gpsData.close();
gpsData = SD.open("GPSdata.txt", FILE_WRITE);
gpsData.print(GPS.latitude,4); //Write latitude to the SD file to 4 decminal places
gpsData.print(GPS.lat); //Which hemispher are we in? N or S?
gpsData.print(",");
gpsData.print(GPS.longitude,4);
gpsData.print(GPS.lon); //Which hemisphere are we in, E or W
gpsData.print(",");
gpsData.println(GPS.altitude);
gpsData.close();
}
}
void readGPS(){ //This function will read and remember two NMEA sentences from GPS
clearGPS(); //Serial port probably has old or corrupt data, so begin by clearing it all out
while(!GPS.newNMEAreceived()) { //Keep reading characters in this loop until a good NMEA sentence is received
c=GPS.read(); //read a character from the GPS
}
GPS.parse(GPS.lastNMEA()); //Once you get a good NMEA, parse it
NMEA1=GPS.lastNMEA(); //Once parsed, save NMEA sentence into NMEA1
while(!GPS.newNMEAreceived()) { //Go out and get the second NMEA sentence, should be different type than the first one read above.
c=GPS.read();
}
GPS.parse(GPS.lastNMEA());
NMEA2=GPS.lastNMEA();
Serial.println(NMEA1);
Serial.println(NMEA2);
Serial.println("");
PrintDateTime();
}
void clearGPS() { //Since between GPS reads, we still have data streaming in, we need to clear the old data by reading a few sentences, and discarding these
while(!GPS.newNMEAreceived()) {
c=GPS.read();
}
GPS.parse(GPS.lastNMEA());
while(!GPS.newNMEAreceived()) {
c=GPS.read();
}
GPS.parse(GPS.lastNMEA());
}
void PrintDateTime(){
int Offset = 1;
GPS.hour = GPS.hour + Offset;
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setCursor(90,100);
if (GPS.hour < 10)
{
tft.print("0");
tft.print(GPS.hour);
}
else if (10 < GPS.hour < 25)
{
tft.print(GPS.hour);
if (GPS.hour = 24){GPS.day = (GPS.day+1);}
}
else
{
GPS.hour = 1;
tft.print("0");
tft.print(GPS.hour);
}
tft.print(":");
if(GPS.minute < 10)
{
tft.print("0");
tft.print(GPS.minute);
}
else
{
tft.print(GPS.minute);
}
tft.print(":");
if(GPS.seconds < 10)
{
tft.print("0");
tft.print(GPS.seconds);
}
else
{
tft.print(GPS.seconds);
}
tft.setCursor(90,120);
if(GPS.day < 10)
{
tft.print("0");
tft.print(GPS.day);
}
else
{
tft.print(GPS.day);
}
tft.print(":");
if(GPS.month < 10)
{
tft.print("0");
tft.print(GPS.month);
}
else
{
tft.print(GPS.month);
}
tft.print(":");
tft.print(GPS.year);
}