Three (too large) 1D-arrays

Hi,

I’m attempting to make a display to place on the steering wheel of a go-kart (outdoor). A few sensors are already on the kart like rpm, speed and a magnetic field transducer. I added a gps and a 3-axis sensor.
I use the gps purely to see at which track I’m at. I use three 1D-arrays: track name, latitude and longitude (don’t know how to work with a 2D, so thiswas the easiest way out). During testing I only used 5 elements in all 3 arrays. I drove around and when I came near a certain coordinate, it printed out whatever I had set it to. After that, I used all 27 track names and their corresponding coordinates. Because I wasn’t sure it would work, I placed my own place at the end (element 28). The program only printed the number of sats and not my own place as it did before.
I tested everything on a Mega, but I’m planning on using an Uno in the final build.

Is it because the arrays are to big for a Mega or an Uno?
If there are any other remarks, please do tell!

//#include <SoftwareSerial.h>    //If Uno

#include <TinyGPS.h>      //C:\Program Files\Arduino\libraries\TinyGPS13
TinyGPS gps;
//SoftwareSerial ss(9, 8);    //If Uno, change "Serial3" to "ss"

static void smartdelay(unsigned long ms);


//All 27 tracks with corresponding latitude and longitude
float Y0, X0;
const float radius = 0.008;
const int numElements = 27;
const char* aTrack[] = {"Cobra Karting", "Genker Kart", "Karting de Bouillon", "Karting de la Famenne", 
                  "Karting des Fagnes", "Sokafran", "Piste de Mondercange", "Circuit Karting Texel",
                  "Kart Racing Oldenzaal", "Kartcentrum Lelystad", "Kartcircuit de Woerd", "Kartcircuit Pottendijk",
                  "Karting Circuits de Lands", "Karting Circuit Nieuw Zevenbergen-Berghem", "Karting Eefde",
                  "Outdoor Karting Vaals", "Skelter Club Hoekse Waard", "Skelterbaan Karba",
                  "Kart Club Kerpen-Manheim", "Kartbahn Dahlemer Binz", "Circuit de la Métropole",
                  "Circuit de Gravelines", "Piste de Karting du Bois Failly", "Karting 55",
                  "Circuit du Ver de Vase", "Circuit de Bucy Le Long"};

const float aLat[] = {50.547520, 50.987577, 49.799079, 50.237516, 50.093329, 50.431951, 49.546623,
		53.057936, 52.307270, 52.450947, 52.055029, 52,819348, 51.461835, 0, 52.186240,    //The "0" is because I couldn't find it on Google Maps
		50.779224, 51.766884, 52.487458, 50.888184, 50.400885, 50.468724, 51.006463,
		49.339405, 49.148541, 50.512927, 49.379397, 49.376419};

const float aLon[] = {5.297019, 5.560920, 5.084363, 5.300431, 4.500532, 5.963109, 5.975146, 4.777937,
	        6.900959, 5.497241, 5.257677, 5.984129, 5.374868, 0, 6.248109, 6.012402, 4.528320,    //The "0" is because I couldn't find it on Google Maps
		6.160578, 6.614027, 5.530997, 3.031443, 2.132614, 2.297785, 5.376794, 2.843410,
		3.293533, 3.424366};

void setup()
{
  Serial.begin(115200);   //Start serial monitor
  Serial3.begin(4800);    //Start readout GPS
  pinMode(13,OUTPUT);
  digitalWrite(13,HIGH); 
}

void loop(){
  if(gps.satellites() == 255 || gps.satellites() == 0){      //If there aren't any sats, the GPS will print "255" or "0"
    digitalWrite(13,HIGH);                                   //If no sats found, turn led 13 on
    Serial.print("No sats found\n");	
  }
  else{
    Serial.print("\n");
    Serial.print(gps.satellites());    //Print number of sats
    digitalWrite(13,LOW);              //Turn led 13 off
    Serial.println(" sats");
   
    for (int i = 0; i < numElements; i++){    //Go through the arrays
      gps.f_get_position(&Y0,&X0);            //Get latitude and longitude from GPS
      if (sqrt(((Y0-aLat[i])*(Y0-aLat[i]))+((X0-aLon[i])*(X0-aLon[i]))) <= radius){    //Calculate if a set coordinate from the array is within the set radius from the GPS' coordinate
        Serial.println(aTrack[i]);    //Print the corresponding track name when the outcome from previous line is true
      }
    }
  }
  smartdelay(1500);
}

