Add new examples and ST7789 320x170 support

GUI examples require an extension library:

https://github.com/Bodmer/TFT_eWidget
This commit is contained in:
Bodmer 2022-07-22 18:09:09 +01:00
parent d94408bdaa
commit f2d8d2f26d
11 changed files with 1432 additions and 7 deletions

View File

@ -1,7 +1,7 @@
This is a stand-alone library that contains both graphics functions This is a stand-alone library that contains both graphics functions
and the TFT chip driver library. It supports the ESP8266, ESP32 and and the TFT chip driver library. It supports the ESP8266, ESP32,
STM32 processors with performance optimised code. Other Arduino IDE STM32 and RP2040 processors with performance optimised code. Other
compatible boards are also supported but the library then uses Arduino IDE compatible boards are also supported but the library
generic functions which will be slower. The library uses 32 bit then uses generic functions which will be slower. The library uses
variables extensively so this will affect performance on 8 and 16 32 bit variables extensively so this will affect performance on 8
bit processors. and 16 bit processors.

View File

@ -34,6 +34,12 @@
#endif #endif
#endif #endif
#if (TFT_HEIGHT == 320) && (TFT_WIDTH == 170)
#ifndef CGRAM_OFFSET
#define CGRAM_OFFSET
#endif
#endif
#if (TFT_HEIGHT == 300) && (TFT_WIDTH == 240) #if (TFT_HEIGHT == 300) && (TFT_WIDTH == 240)
#ifndef CGRAM_OFFSET #ifndef CGRAM_OFFSET
#define CGRAM_OFFSET #define CGRAM_OFFSET

View File

@ -34,6 +34,12 @@
#endif #endif
#endif #endif
#if (TFT_HEIGHT == 320) && (TFT_WIDTH == 170)
#ifndef CGRAM_OFFSET
#define CGRAM_OFFSET
#endif
#endif
#if (TFT_HEIGHT == 300) && (TFT_WIDTH == 240) #if (TFT_HEIGHT == 300) && (TFT_WIDTH == 240)
#ifndef CGRAM_OFFSET #ifndef CGRAM_OFFSET
#define CGRAM_OFFSET #define CGRAM_OFFSET

View File

@ -3753,7 +3753,7 @@ constexpr float LoAlphaTheshold = 1.0/32.0;
constexpr float HiAlphaTheshold = 1.0 - LoAlphaTheshold; constexpr float HiAlphaTheshold = 1.0 - LoAlphaTheshold;
/*************************************************************************************** /***************************************************************************************
** Function name: drawPixel (aplha blended) ** Function name: drawPixel (alpha blended)
** Description: Draw a pixel blended with the screen or bg pixel colour ** Description: Draw a pixel blended with the screen or bg pixel colour
***************************************************************************************/ ***************************************************************************************/
uint16_t TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color, uint8_t alpha, uint32_t bg_color) uint16_t TFT_eSPI::drawPixel(int32_t x, int32_t y, uint32_t color, uint8_t alpha, uint32_t bg_color)

View File

@ -0,0 +1,191 @@
// Button widget demo, requires display with touch screen
// Requires widget library here:
// https://github.com/Bodmer/TFT_eWidget
#include "FS.h"
#include "Free_Fonts.h" // Include the header file attached to this sketch
#include <TFT_eSPI.h> // Hardware-specific library
#include <TFT_eWidget.h> // Widget library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
#define CALIBRATION_FILE "/TouchCalData1"
#define REPEAT_CAL false
TFT_eWidget btnL = TFT_eWidget(&tft);
TFT_eWidget btnR = TFT_eWidget(&tft);
#define BUTTON_W 100
#define BUTTON_H 50
// Create an array of button instances to use in for() loops
// This is more useful where large numbers of buttons are employed
TFT_eWidget* btn[] = {&btnL , &btnR};;
uint8_t buttonCount = sizeof(btn) / sizeof(btn[0]);
void btnL_pressAction(void)
{
if (btnL.justPressed()) {
Serial.println("Left button just pressed");
btnL.drawSmoothButton(true);
}
}
void btnL_releaseAction(void)
{
static uint32_t waitTime = 1000;
if (btnL.justReleased()) {
Serial.println("Left button just released");
btnL.drawSmoothButton(false);
btnL.setReleaseTime(millis());
waitTime = 10000;
}
else {
if (millis() - btnL.getReleaseTime() >= waitTime) {
waitTime = 1000;
btnL.setReleaseTime(millis());
btnL.drawSmoothButton(!btnL.getState());
}
}
}
void btnR_pressAction(void)
{
if (btnR.justPressed()) {
btnR.drawSmoothButton(!btnR.getState(), 3, TFT_BLACK, btnR.getState() ? "OFF" : "ON");
Serial.print("Button toggled: ");
if (btnR.getState()) Serial.println("ON");
else Serial.println("OFF");
btnR.setPressTime(millis());
}
// if button pressed for more than 1 sec...
if (millis() - btnR.getPressTime() >= 1000) {
Serial.println("Stop pressing my buttton.......");
}
else Serial.println("Right button is being pressed");
}
void btnR_releaseAction(void)
{
// Not action
}
void initButtons() {
uint16_t x = (tft.width() - BUTTON_W) / 2;
uint16_t y = tft.height() / 2 - BUTTON_H - 10;
btnL.initButtonUL(x, y, BUTTON_W, BUTTON_H, TFT_WHITE, TFT_RED, TFT_BLACK, "Button", 1);
btnL.setPressAction(btnL_pressAction);
btnL.setReleaseAction(btnL_releaseAction);
btnL.drawSmoothButton(false, 3, TFT_BLACK); // 3 is outline width, TFT_BLACK is the surrounding background colour for anti-aliasing
y = tft.height() / 2 + 10;
btnR.initButtonUL(x, y, BUTTON_W, BUTTON_H, TFT_WHITE, TFT_BLACK, TFT_GREEN, "OFF", 1);
btnR.setPressAction(btnR_pressAction);
//btnR.setReleaseAction(btnR_releaseAction);
btnR.drawSmoothButton(false, 3, TFT_BLACK); // 3 is outline width, TFT_BLACK is the surrounding background colour for anti-aliasing
}
void setup() {
Serial.begin(115200);
tft.begin();
tft.setRotation(0);
tft.fillScreen(TFT_BLACK);
tft.setFreeFont(FF18);
// Calibrate the touch screen and retrieve the scaling factors
touch_calibrate();
initButtons();
}
void loop() {
static uint32_t scanTime = millis();
uint16_t t_x = 9999, t_y = 9999; // To store the touch coordinates
// Scan keys every 50ms at most
if (millis() - scanTime >= 50) {
// Pressed will be set true if there is a valid touch on the screen
bool pressed = tft.getTouch(&t_x, &t_y);
scanTime = millis();
for (uint8_t b = 0; b < buttonCount; b++) {
if (pressed) {
if (btn[b]->contains(t_x, t_y)) {
btn[b]->press(true);
btn[b]->pressAction();
}
}
else {
btn[b]->press(false);
btn[b]->releaseAction();
}
}
}
}
void touch_calibrate()
{
uint16_t calData[5];
uint8_t calDataOK = 0;
// check file system exists
if (!LittleFS.begin()) {
Serial.println("Formating file system");
LittleFS.format();
LittleFS.begin();
}
// check if calibration file exists and size is correct
if (LittleFS.exists(CALIBRATION_FILE)) {
if (REPEAT_CAL)
{
// Delete if we want to re-calibrate
LittleFS.remove(CALIBRATION_FILE);
}
else
{
File f = LittleFS.open(CALIBRATION_FILE, "r");
if (f) {
if (f.readBytes((char *)calData, 14) == 14)
calDataOK = 1;
f.close();
}
}
}
if (calDataOK && !REPEAT_CAL) {
// calibration data valid
tft.setTouch(calData);
} else {
// data not valid so recalibrate
tft.fillScreen(TFT_BLACK);
tft.setCursor(20, 0);
tft.setTextFont(2);
tft.setTextSize(1);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.println("Touch corners as indicated");
tft.setTextFont(1);
tft.println();
if (REPEAT_CAL) {
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.println("Set REPEAT_CAL to false to stop this running again!");
}
tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);
tft.setTextColor(TFT_GREEN, TFT_BLACK);
tft.println("Calibration complete!");
// store data
File f = LittleFS.open(CALIBRATION_FILE, "w");
if (f) {
f.write((const unsigned char *)calData, 14);
f.close();
}
}
}

