#740: To avoid ambiguity the pushSprite for writing a sprite to another sprite has been renamed pushToSprite

#704: Change to 18 bit colurs for SSD1963 with SPI interface

Remove outdated TFT_SPIFFS_Jpeg example
This commit is contained in:
Bodmer 2020-09-07 22:04:42 +01:00
parent aaebc18844
commit d7fdcc0991
12 changed files with 47 additions and 384 deletions

View File

@ -729,7 +729,7 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp)
/***************************************************************************************
** Function name: pushSprite
** Function name: pushToSprite
** Description: Push the sprite to another sprite at x, y
***************************************************************************************/
// Note: The following sprite to sprite colour depths are currently supported:
@ -739,33 +739,33 @@ void TFT_eSprite::pushSprite(int32_t x, int32_t y, uint16_t transp)
// 4bpp -> 4bpp (note: color translation depends on the 2 sprites pallet colors)
// 1bpp -> 1bpp (note: color translation depends on the 2 sprites bitmap colors)
bool TFT_eSprite::pushSprite(TFT_eSprite *spr, int32_t x, int32_t y)
bool TFT_eSprite::pushToSprite(TFT_eSprite *dspr, int32_t x, int32_t y)
{
if (!_created) return false;
if (!spr->created()) return false;
if (!dspr->created()) return false;
// Check destination sprite compatibility
int8_t ds_bpp = spr->getColorDepth();
int8_t ds_bpp = dspr->getColorDepth();
if (_bpp == 16 && ds_bpp != 16 && ds_bpp != 8) return false;
if (_bpp == 8) return false;
if (_bpp == 4 && ds_bpp != 4) return false;
if (_bpp == 1 && ds_bpp != 1) return false;
bool oldSwapBytes = spr->getSwapBytes();
spr->setSwapBytes(false);
spr->pushImage(x, y, _dwidth, _dheight, _img );
spr->setSwapBytes(oldSwapBytes);
bool oldSwapBytes = dspr->getSwapBytes();
dspr->setSwapBytes(false);
dspr->pushImage(x, y, _dwidth, _dheight, _img );
dspr->setSwapBytes(oldSwapBytes);
return true;
}
/***************************************************************************************
** Function name: pushSprite
** Function name: pushToSprite
** Description: Push the sprite to another sprite at x, y with transparent colour
***************************************************************************************/
/* >>>>>> Using a transparent color is not supported at the moment <<<<<<
void TFT_eSprite::pushSprite(TFT_eSprite *spr, int32_t x, int32_t y, uint16_t transp)
void TFT_eSprite::pushToSprite(TFT_eSprite *spr, int32_t x, int32_t y, uint16_t transp)
{
if (!_created) return;

View File

@ -133,13 +133,14 @@ class TFT_eSprite : public TFT_eSPI {
void pushSprite(int32_t x, int32_t y);
void pushSprite(int32_t x, int32_t y, uint16_t transparent);
// Push the sprite to another sprite, this fn calls pushImage() in the destination sprite class.
// >>>>>> Using a transparent color is not supported at the moment <<<<<<
bool pushSprite(TFT_eSprite *spr, int32_t x, int32_t y);
// Push a windowed area of the sprite to the TFT at tx, ty
bool pushSprite(int32_t tx, int32_t ty, int32_t sx, int32_t sy, int32_t sw, int32_t sh);
// Push the sprite to another sprite at x,y. This fn calls pushImage() in the destination sprite (dspr) class.
// >>>>>> Using a transparent color is not supported at the moment <<<<<<
bool pushToSprite(TFT_eSprite *dspr, int32_t x, int32_t y);
bool pushToSprite(TFT_eSprite *dspr, int32_t x, int32_t y, uint16_t transparent);
int16_t drawChar(uint16_t uniCode, int32_t x, int32_t y, uint8_t font),
drawChar(uint16_t uniCode, int32_t x, int32_t y);

View File

@ -293,13 +293,26 @@
// Write 8 bits to TFT
#define tft_Write_8(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)(C)); WR_H
// Write 16 bits to TFT
#define tft_Write_16(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)((C) >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t)((C) >> 0)); WR_H
#if defined (SSD1963_DRIVER)
// 16 bit write with swapped bytes
#define tft_Write_16S(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H
// Write 18 bit color to TFT
#define tft_Write_16(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0xF800)>> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0x07E0)>> 3)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) (((C) & 0x001F)<< 3)); WR_H
// 18 bit color write with swapped bytes
#define tft_Write_16S(C) uint16_t Cswap = ((C) >>8 | (C) << 8); tft_Write_16(Cswap)
#else
// Write 16 bits to TFT
#define tft_Write_16(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H
// 16 bit write with swapped bytes
#define tft_Write_16S(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 0)); WR_H; \
GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 8)); WR_H
#endif
// Write 32 bits to TFT
#define tft_Write_32(C) GPIO.out_w1tc = clr_mask; GPIO.out_w1ts = set_mask((uint8_t) ((C) >> 24)); WR_H; \

View File

@ -11,6 +11,11 @@
#define TFT_HEIGHT 800
#endif
//Set driver type common to all initialisation options
#ifndef SSD1963_DRIVER
#define SSD1963_DRIVER
#endif
// Delay between some initialisation commands
#define TFT_INIT_DELAY 0x80 // Not used unless commandlist invoked

View File

@ -62,7 +62,7 @@
writedata(0x2A);
writecommand(0xF0); //pixel data interface
writedata(0x03);
writedata(0x00); //8 bit bus
delay(1);
@ -166,7 +166,7 @@
writedata(0x2A);
writecommand(0xF0); //pixel data interface
writedata(0x03);
writedata(0x00); //8 bit bus
delay(1);
@ -270,7 +270,7 @@
writedata(0x22); // -- Set to 0x21 to rotate 180 degrees
writecommand(0xF0); //pixel data interface
writedata(0x03);
writedata(0x00); //8 bit bus
delay(10);

View File

@ -16,7 +16,7 @@
#ifndef _TFT_eSPIH_
#define _TFT_eSPIH_
#define TFT_ESPI_VERSION "2.2.19"
#define TFT_ESPI_VERSION "2.2.20"
/***************************************************************************************
** Section 1: Load required header files

View File

@ -1,191 +0,0 @@
/*====================================================================================
This sketch contains support functions to render the Jpeg images.
Created by Bodmer 15th Jan 2017
==================================================================================*/
// Return the minimum of two values a and b
#define minimum(a,b) (((a) < (b)) ? (a) : (b))
//====================================================================================
// Opens the image file and prime the Jpeg decoder
//====================================================================================
void drawJpeg(const char *filename, int xpos, int ypos) {
Serial.println("===========================");
Serial.print("Drawing file: "); Serial.println(filename);
Serial.println("===========================");
// Open the named file (the Jpeg decoder library will close it after rendering image)
fs::File jpegFile = SPIFFS.open( filename, "r"); // File handle reference for SPIFFS
// File jpegFile = SD.open( filename, FILE_READ); // or, file handle reference for SD library
if ( !jpegFile ) {
Serial.print("ERROR: File \""); Serial.print(filename); Serial.println ("\" not found!");
return;
}
// Use one of the three following methods to initialise the decoder:
//boolean decoded = JpegDec.decodeFsFile(jpegFile); // Pass a SPIFFS file handle to the decoder,
//boolean decoded = JpegDec.decodeSdFile(jpegFile); // or pass the SD file handle to the decoder,
boolean decoded = JpegDec.decodeFsFile(filename); // or pass the filename (leading / distinguishes SPIFFS files)
// Note: the filename can be a String or character array type
if (decoded) {
// print information about the image to the serial port
jpegInfo();
// render the image onto the screen at given coordinates
jpegRender(xpos, ypos);
}
else {
Serial.println("Jpeg file format not supported!");
}
}
//====================================================================================
// Decode and render the Jpeg image onto the TFT screen
//====================================================================================
void jpegRender(int xpos, int ypos) {
// retrieve infomration about the image
uint16_t *pImg;
uint16_t mcu_w = JpegDec.MCUWidth;
uint16_t mcu_h = JpegDec.MCUHeight;
uint32_t max_x = JpegDec.width;
uint32_t max_y = JpegDec.height;
// Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs)
// Typically these MCUs are 16x16 pixel blocks
// Determine the width and height of the right and bottom edge image blocks
uint32_t min_w = minimum(mcu_w, max_x % mcu_w);
uint32_t min_h = minimum(mcu_h, max_y % mcu_h);
// save the current image block size
uint32_t win_w = mcu_w;
uint32_t win_h = mcu_h;
// record the current time so we can measure how long it takes to draw an image
uint32_t drawTime = millis();
// save the coordinate of the right and bottom edges to assist image cropping
// to the screen size
max_x += xpos;
max_y += ypos;
// read each MCU block until there are no more
while ( JpegDec.readSwappedBytes()) { // Swap byte order so the SPI buffer can be used
// save a pointer to the image block
pImg = JpegDec.pImage;
// calculate where the image block should be drawn on the screen
int mcu_x = JpegDec.MCUx * mcu_w + xpos; // Calculate coordinates of top left corner of current MCU
int mcu_y = JpegDec.MCUy * mcu_h + ypos;
// check if the image block size needs to be changed for the right edge
if (mcu_x + mcu_w <= max_x) win_w = mcu_w;
else win_w = min_w;
// check if the image block size needs to be changed for the bottom edge
if (mcu_y + mcu_h <= max_y) win_h = mcu_h;
else win_h = min_h;
// copy pixels into a contiguous block
if (win_w != mcu_w)
{
uint16_t *cImg;
int p = 0;
cImg = pImg + win_w;
for (int h = 1; h < win_h; h++)
{
p += mcu_w;
for (int w = 0; w < win_w; w++)
{
*cImg = *(pImg + w + p);
cImg++;
}
}
}
// draw image MCU block only if it will fit on the screen
if ( ( mcu_x + win_w) <= tft.width() && ( mcu_y + win_h) <= tft.height())
{
tft.pushRect(mcu_x, mcu_y, win_w, win_h, pImg);
}
else if ( ( mcu_y + win_h) >= tft.height()) JpegDec.abort();
}
// calculate how long it took to draw the image
drawTime = millis() - drawTime; // Calculate the time it took
// print the results to the serial port
Serial.print ("Total render time was : "); Serial.print(drawTime); Serial.println(" ms");
Serial.println("=====================================");
}
//====================================================================================
// Print information decoded from the Jpeg image
//====================================================================================
void jpegInfo() {
Serial.println("===============");
Serial.println("JPEG image info");
Serial.println("===============");
Serial.print ("Width :"); Serial.println(JpegDec.width);
Serial.print ("Height :"); Serial.println(JpegDec.height);
Serial.print ("Components :"); Serial.println(JpegDec.comps);
Serial.print ("MCU / row :"); Serial.println(JpegDec.MCUSPerRow);
Serial.print ("MCU / col :"); Serial.println(JpegDec.MCUSPerCol);
Serial.print ("Scan type :"); Serial.println(JpegDec.scanType);
Serial.print ("MCU width :"); Serial.println(JpegDec.MCUWidth);
Serial.print ("MCU height :"); Serial.println(JpegDec.MCUHeight);
Serial.println("===============");
Serial.println("");
}
//====================================================================================
// Open a Jpeg file and send it to the Serial port in a C array compatible format
//====================================================================================
void createArray(const char *filename) {
// Open the named file
fs::File jpgFile = SPIFFS.open( filename, "r"); // File handle reference for SPIFFS
// File jpgFile = SD.open( filename, FILE_READ); // or, file handle reference for SD library
if ( !jpgFile ) {
Serial.print("ERROR: File \""); Serial.print(filename); Serial.println ("\" not found!");
return;
}
uint8_t data;
byte line_len = 0;
Serial.println("");
Serial.println("// Generated by a JPEGDecoder library example sketch:");
Serial.println("// https://github.com/Bodmer/JPEGDecoder");
Serial.println("");
Serial.println("#include <pgmspace.h>");
Serial.println("// Remove leading / from array name!");
Serial.print ("const uint8_t ");
while (*filename != '.') Serial.print(*filename++);
Serial.println("[] PROGMEM = {"); // PROGMEM added for AVR processors, it is ignored by Due
while ( jpgFile.available()) {
data = jpgFile.read();
Serial.print("0x"); if (abs(data) < 16) Serial.print("0");
Serial.print(data, HEX); Serial.print(",");// Add value and comma
line_len++;
if ( line_len >= 32) {
line_len = 0;
Serial.println();
}
}
Serial.println("};\r\n");
jpgFile.close();
}
//====================================================================================

