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
 | 
						|
boolean display1 = true;
 | 
						|
boolean 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,
 | 
						|
                           boolean &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,
 | 
						|
           boolean &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) {
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 |