View File

@ -0,0 +1,377 @@
// Attach this header file to your sketch to use the GFX Free Fonts. You can write
// sketches without it, but it makes referencing them easier.
// This calls up ALL the fonts but they only get loaded if you actually
// use them in your sketch.
//
// No changes are needed to this header file unless new fonts are added to the
// library "Fonts/GFXFF" folder.
//
// To save a lot of typing long names, each font can easily be referenced in the
// sketch in three ways, either with:
//
// 1. Font file name with the & in front such as &FreeSansBoldOblique24pt7b
// an example being:
//
// tft.setFreeFont(&FreeSansBoldOblique24pt7b);
//
// 2. FF# where # is a number determined by looking at the list below
// an example being:
//
// tft.setFreeFont(FF32);
//
// 3. An abbreviation of the file name. Look at the list below to see
// the abbreviations used, for example:
//
// tft.setFreeFont(FSSBO24)
//
// Where the letters mean:
// F = Free font
// M = Mono
// SS = Sans Serif (double S to distinguish is form serif fonts)
// S = Serif
// B = Bold
// O = Oblique (letter O not zero)
// I = Italic
// # = point size, either 9, 12, 18 or 24
//
// Setting the font to NULL will select the GLCD font:
//
// tft.setFreeFont(NULL); // Set font to GLCD
#define LOAD_tftFF
#ifdef LOAD_tftFF // Only include the fonts if LOAD_tftFF is defined in User_Setup.h
// Use these when printing or drawing text in GLCD and high rendering speed fonts
#define GFXFF 1
#define GLCD 0
#define FONT2 2
#define FONT4 4
#define FONT6 6
#define FONT7 7
#define FONT8 8
// Use the following when calling setFont()
//
// Reserved for GLCD font // FF0
//
#define TT1 &TomThumb
#define FM9 &FreeMono9pt7b
#define FM12 &FreeMono12pt7b
#define FM18 &FreeMono18pt7b
#define FM24 &FreeMono24pt7b
#define FMB9 &FreeMonoBold9pt7b
#define FMB12 &FreeMonoBold12pt7b
#define FMB18 &FreeMonoBold18pt7b
#define FMB24 &FreeMonoBold24pt7b
#define FMO9 &FreeMonoOblique9pt7b
#define FMO12 &FreeMonoOblique12pt7b
#define FMO18 &FreeMonoOblique18pt7b
#define FMO24 &FreeMonoOblique24pt7b
#define FMBO9 &FreeMonoBoldOblique9pt7b
#define FMBO12 &FreeMonoBoldOblique12pt7b
#define FMBO18 &FreeMonoBoldOblique18pt7b
#define FMBO24 &FreeMonoBoldOblique24pt7b
#define FSS9 &FreeSans9pt7b
#define FSS12 &FreeSans12pt7b
#define FSS18 &FreeSans18pt7b
#define FSS24 &FreeSans24pt7b
#define FSSB9 &FreeSansBold9pt7b
#define FSSB12 &FreeSansBold12pt7b
#define FSSB18 &FreeSansBold18pt7b
#define FSSB24 &FreeSansBold24pt7b
#define FSSO9 &FreeSansOblique9pt7b
#define FSSO12 &FreeSansOblique12pt7b
#define FSSO18 &FreeSansOblique18pt7b
#define FSSO24 &FreeSansOblique24pt7b
#define FSSBO9 &FreeSansBoldOblique9pt7b
#define FSSBO12 &FreeSansBoldOblique12pt7b
#define FSSBO18 &FreeSansBoldOblique18pt7b
#define FSSBO24 &FreeSansBoldOblique24pt7b
#define FS9 &FreeSerif9pt7b
#define FS12 &FreeSerif12pt7b
#define FS18 &FreeSerif18pt7b
#define FS24 &FreeSerif24pt7b
#define FSI9 &FreeSerifItalic9pt7b
#define FSI12 &FreeSerifItalic12pt7b
#define FSI19 &FreeSerifItalic18pt7b
#define FSI24 &FreeSerifItalic24pt7b
#define FSB9 &FreeSerifBold9pt7b
#define FSB12 &FreeSerifBold12pt7b
#define FSB18 &FreeSerifBold18pt7b
#define FSB24 &FreeSerifBold24pt7b
#define FSBI9 &FreeSerifBoldItalic9pt7b
#define FSBI12 &FreeSerifBoldItalic12pt7b
#define FSBI18 &FreeSerifBoldItalic18pt7b
#define FSBI24 &FreeSerifBoldItalic24pt7b
#define FF0 NULL //ff0 reserved for GLCD
#define FF1 &FreeMono9pt7b
#define FF2 &FreeMono12pt7b
#define FF3 &FreeMono18pt7b
#define FF4 &FreeMono24pt7b
#define FF5 &FreeMonoBold9pt7b
#define FF6 &FreeMonoBold12pt7b
#define FF7 &FreeMonoBold18pt7b
#define FF8 &FreeMonoBold24pt7b
#define FF9 &FreeMonoOblique9pt7b
#define FF10 &FreeMonoOblique12pt7b
#define FF11 &FreeMonoOblique18pt7b
#define FF12 &FreeMonoOblique24pt7b
#define FF13 &FreeMonoBoldOblique9pt7b
#define FF14 &FreeMonoBoldOblique12pt7b
#define FF15 &FreeMonoBoldOblique18pt7b
#define FF16 &FreeMonoBoldOblique24pt7b
#define FF17 &FreeSans9pt7b
#define FF18 &FreeSans12pt7b
#define FF19 &FreeSans18pt7b
#define FF20 &FreeSans24pt7b
#define FF21 &FreeSansBold9pt7b
#define FF22 &FreeSansBold12pt7b
#define FF23 &FreeSansBold18pt7b
#define FF24 &FreeSansBold24pt7b
#define FF25 &FreeSansOblique9pt7b
#define FF26 &FreeSansOblique12pt7b
#define FF27 &FreeSansOblique18pt7b
#define FF28 &FreeSansOblique24pt7b
#define FF29 &FreeSansBoldOblique9pt7b
#define FF30 &FreeSansBoldOblique12pt7b
#define FF31 &FreeSansBoldOblique18pt7b
#define FF32 &FreeSansBoldOblique24pt7b
#define FF33 &FreeSerif9pt7b
#define FF34 &FreeSerif12pt7b
#define FF35 &FreeSerif18pt7b
#define FF36 &FreeSerif24pt7b
#define FF37 &FreeSerifItalic9pt7b
#define FF38 &FreeSerifItalic12pt7b
#define FF39 &FreeSerifItalic18pt7b
#define FF40 &FreeSerifItalic24pt7b
#define FF41 &FreeSerifBold9pt7b
#define FF42 &FreeSerifBold12pt7b
#define FF43 &FreeSerifBold18pt7b
#define FF44 &FreeSerifBold24pt7b
#define FF45 &FreeSerifBoldItalic9pt7b
#define FF46 &FreeSerifBoldItalic12pt7b
#define FF47 &FreeSerifBoldItalic18pt7b
#define FF48 &FreeSerifBoldItalic24pt7b
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Now we define "s"tring versions for easy printing of the font name so:
// tft.println(sFF5);
// will print
// Mono bold 9
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define sFF0 "GLCD"
#define sTT1 "Tom Thumb"
#define sFF1 "Mono 9"
#define sFF2 "Mono 12"
#define sFF3 "Mono 18"
#define sFF4 "Mono 24"
#define sFF5 "Mono bold 9"
#define sFF6 "Mono bold 12"
#define sFF7 "Mono bold 18"
#define sFF8 "Mono bold 24"
#define sFF9 "Mono oblique 9"
#define sFF10 "Mono oblique 12"
#define sFF11 "Mono oblique 18"
#define sFF12 "Mono oblique 24"
#define sFF13 "Mono bold oblique 9"
#define sFF14 "Mono bold oblique 12"
#define sFF15 "Mono bold oblique 18"
#define sFF16 "Mono bold oblique 24" // Full text line is too big for 480 pixel wide screen
#define sFF17 "Sans 9"
#define sFF18 "Sans 12"
#define sFF19 "Sans 18"
#define sFF20 "Sans 24"
#define sFF21 "Sans bold 9"
#define sFF22 "Sans bold 12"
#define sFF23 "Sans bold 18"
#define sFF24 "Sans bold 24"
#define sFF25 "Sans oblique 9"
#define sFF26 "Sans oblique 12"
#define sFF27 "Sans oblique 18"
#define sFF28 "Sans oblique 24"
#define sFF29 "Sans bold oblique 9"
#define sFF30 "Sans bold oblique 12"
#define sFF31 "Sans bold oblique 18"
#define sFF32 "Sans bold oblique 24"
#define sFF33 "Serif 9"
#define sFF34 "Serif 12"
#define sFF35 "Serif 18"
#define sFF36 "Serif 24"
#define sFF37 "Serif italic 9"
#define sFF38 "Serif italic 12"
#define sFF39 "Serif italic 18"
#define sFF40 "Serif italic 24"
#define sFF41 "Serif bold 9"
#define sFF42 "Serif bold 12"
#define sFF43 "Serif bold 18"
#define sFF44 "Serif bold 24"
#define sFF45 "Serif bold italic 9"
#define sFF46 "Serif bold italic 12"
#define sFF47 "Serif bold italic 18"
#define sFF48 "Serif bold italic 24"
#else // LOAD_tftFF not defined so setup defaults to prevent error messages
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Free fonts are not loaded in User_Setup.h so we must define all as font 1
// to prevent compile error messages
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define GFXFF 1
#define GLCD 1
#define FONT2 2
#define FONT4 4
#define FONT6 6
#define FONT7 7
#define FONT8 8
#define FF0 1
#define FF1 1
#define FF2 1
#define FF3 1
#define FF4 1
#define FF5 1
#define FF6 1
#define FF7 1
#define FF8 1
#define FF9 1
#define FF10 1
#define FF11 1
#define FF12 1
#define FF13 1
#define FF14 1
#define FF15 1
#define FF16 1
#define FF17 1
#define FF18 1
#define FF19 1
#define FF20 1
#define FF21 1
#define FF22 1
#define FF23 1
#define FF24 1
#define FF25 1
#define FF26 1
#define FF27 1
#define FF28 1
#define FF29 1
#define FF30 1
#define FF31 1
#define FF32 1
#define FF33 1
#define FF34 1
#define FF35 1
#define FF36 1
#define FF37 1
#define FF38 1
#define FF39 1
#define FF40 1
#define FF41 1
#define FF42 1
#define FF43 1
#define FF44 1
#define FF45 1
#define FF46 1
#define FF47 1
#define FF48 1
#define FM9 1
#define FM12 1
#define FM18 1
#define FM24 1
#define FMB9 1
#define FMB12 1
#define FMB18 1
#define FMB24 1
#define FMO9 1
#define FMO12 1
#define FMO18 1
#define FMO24 1
#define FMBO9 1
#define FMBO12 1
#define FMBO18 1
#define FMBO24 1
#define FSS9 1
#define FSS12 1
#define FSS18 1
#define FSS24 1
#define FSSB9 1
#define FSSB12 1
#define FSSB18 1
#define FSSB24 1
#define FSSO9 1
#define FSSO12 1
#define FSSO18 1
#define FSSO24 1
#define FSSBO9 1
#define FSSBO12 1
#define FSSBO18 1
#define FSSBO24 1
#define FS9 1
#define FS12 1
#define FS18 1
#define FS24 1
#define FSI9 1
#define FSI12 1
#define FSI19 1
#define FSI24 1
#define FSB9 1
#define FSB12 1
#define FSB18 1
#define FSB24 1
#define FSBI9 1
#define FSBI12 1
#define FSBI18 1
#define FSBI24 1
#endif // LOAD_tftFF

