XRAD's store x/y coords in array then recall

What is the best strategy for storing x/y (an x/y pair) of coords of an unknow quantity of points into an array (or in another best way) and then be able recall them in a group at one time ( to redraw the displayed points) when scale change is needed (not dynamic scaling, but chosen by user as needed)? The x/y coords are of integer type, without decimal.

I have a gps set of coords that may be hundreds or thousands of x/y points to be stored in pairs, and then at a later time be accessed as a group to show the points on a display.....

I want to scale these points to fit a defined TFT size. If the points extend beyond the map size, I want to be able to adjust the map scale on the fly and redraw all the points. Basically a zoom in, and zoom out function using the 'stored x/y points.

My assumption is that I have to save the points at one scale, and redraw them to whatever scale is necessary. I do not want to access any one set of points, just all of them at one time for rewriting on the display.

Any ideas much appreciated!

Sounds like a job for an array of structs but you will need to declare the array with a fixed number of points.

OUCH

What data type are the values ?
Which Arduino board are you using ?

tha for reply UKHelibob! i'm using teensy 3.2. I don't think a fixed array will work as the x/y points are obtained as i am moving around (the x/y points will be new and added to the array, and not a finite number of points...ie: I do not know how far I will travel) and the number of GPS conversion to x/y are not known. I think I need a variable array (array int pair) as I can't declare the array to a known size .....basically a additive recording of x/y variables to be accessed in a group as needed....(using a class or function? accessed by button press)

the x/y data set needs to be accessed to redraw the pixels on the tft at the appropriate scale.

I could save to SD (teensy 3.6) if needed...

the x/y data types are integers. Here is my current code:



#include <TinyGPS.h>
#include <Adafruit_GFX.h>
#include "Adafruit_ILI9341.h"

#define TFT_CS    8      // TFT CS  pin is connected to arduino pin 8
#define TFT_RST   9      // TFT RST pin is connected to arduino pin 9
#define TFT_DC    10     // TFT DC  pin is connected to arduino pin 10

// initialize ILI9341 TFT library
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);

TinyGPS gps;

bool  oneTimePosition = true;
int long oneTimeLat, oneTimeLong;

unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 1000;

#define  R 6367000 // Radius earth in m

int long x ;
int long y ;
int long homex;
int long homey; 
 
int dx;
int dy;

//not used yet
#define MAP_WIDTH 210
#define MAP_HEIGHT 240
#define MAP_CENTERX 215
#define MAP_CENTERY 120
#define width 210
#define height 240

 

void drawMap() { //draw a map w/dotted cross
  tft.drawRoundRect(110, 0, 210, 240, 10, ILI9341_GREEN);
  for (int x = 55; x < 160; x++) {
    tft.drawPixel((2 * x), 120, ILI9341_GREEN);
  }
  for (int y = 0; y < 120; y++) {
    tft.drawPixel(215, (2 * y), ILI9341_GREEN);
  }
  tft.setCursor(210, 2);
  tft.fillRect(210, 2, 10, 14, ILI9341_BLACK);
  tft.setTextColor(ILI9341_GREEN);  tft.setTextSize(2);
  tft.println("N");
} 
 
 struct XYPoints//not yet used
{
    int xSaved, ySaved;
};



void setup()
{

  Serial.begin(115200);
  Serial1.begin(9600);//my GPS device uses 9600 baud, using teensy Serial1

  tft.begin();
  tft.setRotation(3);
  tft.fillScreen(ILI9341_BLACK);
  tft.setCursor(40, 100);
  tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(3);
  tft.println("GPS ACTIVATED");

  delay(2000);
  tft.fillScreen(ILI9341_BLACK);

  tft.setCursor(0, 0);
  tft.setTextColor(ILI9341_GREEN);  tft.setTextSize(1);
  tft.print("CURRENT POSITION: ");
  tft.setCursor(0, 90);
  tft.print("INITIAL POSITION: ");
  tft.setCursor(0, 150);
  tft.print("CARTESIAN COORD: ");

  drawMap();

  startMillis = millis();
  delay(5000);//allow GPS power up
}