static void smartdelay(unsigned long ms)      //Create smartdelay
{
  unsigned long start = millis();
  do 
  {
    while (Serial3.available())
      gps.encode(Serial3.read());
  } while (millis() - start < ms);
}

Thanks!

Are any of the arrays going to change at run time? If not, put all that stuff in PROGMEM, and leave your SRAM free for stuff that does change.

PaulS: Are any of the arrays going to change at run time? If not, put all that stuff in PROGMEM, and leave your SRAM free for stuff that does change.

Nothing changes during runtime. I'll look tomorrow to see how I need to put it into PROGMEM.

Other question: I now manually type how many elements there are, numElements. I know I'll have to use sizeof() if I want the program to calculate it, but I couldn't get it to work. I also want to compare all three arrays so I know I didn't make any mistakes, but I couldn't find anything on how to count the elements of a char*array.

Post what you tried, but you basically divide the size of the whole array by the size of one item.

I’ve added the PROGMEM and sizeof().

I tried to copy all my arrays to PROGMEM, but it still only prints the number of satellites as it did before. It should print out “My place”.

Sizeof() is working a little bit. There are 28 elements in all 3 arrays. I use 3 times exactly the same function and for the first array (float) it gives me 29. The second (float) and third (char*) gives me 28.

//#include <SoftwareSerial.h>    //If Uno
#include <avr/pgmspace.h>

#include <TinyGPS.h>      //C:\Program Files\Arduino\libraries\TinyGPS13
TinyGPS gps;
//SoftwareSerial ss(9, 8);    //If Uno, change "Serial3" to "ss"

static void smartdelay(unsigned long ms);

float Y0, X0;
const float radius = 0.008;
char string_0[] PROGMEM = "Cobra Karting";
char string_1[] PROGMEM = "Genker Kart";
char string_2[] PROGMEM = "Karting de Bouillon";
char string_3[] PROGMEM = "Karting de la Famenne";
char string_4[] PROGMEM = "Karting des Fagnes";
char string_5[] PROGMEM = "Sokafran";
char string_6[] PROGMEM = "Piste de Mondercange";
char string_7[] PROGMEM = "Circuit Karting Texel";
char string_8[] PROGMEM = "Karting Racing Oldenzaal";
char string_9[] PROGMEM = "Kartcentrum Lelystad";
char string_10[] PROGMEM = "Kartcircuit de Woerd";
char string_11[] PROGMEM = "Kartcircuit Pottendijk";
char string_12[] PROGMEM = "Karting Circuits de Lands";
char string_13[] PROGMEM = "Karting Circuit Nieuw Zevenbergen-Berghem";
char string_14[] PROGMEM = "Karting Eefde";
char string_15[] PROGMEM = "Outdoor Karting Vaals";
char string_16[] PROGMEM = "Skelter Club Hoekse Waard";
char string_17[] PROGMEM = "Skelterbaan Karba";
char string_18[] PROGMEM = "Kart Club Kerpen-Manheim";
char string_19[] PROGMEM = "Karbahn Dahlemer Binz";
char string_20[] PROGMEM = "Circuit de la Métropole";
char string_21[] PROGMEM = "Circuit de Gravelines";
char string_22[] PROGMEM = "Piste de Karting du bois Failly";
char string_23[] PROGMEM = "Karting 55";
char string_24[] PROGMEM = "Circuit de Douvrin";
char string_25[] PROGMEM = "Circuit de ver de Vase";
char string_26[] PROGMEM = "Circuit de Bucy Le Long";
char string_27[] PROGMEM = "My place";
PGM_P aTrack[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5, string_6, string_7, string_8, string_9,
                          string_10, string_11, string_12, string_13, string_14, string_15, string_16, string_17, string_18, string_19,
                          string_20, string_21, string_22, string_23, string_24, string_25, string_26, string_27};