View File

@ -0,0 +1,80 @@
// Demonstrate graph widget functions with a single trace instance
// One trace can be drawn at a time with one trace instance
// Requires widget library here:
// https://github.com/Bodmer/TFT_eWidget
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
#include <TFT_eWidget.h> // Widget library
GraphWidget gr = GraphWidget(&tft); // Graph widget gr instance with pointer to tft
TraceWidget tr = TraceWidget(&gr); // Graph trace tr with pointer to gr
const float gxLow = 0.0;
const float gxHigh = 100.0;
const float gyLow = -512.0;
const float gyHigh = 512.0;
void setup() {
Serial.begin(115200);
tft.begin();
tft.setRotation(3);
tft.fillScreen(TFT_BLACK);
// Graph area is 200 pixels wide, 150 pixels high, dark grey background
gr.createGraph(200, 150, tft.color565(5, 5, 5));
// x scale units is from 0 to 100, y scale units is -512 to 512
gr.setGraphScale(gxLow, gxHigh, gyLow, gyHigh);
// X grid starts at 0 with lines every 20 x-scale units
// Y grid starts at -512 with lines every 64 y-scale units
// blue grid
gr.setGraphGrid(gxLow, 20.0, gyLow, 64.0, TFT_BLUE);
// Draw empty graph, top left corner at pixel coordinate 40,10 on TFT
gr.drawGraph(40, 10);
// Start a trace with using red, trace points are in x and y scale units
// In this example a horizontal line is drawn
tr.startTrace(TFT_RED);
// Add a trace point at 0.0,0.0 on graph
tr.addPoint(0.0, 0.0);
// Add another point at 100.0, 0.0 this will be joined via line to the last point added
tr.addPoint(100.0, 0.0);
// Start a new trace with using white
tr.startTrace(TFT_WHITE);
}
void loop() {
static uint32_t plotTime = millis();
static float gx = 0.0, gy = 0.0;
static float delta = 10.0;
// Create a new plot point every 100ms
if (millis() - plotTime >= 100) {
plotTime = millis();
// Add a plot, first point in a trace will be a single pixel (if within graph area)
tr.addPoint(gx, gy);
gx += 1.0;
if (gy > 500.0) delta = -10.0;
if (gy < -500.0) delta = 10.0;
gy += delta;
// If the end of the graph x ais is reached start a new trace at 0.0,0.0
if (gx > gxHigh) {
gx = 0.0;
gy = 0.0;
// Draw empty graph at 40,10 on display to clear old one
gr.drawGraph(40, 10);
// Start new trace
tr.startTrace(TFT_GREEN);
}
}
}

