Skip to content

Commit 8b381f6

Browse files
author
megasaturnv
committed
Added test code for drawing arrows on the screen
1 parent ef93acb commit 8b381f6

File tree

1 file changed

+205
-0
lines changed

1 file changed

+205
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
#define MAP_WIDTH_PX 128
2+
#define MAP_HEIGHT_PX 103
3+
4+
#define MAP_MIN_LAT -0.5 //bottom of map
5+
#define MAP_MAX_LAT 0.5 //top of map
6+
#define MAP_MIN_LONG -0.5 //left of map
7+
#define MAP_MAX_LONG 0.5 //right of map
8+
9+
#define sclk 13 // Don't change
10+
#define mosi 11 // Don't change
11+
#define cs 10
12+
#define dc A0
13+
#define rst A1 // you can also connect this to the Arduino reset
14+
15+
#include <Adafruit_GFX.h> // Core graphics library
16+
#include <Adafruit_QDTech.h> // Hardware-specific library
17+
#include <SPI.h>
18+
19+
Adafruit_QDTech tft = Adafruit_QDTech(cs, dc, rst);
20+
21+
//2D array of fake locations outside map centered around 0 lat, 0 long
22+
//fakeLocations[latitude][longitude]. i.e. fakeLocations[y coord][x coord]
23+
const float fakeLocations[16][2] = {
24+
{ 1, -1 },
25+
{ 1, -0.25 },
26+
{ 1, 0 },
27+
{ 1, 0.25 },
28+
29+
{ 1, 1},
30+
{ 0.25, 1 },
31+
{ 0, 1},
32+
{ -0.25, 1},
33+
34+
{ -1, 1},
35+
{ -1, 0.25},
36+
{ -1, 0},
37+
{ -1, -0.25},
38+
39+
{ -1, -1 },
40+
{ -0.25, -1 },
41+
{ 0, -1 },
42+
{ 0.25, -1 },
43+
};
44+
45+
void clearTFTMap() {
46+
tft.fillRect(0, 0, 128, 103, QDTech_BLACK); //clear the map drawn on the TFT screen
47+
}
48+
49+
void drawArrow(byte screenX, byte screenY, byte dir) {
50+
//dir is the direction of the arrow. North-West is 0, North is 1, North east is 2 such that:
51+
// NW N NE 0 1 2
52+
// W E = 7 3
53+
// SW S SE 6 5 4
54+
55+
//Note: Dir could be inferred from screenX and screenY...
56+
switch (dir) {
57+
case 0: //NW
58+
// fillTriangle(x0, y0, x1, y1, x2, y2, colour)
59+
tft.fillTriangle(screenX, screenY, screenX + 2, screenY + 5, screenX + 5, screenY + 2, QDTech_RED);
60+
break;
61+
case 1: //N
62+
tft.fillTriangle(screenX, screenY, screenX - 2, screenY + 5, screenX + 2, screenY + 5, QDTech_RED);
63+
break;
64+
case 2: //NE
65+
tft.fillTriangle(screenX, screenY, screenX - 2, screenY + 5, screenX - 5, screenY + 2, QDTech_RED);
66+
break;
67+
case 3: //E
68+
tft.fillTriangle(screenX, screenY, screenX - 5, screenY - 2, screenX - 5, screenY + 2, QDTech_RED);
69+
break;
70+
case 4: //SE
71+
tft.fillTriangle(screenX, screenY, screenX - 2, screenY - 5, screenX - 5, screenY - 2, QDTech_RED);
72+
break;
73+
case 5: //S
74+
tft.fillTriangle(screenX, screenY, screenX + 2, screenY - 5, screenX - 2, screenY - 5, QDTech_RED);
75+
break;
76+
case 6: //SW
77+
tft.fillTriangle(screenX, screenY, screenX + 2, screenY - 5, screenX + 5, screenY - 2, QDTech_RED);
78+
break;
79+
case 7: //W
80+
tft.fillTriangle(screenX, screenY, screenX + 5, screenY + 2, screenX + 5, screenY - 2, QDTech_RED);
81+
break;
82+
}
83+
}
84+
85+
void displayLocationOnMap(float currentLatitude, float currentLongitude) {
86+
//Relative X position on map between 0 and 1
87+
float relativeXPosOnMap = (currentLongitude - MAP_MIN_LONG) / (MAP_MAX_LONG - MAP_MIN_LONG);
88+
//Calculate screen X coordinates for current GPS location
89+
int screenXPos = relativeXPosOnMap * float(MAP_WIDTH_PX);
90+
91+
//Relative Y position on map between 0 and 1
92+
//1.0 - the relative Position because Y-coordinates on screen are inversed relative to latitude (and the standard 'Cartesian' coordinate system
93+
//i.e. Y-coordinate increases as you go down the screen. Latitude increases as you go up the screen.
94+
//There are many ways to fix this problem. e.g. change MAP_MIN_LAT to MAP_MAX_LAT or switching the denominators should have the same result
95+
float relativeYPosOnMap = 1.0 - ((currentLatitude - MAP_MIN_LAT) / (MAP_MAX_LAT - MAP_MIN_LAT));
96+
//Calculate screen Y coordinates for current GPS location.
97+
int screenYPos = relativeYPosOnMap * float(MAP_HEIGHT_PX);
98+
99+
//For debugging
100+
//Serial.println("RelXPos: " + String(relativeXPosOnMap));
101+
//Serial.println("RelYPos: " + String(relativeYPosOnMap));
102+
//Serial.println("MapXPos: " + String(screenXPos));
103+
//Serial.println("MapYPos: " + String(screenYPos));
104+
105+
//if tracker is on-screen
106+
if (relativeXPosOnMap >= 0 && relativeXPosOnMap <= 1 && relativeYPosOnMap >= 0 && relativeYPosOnMap <= 1) {
107+
//Draw pixel on map at current location
108+
tft.drawPixel(screenXPos, screenYPos, QDTech_BLACK); //Clear the pixel first
109+
tft.drawPixel(screenXPos, screenYPos, QDTech_RED);
110+
111+
////if tracker is off-screen////
112+
////corners of map. i.e. position is completely outside the map's boundaries
113+
//if tracker is top-left
114+
} else if (relativeXPosOnMap < 0 && relativeYPosOnMap < 0) {
115+
drawArrow(0, 0, 0);
116+
//if tracker is top-right
117+
} else if (relativeXPosOnMap > 1 && relativeYPosOnMap < 0) {
118+
drawArrow(MAP_WIDTH_PX, 0, 2);
119+
//if tracker is bottom-right
120+
} else if (relativeXPosOnMap > 1 && relativeYPosOnMap > 1) {
121+
drawArrow(MAP_WIDTH_PX, MAP_HEIGHT_PX - 1, 4);
122+
//if tracker is bottom-left
123+
} else if (relativeXPosOnMap < 0 && relativeYPosOnMap > 1) {
124+
drawArrow(0, MAP_HEIGHT_PX - 1, 6);
125+
126+
////edges of map. i.e. position is outside the map in one axis but within the map on the other axis
127+
//if tracker is top-middle
128+
} else if (relativeXPosOnMap >= 0 && relativeXPosOnMap <= 1 && relativeYPosOnMap < 0) {
129+
drawArrow(screenXPos, 0, 1);
130+
//if tracker is middle-right
131+
} else if (relativeXPosOnMap > 1 && relativeYPosOnMap <= 1 && relativeYPosOnMap >= 0) {
132+
drawArrow(MAP_WIDTH_PX, screenYPos, 3);
133+
//if tracker is bottom-middle
134+
} else if (relativeXPosOnMap >= 0 && relativeXPosOnMap <= 1 && relativeYPosOnMap > 1) {
135+
drawArrow(screenXPos, MAP_HEIGHT_PX - 1, 5);
136+
//if tracker is middle-left
137+
} else if (relativeXPosOnMap < 0 && relativeYPosOnMap <= 1 && relativeYPosOnMap >= 0) {
138+
drawArrow(0, screenYPos, 7);
139+
}
140+
}
141+
142+
void setup() {
143+
tft.init();
144+
tft.setRotation(0); // 0 = Portrait, 1 = Landscape
145+
tft.fillScreen(QDTech_BLACK);
146+
tft.setTextWrap(false);
147+
tft.setCursor(0, 0);
148+
tft.setTextColor(QDTech_WHITE);
149+
tft.setTextSize(1);
150+
tft.drawFastHLine(0, 103, 128, QDTech_WHITE); //Note: draw on line 103, which is the 104th line
151+
152+
//Draw arrows rotating in centre of map
153+
//With clearing the map
154+
for (byte i = 0; i <= 7; i++) {
155+
clearTFTMap(); //Clear the map
156+
drawArrow(MAP_WIDTH_PX / 2, MAP_HEIGHT_PX / 2, i);
157+
delay(200);
158+
}
159+
delay(1000);
160+
161+
//Without clearing the map - for arrow comparison
162+
clearTFTMap(); //Clear the map
163+
for (byte i = 0; i <= 7; i++) {
164+
drawArrow(MAP_WIDTH_PX / 2, (i + 1) * 11, i);
165+
delay(200);
166+
}
167+
delay(1000);
168+
169+
//Draw arrows in corners with drawArrow()
170+
clearTFTMap(); //Clear the map
171+
drawArrow(0, 0, 0);
172+
delay(500);
173+
drawArrow(MAP_WIDTH_PX, 0, 2);
174+
delay(500);
175+
drawArrow(MAP_WIDTH_PX, MAP_HEIGHT_PX, 4);
176+
delay(500);
177+
drawArrow(0, MAP_HEIGHT_PX, 6);
178+
delay(1000);
179+
180+
//Draw arrows in corners with displayLocationOnMap(float latitude, float longitude)
181+
//Should be the same result as above
182+
clearTFTMap(); //Clear the map
183+
displayLocationOnMap(1.0, -1.0);
184+
delay(500);
185+
displayLocationOnMap(1.0, 1.0);
186+
delay(500);
187+
displayLocationOnMap(-1.0, 1.0);
188+
delay(500);
189+
displayLocationOnMap(-1.0, -1.0);
190+
delay(1000);
191+
192+
//Draw test locations from fakeLocations 2D array on map
193+
clearTFTMap(); //Clear the map
194+
for (byte i = 0; i < 16; i++) {
195+
//displayLocationOnMap(float latitude, float longitude)
196+
displayLocationOnMap(fakeLocations[i][0], fakeLocations[i][1]);
197+
//tft.println(String(fakeLocations[i][0]) + "," + String(fakeLocations[i][1]));
198+
delay(200);
199+
}
200+
}
201+
202+
void loop() {
203+
204+
}
205+

0 commit comments

Comments
 (0)