float aLat[] PROGMEM = {50.547520, 50.987577, 49.799079, 50.237516, 50.093329, 50.431951, 49.546623, 53.057936, 
                52.307270, 52.450947, 52.055029, 52,819348, 51.461835, 0, 52.186240, 50.779224, 51.766884, 
                52.487458, 50.888184, 50.400885, 50.468724, 51.006463, 49.339405, 49.148541, 50.512927,
                49.379397, 49.376419, 48.85837};

float aLon[] PROGMEM = {5.297019, 5.560920, 5.084363, 5.300431, 4.500532, 5.963109, 5.975146, 4.777937,
	        6.900959, 5.497241, 5.257677, 6.984129, 5.374868, 0, 6.248109, 6.012402, 4.528320,    //The "0" is because I couldn't find it on Google Maps
		6.160578, 6.614027, 5.530997, 3.031443, 2.132614, 5.297785, 5.376794, 2.843410,
		3.293533, 3.424366, 2.294481};

int numElements = 28;
int numElementsLat = 0;
int numElementsLon = 0;
int numElementsTrack = 0;
char buffer[50];

void setup()
{
  Serial.begin(115200);   //Start serial monitor
  Serial3.begin(4800);    //Start readout GPS
  pinMode(13,OUTPUT);
  digitalWrite(13,HIGH);
  numElementsLat = sizeof(aLat)/sizeof(float);
  Serial.print(numElementsLat);
  Serial.print("\t");
  numElementsLon = sizeof(aLon)/sizeof(float);
  Serial.print(numElementsLon);
  Serial.print("\t");
  numElementsTrack = sizeof(aTrack)/sizeof(char*);
  Serial.print(numElementsTrack);
  Serial.print("\n");
  
}

void loop(){
  if(gps.satellites() == 255 || gps.satellites() == 0){      //If there aren't any sats, GPS will return "255" or "0"
    digitalWrite(13,HIGH);                                   //If no sats found, turn led 13 on
    Serial.print("No sats found\n");	
  }
  else{
    Serial.print("\n");
    Serial.print(gps.satellites());    //Print number of sats
    digitalWrite(13,LOW);              //Turn led 13 off
    Serial.println(" sats");
   
    for (int i = 0; i < numElements; i++){    //Go through the arrays
      gps.f_get_position(&Y0,&X0);            //Get latitude and longitude from GPS
      if (sqrt(((Y0-pgm_read_byte(&(aLat[i]))*(Y0-pgm_read_byte(&(aLat[i]))))+((X0-pgm_read_byte(&(aLon[i])))*(X0-pgm_read_byte(&(aLon[i]))))) <= radius)){    //Calculate if a set coordinate from the array is within the set radius from the GPS' coordinate
        for(unsigned char k = 0; k < 6; k++){
          strcpy_P(buffer, (PGM_P)pgm_read_word(&(aTrack[i])));
          Serial.println(buffer);    //Print the corresponding track name when the outcome from previous line is true
        }
      }
    }
  }
  smartdelay(1000);
}

static void smartdelay(unsigned long ms)      //Create smartdelay
{
  unsigned long start = millis();
  do 
  {
    while (Serial3.available())
      gps.encode(Serial3.read());
  } while (millis() - start < ms);
}

You have 3 arrays, two of which have 29 elements and one has 28. Trust the compiler, it doesn't lie about these things.

Hint: did you mean the two zero entries in the float arrays? And all the commas?

MarkT: You have 3 arrays, two of which have 29 elements and one has 28. Trust the compiler, it doesn't lie about these things.

Hint: did you mean the two zero entries in the float arrays? And all the commas?