View File

@ -0,0 +1,105 @@
// Demonstrate graph widget functions with two independant trace instances
// Multiple traces can be drawn at a time with multiple trace instances
// Note: Traces are automatically clipped at graph boundaries by widget library
// Requires widget library here:
// https://github.com/Bodmer/TFT_eWidget
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();
#include <TFT_eWidget.h> // Widget library
GraphWidget gr = GraphWidget(&tft); // Graph widget
// Traces are drawn on tft using graph instance
TraceWidget tr1 = TraceWidget(&gr); // Graph trace 1
TraceWidget tr2 = TraceWidget(&gr); // Graph trace 2
void setup() {
Serial.begin(115200);
delay(5000);
tft.begin();
tft.setRotation(3);
tft.fillScreen(TFT_BLACK);
// Graph area is 200 pixels wide, 150 high, dark grey background
gr.createGraph(200, 150, tft.color565(5, 5, 5));
// x scale units is from 0 to 100, y scale units is -50 to 50
gr.setGraphScale(0.0, 100.0, -50.0, 50.0);
// X grid starts at 0 with lines every 10 x-scale units
// Y grid starts at -50 with lines every 25 y-scale units
// blue grid
gr.setGraphGrid(0.0, 10.0, -50.0, 25.0, TFT_BLUE);
// Draw empty graph, top left corner at 40,10 on TFT
gr.drawGraph(40, 10);
// Start a trace with using red and another with green
tr1.startTrace(TFT_RED);
tr2.startTrace(TFT_GREEN);
// Add points on graph to trace 1 using graph scale factors
tr1.addPoint(0.0, 0.0);
tr1.addPoint(100.0, 0.0);
// Add points on graph to trace 2 using graph scale factors
// Points are off graph so the plotted line is clipped to graph area
tr2.addPoint(0.0, -100.0);
tr2.addPoint(100.0, 100.0);
// Get x,y pixel coordinates of any scaled point on graph
// and ring that point.
tft.drawCircle(gr.getPointX(50.0), gr.getPointY(0.0), 5, TFT_MAGENTA);
// Draw the x axis scale
tft.setTextDatum(TC_DATUM); // Top centre text datum
tft.drawNumber(0, gr.getPointX(0.0), gr.getPointY(-50.0) + 3);
tft.drawNumber(50, gr.getPointX(50.0), gr.getPointY(-50.0) + 3);
tft.drawNumber(100, gr.getPointX(100.0), gr.getPointY(-50.0) + 3);
// Draw the y axis scale
tft.setTextDatum(MR_DATUM); // Middle right text datum
tft.drawNumber(-50, gr.getPointX(0.0), gr.getPointY(-50.0));
tft.drawNumber(0, gr.getPointX(0.0), gr.getPointY(0.0));
tft.drawNumber(50, gr.getPointX(0.0), gr.getPointY(50.0));
// Restart traces with new colours
tr1.startTrace(TFT_WHITE);
tr2.startTrace(TFT_YELLOW);
}
void loop() {
static uint32_t plotTime = millis();
static float gx = 0.0, gy = 0.0;
static float delta = 7.0;
// Sample periodically
if (millis() - plotTime >= 100) {
plotTime = millis();
// Add a new point on each trace
tr1.addPoint(gx, gy);
tr2.addPoint(gx, gy/2.0); // half y amplitude
// Create next plot point
gx += 1.0;
gy += delta;
if (gy > 70.0) { delta = -7.0; gy = 70.0; }
if (gy < -70.0) { delta = 7.0; gy = -70.0; }
// If the end of the graph is reached start 2 new traces
if (gx > 100.0) {
gx = 0.0;
gy = 0.0;
// Draw empty graph at 40,10 on display
gr.drawGraph(40, 10);
// Start new trace
tr1.startTrace(TFT_GREEN);
tr2.startTrace(TFT_YELLOW);
}
}
}