View File

@ -1,36 +0,0 @@
/*====================================================================================
This sketch contains support functions for the ESP6266 SPIFFS filing system
Created by Bodmer 15th Jan 2017
==================================================================================*/
//====================================================================================
// Print a SPIFFS directory list (root directory)
//====================================================================================
void listFiles(void) {
Serial.println();
Serial.println("SPIFFS files found:");
fs::Dir dir = SPIFFS.openDir("/"); // Root directory
String line = "=====================================";
Serial.println(line);
Serial.println(" File name Size");
Serial.println(line);
while (dir.next()) {
String fileName = dir.fileName();
Serial.print(fileName);
int spaces = 25 - fileName.length(); // Tabulate nicely
while (spaces--) Serial.print(" ");
fs::File f = dir.openFile("r");
Serial.print(f.size()); Serial.println(" bytes");
}
Serial.println(line);
Serial.println();
delay(1000);
}
//====================================================================================

View File

@ -1,129 +0,0 @@
/*====================================================================================
This sketch demonstrates loading images which have been stored as files in the
built-in FLASH memory on a NodeMCU 1.0 (ESP8266 based, ESP-12E Module) rendering the
images onto a 160 x 128 pixel TFT screen.
The images are stored in the SPI FLASH Filing System (SPIFFS), which effectively
functions like a tiny "hard drive". This filing system is built into the ESP8266
Core that can be loaded from the IDE "Boards manager" menu option. This is at
version 2.3.0 at the time of sketch creation.
The size of the SPIFFS partition can be set in the IDE as 1Mbyte or 3Mbytes. Either
will work with this sketch. Typically most sketches easily fit within 1 Mbyte so a
3 Mbyte SPIFS partition can be used, in which case it can contain 100's of Jpeg
full screem images.
The Jpeg library can be found here:
https://github.com/Bodmer/JPEGDecoder
Images in the Jpeg format can be created using Paint or IrfanView or other picture
editting software.
Place the images inside the sketch folder, in a folder called "Data". Then upload
all the files in the folder using the Arduino IDE "ESP8266 Sketch Data Upload" option
in the "Tools" menu:
http://www.esp8266.com/viewtopic.php?f=32&t=10081
https://github.com/esp8266/arduino-esp8266fs-plugin/releases
This takes some time, but the SPIFFS content is not altered when a new sketch is
uploaded, so there is no need to upload the same files again!
Note: If open, you must close the "Serial Monitor" window to upload data to SPIFFS!
The IDE will not copy the "data" folder with the sketch if you save the sketch under
another name. It is necessary to manually make a copy and place it in the sketch
folder.
This sketch includes example images in the Data folder.
Saving images, uploading and rendering on the TFT screen couldn't be much easier!
Created by Bodmer 24th Jan 2017 - Tested in Arduino IDE 1.8.0 esp8266 Core 2.3.0
==================================================================================*/
//====================================================================================
// Libraries
//====================================================================================
// Call up the SPIFFS FLASH filing system this is part of the ESP Core
#define FS_NO_GLOBALS
#include <FS.h>
// JPEG decoder library
#include <JPEGDecoder.h>
// SPI library, built into IDE
#include <SPI.h>
// Call up the TFT library
#include <TFT_eSPI.h> // Hardware-specific library for ESP8266
// The TFT control pins are set in the User_Setup.h file <<<<<<<<<<<<<<<<< NOTE!
// that can be found in the "src" folder of the library
// Invoke TFT library
TFT_eSPI tft = TFT_eSPI();
//====================================================================================
// Setup
//====================================================================================
void setup()
{
Serial.begin(250000); // Used for messages and the C array generator
delay(10);
Serial.println("NodeMCU decoder test!");
tft.begin();
tft.setRotation(0); // 0 & 2 Portrait. 1 & 3 landscape
tft.fillScreen(TFT_BLACK);
if (!SPIFFS.begin()) {
Serial.println("SPIFFS initialisation failed!");
while (1) yield(); // Stay here twiddling thumbs waiting
}
Serial.println("\r\nInitialisation done.");
listFiles(); // Lists the files so you can see what is in the SPIFFS
}
//====================================================================================
// Loop
//====================================================================================
void loop()
{
// Note the / before the SPIFFS file name must be present, this means the file is in
// the root directory of the SPIFFS, e.g. "/Tiger.jpg" for a file called "Tiger.jpg"
tft.setRotation(0); // portrait
tft.fillScreen(random(0xFFFF));
drawJpeg("/EagleEye160.jpg", 0, 16);
delay(2000);
tft.fillScreen(random(0xFFFF));
drawJpeg("/tiger160.jpg", 4, 0);
delay(2000);
tft.setRotation(1); // landscape
//tft.fillScreen(random(0xFFFF));
drawJpeg("/arduino160.jpg", 0, 0);
delay(2000);
tft.fillScreen(TFT_BLACK);
drawJpeg("/Baboon160.jpg", 0, 4);
delay(2000);
tft.fillScreen(random(0xFFFF));
drawJpeg("/Mouse160.jpg", 0, 11);
delay(2000);
// Create arrays from the jpeg images and send them to the serial port for copy and
// pasting into a sketch (used to make arrays fot the TFT_FLASH_Jpeg sketch)
//createArray("/EagleEye160.jpg");
//createArray("/tiger160.jpg");
//createArray("/Baboon160.jpg");
//createArray("/Mouse160.jpg");
//while(1) yield(); // Stay here
}
//====================================================================================

