#include <TFT_eSPI.h>
#include <SPI.h> // this is needed for display
#include <PNGdec.h>
#include "BG.h"
#include "Free_Fonts.h"
#define MAX_IMAGE_WIDTH 320
int16_t xpos = 0;
int16_t ypos = 0;
#include "NotoSansBold15.h"
#define CF_OL24 &Orbitron_Light_24
#define CF_OL32 &Orbitron_Light_32
#define CF_RT24 &Roboto_Thin_24
// 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
//gauge geometry
const int gauge_w = 250;
const int gauge_h = 20;
const int gauge_r = 5;
const int gauge_t = 2;
//gauge colours
const int gauge_border = 0x6b6d;
const int gauge_back = 0x4208;
const int gauge_fill = TFT_MAROON;
//gauge location
const int gauge_x = 5;
const int gauge_y = 30;
const int gauge_spacing = 30;
//ballast status variables
int ballast_port;
int ballast_port_old;
const int port_pin = 34;
int ballast_kgb;
int ballast_kgb_old;
int ballast_stbd;
int ballast_stbd_old;
PNG png;
//init TFT
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite background = TFT_eSprite(&tft);
//create sprite to hold background image (320x170)
void initPNGBack(TFT_eSprite &sprite) {
sprite.createSprite(320, 170);
int16_t rc = png.openFLASH((uint8_t *)BG, sizeof(BG), pngDraw);
Serial.println(rc);
if (rc == PNG_SUCCESS) {
Serial.println("Successfully opened png file");
sprite.startWrite();
rc = png.decode(NULL, 0);
sprite.endWrite();
}
}
//draw backdround sprite and screen label
void drawPNGBack(char* label) {
background.pushSprite(0, 0);
tft.setFreeFont(CF_OL24);
tft.setTextDatum(MC_DATUM);
tft.setTextSize(1);
tft.setCursor(5, 20);
tft.print(label);
}
//helper function to draw PNG
void pngDraw(PNGDRAW *pDraw) {
uint16_t lineBuffer[MAX_IMAGE_WIDTH];
png.getLineAsRGB565(pDraw, lineBuffer, PNG_RGB565_BIG_ENDIAN, 0xffffffff);
background.pushImage(xpos, ypos + pDraw->y, pDraw->iWidth, 1, lineBuffer);
}
//draw gauge outline and label at given position
void initGauge(int x, int y, char* label) {
int txt_corr = 5;
// Load the font
//tft.loadFont(NotoSansBold15);
tft.setFreeFont(FSS9);
tft.setTextSize(1);
tft.setTextDatum(BL_DATUM);
tft.setCursor(x, y + gauge_h / 2 + txt_corr);
tft.print(label);
tft.fillSmoothRoundRect(x + 50, y, gauge_w, gauge_h, gauge_r, gauge_border, TFT_BLACK);
tft.fillSmoothRoundRect(x + 50 + gauge_t, y + gauge_t, gauge_w - 2 * gauge_t, gauge_h - 2 * gauge_t, gauge_r - gauge_t, gauge_back, gauge_border);
}
//update gauge
void updateGauge(int x, int y, float progress) {
int fore_start = x + 50 + gauge_t;
float fore_width = (gauge_w - 2 * gauge_t) * (progress / 100);
float back_start = fore_width - 5 + fore_start;
float back_width = (gauge_w - 2 * gauge_t) - fore_width + 5;
if (progress <= 5) {
tft.fillSmoothRoundRect(x + 50 + gauge_t, y + gauge_t, gauge_w - 2 * gauge_t, gauge_h - 2 * gauge_t, gauge_r - gauge_t, gauge_back, gauge_border);
tft.fillSmoothRoundRect(x + 50 + gauge_t, y + gauge_t, 5, gauge_h - 2 * gauge_t, gauge_r - gauge_t, gauge_fill, gauge_border);
} else {
tft.fillSmoothRoundRect(back_start, y + gauge_t, back_width, gauge_h - 2 * gauge_t, gauge_r - gauge_t, gauge_back, gauge_border);
tft.fillSmoothRoundRect(fore_start, y + gauge_t, fore_width, gauge_h - 2 * gauge_t, gauge_r - gauge_t, gauge_fill, gauge_border);
}
}
void drawGaugeSet() {
initGauge(gauge_x, gauge_y, "PORT");
initGauge(gauge_x, gauge_y + gauge_spacing, "KGB");
initGauge(gauge_x, gauge_y + gauge_spacing * 2, "STBD");
}
void drawDataScreen() {
drawPNGBack("DATA");
tft.setFreeFont(FSSBO24);
tft.setTextDatum(BC_DATUM);
tft.setTextSize(1);
tft.setCursor(120, 60);
tft.print(random(0,88));
tft.setTextSize(1);
tft.fillRect(5,70,60,60, gauge_back);
tft.setFreeFont(TT1);
tft.setCursor(6+30,65);
tft.print("PORT");
tft.setFreeFont(FSSB12);
tft.setCursor(6, 120);
tft.print(random(0,100));
}
void setup() {
Serial.begin(115200);
//init TFT
tft.init();
tft.setRotation(1);
tft.setTextSize(1);
tft.fillScreen(TFT_BLACK);
tft.setRotation(1);
initPNGBack(background); //build background sprite
drawPNGBack("BALLAST"); //push background sprite and label
drawGaugeSet(); //init gauges
}
void update_gauge(int &new_value, int &old_value, int pin, int x, int y) {
new_value = map(analogRead(pin), 0, 4095, 0, 100);
if (new_value != old_value) {
updateGauge(x, y, new_value);
old_value = new_value;
}
}
void loop() {
//ballast_port = map(analogRead(34), 0, 4095, 0, 100);
/*
if (ballast_port != ballast_port_old) {
updateGauge(gauge_x, gauge_y, ballast_port);
ballast_port_old = ballast_port;
}
*/
update_gauge(ballast_port, ballast_port_old, port_pin, gauge_x, gauge_y);
update_gauge(ballast_kgb, ballast_kgb_old, port_pin, gauge_x, gauge_y + gauge_spacing);
update_gauge(ballast_stbd, ballast_stbd_old, port_pin, gauge_x, gauge_y + gauge_spacing * 2);
delay(5000);
drawDataScreen();
}