View File

@ -0,0 +1,82 @@
/*
Example animated analogue meters
Needs Font 2 (also Font 4 if using large scale label)
Make sure all the display driver and pin connections are correct by
editing the User_Setup.h file in the TFT_eSPI library folder.
#########################################################################
###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
#########################################################################
Requires widget library here:
https://github.com/Bodmer/TFT_eWidget
*/
#include <TFT_eSPI.h> // Hardware-specific library
#include <TFT_eWidget.h> // Widget library
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
MeterWidget amps = MeterWidget(&tft);
MeterWidget volts = MeterWidget(&tft);
MeterWidget ohms = MeterWidget(&tft);
#define LOOP_PERIOD 35 // Display updates every 35 ms
void setup(void)
{
tft.init();
tft.setRotation(0);
Serial.begin(115200); // For debug
// Colour zones are set as a start and end percentage of full scale (0-100)
// If start and end of a colour zone are the same then that colour is not used
// --Red-- -Org- -Yell- -Grn-
amps.setZones(75, 100, 50, 75, 25, 50, 0, 25); // Example here red starts at 75% and ends at 100% of full scale
// Meter is 239 pixels wide and 126 pixels high
amps.analogMeter(0, 0, 2.0, "mA", "0", "0.5", "1.0", "1.5", "2.0"); // Draw analogue meter at 0, 0
// Colour draw order is red, orange, yellow, green. So red can be full scale with green drawn
// last on top to indicate a "safe" zone.
// -Red- -Org- -Yell- -Grn-
volts.setZones(0, 100, 25, 75, 0, 0, 40, 60);
volts.analogMeter(0, 128, 10.0, "V", "0", "2.5", "5", "7.5", "10"); // Draw analogue meter at 0, 128
// No coloured zones if not defined
ohms.analogMeter(0, 256, 100, "R", "0", "", "50", "", "100"); // Draw analogue meter at 0, 128
}
void loop()
{
static int d = 0;
static uint32_t updateTime = 0;
if (millis() - updateTime >= LOOP_PERIOD)
{
updateTime = millis();
d += 4; if (d > 360) d = 0;
// Create a Sine wave for testing, value is in range 0 - 100
float value = 50.0 + 50.0 * sin((d + 0) * 0.0174532925);
float current;
mapValue(value, current, (float)0.0, (float)100.0, (float)0.0, (float)2.0);
//Serial.print("I = "); Serial.print(current);
amps.updateNeedle(current, 0);
float voltage;
mapValue(value, voltage, (float)0.0, (float)100.0, (float)0.0, (float)10.0);
//Serial.print(", V = "); Serial.println(voltage);
volts.updateNeedle(voltage, 0);
float resistance;
mapValue(value, resistance, (float)0.0, (float)100.0, (float)0.0, (float)100.0);
//Serial.print(", R = "); Serial.println(resistance);
ohms.updateNeedle(resistance, 0);
}
}

View File