View File

@ -153,8 +153,8 @@ void jpegRender(int xpos, int ypos) {
// Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs)
// Typically these MCUs are 16x16 pixel blocks
// Determine the width and height of the right and bottom edge image blocks
uint32_t min_w = min(mcu_w, max_x % mcu_w);
uint32_t min_h = min(mcu_h, max_y % mcu_h);
uint32_t min_w = jpg_min(mcu_w, max_x % mcu_w);
uint32_t min_h = jpg_min(mcu_h, max_y % mcu_h);
// save the current image block size
uint32_t win_w = mcu_w;

View File

@ -1,6 +1,6 @@
{
"name": "TFT_eSPI",
"version": "2.2.19",
"version": "2.2.20",
"keywords": "Arduino, tft, ePaper, display, STM32, ESP8266, NodeMCU, ESP32, M5Stack, ILI9341, ST7735, ILI9163, S6D02A1, ILI9486, ST7789, RM68140",
"description": "A TFT and ePaper SPI graphics library with optimisation for ESP8266, ESP32 and STM32",
"repository":

View File

@ -1,5 +1,5 @@
name=TFT_eSPI
version=2.2.19
version=2.2.20
author=Bodmer
maintainer=Bodmer
sentence=TFT graphics library for Arduino processors with performance optimisation for STM32, ESP8266 and ESP32