329 lines
9.3 KiB
C++
329 lines
9.3 KiB
C++
/*
|
|
|
|
This program provides cartesian type graph function
|
|
|
|
Revisions
|
|
rev date author description
|
|
1 12-24-2015 kasprzak initial creation
|
|
|
|
Updated by Bodmer to be an example for the library here:
|
|
https://github.com/Bodmer/TFT_eSPI
|
|
|
|
*/
|
|
|
|
#include <TFT_eSPI.h> // Hardware-specific library
|
|
#include <SPI.h>
|
|
|
|
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library with default width and height
|
|
|
|
|
|
#define LTBLUE 0xB6DF
|
|
#define LTTEAL 0xBF5F
|
|
#define LTGREEN 0xBFF7
|
|
#define LTCYAN 0xC7FF
|
|
#define LTRED 0xFD34
|
|
#define LTMAGENTA 0xFD5F
|
|
#define LTYELLOW 0xFFF8
|
|
#define LTORANGE 0xFE73
|
|
#define LTPINK 0xFDDF
|
|
#define LTPURPLE 0xCCFF
|
|
#define LTGREY 0xE71C
|
|
|
|
#define BLUE 0x001F
|
|
#define TEAL 0x0438
|
|
#define GREEN 0x07E0
|
|
#define CYAN 0x07FF
|
|
#define RED 0xF800
|
|
#define MAGENTA 0xF81F
|
|
#define YELLOW 0xFFE0
|
|
#define ORANGE 0xFC00
|
|
#define PINK 0xF81F
|
|
#define PURPLE 0x8010
|
|
#define GREY 0xC618
|
|
#define WHITE 0xFFFF
|
|
#define BLACK 0x0000
|
|
|
|
#define DKBLUE 0x000D
|
|
#define DKTEAL 0x020C
|
|
#define DKGREEN 0x03E0
|
|
#define DKCYAN 0x03EF
|
|
#define DKRED 0x6000
|
|
#define DKMAGENTA 0x8008
|
|
#define DKYELLOW 0x8400
|
|
#define DKORANGE 0x8200
|
|
#define DKPINK 0x9009
|
|
#define DKPURPLE 0x4010
|
|
#define DKGREY 0x4A49
|
|
|
|
// these are the only external variables used by the graph function
|
|
// it's a flag to draw the coordinate system only on the first call to the Graph() function
|
|
// and will mimize flicker
|
|
// also create some variables to store the old x and y, if you draw 2 graphs on the same display
|
|
// you will need to store ox and oy per each display
|
|
bool display1 = true;
|
|
bool update1 = true;
|
|
|
|
double ox = -999, oy = -999; // Force them to be off screen
|
|
|
|
/*
|
|
|
|
function to draw a cartesian coordinate system and plot whatever data you want
|
|
just pass x and y and the graph will be drawn
|
|
|
|
huge arguement list
|
|
&d name of your display object
|
|
x = x data point
|
|
y = y datapont
|
|
gx = x graph location (lower left)
|
|
gy = y graph location (lower left)
|
|
w = width of graph
|
|
h = height of graph
|
|
xlo = lower bound of x axis
|
|
xhi = upper bound of x asis
|
|
xinc = division of x axis (distance not count)
|
|
ylo = lower bound of y axis
|
|
yhi = upper bound of y asis
|
|
yinc = division of y axis (distance not count)
|
|
title = title of graph
|
|
xlabel = x asis label
|
|
ylabel = y asis label
|
|
&redraw = flag to redraw graph on first call only
|
|
color = plotted trace colour
|
|
*/
|
|
|
|
|
|
void Graph(TFT_eSPI &tft, double x, double y, byte dp,
|
|
double gx, double gy, double w, double h,
|
|
double xlo, double xhi, double xinc,
|
|
double ylo, double yhi, double yinc,
|
|
char *title, char *xlabel, char *ylabel,
|
|
bool &redraw, unsigned int color) {
|
|
|
|
double ydiv, xdiv;
|
|
double i;
|
|
double temp;
|
|
int rot, newrot;
|
|
|
|
// gcolor = graph grid colors
|
|
// acolor = axes line colors
|
|
// pcolor = color of your plotted data
|
|
// tcolor = text color
|
|
// bcolor = background color
|
|
unsigned int gcolor = DKBLUE;
|
|
unsigned int acolor = RED;
|
|
unsigned int pcolor = color;
|
|
unsigned int tcolor = WHITE;
|
|
unsigned int bcolor = BLACK;
|
|
|
|
if (redraw == true) {
|
|
|
|
redraw = false;
|
|
// initialize old x and old y in order to draw the first point of the graph
|
|
// but save the transformed value
|
|
// note my transform funcition is the same as the map function, except the map uses long and we need doubles
|
|
//ox = (x - xlo) * ( w) / (xhi - xlo) + gx;
|
|
//oy = (y - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
|
|
|
|
tft.setTextDatum(MR_DATUM);
|
|
|
|
// draw y scale
|
|
for ( i = ylo; i <= yhi; i += yinc) {
|
|
// compute the transform
|
|
temp = (i - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
|
|
|
|
if (i == 0) {
|
|
tft.drawLine(gx, temp, gx + w, temp, acolor);
|
|
tft.setTextColor(acolor, bcolor);
|
|
tft.drawString(xlabel, (int)(gx + w) , (int)temp, 2);
|
|
}
|
|
else {
|
|
tft.drawLine(gx, temp, gx + w, temp, gcolor);
|
|
}
|
|
// draw the axis labels
|
|
tft.setTextColor(tcolor, bcolor);
|
|
// precision is default Arduino--this could really use some format control
|
|
tft.drawFloat(i, dp, gx - 4, temp, 1);
|
|
}
|
|
|
|
// draw x scale
|
|
for (i = xlo; i <= xhi; i += xinc) {
|
|
|
|
// compute the transform
|
|
temp = (i - xlo) * ( w) / (xhi - xlo) + gx;
|
|
if (i == 0) {
|
|
tft.drawLine(temp, gy, temp, gy - h, acolor);
|
|
tft.setTextColor(acolor, bcolor);
|
|
tft.setTextDatum(BC_DATUM);
|
|
tft.drawString(ylabel, (int)temp, (int)(gy - h - 8) , 2);
|
|
}
|
|
else {
|
|
tft.drawLine(temp, gy, temp, gy - h, gcolor);
|
|
}
|
|
// draw the axis labels
|
|
tft.setTextColor(tcolor, bcolor);
|
|
tft.setTextDatum(TC_DATUM);
|
|
// precision is default Arduino--this could really use some format control
|
|
tft.drawFloat(i, dp, temp, gy + 7, 1);
|
|
}
|
|
|
|
//now draw the graph labels
|
|
tft.setTextColor(tcolor, bcolor);
|
|
tft.drawString(title, (int)(gx + w / 2) , (int)(gy - h - 30), 4);
|
|
}
|
|
|
|
// the coordinates are now drawn, plot the data
|
|
// the entire plotting code are these few lines...
|
|
// recall that ox and oy are initialized above
|
|
//x = (x - xlo) * ( w) / (xhi - xlo) + gx;
|
|
//y = (y - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
|
|
//tft.drawLine(ox, oy, x, y, pcolor);
|
|
// it's up to you but drawing 2 more lines to give the graph some thickness
|
|
//tft.drawLine(ox, oy + 1, x, y + 1, pcolor);
|
|
//tft.drawLine(ox, oy - 1, x, y - 1, pcolor);
|
|
//ox = x;
|
|
//oy = y;
|
|
|
|
}
|
|
|
|
void Trace(TFT_eSPI &tft, double x, double y, byte dp,
|
|
double gx, double gy,
|
|
double w, double h,
|
|
double xlo, double xhi, double xinc,
|
|
double ylo, double yhi, double yinc,
|
|
char *title, char *xlabel, char *ylabel,
|
|
bool &update1, unsigned int color)
|
|
{
|
|
double ydiv, xdiv;
|
|
double i;
|
|
double temp;
|
|
int rot, newrot;
|
|
|
|
//unsigned int gcolor = DKBLUE; // gcolor = graph grid color
|
|
unsigned int acolor = RED; // acolor = main axes and label color
|
|
unsigned int pcolor = color; // pcolor = color of your plotted data
|
|
unsigned int tcolor = WHITE; // tcolor = text color
|
|
unsigned int bcolor = BLACK; // bcolor = background color
|
|
|
|
// initialize old x and old y in order to draw the first point of the graph
|
|
// but save the transformed value
|
|
// note my transform funcition is the same as the map function, except the map uses long and we need doubles
|
|
if (update1) {
|
|
update1 = false;
|
|
|
|
ox = (x - xlo) * ( w) / (xhi - xlo) + gx;
|
|
oy = (y - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
|
|
|
|
if ((ox < gx) || (ox > gx+w)) {update1 = true; return;}
|
|
if ((oy < gy-h) || (oy > gy)) {update1 = true; return;}
|
|
|
|
|
|
tft.setTextDatum(MR_DATUM);
|
|
|
|
// draw y scale
|
|
for ( i = ylo; i <= yhi; i += yinc) {
|
|
// compute the transform
|
|
temp = (i - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
|
|
|
|
if (i == 0) {
|
|
tft.setTextColor(acolor, bcolor);
|
|
tft.drawString(xlabel, (int)(gx + w) , (int)temp, 2);
|
|
}
|
|
// draw the axis labels
|
|
tft.setTextColor(tcolor, bcolor);
|
|
// precision is default Arduino--this could really use some format control
|
|
tft.drawFloat(i, dp, gx - 4, temp, 1);
|
|
}
|
|
|
|
// draw x scale
|
|
for (i = xlo; i <= xhi; i += xinc) {
|
|
|
|
// compute the transform
|
|
temp = (i - xlo) * ( w) / (xhi - xlo) + gx;
|
|
if (i == 0) {
|
|
tft.setTextColor(acolor, bcolor);
|
|
tft.setTextDatum(BC_DATUM);
|
|
tft.drawString(ylabel, (int)temp, (int)(gy - h - 8) , 2);
|
|
}
|
|
|
|
// draw the axis labels
|
|
tft.setTextColor(tcolor, bcolor);
|
|
tft.setTextDatum(TC_DATUM);
|
|
// precision is default Arduino--this could really use some format control
|
|
tft.drawFloat(i, dp, temp, gy + 7, 1);
|
|
}
|
|
|
|
//now draw the graph labels
|
|
tft.setTextColor(tcolor, bcolor);
|
|
tft.drawString(title, (int)(gx + w / 2) , (int)(gy - h - 30), 4);
|
|
}
|
|
|
|
// the coordinates are now drawn, plot the data
|
|
// the entire plotting code are these few lines...
|
|
// recall that ox and oy are initialized above
|
|
x = (x - xlo) * ( w) / (xhi - xlo) + gx;
|
|
y = (y - ylo) * (gy - h - gy) / (yhi - ylo) + gy;
|
|
|
|
if ((x < gx) || (x > gx+w)) {update1 = true; return;}
|
|
if ((y < gy-h) || (y > gy)) {update1 = true; return;}
|
|
|
|
|
|
tft.drawLine(ox, oy, x, y, pcolor);
|
|
// it's up to you but drawing 2 more lines to give the graph some thickness
|
|
//tft.drawLine(ox, oy + 1, x, y + 1, pcolor);
|
|
//tft.drawLine(ox, oy - 1, x, y - 1, pcolor);
|
|
ox = x;
|
|
oy = y;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
End of graphing function
|
|
|
|
*/
|
|
|
|
|
|
|
|
void setup() {
|
|
double x, y;
|
|
|
|
tft.begin();
|
|
tft.fillScreen(BLACK);
|
|
tft.setRotation(1);
|
|
|
|
Graph(tft, x, y, 1, 60, 290, 390, 260, 0, 6.5, 1, -1, 1, .25, "", "", "", display1, YELLOW);
|
|
|
|
//delay(1000);
|
|
|
|
update1 = true;
|
|
for (x = 0; x <= 6.3; x += .1) {
|
|
y = sin(x);
|
|
Trace(tft, x, y, 1, 60, 290, 390, 260, 0, 6.5, 1, -1, 1, .25, "Sin(x)", "x", "fn(x)", update1, YELLOW);
|
|
}
|
|
|
|
delay(2000);
|
|
|
|
update1 = true;
|
|
for (x = 0; x <= 6.3; x += .1) {
|
|
y = cos(x);
|
|
Trace(tft, x, y, 1, 60, 290, 390, 260, 0, 6.5, 1, -1, 1, .25, "Sin(x) + Cos(x)", " x", "fn(x)", update1, TFT_PINK);
|
|
}
|
|
|
|
delay(2000);
|
|
|
|
update1 = true;
|
|
for (x = 0; x <= 6.3; x += .02) {
|
|
y = tan(x);
|
|
Trace(tft, x, y, 1, 60, 290, 390, 260, 0, 6.5, 1, -1, 1, .25, "Sin(x) + Cos(x) + Tan(x)", " x", "fn(x)", update1, CYAN);
|
|
}
|
|
}
|
|
|
|
|
|
void loop(void) {
|
|
|
|
}
|
|
|
|
|
|
|
|
|