@ -0,0 +1,377 @@
// Attach this header file to your sketch to use the GFX Free Fonts. You can write
// sketches without it, but it makes referencing them easier.
// This calls up ALL the fonts but they only get loaded if you actually
// use them in your sketch.
//
// No changes are needed to this header file unless new fonts are added to the
// library "Fonts/GFXFF" folder.
//
// To save a lot of typing long names, each font can easily be referenced in the
// sketch in three ways, either with:
//
// 1. Font file name with the & in front such as &FreeSansBoldOblique24pt7b
// an example being:
//
// tft.setFreeFont(&FreeSansBoldOblique24pt7b);
//
// 2. FF# where # is a number determined by looking at the list below
// an example being:
//
// tft.setFreeFont(FF32);
//
// 3. An abbreviation of the file name. Look at the list below to see
// the abbreviations used, for example:
//
// tft.setFreeFont(FSSBO24)
//
// Where the letters mean:
// F = Free font
// M = Mono
// SS = Sans Serif (double S to distinguish is form serif fonts)
// S = Serif
// B = Bold
// O = Oblique (letter O not zero)
// I = Italic
// # = point size, either 9, 12, 18 or 24
//
// Setting the font to NULL will select the GLCD font:
//
// tft.setFreeFont(NULL); // Set font to GLCD
#define LOAD_tftFF
#ifdef LOAD_tftFF // Only include the fonts if LOAD_tftFF is defined in User_Setup.h
// Use these when printing or drawing text in GLCD and high rendering speed fonts
#define GFXFF 1
#define GLCD 0
#define FONT2 2
#define FONT4 4
#define FONT6 6
#define FONT7 7
#define FONT8 8
// Use the following when calling setFont()
//
// Reserved for GLCD font // FF0
//
#define TT1 &TomThumb
#define FM9 &FreeMono9pt7b
#define FM12 &FreeMono12pt7b
#define FM18 &FreeMono18pt7b
#define FM24 &FreeMono24pt7b
#define FMB9 &FreeMonoBold9pt7b
#define FMB12 &FreeMonoBold12pt7b
#define FMB18 &FreeMonoBold18pt7b
#define FMB24 &FreeMonoBold24pt7b
#define FMO9 &FreeMonoOblique9pt7b
#define FMO12 &FreeMonoOblique12pt7b
#define FMO18 &FreeMonoOblique18pt7b
#define FMO24 &FreeMonoOblique24pt7b
#define FMBO9 &FreeMonoBoldOblique9pt7b
#define FMBO12 &FreeMonoBoldOblique12pt7b
#define FMBO18 &FreeMonoBoldOblique18pt7b
#define FMBO24 &FreeMonoBoldOblique24pt7b
#define FSS9 &FreeSans9pt7b
#define FSS12 &FreeSans12pt7b
#define FSS18 &FreeSans18pt7b
#define FSS24 &FreeSans24pt7b
#define FSSB9 &FreeSansBold9pt7b
#define FSSB12 &FreeSansBold12pt7b
#define FSSB18 &FreeSansBold18pt7b
#define FSSB24 &FreeSansBold24pt7b
#define FSSO9 &FreeSansOblique9pt7b
#define FSSO12 &FreeSansOblique12pt7b
#define FSSO18 &FreeSansOblique18pt7b
#define FSSO24 &FreeSansOblique24pt7b
#define FSSBO9 &FreeSansBoldOblique9pt7b
#define FSSBO12 &FreeSansBoldOblique12pt7b
#define FSSBO18 &FreeSansBoldOblique18pt7b
#define FSSBO24 &FreeSansBoldOblique24pt7b
#define FS9 &FreeSerif9pt7b
#define FS12 &FreeSerif12pt7b
#define FS18 &FreeSerif18pt7b
#define FS24 &FreeSerif24pt7b
#define FSI9 &FreeSerifItalic9pt7b
#define FSI12 &FreeSerifItalic12pt7b
#define FSI19 &FreeSerifItalic18pt7b
#define FSI24 &FreeSerifItalic24pt7b
#define FSB9 &FreeSerifBold9pt7b
#define FSB12 &FreeSerifBold12pt7b
#define FSB18 &FreeSerifBold18pt7b
#define FSB24 &FreeSerifBold24pt7b
#define FSBI9 &FreeSerifBoldItalic9pt7b
#define FSBI12 &FreeSerifBoldItalic12pt7b
#define FSBI18 &FreeSerifBoldItalic18pt7b
#define FSBI24 &FreeSerifBoldItalic24pt7b
#define FF0 NULL //ff0 reserved for GLCD
#define FF1 &FreeMono9pt7b
#define FF2 &FreeMono12pt7b
#define FF3 &FreeMono18pt7b
#define FF4 &FreeMono24pt7b
#define FF5 &FreeMonoBold9pt7b
#define FF6 &FreeMonoBold12pt7b
#define FF7 &FreeMonoBold18pt7b
#define FF8 &FreeMonoBold24pt7b
#define FF9 &FreeMonoOblique9pt7b
#define FF10 &FreeMonoOblique12pt7b
#define FF11 &FreeMonoOblique18pt7b
#define FF12 &FreeMonoOblique24pt7b
#define FF13 &FreeMonoBoldOblique9pt7b
#define FF14 &FreeMonoBoldOblique12pt7b
#define FF15 &FreeMonoBoldOblique18pt7b
#define FF16 &FreeMonoBoldOblique24pt7b
#define FF17 &FreeSans9pt7b
#define FF18 &FreeSans12pt7b
#define FF19 &FreeSans18pt7b
#define FF20 &FreeSans24pt7b
#define FF21 &FreeSansBold9pt7b
#define FF22 &FreeSansBold12pt7b
#define FF23 &FreeSansBold18pt7b
#define FF24 &FreeSansBold24pt7b
#define FF25 &FreeSansOblique9pt7b
#define FF26 &FreeSansOblique12pt7b
#define FF27 &FreeSansOblique18pt7b
#define FF28 &FreeSansOblique24pt7b
#define FF29 &FreeSansBoldOblique9pt7b
#define FF30 &FreeSansBoldOblique12pt7b
#define FF31 &FreeSansBoldOblique18pt7b
#define FF32 &FreeSansBoldOblique24pt7b
#define FF33 &FreeSerif9pt7b
#define FF34 &FreeSerif12pt7b
#define FF35 &FreeSerif18pt7b
#define FF36 &FreeSerif24pt7b
#define FF37 &FreeSerifItalic9pt7b
#define FF38 &FreeSerifItalic12pt7b
#define FF39 &FreeSerifItalic18pt7b
#define FF40 &FreeSerifItalic24pt7b
#define FF41 &FreeSerifBold9pt7b
#define FF42 &FreeSerifBold12pt7b
#define FF43 &FreeSerifBold18pt7b
#define FF44 &FreeSerifBold24pt7b
#define FF45 &FreeSerifBoldItalic9pt7b
#define FF46 &FreeSerifBoldItalic12pt7b
#define FF47 &FreeSerifBoldItalic18pt7b
#define FF48 &FreeSerifBoldItalic24pt7b
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Now we define "s"tring versions for easy printing of the font name so:
// tft.println(sFF5);
// will print
// Mono bold 9
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define sFF0 "GLCD"
#define sTT1 "Tom Thumb"
#define sFF1 "Mono 9"
#define sFF2 "Mono 12"
#define sFF3 "Mono 18"
#define sFF4 "Mono 24"
#define sFF5 "Mono bold 9"
#define sFF6 "Mono bold 12"
#define sFF7 "Mono bold 18"
#define sFF8 "Mono bold 24"
#define sFF9 "Mono oblique 9"
#define sFF10 "Mono oblique 12"
#define sFF11 "Mono oblique 18"
#define sFF12 "Mono oblique 24"
#define sFF13 "Mono bold oblique 9"
#define sFF14 "Mono bold oblique 12"
#define sFF15 "Mono bold oblique 18"
#define sFF16 "Mono bold oblique 24" // Full text line is too big for 480 pixel wide screen
#define sFF17 "Sans 9"
#define sFF18 "Sans 12"
#define sFF19 "Sans 18"
#define sFF20 "Sans 24"
#define sFF21 "Sans bold 9"
#define sFF22 "Sans bold 12"
#define sFF23 "Sans bold 18"
#define sFF24 "Sans bold 24"
#define sFF25 "Sans oblique 9"
#define sFF26 "Sans oblique 12"
#define sFF27 "Sans oblique 18"
#define sFF28 "Sans oblique 24"
#define sFF29 "Sans bold oblique 9"
#define sFF30 "Sans bold oblique 12"
#define sFF31 "Sans bold oblique 18"
#define sFF32 "Sans bold oblique 24"
#define sFF33 "Serif 9"
#define sFF34 "Serif 12"
#define sFF35 "Serif 18"
#define sFF36 "Serif 24"
#define sFF37 "Serif italic 9"
#define sFF38 "Serif italic 12"
#define sFF39 "Serif italic 18"
#define sFF40 "Serif italic 24"
#define sFF41 "Serif bold 9"
#define sFF42 "Serif bold 12"
#define sFF43 "Serif bold 18"
#define sFF44 "Serif bold 24"
#define sFF45 "Serif bold italic 9"
#define sFF46 "Serif bold italic 12"
#define sFF47 "Serif bold italic 18"
#define sFF48 "Serif bold italic 24"
#else // LOAD_tftFF not defined so setup defaults to prevent error messages
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// Free fonts are not loaded in User_Setup.h so we must define all as font 1
// to prevent compile error messages
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define GFXFF 1
#define GLCD 1
#define FONT2 2
#define FONT4 4
#define FONT6 6
#define FONT7 7
#define FONT8 8
#define FF0 1
#define FF1 1
#define FF2 1
#define FF3 1
#define FF4 1
#define FF5 1
#define FF6 1
#define FF7 1
#define FF8 1
#define FF9 1
#define FF10 1
#define FF11 1
#define FF12 1
#define FF13 1
#define FF14 1
#define FF15 1
#define FF16 1
#define FF17 1
#define FF18 1
#define FF19 1
#define FF20 1
#define FF21 1
#define FF22 1
#define FF23 1
#define FF24 1
#define FF25 1
#define FF26 1
#define FF27 1
#define FF28 1
#define FF29 1
#define FF30 1
#define FF31 1
#define FF32 1
#define FF33 1
#define FF34 1
#define FF35 1
#define FF36 1
#define FF37 1
#define FF38 1
#define FF39 1
#define FF40 1
#define FF41 1
#define FF42 1
#define FF43 1
#define FF44 1
#define FF45 1
#define FF46 1
#define FF47 1
#define FF48 1
#define FM9 1
#define FM12 1
#define FM18 1
#define FM24 1
#define FMB9 1
#define FMB12 1
#define FMB18 1
#define FMB24 1
#define FMO9 1
#define FMO12 1
#define FMO18 1
#define FMO24 1
#define FMBO9 1
#define FMBO12 1
#define FMBO18 1
#define FMBO24 1
#define FSS9 1
#define FSS12 1
#define FSS18 1
#define FSS24 1
#define FSSB9 1
#define FSSB12 1
#define FSSB18 1
#define FSSB24 1
#define FSSO9 1
#define FSSO12 1
#define FSSO18 1
#define FSSO24 1
#define FSSBO9 1
#define FSSBO12 1
#define FSSBO18 1
#define FSSBO24 1
#define FS9 1
#define FS12 1
#define FS18 1
#define FS24 1
#define FSI9 1
#define FSI12 1
#define FSI19 1
#define FSI24 1
#define FSB9 1
#define FSB12 1
#define FSB18 1
#define FSB24 1
#define FSBI9 1
#define FSBI12 1
#define FSBI18 1
#define FSBI24 1
#endif // LOAD_tftFF