void loop()
{

  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (Serial1.available())
    {
      char c = Serial1.read();
      // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  if (newData) {

    float flat, flon;
    unsigned long age;
    gps.f_get_position(&flat, &flon, &age);
     
    tft.fillRect(20, 15, 90, 10, ILI9341_BLACK);
    tft.setCursor(0, 15);
    tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
    tft.print("LAT: ");
    tft.println(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);

    tft.fillRect(20, 30, 90, 10, ILI9341_BLACK);
    tft.setCursor(0, 30);
    tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
    tft.print("LON: ");
    tft.println(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);

    //record initial home position and display data on tft
    if (oneTimePosition == true)  {
      tft.setCursor(0, 105);
      tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
      tft.print("LAT: ");
      tft.println(flat, 6);
      tft.setCursor(0, 120);
      tft.print("LON: ");
      tft.println(flon, 6);

      float radiansX = ( flat * (asin(1)) / 90 );
      float radiansY = ( flon * (asin(1)) / 90 );
       
      homex = R * radiansY * cos(radiansX);
      homey = R * radiansX;
 
      oneTimePosition = false;
    }

    float radiansX = ( flat * (asin(1)) / 90 );
    float radiansY = ( flon * (asin(1)) / 90 );
 
    x = R * radiansY * cos(radiansX);
    y = R * radiansX;


    if (homex != x) {
      dx = (x - homex)  ;
      //dx = dx;//  scale here with function/class??? 
      dx = dx + 215;
    }

    if (homey != y) {
      dy = (y - homey)  ;
      //dy=dy; 
      dy = -dy + 120;//reverse N/S here
    }


    //draw the newest x,y coord pixel every second
    tft.drawPixel( dx, dy, ILI9341_WHITE);
 
    //clear radians tft X Y ...
    tft.fillRect(60, 200, 40, 40, ILI9341_BLACK);
    tft.setCursor(0, 200);
    tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
    tft.print("RADIANS X: ");
    tft.println(radiansX);
    tft.setCursor(0, 220);
    tft.print("RADIANS Y: ");
    tft.println(radiansY);

    //update and show current X Y ...
    tft.fillRect(10, 165, 90, 30, ILI9341_BLACK);
    tft.setCursor(0, 165);
    tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
    tft.print("X: ");
    tft.println(dx);
    tft.setCursor(0, 180);
    tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
    tft.print("Y: ");
    tft.println(dy);

    //update and show precision and satellites
    tft.fillRect(60, 45, 40, 10, ILI9341_BLACK);
    tft.setCursor(0, 45);
    tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
    tft.print("SATELITES: ");
    tft.println(gps.satellites());
    tft.fillRect(60, 60, 40, 10, ILI9341_BLACK);
    tft.setCursor(0, 60);
    tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(1);
    tft.print("PRECISION: ");
    tft.println(gps.hdop());
  }
}

Perhaps, but the memory available in your Teensy 3.2 is surely finite. So, unless you're the first person to have figured out how to store an infinite amount of data in a finite amount of memory, you'll have to deal with that .... one way or the other.

Nice! yea gfValvo..I wish I could predict the number of x/y pairs..but assuming a walk of 10 miles (15 min per mile) and 1 sec x/y data interval...that's 9000 pairs of x/y coords per 2.5 hours...I should be able to record at least 10 hours on a 16g SD....

thoughts?

Yea:

  1. At 4 MPH, why do you need 1-second resolution (~5.9 ft)?

  2. Right, get a Teensy 3.5 or 3.6 as the SD card is-built in.

  3. Your story has changed slightly as your original post did not mention an SD card. So our original assumption was storing the data in processor memory.

Also, have you determined the Lat / Lon precision required to achieve 5.9 ft resolution? Does the GPS supply that? What data types will you need to represent it?

gfvalvo: My second post states possible SD storage...:wink: I;m not sure what I need. Just considering all options....

At 4mph...i don't need 1 sec res, but perhaps I'll get on a bicycle. Just trying to code for scaling via storage. I guess I could assume a finite array of 10,000 pairs...but that might limit my daily travel....

I may need something like:
std::vector

which I know nothing about really....so time to read up more ..

perhaps someone has a bit of helpful code to share....

"Also, have you determined the Lat / Lon precision required to achieve 5.9 ft resolution? Does the GPS supply that? What data types will you need to represent it?"

reply: the exact scaling (location resolution) is not necessary..it's just the scaling to the tft display I'm after. and Yes, my GPS is accurate to ~3.5 to 2.5 meter

the data types are integers converted to x/y for tft pixel display in the above program. I just need to store the x/y integer pairs....

Thank you!

Solved! Heto from stack overflow helped me out!

https://stackoverflow.com/questions/707 ... r-to-int-c

// re-open the file for reading:
myFile = SD.open("GPS");
if (myFile) {
 //Serial.println("GPS:");

 drawMap();

 // read from the file until there's nothing else in it:
 while (myFile.available()) {
   //Serial.write(myFile.read());

   buffer = myFile.readStringUntil('\n');

   char *x_str;
   x_str = strtok((char*)buffer.c_str(), ",");
   int SDdx = atoi(x_str);

   char *y_str;
   y_str = strtok(NULL, ",");
   int SDdy = atoi(y_str);

}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.