XRAD
Well-known member
XRAD'S Teensy 3.6 How to read write to SD x/y integer coord pairs?
Hello,
I have a GPS point set which is converted to x/y points (integers) for tft pixel display. I have the display points showing up just fine for a walk around the area within the bounds of my TFT 'map.' But when I want to scale the pixel points to a larger area (zoom in or zoom out), I will need to redraw all the current points and display the new 'map' of pixels at selected 'scale.'
I 'think' that I have to save the points to SD in order to redraw them (otherwise, I will only have the currently calculated x/y point pair to draw)
However! I am trying to save an 'unknown' quantity of x/y integer pair points to the SD (unknown because I may walk for 1 minute, or one hour, and the points set may need to be stored via an adaptive array (vector array?). Then, if I scale the map up or down, all the points saved would be redrawn to a TFT at the chosen scale (basically zoom in/zoom out )
1) So...is this the best strategy?
2) How do I save a dynamic/variable sized array of 'pairs'?
2) and how do I recall them in 'pairs' and display them all to the TFT as a group?
Thank you for any tips!! Pic of a live display of plotted points at base scale.... (accuracy meters to pixels is NOT required)
here is my code so far:
Hello,
I have a GPS point set which is converted to x/y points (integers) for tft pixel display. I have the display points showing up just fine for a walk around the area within the bounds of my TFT 'map.' But when I want to scale the pixel points to a larger area (zoom in or zoom out), I will need to redraw all the current points and display the new 'map' of pixels at selected 'scale.'
I 'think' that I have to save the points to SD in order to redraw them (otherwise, I will only have the currently calculated x/y point pair to draw)
However! I am trying to save an 'unknown' quantity of x/y integer pair points to the SD (unknown because I may walk for 1 minute, or one hour, and the points set may need to be stored via an adaptive array (vector array?). Then, if I scale the map up or down, all the points saved would be redrawn to a TFT at the chosen scale (basically zoom in/zoom out )
1) So...is this the best strategy?
2) How do I save a dynamic/variable sized array of 'pairs'?
2) and how do I recall them in 'pairs' and display them all to the TFT as a group?
Thank you for any tips!! Pic of a live display of plotted points at base scale.... (accuracy meters to pixels is NOT required)
here is my code so far:
Code:
#include <SD.h>
#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 long homeX;
int long homeY;
int centeredX;
int centeredY;
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
File myFile;
/*
void drawCross() {//draw a solid cross
tft.drawFastVLine(215, 0, 240, ILI9341_GREEN);
tft.drawFastHLine(110, 120, 210, ILI9341_GREEN);
}
*/
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");
}
void setup()
{
Serial.begin(115200);
Serial1.begin(9600);//my GPS device uses 9600 baud, using teensy Serial1
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(BUILTIN_SDCARD)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
// re-open the file for reading:
myFile = SD.open("test.txt");
if (myFile) {
Serial.println("test.txt:");
// read from the file until there's nothing else in it:
while (myFile.available()) {
Serial.write(myFile.read());
}
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
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);
//Serial.print("LAT=");
//Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 4);
//Serial.print(" LON=");
//Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 4);
//Serial.print(" SAT=");
//Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
//Serial.print(" PREC=");
//Serial.println(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
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 );
//Serial.print("radians x: ");
//Serial.println(radiansX);
//Serial.print("radians y: ");
//Serial.println(radiansY);
homex = R * radiansY * cos(radiansX);
homey = R * radiansX;
//Serial.print("homex: ");
//Serial.println(homex);
//Serial.print("homey: ");
//Serial.println(homey);
//tft.drawPixel( homex, homey, ILI9341_WHITE);//draw home pixel
oneTimePosition = false;
}
float radiansX = ( flat * (asin(1)) / 90 );
float radiansY = ( flon * (asin(1)) / 90 );
//Serial.print("radians new x: ");
//Serial.println(radiansX);
//Serial.print("radians new y: ");
//Serial.println(radiansY);
x = R * radiansY * cos(radiansX);
y = R * radiansX;
if (homex != x) {
dx = (x - homex);
dx = dx + 215;
}
if (homey != y) {
dy = (y - homey) ;
dy = -dy + 120;//reverse N/S here
}
//record x/y data pairs to SD here?
//draw the newest x,y coord pixel every second
tft.drawPixel( dx, dy, ILI9341_WHITE);
Serial.print("x coord pixel: ");
Serial.println(dx);
Serial.print("y coord pixel: ");
Serial.println(dy);
Serial.println("");
//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());
}
}
Attachments
Last edited: