206 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			206 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C++
		
	
	
	
/*
 | 
						|
  Display "flicker free" scrolling text and updating number
 | 
						|
 | 
						|
  This sketch uses 8 bit colour sprites to save RAM.
 | 
						|
 | 
						|
  Example for library:
 | 
						|
  https://github.com/Bodmer/TFT_eSPI
 | 
						|
 | 
						|
  The sketch has been tested on a 320x240 ILI9341 based TFT, it
 | 
						|
  coule be adapted for other screen sizes.
 | 
						|
 | 
						|
  A Sprite is notionally an invisible graphics screen that is
 | 
						|
  kept in the processors RAM. Graphics can be drawn into the
 | 
						|
  Sprite just as it can be drawn directly to the screen. Once
 | 
						|
  the Sprite is completed it can be plotted onto the screen in
 | 
						|
  any position. If there is sufficient RAM then the Sprite can
 | 
						|
  be the same size as the screen and used as a frame buffer.
 | 
						|
 | 
						|
  A 16 bit colour Sprite occupies (2 * width * height) bytes.
 | 
						|
 | 
						|
  An 8 bit colour Sprite occupies (width * height) bytes.
 | 
						|
 | 
						|
  On a ESP8266, 16 bit Sprite sizes up to 128 x 160 can be accomodated,
 | 
						|
  this size requires 128*160*2 bytes (40kBytes) of RAM.
 | 
						|
 | 
						|
  This sketch sets the colour depth to 8 bits so larger sprites can be
 | 
						|
  created. 8 bit colour sprites use half amount of RAM. If the colour
 | 
						|
  depth is not specified then 16 bits is assumed.
 | 
						|
 | 
						|
  You need to make the sprite  small enough to fit, with RAM spare for
 | 
						|
  any "local variables" that may be needed by your sketch and libraries.
 | 
						|
 | 
						|
  Created by Bodmer 21/11/17
 | 
						|
 | 
						|
  #########################################################################
 | 
						|
  ###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
 | 
						|
  #########################################################################
 | 
						|
*/
 | 
						|
 | 
						|
// Size of sprite image for the scrolling text, this requires ~14 Kbytes of RAM
 | 
						|
#define IWIDTH  240
 | 
						|
#define IHEIGHT 30
 | 
						|
 | 
						|
// Pause in milliseconds to set scroll speed
 | 
						|
#define WAIT 0
 | 
						|
 | 
						|
#include <TFT_eSPI.h>                 // Include the graphics library (this includes the sprite functions)
 | 
						|
 | 
						|
TFT_eSPI    tft = TFT_eSPI();         // Create object "tft"
 | 
						|
 | 
						|
TFT_eSprite img = TFT_eSprite(&tft);  // Create Sprite object "img" with pointer to "tft" object
 | 
						|
//                                    // the pointer is used by pushSprite() to push it onto the TFT
 | 
						|
 | 
						|
// -------------------------------------------------------------------------
 | 
						|
// Setup
 | 
						|
// -------------------------------------------------------------------------
 | 
						|
void setup(void) {
 | 
						|
  tft.init();
 | 
						|
  tft.setRotation(0);
 | 
						|
 | 
						|
  tft.fillScreen(TFT_BLUE);
 | 
						|
}
 | 
						|
 | 
						|
// -------------------------------------------------------------------------
 | 
						|
// Main loop
 | 
						|
// -------------------------------------------------------------------------
 | 
						|
void loop() {
 | 
						|
 | 
						|
  while (1)
 | 
						|
  {
 | 
						|
    // Set colour depth of Sprite to 8 (or 16) bits
 | 
						|
    img.setColorDepth(8);
 | 
						|
    
 | 
						|
    // Create the sprite and clear background to black
 | 
						|
    img.createSprite(IWIDTH, IHEIGHT);
 | 
						|
    //img.fillSprite(TFT_BLACK); // Optional here as we fill the sprite later anyway
 | 
						|
 | 
						|
    for (int pos = IWIDTH; pos > 0; pos--)
 | 
						|
    {
 | 
						|
      build_banner("Hello World", pos);
 | 
						|
      img.pushSprite(0, 0);
 | 
						|
 | 
						|
      build_banner("TFT_eSPI sprite" , pos);
 | 
						|
      img.pushSprite(0, 50);
 | 
						|
 | 
						|
      delay(WAIT);
 | 
						|
    }
 | 
						|
 | 
						|
    // Delete sprite to free up the memory
 | 
						|
    img.deleteSprite();
 | 
						|
 | 
						|
    // Create a sprite of a different size
 | 
						|
    numberBox(random(100), 60, 100);
 | 
						|
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// #########################################################################
 | 
						|
// Build the scrolling sprite image from scratch, draw text at x = xpos
 | 
						|
// #########################################################################
 | 
						|
 | 
						|
void build_banner(String msg, int xpos)
 | 
						|
{
 | 
						|
  int h = IHEIGHT;
 | 
						|
 | 
						|
  // We could just use fillSprite(color) but lets be a bit more creative...
 | 
						|
 | 
						|
  // Fill with rainbow stripes
 | 
						|
  while (h--) img.drawFastHLine(0, h, IWIDTH, rainbow(h * 4));
 | 
						|
 | 
						|
  // Draw some graphics, the text will apear to scroll over these
 | 
						|
  img.fillRect  (IWIDTH / 2 - 20, IHEIGHT / 2 - 10, 40, 20, TFT_YELLOW);
 | 
						|
  img.fillCircle(IWIDTH / 2, IHEIGHT / 2, 10, TFT_ORANGE);
 | 
						|
 | 
						|
  // Now print text on top of the graphics
 | 
						|
  img.setTextSize(1);           // Font size scaling is x1
 | 
						|
  img.setTextFont(4);           // Font 4 selected
 | 
						|
  img.setTextColor(TFT_BLACK);  // Black text, no background colour
 | 
						|
  img.setTextWrap(false);       // Turn of wrap so we can print past end of sprite
 | 
						|
 | 
						|
  // Need to print twice so text appears to wrap around at left and right edges
 | 
						|
  img.setCursor(xpos, 2);  // Print text at xpos
 | 
						|
  img.print(msg);
 | 
						|
 | 
						|
  img.setCursor(xpos - IWIDTH, 2); // Print text at xpos - sprite width
 | 
						|
  img.print(msg);
 | 
						|
}
 | 
						|
 | 
						|
// #########################################################################
 | 
						|
// Create sprite, plot graphics in it, plot to screen, then delete sprite
 | 
						|
// #########################################################################
 | 
						|
void numberBox(int num, int x, int y)
 | 
						|
{
 | 
						|
  // Create a sprite 80 pixels wide, 50 high (8kbytes of RAM needed)
 | 
						|
  img.createSprite(80, 50);
 | 
						|
 | 
						|
  // Fill it with black
 | 
						|
  img.fillSprite(TFT_BLACK);
 | 
						|
 | 
						|
  // Draw a backgorund of 2 filled triangles
 | 
						|
  img.fillTriangle(  0, 0,  0, 49, 40, 25, TFT_RED);
 | 
						|
  img.fillTriangle( 79, 0, 79, 49, 40, 25, TFT_DARKGREEN);
 | 
						|
 | 
						|
  // Set the font parameters
 | 
						|
  img.setTextSize(1);           // Font size scaling is x1
 | 
						|
  img.setFreeFont(&FreeSerifBoldItalic24pt7b);  // Select free font
 | 
						|
  img.setTextColor(TFT_WHITE);  // White text, no background colour
 | 
						|
 | 
						|
  // Set text coordinate datum to middle centre
 | 
						|
  img.setTextDatum(MC_DATUM);
 | 
						|
 | 
						|
  // Draw the number in middle of 80 x 50 sprite
 | 
						|
  img.drawNumber(num, 40, 25);
 | 
						|
 | 
						|
  // Push sprite to TFT screen CGRAM at coordinate x,y (top left corner)
 | 
						|
  img.pushSprite(x, y);
 | 
						|
 | 
						|
  // Delete sprite to free up the RAM
 | 
						|
  img.deleteSprite();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// #########################################################################
 | 
						|
// Return a 16 bit rainbow colour
 | 
						|
// #########################################################################
 | 
						|
unsigned int rainbow(byte value)
 | 
						|
{
 | 
						|
  // Value is expected to be in range 0-127
 | 
						|
  // The value is converted to a spectrum colour from 0 = red through to 127 = blue
 | 
						|
 | 
						|
  byte red   = 0; // Red is the top 5 bits of a 16 bit colour value
 | 
						|
  byte green = 0;// Green is the middle 6 bits
 | 
						|
  byte blue  = 0; // Blue is the bottom 5 bits
 | 
						|
 | 
						|
  byte sector = value >> 5;
 | 
						|
  byte amplit = value & 0x1F;
 | 
						|
 | 
						|
  switch (sector)
 | 
						|
  {
 | 
						|
    case 0:
 | 
						|
      red   = 0x1F;
 | 
						|
      green = amplit;
 | 
						|
      blue  = 0;
 | 
						|
      break;
 | 
						|
    case 1:
 | 
						|
      red   = 0x1F - amplit;
 | 
						|
      green = 0x1F;
 | 
						|
      blue  = 0;
 | 
						|
      break;
 | 
						|
    case 2:
 | 
						|
      red   = 0;
 | 
						|
      green = 0x1F;
 | 
						|
      blue  = amplit;
 | 
						|
      break;
 | 
						|
    case 3:
 | 
						|
      red   = 0;
 | 
						|
      green = 0x1F - amplit;
 | 
						|
      blue  = 0x1F;
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  return red << 11 | green << 6 | blue;
 | 
						|
}
 | 
						|
 | 
						|
 |