// INCLUDES *******************************************************************
#include <RTClib.h>
// #include "OCR_A_Extended24.h"
// #include "OCR_A_Extended16.h"
#include <TFT_eSPI.h> // Graphics and font library for ILI9341 driver chip
#include <SPI.h>
#include "dht_nonblocking.h"
// DEFINES ********************************************************************
RTC_DS3231 rtc;
#define DHT_SENSOR_TYPE DHT_TYPE_22
#define GFXFF 1
#define OCRA24 OCR_A_Extended24
#define OCRA16 OCR_A_Extended16
#define K TFT_BLACK
#define W TFT_WHITE
#define R TFT_RED
#define G tft.color565(100, 100, 100)
#define G2 tft.color565(150, 150, 150)
const int GRAPH_HEIGHT = 162;
const int GRAPH_WIDTH = 270;
const int XAXIS_HEIGHT = 15;
const int XAXIS_WIDTH = 320;
const int GRAPHX = 25;
const int GRAPHY = 40;
const int XAXISX = 0;
const int XAXISY = 210;
// GLOBALS ********************************************************************
static const int xmin = 0;
static const int xmax = 100;
static const int ymin = 20;
static const int ymax = 100;
static const int ydivs = 10;
char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thur", "Fri", "Sat"};
char monthsOfTheYear[12][10] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov","Dec"};
char twelveHour[2][4] = {"AM", "PM"};
static const int DHT_SENSOR_PIN = 13;
DHT_nonblocking dht_sensor(DHT_SENSOR_PIN, DHT_SENSOR_TYPE);
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite graph = TFT_eSprite(&tft);
TFT_eSprite xaxis = TFT_eSprite(&tft);
TFT_eSprite dt = TFT_eSprite(&tft);
int grid;
int gridWidth = 0;
int ysections = (ymax - ymin) / ydivs;
int yincr = GRAPH_HEIGHT / ysections;
const int xincr = 15;
bool isGraphScrolling = false;
int c = 0;
int minuteCounter = 0;
unsigned long previous_measurement;
int xmodulo;
// FUNCTIOMNS AND METHODDS ====================================================
void setup() {
Serial.begin(115200);
while (!Serial);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1) delay(10);
}
tft.init();
tft.fillScreen(K);
tft.setRotation(1);
tft.setTextColor(W);
tft.setTextDatum(MR_DATUM); // Middle right text datum
tft.drawNumber(ymin, 20, (GRAPH_HEIGHT + GRAPHY));
for(int i = 1; i <= ysections; i++){
tft.drawNumber((i*ydivs) + ymin, 20, GRAPH_HEIGHT - (yincr * i) + GRAPHY);
}
tft.setTextDatum(ML_DATUM);
tft.drawNumber(ymin, (GRAPH_WIDTH + GRAPHX) + 5, (GRAPH_HEIGHT + GRAPHY));
for(int i = 1; i <= ysections; i++){
tft.drawNumber((i*ydivs) + ymin, (GRAPH_WIDTH + GRAPHX) + 5, GRAPH_HEIGHT - (yincr * i) + GRAPHY);
}
tft.drawRect(GRAPHX - 1, GRAPHY - 1, GRAPH_WIDTH + 2, GRAPH_HEIGHT + 2, G);
xaxis.setColorDepth(8);
graph.setColorDepth(8);
dt.setColorDepth(8);
xaxis.createSprite(XAXIS_WIDTH, XAXIS_HEIGHT);
graph.createSprite(GRAPH_WIDTH, GRAPH_HEIGHT);
dt.createSprite(GRAPH_WIDTH + 10, XAXIS_HEIGHT);
xaxis.fillSprite(K);
graph.fillSprite(K);
dt.fillSprite(K);
dt.setTextColor(W, K);
xaxis.setTextColor(W);
xaxis.setTextDatum(CC_DATUM);
for(int i = GRAPHX + xincr; i <= (GRAPH_WIDTH + xincr); i += xincr){
minuteCounter++;
if(minuteCounter % 5 == 0){
if(minuteCounter < 10){
xaxis.drawString(":0" + String(minuteCounter), i, 5);
}else{
xaxis.drawString(":" + String(minuteCounter), i, 5);
}
}else{
xaxis.drawFastVLine(i, 2, 3, G);
}
}
graph.drawFastHLine(0, GRAPH_HEIGHT, GRAPH_WIDTH, G);
for (int p = 0; p <= ysections; p++){
graph.drawFastHLine(0, GRAPH_HEIGHT - (yincr * p), GRAPH_WIDTH, G);
}
for(int q = xincr; q <= GRAPH_WIDTH; q += xincr){
graph.drawFastVLine(q, 0, GRAPH_HEIGHT, G);
c++;
}
xmodulo = GRAPH_WIDTH % xincr;
if(xmodulo == 0) xmodulo = xincr;
grid = (xmodulo == 0) ? xincr : xmodulo;
xaxis.pushSprite(XAXISX, XAXISY);
dt.pushSprite(25, 225);
// dt.loadFont(OCRA16);
// tft.loadFont(OCRA24);
}
float getX(float xval){
float gx = 0.5 + (((GRAPH_WIDTH - 0) * (xval - xmin)) / (xmax - xmin));
return GRAPHX + gx;
}
float getY(float yval){
float gy = 0.5 + (((GRAPH_HEIGHT - 0) * (yval - ymin)) / (ymax - ymin));
return GRAPHY + gy;
}
static bool measure_environment(float *temperature, float *humidity){
static unsigned long measurement_timestamp = millis();
/* Measure once every four seconds. */
previous_measurement = millis() - measurement_timestamp;
if( previous_measurement > 3800ul){
if(dht_sensor.measure( temperature, humidity) == true){
measurement_timestamp = millis();
return(true);
}
}
return(false);
}
//==========================================================================================
void loop() {
float temperature;
float humidity;
float fahrenheit = 0.1;
DateTime now = rtc.now();
if(isGraphScrolling == false && gridWidth >= GRAPH_WIDTH) isGraphScrolling = true;
if( measure_environment(&temperature, &humidity) == true){
fahrenheit = ((temperature * 9) / 5) + 32;
tft.setTextPadding(80);
tft.setTextDatum(TL_DATUM);
tft.setTextColor(R, K);
tft.drawString("Temp: ", 8, 7, GFXFF);
tft.drawFloat(fahrenheit, 1, 83, 7, GFXFF);
tft.drawString("°", 143, 7);
tft.setTextColor(G2, K);
tft.drawString("Hum:", 175, 7);
tft.drawFloat(humidity, 1, 235, 7);
tft.drawString("%", 295, 7, GFXFF);
if(isGraphScrolling == false){
graph.drawFastVLine(gridWidth, (GRAPH_HEIGHT + GRAPHY) - getY(fahrenheit) + 3, 2, R);
graph.drawFastVLine(gridWidth, (GRAPH_HEIGHT + GRAPHY) - getY(humidity) + 3, 2, G2);
} else {
graph.drawFastVLine(GRAPH_WIDTH-1, (GRAPH_HEIGHT + GRAPHY) - getY(fahrenheit) + 3, 2, R);
graph.drawFastVLine(GRAPH_WIDTH-1, (GRAPH_HEIGHT + GRAPHY) - getY(humidity) + 3, 2, G2);
}
// Push the sprites onto the TFT at specified coordinates
graph.pushSprite(GRAPHX, GRAPHY);
xaxis.pushSprite(XAXISX, XAXISY);
dt.pushSprite(25, 225);
if(isGraphScrolling == true){
graph.scroll(-1, 0);
xaxis.scroll(-1, 0);
grid++;
} else {
gridWidth++;
}
int h = 0, m = 0;
if(isGraphScrolling == true){
if (grid >= xincr){
grid = 0;
graph.drawFastVLine(GRAPH_WIDTH - 1, 0, GRAPH_HEIGHT, G); // draw line on graph
minuteCounter++;
if(minuteCounter % 5 == 0){
if(minuteCounter > 59){
h = minuteCounter / 60;
}
m = minuteCounter % 60;
// xaxis.drawNumber(minuteCounter, GRAPH_WIDTH - 1 + GRAPHX, 0);
if(h < 1){
if(m < 10) xaxis.drawString(":0" + String(m), GRAPH_WIDTH - 1 + GRAPHX, 5);
else xaxis.drawString(":" + String(m), GRAPH_WIDTH - 1 + GRAPHX, 5);
}else{
if(m < 10) xaxis.drawString(String(h) + ":0" + String(m), GRAPH_WIDTH - 1 + GRAPHX, 5);
else xaxis.drawString(String(h) + ":" + String(m), GRAPH_WIDTH - 1 + GRAPHX, 5);
}
} else {
xaxis.drawFastVLine(GRAPH_WIDTH - 1 + GRAPHX, 2, 3, G);
}
} else { // Otherwise draw points spaced 10 pixels for the horizontal grid lines
graph.drawPixel(GRAPH_WIDTH-1, GRAPH_HEIGHT, G);
for (int p = 0; p <= ysections; p++){
graph.drawPixel(GRAPH_WIDTH-1, GRAPH_HEIGHT - (yincr * p), G);
}
}
}
}
dt.setTextDatum(CC_DATUM);
dt.setTextPadding(50);
char buf[] = "hh:mm:ss";
dt.drawString(String(daysOfTheWeek[now.dayOfTheWeek()]) + ", " + String(monthsOfTheYear[now.month()]) + " " + String(now.day()) + " | " + now.toString(buf), GRAPH_WIDTH / 2, 10);
dt.pushSprite(25, 225);
}
//==========================================================================================