Two have 28 elements, one has 29. The two zero entries are because I couldnt find the coordinates. I looked if I used the comma's (, or .) correct and I found a mistake! It now prints 3 times 28. Thanks MarkT!

White space in array declarations is usually irrelevant. Make things easy on your self, and declare the arrays with the same number of elements on each line. That makes it much easier to see when things go wrong.

PGM_P aTrack[] PROGMEM = {
   string_0, string_1, string_2, string_3,
   string_4, string_5, string_6, string_7,
   string_8, string_9, string_10, string_11,
   string_12, string_13, string_14, string_15,
   string_16, string_17, string_18, string_19,
   string_20, string_21, string_22, string_23, 
   string_24, string_25, string_26, string_27
};

Another thing that helps would be names like string_00, etc., so all names are the same length.

An added benefit is no horizontal scrolling is needed to count elements.

PaulS:
White space in array declarations is usually irrelevant. Make things easy on your self, and declare the arrays with the same number of elements on each line. That makes it much easier to see when things go wrong.

PGM_P aTrack[] PROGMEM = {

string_0, string_1, string_2, string_3,
  string_4, string_5, string_6, string_7,
  string_8, string_9, string_10, string_11,
  string_12, string_13, string_14, string_15,
  string_16, string_17, string_18, string_19,
  string_20, string_21, string_22, string_23,
  string_24, string_25, string_26, string_27
};




Another thing that helps would be names like string_00, etc., so all names are the same length.

An added benefit is no horizontal scrolling is needed to count elements.

Thanks for those tips, Paul!

Do you, or anyone else, see a problem to why it isn’t showing the correct name?

There are 2 lines which I don’t fully understand:

