/* ESP32 Temperature Sensor
A analog meter for temperature
*/
#include <TFT_eSPI.h>
#include <SPI.h> // this is needed for display
// The display also uses hardware SPI, plus #9 & #10
#define TFT_CS 15
#define TFT_DC 2
#define TFT_MOSI 23
#define TFT_SCLK 18
#define TFT_GREY 0x5AEB
#define TFT_ORANGE 0xFD20 /* 255, 165, 0 */
TFT_eSPI tft = TFT_eSPI(); // Invoke custom library with default width and height
TFT_eSprite back = TFT_eSprite(&tft);
TFT_eSprite needle = TFT_eSprite(&tft);
#define CENTER_X tft.width() / 2
#define NEEDLE_WIDTH 20
#define NEEDLE_HEIGHT 80
#define BACK_WIDTH 170
#define BACK_HEIGHT 170
#define M_SIZE 0.667
void setup(void) {
Serial.begin(115200);
tft.begin();
tft.setRotation(0);
tft.setPivot(CENTER_X, CENTER_X);
Serial.println("TFT set up");
back.createSprite(BACK_WIDTH, BACK_HEIGHT);
needle.createSprite(NEEDLE_WIDTH, NEEDLE_HEIGHT);
drawMeterTicks();
}
void loop() {
delay(10);
renderAnimationFrame();
}
int angle = 270;
void renderAnimationFrame() {
// This needs to be here because we have to refresh where the needle used to be
back.fillCircle(85, 85, 45, TFT_BLACK);
needle.fillSprite(TFT_BLACK);
needle.drawWedgeLine(10, 0, 10, 40, 1, 10, TFT_RED);
needle.pushRotated(&back, angle, TFT_BLACK);
back.pushSprite(0, 0);
angle++;
if (angle >= 360) angle = 0;
if (angle >= 90 && angle <= 270) angle = 270;
}
void drawMeterTicks() {
for (int i = -50; i < 51; i += 5) {
// Long scale tick length
int tl = 15;
// Coordinates of tick to draw
float sx = cos((i - 90) * 0.0174532925);
float sy = sin((i - 90) * 0.0174532925);
uint16_t x0 = sx * (M_SIZE*100 + tl) + M_SIZE*120;
uint16_t y0 = sy * (M_SIZE*100 + tl) + M_SIZE*150;
uint16_t x1 = sx * M_SIZE*100 + M_SIZE*120;
uint16_t y1 = sy * M_SIZE*100 + M_SIZE*150;
// Coordinates of next tick for zone fill
float sx2 = cos((i + 5 - 90) * 0.0174532925);
float sy2 = sin((i + 5 - 90) * 0.0174532925);
int x2 = sx2 * (M_SIZE*100 + tl) + M_SIZE*120;
int y2 = sy2 * (M_SIZE*100 + tl) + M_SIZE*150;
int x3 = sx2 * M_SIZE*100 + M_SIZE*120;
int y3 = sy2 * M_SIZE*100 + M_SIZE*150;
back.fillTriangle(x0, y0, x1, y1, x2, y2, TFT_WHITE);
back.fillTriangle(x1, y1, x2, y2, x3, y3, TFT_WHITE);
// Short scale tick length
if (i % 25 != 0) tl = 8;
// Recalculate coords incase tick lenght changed
x0 = sx * (M_SIZE*100 + tl) + M_SIZE*120;
y0 = sy * (M_SIZE*100 + tl) + M_SIZE*150;
x1 = sx * M_SIZE*100 + M_SIZE*120;
y1 = sy * M_SIZE*100 + M_SIZE*150;
// Draw tick
back.drawLine(x0, y0, x1, y1, TFT_BLACK);
// Check if labels should be drawn, with position tweaks
if (i % 25 == 0) {
// Calculate label positions
x0 = sx * (M_SIZE*100 + tl + 10) + M_SIZE*120;
y0 = sy * (M_SIZE*100 + tl + 10) + M_SIZE*150;
switch (i / 25) {
case -2: back.drawCentreString("-20", x0+4, y0-4, 1); break;
case -1: back.drawCentreString("-10", x0+2, y0, 1); break;
case 0: back.drawCentreString("0", x0, y0, 1); break;
case 1: back.drawCentreString("10", x0, y0, 1); break;
case 2: back.drawCentreString("20", x0-2, y0-4, 1); break;
}
}
// Now draw the arc of the scale
sx = cos((i + 5 - 90) * 0.0174532925);
sy = sin((i + 5 - 90) * 0.0174532925);
x0 = sx * M_SIZE*100 + M_SIZE*120;
y0 = sy * M_SIZE*100 + M_SIZE*150;
// Draw scale arc, don't draw the last part
if (i < 50) back.drawLine(x0, y0, x1, y1, TFT_BLACK);
}
}