/*
This is for the wood box controller with a color display.
It has the following components:
A 3.5" tft color 480x360 color display shield with a micro SD socket,
An ATMEGA 2560 Rev3 Arduino,
An intermediary proto shield with attached battery charger and discrete components,
A 3-way toggle switch and an incremental encoder with pushbutton,
An RC8803 real-time clock-calendar,
A DME688 environmental sensor,
John Saunders 1/17/2022
*/
// --------------- Display includes, etc ---------------
#include <MCUFRIEND_kbv.h> // Hardware-specific library
#include <Adafruit_GFX.h> // Core graphics library
#include <EEPROM.h>
#include <FreeDefaultFonts.h>
#include <Fonts/FreeSerif18pt7b.h>
#include <Fonts/FreeSans24pt7b.h>
MCUFRIEND_kbv tft;
#define BLACK 0x0000
#define RED 0xF800
#define ORANGE 0xFDA0
#define YELLOW 0xFFE0
#define GREEN 0x07E0
#define WHITE 0xFFFF
#define BLUE 0X00FF
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define GREY 0x8410
#define ID 0x9486
// -------- Secure Digital Drive includes, etc -----------
#include <SPI.h>
#include <SD.h>
#define SS 53
#define CMDS 67
#define DISPS 68
// --------------- RTC includes, etc ---------------
#include <SparkFun_RV8803.h>
RV8803 rtc;
// --------------- DME688 includes, etc ---------------
#include "Zanshin_BME680.h"
BME680_Class BME680;
// ------------ Control & Sensing defines ---------------
#define SWUP 22 // Toggle switch up, low active
#define SWDN 24 // Toggle switch dowwn, low active
#define usbTestPort A5
#define testControlPort 47
#define HOMEPAGE 15
#define INFOPAGE 11
#define PAGE2 12
#define PAGE3 14
#define PAGE4 10
#define PAGE5 8
#define PAGE6 0
#define PAGE1 13
#define ADJHOUR 7
#define ADJWD 5
#define ADJDATE 4
#define ADJMONTH 6
#define ADJYEAR 2
#define ADJMIN 3
#define SETTEMP 9
#define SETPRESS 1
// ------------ Constants -----------------------
const int bigTimeLoc = 150;
const int infoTimeLoc = 240;
const int adjFlagLoc = 260;
const uint8_t hiLimit[5] = {59, 23, 6, 31, 11};
const uint8_t loLimit[5] = { 0, 0, 0, 1, 0};
const int hiMode = 368;
// const int loMode = 301;
const int loMode = 280; //11/17/2022
const int tempEAddr = 5;
const int pressEAddr = 7;
const String days[7] = {
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
};
const String months[12] = {
"January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"
};
const String hdrText[] = {
"Living Room Lights", "Outside Lights", "Cube Alarm", "Atmosphere", "Color LED Display", "Tower Display"
};
const byte codeType[] = {
CMDS, CMDS, CMDS, DISPS, DISPS, DISPS
};
const int onPos = 330;
const int offPos = 400;
const int codePos = 380;
const int numPlates = 87;
const int numUnames = 14;
const int numCaps = 40;
const int numFiles = 18;
// The program shows an 8-character password with lower and upper-case letters,
// numbers and symbols from plates and caps.
// The combination is a 6-number code in a file on a micro SD chip, including
// the login name from unames.
const String plates[numPlates] = {
// 0 1 2 3 4 5 6 7 8 9
"00to09","Betsy2","gh7097","yrb598","Midnig","A399/6","fgh345","4pty14","Betsy2","2+5:3”
"10to19","6ksub3","312spa","132spa","2aur32","bla649","5y4499","681frg","6ksub3","aa01a3”
”20to29","dhy790","1cF228","bny289","betsy2","fcc832","2cf460","dfg265","dhy790","4dkj21”
”30to39","gnr490","fvv775","1fr662","jqw061","kgy114","ghe136","ghj345","gnr490","jgh345”
"40to49","kku966","khh678","khh644","kvp773","2kwn25","khh669","khj284","kku966","kpd247”
"50to59","mcj782","lhh678","le7926","mnb293","old861","lkl947","2m8782","mcj782","mdt700”
”60to69","pvo085","ptd922","ozk901","rzv493","sheel3","pty147","pty516","pvo085","pxj106”
”70to79","vhj491"," srarty","sna338","xvz665","yax738","suy808","tuk425","vhj491","wkc453”
”80to89","cvh140","sdp765","U49-pl","cvh140","dfg765","lsy942","jkl890"
};
const String unames[numUnames] = {
// 0 1 2 3
//Deleted for security. These are actual email addresses or login names
// 4 5 6 7 8 9
//Deleted for security
// 10 11 12 13
//Deleted for security};
const String caps[numCaps] = { // These are made up
//0 1 2 3 4 5 6 7 8 9
//Deleted for security. These are two additional characters
//10 1 2 3 4 5 6 7 8 9
//Deleted for security
//20 1 2 3 4 5 6 7 8 9
//Deleted for security
//30 1 2 3 4 5 6 7 8 9
//Deleted for security
"};
String filenameList[numFiles] = {
// 0 1 2 3 4 5
"C00", "C01", "C02", "D00", "D01", "D02",
// 6 7 8 9 10 11
"W01", "W02", "W03", "W04", "W05", "W06",
//12 13 14 15 16 17
"W07", "W08", "W09", "W10", "W11", "W12"
};
enum enumTimeDate {
EMIN, EHR, EWD, EDAT, EMTH
};
// ------------------------- Global Variables ---------------------
uint8_t nowInts[5]; //minutes,hours,weekday,date,month)
boolean chgFlag, modeFlag;
int tempFlag, pressFlag;
enumTimeDate setIndex;
uint8_t currSeconds, prevSeconds, prevMinutes, prevHours, prevWeekday;
uint16_t fullYear;
int32_t prevTemp, prevHumidity, prevPressure, prevGas, prevVccVolts;
int adjTimeLoc = 130;
int spacing = 43;
int indent = 5;
int pwPos = 320;
int ypos = 20;
bool sdInit; //11/17/2023
void setup() {
pinMode(SS, OUTPUT); // Wired CS pin for SDI
digitalWrite(SS, HIGH);
pinMode(testControlPort, OUTPUT);
digitalWrite(testControlPort, 0);
for (byte i = 22; i <= 34; i++) { //Controls
pinMode(i, INPUT_PULLUP);
}
// display
tft.begin(ID);
tft.setRotation(1);
tempFlag = EEPROM.read(tempEAddr);
pressFlag = EEPROM.read(pressEAddr);
analogReference(DEFAULT);
modeFlag = false;
// rtc
Wire.begin();
rtc.begin();
prevSeconds = 0;
prevMinutes = 0;
prevHours = 0;
fillTimeDate();
prevWeekday = nowInts[EWD];
chgFlag = false;
rtc.set24Hour();
tft.fillScreen(BLACK);
// BME688
BME680.begin(I2C_FAST_MODE); // Start BME680 using I2C protocol
BME680.setOversampling(TemperatureSensor, Oversample16); // Use enumerated type values
BME680.setOversampling(HumiditySensor, Oversample16); // Use enumerated type values
BME680.setOversampling(PressureSensor, Oversample16); // Use enumerated type values
BME680.setIIRFilter(IIR4); // Use enumerated type values
BME680.setGas(320, 150); // 320�c for 150 milliseconds
randomSeed(rtc.getSeconds());
// delay(300);
delay(500); // 11/17/2022
// Secure Digital Drive
sdInit = SD.begin(SS); //11/17/2022
}
void loop() {
static int prevEncoderPosition = HOMEPAGE;
modeFlag = (analogRead(usbTestPort) < hiMode) && (analogRead(usbTestPort) > loMode);
if (modeFlag) {
adjTimeLoc = 120;
}
else {
adjTimeLoc = 130;
}
fillTimeDate();
int encoderPosition = digitalRead(26) + (2 * digitalRead(28)) + (4 * digitalRead(30)) + (8 * digitalRead(32));
if ((encoderPosition != prevEncoderPosition) || (nowInts[EWD] != prevWeekday)) {
tft.fillScreen(BLACK);
displayFixed(encoderPosition);
prevEncoderPosition = encoderPosition;
prevSeconds = 0;
prevMinutes = 0;
prevHours = 0;
}
displayVariable(encoderPosition);
}
// ------------------------- Second level Functions ---------------------
void fillTimeDate(void) {
rtc.updateTime();
currSeconds = rtc.getSeconds();;
nowInts[EMIN] = rtc.getMinutes();
nowInts[EHR] = rtc.getHours();
nowInts[EWD] = rtc.getWeekday();
nowInts[EDAT] = rtc.getDate();
nowInts[EMTH] = rtc.getMonth() - 1;
fullYear = rtc.getYear();
}
void setTimeDate(enumTimeDate index) {
switch (index) {
case EMIN:
rtc.setMinutes(nowInts[EMIN]);
break;
case EHR:
rtc.setHours(nowInts[EHR]);
break;
case EWD:
rtc.setWeekday(nowInts[EWD]);
break;
case EDAT:
rtc.setDate(nowInts[EDAT]);
break;
case EMTH:
rtc.setMonth((nowInts[EMTH] + 1));
break;
}
}
void displayTime(int row) {
if (row > 360) {
return;
}
tft.setFont(&FreeSerif18pt7b);
tft.setTextSize(1);
if (nowInts[EHR] != prevHours) {
tft.setCursor(10, row);
tft.setTextColor(BLACK);
tft.print(prevHours);
tft.setTextColor(WHITE);
tft.setCursor(10, row);
tft.print(nowInts[EHR]);
prevHours = nowInts[EHR];
}
if (nowInts[EMIN] != prevMinutes) {
tft.setCursor(60, row);
tft.setTextColor(BLACK);
tft.print(prevMinutes);
tft.setTextColor(WHITE);
tft.setCursor(60, row);
tft.print(nowInts[EMIN]);
prevMinutes = nowInts[EMIN];
}
}
void displayDate(int row) {
tft.setFont(&FreeSerif18pt7b);
tft.setTextColor(WHITE);
tft.setCursor(50, row);
tft.print(":");
tft.setCursor(105, row);
tft.print(days[nowInts[EWD]]);
tft.setCursor(105, (row + 45));
tft.print(months[nowInts[EMTH]]);
tft.print(" ");
tft.print(nowInts[EDAT]);
tft.print(" ");
tft.print(fullYear);
prevWeekday = nowInts[EWD];
}
void displayHeading(byte indx) {
const int vlc1Pos = 350;
const int vlc2Pos = 422;
const int vldPos = 420;
const int hlPos = 50;
indent = 10;
ypos = 35;
tft.setFont(&FreeSerif18pt7b);
tft.setTextColor(WHITE);
tft.setCursor(indent, ypos);
tft.print(hdrText[indx]);
if (codeType[indx] == CMDS) {
tft.drawFastVLine(vlc1Pos, hlPos, 300, GREEN);
tft.setCursor(onPos, ypos);
tft.print("ON");
tft.drawFastVLine(vlc2Pos, hlPos, 300, GREEN);
tft.setCursor(offPos, ypos);
tft.print("OFF");
}
else {
tft.drawFastVLine(vldPos, hlPos, 300, GREEN);
tft.setCursor(codePos, ypos);
tft.print("CODE");
}
tft.drawFastHLine(0, hlPos, 475, GREEN);
}
void Adjust(enumTimeDate indx) {
if (modeFlag) {
return;
}
if (!chgFlag) {
if (digitalRead(SWUP) == 0) {
if (nowInts[indx] < hiLimit[indx]) {
nowInts[indx]++;
}
else {
nowInts[indx] = loLimit[indx];
}
chgFlag = true;
setIndex = indx;
}
if (digitalRead(SWDN) == 0) {
if (nowInts[indx] > loLimit[indx]) {
nowInts[indx]--;
}
else {
nowInts[indx] = hiLimit[indx];
}
chgFlag = true;
setIndex = indx;
}
if (chgFlag) {
setTimeDate(indx);
fillTimeDate();
displayTime(adjTimeLoc);
tft.fillRect(105, (adjTimeLoc - 42), 300, 80, BLACK);
displayDate(adjTimeLoc);
chgFlag = false;
while ((digitalRead(SWUP) == 0) || (digitalRead(SWDN) == 0));
}
}
}
void adjustYear(void) {
if (modeFlag) {
return;
}
uint16_t currYear = rtc.getYear();
if (!chgFlag) {
if (digitalRead(SWUP) == 0) {
if (currYear < 2040) {
currYear++;
}
else {
currYear = 2000;
}
chgFlag = true;
}
if (digitalRead(SWDN) == 0) {
if (currYear > 1934) {
currYear--;
}
else {
currYear = 2000;
}
chgFlag = true;
}
if (chgFlag) {
rtc.setYear(currYear);
fillTimeDate();
displayTime(adjTimeLoc);
tft.fillRect(105, (adjTimeLoc - 31), 270, 80, BLACK);
displayDate(adjTimeLoc);
chgFlag = false;
while ((digitalRead(SWUP) == 0) || (digitalRead(SWDN) == 0));
}
}
}
// ------------ Top-level Display Functions ---------------
void displayWfile(byte filenameIndex) {
File myFile;
String filename;
char item;
int line = 0;
int numBuf[8];
int indx;
ypos = 22;
indent = 0;
spacing = 29;
if ((filenameIndex < 0) || (filenameIndex >= numFiles)) {
filenameIndex = 6;
}
filename = String("/");
filename += String(filenameList[filenameIndex]);
filename += String(".txt");
Serial.println(filename);
if (sdInit) { // 11/17/2022
myFile = SD.open(filename);
}
else {
sdInit = SD.begin(SS);
}
if (myFile) {
// read from the file until there's nothing else in it:
tft.fillScreen(BLACK);
tft.setCursor(indent, ypos);
tft.setFont(&FreeSerif18pt7b);
tft.setTextColor(WHITE);
while ((myFile.available()) && (digitalRead(SWDN) == 1)) {
for (int i = 0; i < 6; i ++) {
item = myFile.read();
numBuf[i] = item;
}
do {
item = myFile.read();
tft.print(item);
} while (item != '\n');
ypos += spacing;
tft.setCursor(indent, ypos);
indx = 10 * numBuf[0] + numBuf[1] - 528;
tft.print(unames[indx]);
tft.setCursor(pwPos, ypos);
indx = 10 * numBuf[2] + numBuf[3] - 528;
tft.print(plates[indx]);
indx = 10 * numBuf[4] + numBuf[5] - 528;
tft.print(caps[indx]);
line++;
if (line < 4) {
ypos += 20;
tft.drawFastHLine(0, ypos, 420, GREEN);
ypos += 10;
}
else {
break;
}
ypos += spacing;
tft.setCursor(indent, ypos);
}
}
else {
tft.setCursor(indent, 150);
tft.setFont(&FreeSerif18pt7b);
tft.print("Could not open file ");
tft.print(filename);
}
// close the file:
myFile.close();
delay(1000);
}
void displayList(byte filenameIndex) {
File myFile;
String filename;
char item;
ypos = 90;
indent = 0;
spacing = 32;
char codes[2];
if ((filenameIndex < 0) || (filenameIndex >= numFiles)) {
filenameIndex = 6;
}
filename = String("/");
filename += String(filenameList[filenameIndex]);
filename += String(".txt");
Serial.println(filename);
if (sdInit) {
myFile = SD.open(filename);
}
else {
sdInit = SD.begin(SS);
}
if (myFile) {
tft.setCursor(indent, ypos);
tft.setFont(&FreeSerif18pt7b);
while ((myFile.available()) && (digitalRead(SWDN) == 1)) {
for (int i = 0; i < 2; i ++) {
item = myFile.read();
codes[i] = item;
}
do {
item = myFile.read();
tft.print(item);
} while (item != '\n');
if (codeType[filenameIndex] == CMDS) {
tft.setCursor((onPos + 40), ypos);
tft.print(codes[0]);
tft.setCursor((offPos + 40), ypos);
tft.print(codes[1]);
}
else {
tft.setCursor((codePos + 50), ypos);
tft.print(codes[0]);
tft.print(codes[1]);
}
ypos += spacing;
tft.setCursor(indent, ypos);
}
}
else {
tft.setCursor(indent, 150);
tft.setFont(&FreeSerif18pt7b);
tft.print("Could not open file ");
tft.print(filename);
}
// close the file:
myFile.close();
}
void displayFixed(int pos) {
tft.setFont(&FreeSans24pt7b);
tft.setTextColor(CYAN);
tft.setTextSize(1);
tft.setCursor(10, 50);
switch (pos) {
case HOMEPAGE:
tft.setFont(&FreeSans24pt7b);
tft.setCursor(20, 50);
tft.setTextColor(WHITE);
tft.print("John's ");
tft.setTextColor(RED);
tft.print("C");
tft.setTextColor(ORANGE);
tft.print("O");
tft.setTextColor(YELLOW);
tft.print("L");
tft.setTextColor(GREEN);
tft.print("O");
tft.setTextColor(BLUE);
tft.print("R");
tft.setTextColor(WHITE);
tft.print(" Clock");
tft.setFont(&FreeSerif18pt7b);
tft.setTextSize(2);
tft.setCursor(150, bigTimeLoc);
tft.print(":");
tft.setCursor(250, bigTimeLoc);
tft.print(":");
tft.setTextSize(1);
tft.setCursor(20, 220);
tft.println(" John Saunders");
tft.println(" Designed and made it in 2022");
tft.print(" He was 88 years old!");
break;
case INFOPAGE:
displayDate(infoTimeLoc);
tft.setCursor(10, 35);
tft.setFont(&FreeSerif18pt7b);
tft.setTextColor(MAGENTA);
tft.print("Temperature = ");
tft.setCursor(330, 35);
tft.print((char)tempFlag);
tft.setCursor(10, 70);
tft.setTextColor(GREEN);
tft.print( "Humidity = ");
tft.setCursor(300, 70);
tft.print("%");
tft.setCursor(10, 105);
tft.setTextColor(YELLOW);
tft.print("Pressure = ");
tft.setCursor(300, 105);
if (pressFlag == 80) {
tft.print("hPa");
}
else {
tft.print("in Hg");
}
tft.setTextColor(CYAN);
tft.setCursor(10, 140);
tft.print( "Gas resistance = ");
tft.setTextColor(ORANGE);
tft.setCursor(10, 175);
tft.print( "USB Volts = ");
tft.setCursor(280, 175);
tft.print("V");
prevTemp = 0;
prevHumidity = 0;
prevPressure = 0;
prevGas = 0;
prevVccVolts = 0;
break;
case PAGE1:
displayHeading(0);
if (modeFlag) {
displayWfile(6);
}
else {
displayList(0);
}
break;
case PAGE2:
displayHeading(1);
if (modeFlag) {
displayWfile(7);
}
else {
displayList(1);
}
break;
case PAGE3:
displayHeading(2);
if (modeFlag) {
displayWfile(8);
}
else {
displayList(2);
}
break;
case PAGE4:
displayHeading(3);
if (modeFlag) {
displayWfile(9);
}
else {
displayList(3);
}
break;
case PAGE5:
displayHeading(4);
if (modeFlag) {
displayWfile(10);
}
else {
displayList(4);
}
break;
case PAGE6:
displayHeading(5);
if (modeFlag) {
displayWfile(11);
}
else {
displayList(5);
}
break;
case ADJHOUR:
spacing = 29;
ypos = 22;
indent = 0;
if (modeFlag) {
displayWfile(16);
}
else {
tft.print("Adjust Hour");
displayDate(adjTimeLoc);
}
break;
case ADJWD:
spacing = 29;
ypos = 22;
indent = 0;
if (modeFlag) {
displayWfile(15);
}
else {
tft.print("Adjust Weekday");
displayDate(adjTimeLoc);
}
break;
case ADJDATE:
spacing = 29;
ypos = 22;
indent = 0;
if (modeFlag) {
displayWfile(14);
}
else {
tft.print("Adjust Date");
displayDate(adjTimeLoc);
}
break;
case ADJMONTH:
spacing = 29;
ypos = 22;
indent = 0;
if (modeFlag) {
displayWfile(13);
}
else {
tft.print("Adjust Month");
displayDate(adjTimeLoc);
}
break;
case ADJYEAR:
spacing = 29;
ypos = 22;
indent = 0;
if (modeFlag) {
displayWfile(12);
}
else {
tft.print("AdjustYear");
displayDate(adjTimeLoc);
}
break;
case ADJMIN:
spacing = 29;
ypos = 22;
indent = 0;
if (modeFlag) {
displayWfile(17);
}
else {
tft.print("Adjust Minutes");
displayDate(adjTimeLoc);
}
break;
case SETTEMP:
if (modeFlag) {
tft.println(" Password Generator");
}
else {
tft.println("Set Temperature Units");
tft.setCursor(10, adjTimeLoc);
tft.print("Units set to ");
}
break;
case SETPRESS:
tft.print("Set Pressure Units");
tft.setCursor(10, adjTimeLoc);
tft.print("Units set to ");
break;
}
}
void displayVariable(int pos) {
const byte pwLoLimit[8] = { 97, 97, 97, 48, 48, 48, 35, 65};
const byte pwHiLimit[8] = {122, 122, 122, 57, 57, 57, 43, 90};
switch (pos) {
case HOMEPAGE:
tft.setFont(&FreeSerif18pt7b);
tft.setTextSize(2);
if (nowInts[EHR] != prevHours) {
tft.setCursor(75, bigTimeLoc);
tft.setTextColor(BLACK);
tft.print(prevHours);
tft.setTextColor(WHITE);
tft.setCursor(75, bigTimeLoc);
tft.print(nowInts[EHR]);
prevHours = nowInts[EHR];
}
if (nowInts[EMIN] != prevMinutes) {
tft.setCursor(175, bigTimeLoc);
tft.setTextColor(BLACK);
tft.print(prevMinutes);
tft.setTextColor(WHITE);
tft.setCursor(175, bigTimeLoc);
tft.print(nowInts[EMIN]);
prevMinutes = nowInts[EMIN];
}
if (currSeconds != prevSeconds) {
tft.setTextColor(BLACK);
tft.setCursor(275, bigTimeLoc);
tft.print(prevSeconds);
tft.setTextColor(WHITE);
tft.setCursor(275, bigTimeLoc);
tft.print(currSeconds);
prevSeconds = currSeconds;
}
break;
case INFOPAGE:
displayEnvironmental();
displayTime(infoTimeLoc);
break;
case PAGE2:
break;
case PAGE3:
break;
case PAGE4:
break;
case PAGE5:
break;
case PAGE6:
break;
case PAGE1:
break;
case ADJHOUR:
displayTime(adjTimeLoc);
Adjust(EHR);
break;
case ADJWD:
displayTime(adjTimeLoc);
Adjust(EWD);
break;
case ADJDATE:
displayTime(adjTimeLoc);
Adjust(EDAT);
break;
case ADJMONTH:
displayTime(adjTimeLoc);
Adjust(EMTH);
break;
case ADJYEAR:
displayTime(adjTimeLoc);
adjustYear();
break;
case ADJMIN:
displayTime(adjTimeLoc);
Adjust(EMIN);
break;
case SETTEMP:
tft.setTextColor(WHITE);
if (modeFlag) {
tft.fillRect(35, (adjTimeLoc - 40), 300, 50, BLACK);
tft.setCursor(40, adjTimeLoc);
for (int i = 0; i < 8; i++) {
tft.print((char)random(pwLoLimit[i], pwHiLimit[i]));
}
while (digitalRead(SWDN) == 1);
}
else {
tft.fillRect(adjFlagLoc, (adjTimeLoc - 40), 70, 50, BLACK);
tft.setCursor(adjFlagLoc, adjTimeLoc);
tft.print((char)tempFlag);
if ((digitalRead(SWUP) == 1) && (digitalRead(SWDN) == 1 )) {
delay(1000);
}
if (digitalRead(SWUP) == 0) {
tempFlag = 67;
tft.print("C");
EEPROM.write(tempEAddr, 67);
while (digitalRead(SWUP) == 0);
}
if (digitalRead(SWDN) == 0) {
tempFlag = 70;
tft.print("F");
EEPROM.write(tempEAddr, 70);
}
while (digitalRead(SWDN) == 0);
}
break;
case SETPRESS:
tft.fillRect(adjFlagLoc, (adjTimeLoc - 40), 110, 50, BLACK);
tft.setCursor(adjFlagLoc, adjTimeLoc);
tft.setTextColor(WHITE);
if (pressFlag == 80) {
tft.print("hPa");
}
else {
tft.print("in Hg");
}
if ((digitalRead(SWUP) == 1) && (digitalRead(SWDN) == 1 )) {
delay(1000);
}
if (digitalRead(SWUP) == 0) {
pressFlag = 80;
tft.fillRect(adjFlagLoc, (adjTimeLoc - 40), 110, 50, BLACK);
tft.setCursor(adjFlagLoc, (adjTimeLoc));
tft.setTextColor(WHITE);
tft.print("hPa");
EEPROM.write(pressEAddr, 80);
while (digitalRead(SWUP) == 0);
}
if (digitalRead(SWDN) == 0) {
pressFlag = 72;
tft.fillRect(adjFlagLoc, (adjTimeLoc - 40), 110, 50, BLACK);
tft.setCursor(adjFlagLoc, adjTimeLoc);
tft.setTextColor(WHITE);
tft.print("in Hg");
EEPROM.write(pressEAddr, 72);
while (digitalRead(SWDN) == 0);
}
break;
}
}
void displayEnvironmental(void) {
boolean changed = false;
int32_t temp, humidity, pressure, gas, vccVolts; // Variable to store readings
int32_t altVal;
char buf[15];
digitalWrite(testControlPort, 1);
altVal = analogRead(usbTestPort);
digitalWrite(testControlPort, 0);
vccVolts = 244736 / altVal;
BME680.getSensorData(temp, humidity, pressure, gas);
delay(50);
delay(50); tft.setFont(&FreeSerif18pt7b);
if (temp != prevTemp) {
tft.fillRect(220, 12, 95, 35, BLACK);
prevTemp = temp;
if (tempFlag == 67) {
altVal = temp;
}
else {
altVal = (temp * 9.0) / 5.0;
altVal += 3200;
}
tft.setTextColor(MAGENTA);
tft.setCursor(225, 35);
sprintf(buf, "%3d.%01d", (int8_t)(altVal / 100), (uint8_t)(altVal % 100)); // Temperature in decidegrees
tft.print(buf);
changed = true;
}
if (humidity != prevHumidity) {
tft.fillRect(160, 40, 115, 35, BLACK);
prevHumidity = humidity;
tft.setCursor(170, 70);
tft.setTextColor(GREEN);
sprintf(buf, "%3d.%01d", (int8_t)(humidity / 1000), (uint16_t)(humidity % 1000)); // Humidity in milli-percent
tft.print(buf);
changed = true;
}
if (pressure != prevPressure) {
tft.fillRect(170, 75, 115, 35, BLACK);
if (pressFlag == 80) {
altVal = pressure;
}
else {
altVal = pressure * 0.02983;
}
prevPressure = pressure;
tft.setCursor(150, 105);
tft.setTextColor(YELLOW);
sprintf(buf, "%7d.%01d", (int16_t)(altVal / 100), (uint8_t)(altVal % 100)); // Pressure in hepa Pascals or in Hg
tft.print(buf);
changed = true;
}
if (gas != prevGas) {
tft.fillRect(320, 110, 105, 35, BLACK);
prevGas = gas;
tft.setCursor(250, 140);
tft.setTextColor(CYAN);
sprintf(buf, "%4d.%01d", (int16_t)(gas / 100), (uint8_t)(gas % 100)); // Resistance in milliohms
tft.print(buf);
changed = true;
}
if (vccVolts != prevVccVolts) {
tft.fillRect(160, 145, 105, 35, BLACK);
prevVccVolts = vccVolts;
tft.setCursor(200, 175);
tft.setTextColor(ORANGE);
sprintf(buf, "%1d.%02d", (int16_t)(vccVolts / 100), (uint8_t)(vccVolts % 100)); // Resistance in milliohms
tft.print(buf);
changed = true;
}
if (changed) {
delay(1000);
}