for(unsigned char k = 0; k < 6; k++){
            strcpy_P(buffer, (PGM_P)pgm_read_word(&(aTracks[i])));    //Copy track name from PROGMEM to SRAM

Is the for statement needed to retrieve the track name word for word? While doing this, it also copies word for word from PROGMEM tot SRAM?

Full code:

//#include <SoftwareSerial.h>    //If Uno
#include <avr/pgmspace.h>

#include <TinyGPS.h>      //C:\Program Files\Arduino\libraries\TinyGPS13
TinyGPS gps;
//SoftwareSerial ss(9, 8);    //If Uno, change "Serial3" to "ss"

static void smartdelay(unsigned long ms);

float Y0, X0;
const float radius = 0.008;
char string_00[] PROGMEM = "Cobra Karting";
char string_01[] PROGMEM = "Genker Kart";
char string_02[] PROGMEM = "Karting de Bouillon";
char string_03[] PROGMEM = "Karting de la Famenne";
char string_04[] PROGMEM = "Karting des Fagnes";
char string_05[] PROGMEM = "Sokafran";
char string_06[] PROGMEM = "Piste de Mondercange";
char string_07[] PROGMEM = "Circuit Karting Texel";
char string_08[] PROGMEM = "Karting Racing Oldenzaal";
char string_09[] PROGMEM = "Kartcentrum Lelystad";
char string_10[] PROGMEM = "Kartcircuit de Woerd";
char string_11[] PROGMEM = "Kartcircuit Pottendijk";
char string_12[] PROGMEM = "Karting Circuits de Lands";
char string_13[] PROGMEM = "Karting Circuit Nieuw Zevenbergen-Berghem";
char string_14[] PROGMEM = "Karting Eefde";
char string_15[] PROGMEM = "Outdoor Karting Vaals";
char string_16[] PROGMEM = "Skelter Club Hoekse Waard";
char string_17[] PROGMEM = "Skelterbaan Karba";
char string_18[] PROGMEM = "Kart Club Kerpen-Manheim";
char string_19[] PROGMEM = "Karbahn Dahlemer Binz";
char string_20[] PROGMEM = "Circuit de la Métropole";
char string_21[] PROGMEM = "Circuit de Gravelines";
char string_22[] PROGMEM = "Piste de Karting du bois Failly";
char string_23[] PROGMEM = "Karting 55";
char string_24[] PROGMEM = "Circuit de Douvrin";
char string_25[] PROGMEM = "Circuit de ver de Vase";
char string_26[] PROGMEM = "Circuit de Bucy Le Long";
char string_27[] PROGMEM = "My place";

PGM_P aTracks[] PROGMEM = {
  string_00, string_01, string_02, string_03,
  string_04, string_05, string_06, string_07,
  string_08, string_09, string_10, string_11,
  string_12, string_13, string_14, string_15,
  string_16, string_17, string_18, string_19,
  string_20, string_21, string_22, string_23,
  string_24, string_25, string_26, string_27};

float aLat[] PROGMEM = {
  50.547520, 50.987577, 49.799079, 50.237516,
  50.093329, 50.431951, 49.546623, 53.057936, 
  52.307270, 52.450947, 52.055029, 52.819348,
  51.461835, 00.000000, 52.186240, 50.779224,
  51.766884, 52.487458, 50.888184, 50.400885,
  50.468724, 51.006463, 49.339405, 49.148541,
  50.512927, 49.379397, 49.376419, 48.85837};

float aLon[] PROGMEM = {
  5.297019, 5.560920, 5.084363, 5.300431,
  4.500532, 5.963109, 5.975146, 4.777937,
  6.900959, 5.497241, 5.257677, 6.984129,
  5.374868, 0.000000, 6.248109, 6.012402,
  4.528320, 6.160578, 6.614027, 5.530997,
  3.031443, 2.132614, 5.297785, 5.376794,
  2.843410, 3.293533, 3.424366, 2.294481};

int numElements = 0;
int numElementsLat = 0;
int numElementsLon = 0;
int numElementsTracks = 0;
char buffer[50];

void setup()
{
  Serial.begin(115200);   //Start serial monitor
  Serial3.begin(4800);    //Start readout GPS
  pinMode(13,OUTPUT);
  digitalWrite(13,HIGH);
  numElementsLat = sizeof(aLat)/sizeof(float);
  //  Serial.print(numElementsLat);
  //  Serial.print("\t");
  numElementsLon = sizeof(aLon)/sizeof(float);
  //  Serial.print(numElementsLon);
  //  Serial.print("\t");
  numElementsTracks = sizeof(aTracks)/sizeof(char*);
  //  Serial.print(numElementsTrack);
  //  Serial.print("\n");

}

void loop(){
  if((numElementsLat == numElementsLon)&& (numElementsLon == numElementsTracks)){
    numElements = numElementsLat;
    if(gps.satellites() == 255 || gps.satellites() == 0){      //If there aren't any sats, GPS will return "255" or "0"
      digitalWrite(13,HIGH);                                   //If no sats found, turn led 13 on
      Serial.print("No sats found\n");	
    }
    else{
      Serial.print("\n");
      Serial.print(gps.satellites());    //Print number of sats
      digitalWrite(13,LOW);              //Turn led 13 off
      Serial.println(" sats");

      for (int i = 0; i < numElements; i++){    //Go through the arrays
        gps.f_get_position(&Y0,&X0);            //Get latitude and longitude from GPS
        if (sqrt(((Y0-pgm_read_byte(&(aLat[i]))*(Y0-pgm_read_byte(&(aLat[i]))))+((X0-pgm_read_byte(&(aLon[i])))*(X0-pgm_read_byte(&(aLon[i]))))) <= radius)){
          for(unsigned char k = 0; k < 6; k++){
            strcpy_P(buffer, (PGM_P)pgm_read_word(&(aTracks[i]))); 
            Serial.println(buffer);    //Print the corresponding track name
          }
        }
      }
    }
  }
  else {
    Serial.println("Arrays are not equal!");
    Serial.print("Tracks: ");
    Serial.print(numElementsTracks);
    Serial.print("\nLat: ");
    Serial.print(numElementsLat);
    Serial.print("\nLon: ");
    Serial.print(numElementsLon);
    Serial.print("\n");
  }

  smartdelay(1000);
}

static void smartdelay(unsigned long ms)      //Create smartdelay
{
  unsigned long start = millis();
  do 
  {
    while (Serial3.available())
      gps.encode(Serial3.read());
  } 
  while (millis() - start < ms);
}

Discard the previous code. I changed the strcpy_P code and I think it’s now more correct then it previously was. Now it prints the number of sats and a few track names. It should only print number of sats and “My place”.
I also tried to print all the track names, but the ones he printed out previously, he now doesn’t print them.

The code below will print:number of sats, string_02, 06, 22, 23, 25, 26. (He prints the actual names, but this is easier to type.)

//#include <SoftwareSerial.h>    //If Uno
#include <avr/pgmspace.h>

#include <TinyGPS.h>      //C:\Program Files\Arduino\libraries\TinyGPS13
TinyGPS gps;
//SoftwareSerial ss(9, 8);    //If Uno, change "Serial3" to "ss"

static void smartdelay(unsigned long ms);

float Y0, X0;
const float radius = 0.008;
char string_00[] PROGMEM = "Cobra Karting";
char string_01[] PROGMEM = "Genker Kart";
char string_02[] PROGMEM = "Karting de Bouillon";
char string_03[] PROGMEM = "Karting de la Famenne";
char string_04[] PROGMEM = "Karting des Fagnes";
char string_05[] PROGMEM = "Sokafran";
char string_06[] PROGMEM = "Piste de Mondercange";
char string_07[] PROGMEM = "Circuit Karting Texel";
char string_08[] PROGMEM = "Karting Racing Oldenzaal";
char string_09[] PROGMEM = "Kartcentrum Lelystad";
char string_10[] PROGMEM = "Kartcircuit de Woerd";
char string_11[] PROGMEM = "Kartcircuit Pottendijk";
char string_12[] PROGMEM = "Karting Circuits de Lands";
char string_13[] PROGMEM = "Karting Circuit Nieuw Zevenbergen-Berghem";
char string_14[] PROGMEM = "Karting Eefde";
char string_15[] PROGMEM = "Outdoor Karting Vaals";
char string_16[] PROGMEM = "Skelter Club Hoekse Waard";
char string_17[] PROGMEM = "Skelterbaan Karba";
char string_18[] PROGMEM = "Kart Club Kerpen-Manheim";
char string_19[] PROGMEM = "Karbahn Dahlemer Binz";
char string_20[] PROGMEM = "Circuit de la Métropole";
char string_21[] PROGMEM = "Circuit de Gravelines";
char string_22[] PROGMEM = "Piste de Karting du bois Failly";
char string_23[] PROGMEM = "Karting 55";
char string_24[] PROGMEM = "Circuit de Douvrin";
char string_25[] PROGMEM = "Circuit de ver de Vase";
char string_26[] PROGMEM = "Circuit de Bucy Le Long";
char string_27[] PROGMEM = "My place";

PROGMEM const char* aTracks[] = {
  string_00, string_01, string_02, string_03,
  string_04, string_05, string_06, string_07,
  string_08, string_09, string_10, string_11,
  string_12, string_13, string_14, string_15,
  string_16, string_17, string_18, string_19,
  string_20, string_21, string_22, string_23,
  string_24, string_25, string_26, string_27};

float aLat[] PROGMEM = {
  50.547520, 50.987577, 49.799079, 50.237516,
  50.093329, 50.431951, 49.546623, 53.057936, 
  52.307270, 52.450947, 52.055029, 52.819348,
  51.461835, 00.000000, 52.186240, 50.779224,
  51.766884, 52.487458, 50.888184, 50.400885,
  50.468724, 51.006463, 49.339405, 49.148541,
  50.512927, 49.379397, 49.376419, 48.85837};

float aLon[] PROGMEM = {
  5.297019, 5.560920, 5.084363, 5.300431,
  4.500532, 5.963109, 5.975146, 4.777937,
  6.900959, 5.497241, 5.257677, 6.984129,
  5.374868, 0.000000, 6.248109, 6.012402,
  4.528320, 6.160578, 6.614027, 5.530997,
  3.031443, 2.132614, 5.297785, 5.376794,
  2.843410, 3.293533, 3.424366, 2.294481};

int numElements = 0;
int numElementsLat = 0;
int numElementsLon = 0;
int numElementsTracks = 0;
char buffer[50];

void setup()
{
  Serial.begin(115200);   //Start serial monitor
  Serial3.begin(4800);    //Start readout GPS
  pinMode(13,OUTPUT);
  digitalWrite(13,HIGH);
  numElementsLat = sizeof(aLat)/sizeof(float);
  //  Serial.print(numElementsLat);
  //  Serial.print("\t");
  numElementsLon = sizeof(aLon)/sizeof(float);
  //  Serial.print(numElementsLon);
  //  Serial.print("\t");
  numElementsTracks = sizeof(aTracks)/sizeof(char*);
  //  Serial.print(numElementsTrack);
  //  Serial.print("\n");

}

void loop(){
  if((numElementsLat == numElementsLon)&& (numElementsLon == numElementsTracks)){
    numElements = numElementsLat;
    if(gps.satellites() == 255 || gps.satellites() == 0){      //If there aren't any sats, GPS will return "255" or "0"
      digitalWrite(13,HIGH);                                   //If no sats found, turn led 13 on
      Serial.print("No sats found\n");	
    }
    else{
      Serial.print("\n");
      Serial.print(gps.satellites());    //Print number of sats
      digitalWrite(13,LOW);              //Turn led 13 off
      Serial.println(" sats");

      for (int i = 0; i < numElements; i++){    //Go through the arrays
        gps.f_get_position(&Y0,&X0);            //Get latitude and longitude from GPS
        //If distance between the 2 coordinates is smaller or equal to radius, print corresponding track name
        if (sqrt(((Y0-(pgm_read_float(&(aLat[i])))*(Y0-(pgm_read_float(&(aLat[i])))))+
          ((X0-(pgm_read_float(&(aLon[i]))))*(X0-(pgm_read_float(&(aLon[i])))))) <= radius)){
            strcpy_P(buffer, (char*)pgm_read_word(&(aTracks[i])));    //Copy track name from PROGMEM to SRAM
            Serial.println(buffer);
          }
        }
      }
    }
  else {            //If the 3 arrays aren't equal
    Serial.println("Arrays are not equal!");
    Serial.print("Tracks: ");
    Serial.print(numElementsTracks);
    Serial.print("\nLat: ");
    Serial.print(numElementsLat);
    Serial.print("\nLon: ");
    Serial.print(numElementsLon);
    Serial.print("\n");
//    Serial.print(pgm_read_float(&(aLat[1])),6);
//    Serial.print("\n");
  }

  smartdelay(2000);
}

static void smartdelay(unsigned long ms)      //Create smartdelay
{
  unsigned long start = millis();
  do 
  {
    while (Serial3.available())
      gps.encode(Serial3.read());
  } 
  while (millis() - start < ms);
}
      for (int i = 0; i < numElements; i++){    //Go through the arrays
        gps.f_get_position(&Y0,&X0);            //Get latitude and longitude from GPS

Why do you need to get the position each time? Isn’t the idea to compare one position to 28 other positions?

        if (sqrt(((Y0-(pgm_read_float(&(aLat[i])))*(Y0-(pgm_read_float(&(aLat[i])))))+
          ((X0-(pgm_read_float(&(aLon[i]))))*(X0-(pgm_read_float(&(aLon[i])))))) <= radius)){

Read the values once, and store them in temporary values. It’s really hard to read that code with the 14 bazilllion parentheses.

  smartdelay(2000);

A smart delay would properly handle a value of 0. Yours does not. You should have a while statement, not a do/while statement in the function.

I can see the benefit of storing the track names in PROGMEM. I can’t see the real benefit in storing the 28 pointers to the names in PROGMEM, too. They do not take up a whole lot of space.