View File

@ -0,0 +1,201 @@
// Slider widget demo, requires display with touch screen
// Requires widget library here:
// https://github.com/Bodmer/TFT_eWidget
#include "FS.h"
#include <LittleFS.h>
#include "Free_Fonts.h" // Include the header file attached to this sketch
#include <TFT_eSPI.h>
#include <TFT_eWidget.h> // Widget library
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite knob = TFT_eSprite(&tft); // Sprite for the slide knob
#define CALIBRATION_FILE "/TouchCalData1"
#define REPEAT_CAL false
SliderWidget s1 = SliderWidget(&tft, &knob); // Slider 1 widget
SliderWidget s2 = SliderWidget(&tft, &knob); // Slider 2 widget
void setup() {
Serial.begin(115200);
tft.begin();
tft.setRotation(0);
tft.fillScreen(TFT_BLACK);
tft.setFreeFont(FF18);
// Calibrate the touch screen and retrieve the scaling factors
if (REPEAT_CAL) {
touch_calibrate();
tft.fillScreen(TFT_BLACK);
}
// Create a parameter set for the slider
slider_t param;
// Slider slot parameters
param.slotWidth = 9; // Note: ends of slot will be rounded and anti-aliased
param.slotLength = 200; // Length includes rounded ends
param.slotColor = TFT_BLUE; // Slot colour
param.slotBgColor = TFT_BLACK; // Slot background colour for anti-aliasing
param.orientation = H_SLIDER; // sets it "true" for horizontal
// Slider control knob parameters (smooth rounded rectangle)
param.knobWidth = 15; // Always along x axis
param.knobHeight = 25; // Always along y axis
param.knobRadius = 5; // Corner radius
param.knobColor = TFT_WHITE; // Anti-aliased with slot backgound colour
param.knobLineColor = TFT_RED; // Colour of marker line (set to same as knobColor for no line)
// Slider range and movement speed
param.sliderLT = 0; // Left side for horizontal, top for vertical slider
param.sliderRB = 100; // Right side for horizontal, bottom for vertical slider
param.startPosition = 50; // Start position for control knob
param.sliderDelay = 0; // Microseconds per pixel movement delay (0 = no delay)
// Create slider using parameters and plot at 0,0
s1.drawSlider(0, 0, param);
// Show bounding box (1 pixel outside slider working area)
int16_t x, y; // x and y can be negative
uint16_t w, h; // Width and height
s1.getBoundingRect(&x, &y, &w, &h); // Update x,y,w,h with bounding box
tft.drawRect(x, y, w, h, TFT_DARKGREY); // Draw rectangle outline
/*
// Alternative discrete fns to create/modify same slider - but fn sequence is important...
s1.createSlider(9, 200, TFT_BLUE, TFT_BLACK, H_SLIDER);
s1.createKnob(15, 25, 5, TFT_WHITE, TFT_RED);
s1.setSliderScale(0, 100);
s1.drawSlider(0, 0);
*/
delay(1000);
s1.setSliderPosition(50);
delay(1000);
s1.setSliderPosition(100);
// Update any parameters that are different for slider 2
param.slotWidth = 4;
param.orientation = V_SLIDER; // sets it "false" for vertical
param.knobWidth = 19;
param.knobHeight = 19;
param.knobRadius = 19/2; // Half w and h so creates a circle
param.sliderLT = 200; // Top for vertical slider
param.sliderRB = 0; // Bottom for vertical slider
param.sliderDelay = 2000; // 2ms per pixel movement delay (movement is blocking until complete)
s2.drawSlider(0, 50, param);
s2.getBoundingRect(&x, &y, &w, &h);
tft.drawRect(x, y, w, h, TFT_DARKGREY);
/*
// Alternative discrete fns to create/modify same slider - but fn sequence is important...
s2.createSlider(4, 200, TFT_BLUE, TFT_BLACK, V_SLIDER);
s2.createKnob(19, 19, 9, TFT_WHITE, TFT_RED);
s2.setSliderScale(200, 0, 2000);
s2.drawSlider(0, 50);
*/
// Move slider under software control
delay(1000);
s2.setSliderPosition(50);
delay(1000);
s2.setSliderPosition(100);
}
void loop() {
static uint32_t scanTime = millis();
uint16_t t_x = 9999, t_y = 9999; // To store the touch coordinates
// Scan for touch every 50ms
if (millis() - scanTime >= 20) {
// Pressed will be set true if there is a valid touch on the screen
if( tft.getTouch(&t_x, &t_y, 250) ) {
if (s1.checkTouch(t_x, t_y)) {
Serial.print("Slider 1 = "); Serial.println(s1.getSliderPosition());
}
if (s2.checkTouch(t_x, t_y)) {
Serial.print("Slider 2 = "); Serial.println(s2.getSliderPosition());
}
}
scanTime = millis();
}
//s1.moveTo(random(101));
//delay(250);
//s2.moveTo(random(101));
//delay(250);
}
void touch_calibrate()
{
uint16_t calData[5];
uint8_t calDataOK = 0;
// check file system exists
if (!LittleFS.begin()) {
Serial.println("Formating file system");
LittleFS.format();
LittleFS.begin();
}
// check if calibration file exists and size is correct
if (LittleFS.exists(CALIBRATION_FILE)) {
if (REPEAT_CAL)
{
// Delete if we want to re-calibrate
LittleFS.remove(CALIBRATION_FILE);
}
else
{
File f = LittleFS.open(CALIBRATION_FILE, "r");
if (f) {
if (f.readBytes((char *)calData, 14) == 14)
calDataOK = 1;
f.close();
}
}
}
if (calDataOK && !REPEAT_CAL) {
// calibration data valid
tft.setTouch(calData);
} else {
// data not valid so recalibrate
tft.fillScreen(TFT_BLACK);
tft.setCursor(20, 0);
tft.setTextFont(2);
tft.setTextSize(1);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.println("Touch corners as indicated");
tft.setTextFont(1);
tft.println();
if (REPEAT_CAL) {
tft.setTextColor(TFT_RED, TFT_BLACK);
tft.println("Set REPEAT_CAL to false to stop this running again!");
}
tft.calibrateTouch(calData, TFT_MAGENTA, TFT_BLACK, 15);
tft.setTextColor(TFT_GREEN, TFT_BLACK);
tft.println("Calibration complete!");
// store data
File f = LittleFS.open(CALIBRATION_FILE, "w");
if (f) {
f.write((const unsigned char *)calData, 14);
f.close();
}
}
}