I have been developing a project using the 1.8" TFT breakout. I have downloaded the Adafruit_GFX and Adafruit_ST7735 libraries from GitHub and was able to get the graphicstest sketch running.
I was unable to get the spitftbitmap example working. While the SD card initiated I always got a 'file not found' error.
I chocked that up as insignificant and continued developing my project.
But now, I'm wondering if there's something wrong with the TFT, my Arduino, the libraries, or my code - because very minor changes to my code cause the my program to go haywire.
I've attached the code I am using, and will try to describe some scenarios that inadvertently kill my code - none of which make sense to me.
As is, the code 'sort of' works. There is currently one glitch, in that when the system prints 'Aux Heat On' (line 244), it prints 'Aux Heat On#Heat Pump On'
Code: Select all
// Thermostat Code v0.2
// Ken Schnautz
// 2014 Jan 20
// Designed for use with a two-stage heat, one-stage cool unit;
// Heat pump with auxillary (electric) coils, A/C
// v0.1 -- Original code with options for (1) mode: HEAT
// v0.2 -- Added option for (2) additional modes: COOL, AUTO.
// Migrated 'is/wasCooling' and 'is/wasHeating' into HVAC routine.
// Added fanDelay to keep fan running temporarily upon entering Standby
// Added Heat2AuxTimeout to allow AUX to kick in if Heat pump can't keep up
// Added waitCycle to keep system from coming on immediately after turning off
// Added temp correction algorithm to help stabilize temp sensor with poor power stability
// Added global temp correction value
// v0.3 -- Added preliminary screen outputs
//------------------------
// Original System Wires:
// (R) Red - 24VAC
// (B) Blue - Common
// (W) White - Stage two heat (aux - electric strip)
// (T) Tan - Thermistor on outdoor unit
// (G) Green - Fan
// (X2) Black - Emergency (electric strip w/o compressor)
// (Y) Yellow - Stage one heat (Compressor - heat pump)
// (O) Orange - Reversing valve (for cooling)
// We will not be using (T) wire in this original code version.
//------------------------
//------------------------
// AdaFruit 1.8TFT Display
//------------------------
//#define sclk 13
//#define mosi 11
#define TFTcs 10
#define TFTdc 9
#define TFTrst -1 // was 8 -- reset
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
Adafruit_ST7735 tft = Adafruit_ST7735(TFTcs, TFTdc, TFTrst);
//------------------------
//PINS
#define mySetTemp 65.0
#define myVariance 2.0
#define TempCalibration 0.0 //temp seems to read low by 1.5 deg
#define PowerCorrection 0.0 //when relay is engaged, temp reads high by 3.51deg
#define modeHEAT 1
#define modeCOOL 2
#define modeAUTO 3
#define pinFAN 2
#define pinPUMP 3
#define pinAUX 4
#define pinCOOL 5
#define pinEMER 6
//ANALOG IN PINS
#define pinTEMP 0
//HVAC COMMANDS
#define cmdOFF 1
#define cmdFAN 2
#define cmdHEAT 3
#define cmdCOOL 4
#define cmdEMER 5
#define ON 1
#define OFF 0
#define tempArrayLength 20
#define fanDelay 120000 // Fan runs 1min after system turns off
#define waitCycle 300000 // Keeps the system from coming on within 2min of turning off
#define Heat2AuxTimeout 600000 // if Heat is run for this long, it switches to AUX heat instead
// Define Variables
int mode; // used for HVAC modes
unsigned long int timestamp; // used for timing operations
unsigned long int lastRunning; // used to keep track of when the unit turned off
unsigned long int lastStandby; // used to keep track of when the unit turned on
float T; //current temperature
float Traw[tempArrayLength]; // history of temp measurements, to be averaged into T
int Ts; //user's Temp Setpoint
int Tv; //allowable variance in temp
int Th; //calculated high temp limit
int Tl; //calculated low temp limit
boolean isHeating = 0;
boolean isCooling = 0;
boolean wasHeating = 0;
boolean wasCooling = 0;
void setup(){
Serial.begin(9600);
tft.initR(INITR_REDTAB); // initialize a ST7735S (TFT display)
// Initialization Screen
drawInitScreen();
//what mode are we going to operate?
mode=modeHEAT;
timestamp = 1000; // delay startup
lastRunning = 0;
lastStandby = 0;
//SETUP PIN MODES
pinMode(pinFAN,OUTPUT);
pinMode(pinPUMP,OUTPUT);
pinMode(pinAUX,OUTPUT);
pinMode(pinCOOL,OUTPUT);
pinMode(pinEMER,OUTPUT);
drawRelaysReady();
Ts = mySetTemp;
Tv = myVariance;
//fill temp array with current temp
for(int pos = 0; pos<tempArrayLength;pos++){
Traw[pos] = ((((analogRead(pinTEMP)*5.0/1024.0) - 0.5)*100)*9.0/5.0 +32.0 + TempCalibration + PowerCorrection*isHeating);
}
drawTempsSet();
drawEndInit();
drawClearScreen();
drawMode();
drawModeSelection();
}
void loop(){
if(millis()>=timestamp){ //this command lets the system wait for the next desired timestamp
//Commands to run every 1s:
if(!(timestamp % 1000)){
//get current temp and average
for(int pos = 0; pos<(tempArrayLength - 1);pos++){
Traw[pos]=Traw[pos+1];
}
Traw[tempArrayLength - 1] = ((((analogRead(pinTEMP)*5.0/1024.0) - 0.5)*100)*9.0/5.0 +32.0 + TempCalibration + PowerCorrection*isHeating); //added adjustment -3.51deg while isHeating
T = 0;
for(int pos = 0; pos<tempArrayLength;pos++){
T += Traw[pos];
}
T = T/(tempArrayLength);
Ts = analogRead(1)/1024.0*30.0+50.0; //mock setpoint from 50 to 80 using pot on AI1
Th = Ts + Tv;
Tl = Ts - Tv;
drawTempSettings();
//Update Temp on Screen
drawTemp();
//Draw Temp bar
drawTempBar();
}
//Commands to run every 5s:
if(!(timestamp % 5000)){
//LOGIC FOR HVAC GOES HERE
// Serial.println();
// Serial.print(timestamp); Serial.print(": ");
// Serial.print("AVG=");
// Serial.print(T); // Averaged Temp
// Serial.print(" mode="); Serial.print(mode);
// Serial.print(" Tl="); Serial.print(Tl);
// Serial.print(" Ts="); Serial.print(Ts);
// Serial.print(" Th="); Serial.print(Th);
// Serial.print(" isC="); Serial.print(isCooling);
// Serial.print(" isH="); Serial.print(isHeating);
// Serial.print(" wasC="); Serial.print(wasCooling);
// Serial.print(" wasH="); Serial.print(wasHeating);
// Serial.print(" lastRun"); Serial.print(lastRunning);
// Serial.print(" lastSby"); Serial.print(lastStandby);
// Serial.println();
drawModeSelection();
drawTemp();
switch (mode){
case modeHEAT:
if(T<Ts) HVAC(cmdHEAT);
else if((T<Th)&& isHeating) HVAC(cmdHEAT);
else HVAC(cmdOFF);
break;
case modeCOOL:
if(T>Ts) HVAC(cmdCOOL);
else if((T>Tl)&& isCooling) HVAC(cmdCOOL);
else HVAC(cmdOFF);
break;
case modeAUTO:
if(T>=Ts && isHeating) HVAC(cmdOFF);
else if(T<=Ts && isCooling) HVAC(cmdOFF);
else if(T>=Th) HVAC(cmdCOOL); //this isnt going to work when system needs to switch from heat to cool
else if(T<=Tl) HVAC(cmdHEAT); //this isnt going to work when system needs to switch from cool to heat
else HVAC(cmdOFF);
break;
}
}
timestamp = timestamp + 500; //run code again in +0.1s intervals
}
}
void HVAC(int command){
tft.fillRect(0, 100, 120, 60, ST7735_BLACK);
tft.setCursor(0, 100);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
switch(command){
case cmdOFF:
if(isHeating) wasHeating=1; if(isCooling) wasCooling=1;
lastStandby = timestamp; // note the last time system in Standby
//determine if the fan should continue running if (1) the heat/cool was recently turned off and (2) the system has been running already
if(!(lastRunning==0) && (timestamp<(lastRunning + fanDelay))){
FAN(ON); //keep fan running temporalily if just turning off the system
/*Serial.println("<Fan Remaining On>");*/
tft.println("Fan Remaining On");
}
else {
FAN(OFF);
tft.println("Standby");
}
PUMP(OFF); AUX(OFF); COOL(OFF); EMER(OFF);
isHeating=0; isCooling=0;
/*Serial.print("<STANDBY>");*/
break;
case cmdFAN:
FAN(ON); PUMP(OFF); AUX(OFF); COOL(OFF); EMER(OFF);
/*Serial.print("<FAN>");*/
tft.println("Fan On");
break;
case cmdHEAT:
//(1)don't turn heat on immediately after turning off
// unless (2) the system is already heating or (3) the system has never run
if((timestamp>=(lastRunning + waitCycle))||isHeating||lastRunning==0){
//determine when heat pump vs aux heat is used - if Ts is 2 degrees above T, then use AUX.
//if the current temp is 2deg below setpoint OR the heatpump has been on for 10min, then use AUX
if(((Ts-T)>2.0)||(lastRunning>lastStandby+Heat2AuxTimeout)){FAN(ON); PUMP(ON); AUX(ON); COOL(OFF); EMER(OFF); /*Serial.print(" AUX HEAT");*/ tft.println("Aux Heat On");}
else {FAN(ON); PUMP(ON); AUX(OFF); COOL(OFF); EMER(OFF); /*Serial.print("<HEAT>");*/ tft.println("Heat Pump On");}
isHeating = 1;
lastRunning = timestamp;
}
else {
//Serial.print("<System Heat Delayed>");
tft.println("Heat Delayed"); lastStandby = timestamp; // note the last time system in Standby
}
break;
case cmdCOOL:
//(1)don't turn cool on immediately after turning off
// unless (2) the system is already cooling or (3) the system has never run
if((timestamp>=(lastRunning + waitCycle))||isCooling||lastRunning==0){ //don't turn heat on immediately after turning off
if((timestamp<(lastRunning + fanDelay))) FAN(ON); //keep fan running temporalily if just turning off the system
else FAN(OFF);
FAN(ON); PUMP(ON); AUX(OFF); COOL(ON); EMER(OFF); isCooling = 1; /*Serial.print(" A/C");*/ tft.println("A/C On");
lastRunning = timestamp;
}
else {
/*Serial.print("<System Cool Delayed>");*/ tft.println("A/C Delayed"); lastStandby = timestamp; // note the last time system in Standby
}
break;
case cmdEMER:
FAN(ON); PUMP(OFF); AUX(OFF); COOL(OFF); EMER(ON); isHeating = 1; /*Serial.print("<EMERGENCY HEAT>");*/ tft.println("Emergency Heating");
lastRunning = timestamp;
break;
}
}
void FAN(boolean command){
if(command) digitalWrite(pinFAN,HIGH);
else digitalWrite(pinFAN,LOW);
}
void PUMP(boolean command){
if(command) digitalWrite(pinPUMP,HIGH);
else digitalWrite(pinPUMP,LOW);
}
void AUX(boolean command){
if(command) digitalWrite(pinAUX,HIGH);
else digitalWrite(pinAUX,LOW);
}
void COOL(boolean command){
if(command) digitalWrite(pinCOOL,HIGH);
else digitalWrite(pinCOOL,LOW);
}
void EMER(boolean command){
if(command) digitalWrite(pinEMER,HIGH);
else digitalWrite(pinEMER,LOW);
}
//DRAWING
void drawInitScreen(void){
tft.fillScreen(ST7735_BLACK);
tft.setCursor(0, 0);
tft.setTextColor(ST7735_BLUE);
tft.setTextSize(1);
tft.println("TSTAT Initializing...");
}
void drawRelaysReady(void){
tft.setCursor(0, 10);
tft.setTextColor(ST7735_YELLOW);
tft.setTextSize(1);
tft.println("Relays READY");
}
void drawTempsSet(void){
tft.setCursor(0, 20);
tft.setTextSize(1);
tft.setTextColor(ST7735_CYAN);
tft.print("Tl = ");
tft.println(Tl);
tft.setTextColor(ST7735_WHITE);
tft.print("Ts = ");
tft.println(Ts);
tft.setTextColor(ST7735_MAGENTA);
tft.print("Th = ");
tft.println(Th);
tft.println();
tft.setTextColor(ST7735_WHITE);
tft.println("Current Temp Est.");
tft.setTextSize(2);
tft.println(Traw[0]);
}
void drawEndInit(void){
tft.setCursor(0, 90);
tft.setTextSize(1);
tft.setTextColor(ST7735_CYAN);
tft.println("end Initialization. ");
}
void drawClearScreen(void){
tft.fillScreen(ST7735_BLACK);
}
void drawTempSettings(void){
tft.fillRect(10, 14, 104, 7, ST7735_BLACK);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.setCursor(5, 14);
if(mode==modeHEAT){
tft.print(" Ts="); tft.print(Ts);
tft.print(" Th="); tft.print(Th);
}
if(mode==modeCOOL){
tft.print(" Tl="); tft.print(Tl);
tft.print(" Ts="); tft.print(Ts);
}
if(mode==modeAUTO){
tft.print(" Tl="); tft.print(Tl);
tft.print(" Th="); tft.print(Th);
}
//CURRENT TEMP AREA
tft.setCursor(0, 30);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.println("Current Temp:");
}
void drawTemp(void){
tft.fillRect(0, 40, 75, 15, ST7735_BLACK);
tft.setCursor(0, 40);
tft.setTextSize(2);
tft.setTextColor(ST7735_WHITE);
tft.print(T);
}
void drawMode(void){
//TOP BAR with MODES
tft.fillRect(0,0,128,13, ST7735_BLUE);
tft.setCursor(0, 3);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.print(" HEAT COOL AUTO");
delay(10);
}
void drawModeSelection(void){
//draw a blue box where mode is inactive and a yellow one where active
if(mode==modeHEAT) tft.drawRect(8,1,31,11,ST7735_YELLOW);
if(mode!=modeHEAT) tft.drawRect(8,1,31,11,ST7735_BLUE);
delay(10);
if(mode==modeCOOL) tft.drawRect(50,1,32,11,ST7735_YELLOW);
if(mode!=modeCOOL) tft.drawRect(50,1,32,11,ST7735_BLUE);
delay(10);
if(mode==modeAUTO) tft.drawRect(92,1,31,11,ST7735_YELLOW);
if(mode!=modeAUTO) tft.drawRect(92,1,31,11,ST7735_BLUE);
delay(10);
}
void drawTempBar(void){
#define BARWIDTH 108
//Determin min and max temps for plot. Lowest temp - 2deg up to highest temp+ 2 degrees
int minTemp; int maxTemp;
if(mode==modeHEAT) minTemp = (min(Ts, T) - 2);
else minTemp = (min(Tl, T) - 2);
if(mode==modeCOOL) maxTemp = (max(Ts, T) +2);
else maxTemp = (max(Th, T) + 2);
int TCtr = 10 + (T-minTemp)*BARWIDTH/(maxTemp-minTemp);
int TsCtr = 10 + (Ts-minTemp)*BARWIDTH/(maxTemp-minTemp);
int TlCtr = 10 + (Tl-minTemp)*BARWIDTH/(maxTemp-minTemp);
int ThCtr = 10 + (Th-minTemp)*BARWIDTH/(maxTemp-minTemp);
int TminCtr = 10;
int TmaxCtr = 10 + BARWIDTH;
tft.fillRect(3, 60, 122, 7, ST7735_BLACK); //background for upper temps
tft.fillRect(10, 70, BARWIDTH, 10, ST7735_BLUE); //temp bar
tft.fillRect(3, 83, 122, 7, ST7735_BLACK); //background for lower temps
//draw ticks for each degree
for(int degmark = minTemp; degmark<=maxTemp; degmark++){
tft.drawLine(10+ (degmark-minTemp)*BARWIDTH/(maxTemp-minTemp), 70, 10 + (degmark-minTemp)*BARWIDTH/(maxTemp-minTemp), 79, ST7735_GREEN); // line at degmark
}
//Draw in Min Temp
tft.setCursor(TminCtr - 5, 60);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.print(int(minTemp));
//Draw in Max Temp
tft.setCursor(TmaxCtr-5, 60);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.print(int(maxTemp));
tft.drawLine(10,80,BARWIDTH+10,80,ST7735_GREEN); //line below Tl/Ts/Th markers
if(mode!=modeAUTO){ //AUTO does not need Ts drawn in
//Write in Ts
tft.setCursor(TsCtr-5 , 60);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.print(int(Ts));
//Draw the Ts marker
tft.fillTriangle(TsCtr, 74, TsCtr - 2, 69, TsCtr + 2, 69, ST7735_WHITE);
delay(0); //it seems to need this to prevent it from crashing
}
else {
//Write in Tl
tft.setCursor(TlCtr-5 , 60);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.print(int(Tl));
//Draw the Tl marker
tft.fillTriangle(TlCtr, 74, TlCtr - 2, 69, TlCtr + 2, 69, ST7735_WHITE);
delay(0); //it seems to need this to prevent it from crashing
//Write in Th
tft.setCursor(ThCtr-5 , 60);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.print(int(Th));
//Draw the Ts marker
tft.fillTriangle(ThCtr, 74, ThCtr - 2, 69, ThCtr + 2, 69, ST7735_WHITE);
}
//Write in Current Temp
tft.setCursor(TCtr-5, 83);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.print(int(T));
//draw in the marker for T
tft.drawLine(10,69,BARWIDTH+10,69,ST7735_GREEN);
tft.fillTriangle(TCtr, 75, TCtr-2, 80, TCtr+2, 80, ST7735_WHITE);
}
void drawSystem(void){
tft.fillRect(0, 60, 90, 15, ST7735_RED);
tft.setCursor(0, 60);
tft.setTextSize(2);
tft.setTextColor(ST7735_WHITE);
if(digitalRead(pinFAN)){
tft.print("Fan ON");
}
if(!digitalRead(pinFAN)){
tft.print("Fan OFF");
}
}
1) changing 'drawTriangle' to 'fillTriangle' causes the next analogRead(0) to return 1024, regardless of actual value.
2) commenting out else{} in lines 440-467 caused unwanted results, even though those lines were never run. if(mode=!modeAUTO) was always true, thus the else{} shouldn't affect the run of a program.
By removing most of my initiation screens and their subroutines, I got rid of the 'Aux Heat On#Heat Pump On' problem. It now shows 'Aux Heat On', like it should.
Code: Select all
// Thermostat Code v0.2
// Ken Schnautz
// 2014 Jan 20
// Designed for use with a two-stage heat, one-stage cool unit;
// Heat pump with auxillary (electric) coils, A/C
// v0.1 -- Original code with options for (1) mode: HEAT
// v0.2 -- Added option for (2) additional modes: COOL, AUTO.
// Migrated 'is/wasCooling' and 'is/wasHeating' into HVAC routine.
// Added fanDelay to keep fan running temporarily upon entering Standby
// Added Heat2AuxTimeout to allow AUX to kick in if Heat pump can't keep up
// Added waitCycle to keep system from coming on immediately after turning off
// Added temp correction algorithm to help stabilize temp sensor with poor power stability
// Added global temp correction value
// v0.3 -- Added preliminary screen outputs
//------------------------
// Original System Wires:
// (R) Red - 24VAC
// (B) Blue - Common
// (W) White - Stage two heat (aux - electric strip)
// (T) Tan - Thermistor on outdoor unit
// (G) Green - Fan
// (X2) Black - Emergency (electric strip w/o compressor)
// (Y) Yellow - Stage one heat (Compressor - heat pump)
// (O) Orange - Reversing valve (for cooling)
// We will not be using (T) wire in this original code version.
//------------------------
//------------------------
// AdaFruit 1.8TFT Display
//------------------------
//#define sclk 13
//#define mosi 11
#define TFTcs 10
#define TFTdc 9
#define TFTrst -1 // was 8 -- reset
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library
#include <SPI.h>
Adafruit_ST7735 tft = Adafruit_ST7735(TFTcs, TFTdc, TFTrst);
//------------------------
//PINS
#define mySetTemp 65.0
#define myVariance 2.0
#define TempCalibration 0.0 //temp seems to read low by 1.5 deg
#define PowerCorrection 0.0 //when relay is engaged, temp reads high by 3.51deg
#define modeHEAT 1
#define modeCOOL 2
#define modeAUTO 3
#define pinFAN 2
#define pinPUMP 3
#define pinAUX 4
#define pinCOOL 5
#define pinEMER 6
//ANALOG IN PINS
#define pinTEMP 0
//HVAC COMMANDS
#define cmdOFF 1
#define cmdFAN 2
#define cmdHEAT 3
#define cmdCOOL 4
#define cmdEMER 5
#define ON 1
#define OFF 0
#define tempArrayLength 20
#define fanDelay 120000 // Fan runs 1min after system turns off
#define waitCycle 300000 // Keeps the system from coming on within 2min of turning off
#define Heat2AuxTimeout 600000 // if Heat is run for this long, it switches to AUX heat instead
// Define Variables
int mode; // used for HVAC modes
unsigned long int timestamp; // used for timing operations
unsigned long int lastRunning; // used to keep track of when the unit turned off
unsigned long int lastStandby; // used to keep track of when the unit turned on
float T; //current temperature
float Traw[tempArrayLength]; // history of temp measurements, to be averaged into T
int Ts; //user's Temp Setpoint
int Tv; //allowable variance in temp
int Th; //calculated high temp limit
int Tl; //calculated low temp limit
boolean isHeating = 0;
boolean isCooling = 0;
boolean wasHeating = 0;
boolean wasCooling = 0;
void setup(){
Serial.begin(9600);
tft.initR(INITR_REDTAB); // initialize a ST7735S (TFT display)
// Initialization Screen
// drawInitScreen();
//what mode are we going to operate?
mode=modeHEAT;
timestamp = 1000; // delay startup
lastRunning = 0;
lastStandby = 0;
//SETUP PIN MODES
pinMode(pinFAN,OUTPUT);
pinMode(pinPUMP,OUTPUT);
pinMode(pinAUX,OUTPUT);
pinMode(pinCOOL,OUTPUT);
pinMode(pinEMER,OUTPUT);
// drawRelaysReady();
Ts = mySetTemp;
Tv = myVariance;
//fill temp array with current temp
for(int pos = 0; pos<tempArrayLength;pos++){
Traw[pos] = ((((analogRead(pinTEMP)*5.0/1024.0) - 0.5)*100)*9.0/5.0 +32.0 + TempCalibration + PowerCorrection*isHeating);
}
drawClearScreen();
drawMode();
drawModeSelection();
}
void loop(){
if(millis()>=timestamp){ //this command lets the system wait for the next desired timestamp
//Commands to run every 1s:
if(!(timestamp % 1000)){
//get current temp and average
for(int pos = 0; pos<(tempArrayLength - 1);pos++){
Traw[pos]=Traw[pos+1];
}
Traw[tempArrayLength - 1] = ((((analogRead(pinTEMP)*5.0/1024.0) - 0.5)*100)*9.0/5.0 +32.0 + TempCalibration + PowerCorrection*isHeating); //added adjustment -3.51deg while isHeating
T = 0;
for(int pos = 0; pos<tempArrayLength;pos++){
T += Traw[pos];
}
T = T/(tempArrayLength);
Ts = analogRead(1)/1024.0*30.0+50.0; //mock setpoint from 50 to 80 using pot on AI1
Th = Ts + Tv;
Tl = Ts - Tv;
drawTempSettings();
//Update Temp on Screen
drawTemp();
//Draw Temp bar
drawTempBar();
}
//Commands to run every 5s:
if(!(timestamp % 5000)){
//LOGIC FOR HVAC GOES HERE
// Serial.println();
// Serial.print(timestamp); Serial.print(": ");
// Serial.print("AVG=");
// Serial.print(T); // Averaged Temp
// Serial.print(" mode="); Serial.print(mode);
// Serial.print(" Tl="); Serial.print(Tl);
// Serial.print(" Ts="); Serial.print(Ts);
// Serial.print(" Th="); Serial.print(Th);
// Serial.print(" isC="); Serial.print(isCooling);
// Serial.print(" isH="); Serial.print(isHeating);
// Serial.print(" wasC="); Serial.print(wasCooling);
// Serial.print(" wasH="); Serial.print(wasHeating);
// Serial.print(" lastRun"); Serial.print(lastRunning);
// Serial.print(" lastSby"); Serial.print(lastStandby);
// Serial.println();
drawModeSelection();
drawTemp();
switch (mode){
case modeHEAT:
if(T<Ts) HVAC(cmdHEAT);
else if((T<Th)&& isHeating) HVAC(cmdHEAT);
else HVAC(cmdOFF);
break;
case modeCOOL:
if(T>Ts) HVAC(cmdCOOL);
else if((T>Tl)&& isCooling) HVAC(cmdCOOL);
else HVAC(cmdOFF);
break;
case modeAUTO:
if(T>=Ts && isHeating) HVAC(cmdOFF);
else if(T<=Ts && isCooling) HVAC(cmdOFF);
else if(T>=Th) HVAC(cmdCOOL); //this isnt going to work when system needs to switch from heat to cool
else if(T<=Tl) HVAC(cmdHEAT); //this isnt going to work when system needs to switch from cool to heat
else HVAC(cmdOFF);
break;
}
}
timestamp = timestamp + 500; //run code again in +0.1s intervals
}
}
void HVAC(int command){
tft.fillRect(0, 100, 120, 60, ST7735_BLACK);
tft.setCursor(0, 100);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
switch(command){
case cmdOFF:
if(isHeating) wasHeating=1; if(isCooling) wasCooling=1;
lastStandby = timestamp; // note the last time system in Standby
//determine if the fan should continue running if (1) the heat/cool was recently turned off and (2) the system has been running already
if(!(lastRunning==0) && (timestamp<(lastRunning + fanDelay))){
FAN(ON); //keep fan running temporalily if just turning off the system
/*Serial.println("<Fan Remaining On>");*/
tft.println("Fan Remaining On");
}
else {
FAN(OFF);
tft.println("Standby");
}
PUMP(OFF); AUX(OFF); COOL(OFF); EMER(OFF);
isHeating=0; isCooling=0;
/*Serial.print("<STANDBY>");*/
break;
case cmdFAN:
FAN(ON); PUMP(OFF); AUX(OFF); COOL(OFF); EMER(OFF);
/*Serial.print("<FAN>");*/
tft.println("Fan On");
break;
case cmdHEAT:
//(1)don't turn heat on immediately after turning off
// unless (2) the system is already heating or (3) the system has never run
if((timestamp>=(lastRunning + waitCycle))||isHeating||lastRunning==0){
//determine when heat pump vs aux heat is used - if Ts is 2 degrees above T, then use AUX.
//if the current temp is 2deg below setpoint OR the heatpump has been on for 10min, then use AUX
if(((Ts-T)>2.0)||(lastRunning>lastStandby+Heat2AuxTimeout)){FAN(ON); PUMP(ON); AUX(ON); COOL(OFF); EMER(OFF); /*Serial.print(" AUX HEAT");*/ tft.println("Aux Heat On");}
else {FAN(ON); PUMP(ON); AUX(OFF); COOL(OFF); EMER(OFF); /*Serial.print("<HEAT>");*/ tft.println("Heat Pump On");}
isHeating = 1;
lastRunning = timestamp;
}
else {
//Serial.print("<System Heat Delayed>");
tft.println("Heat Delayed"); lastStandby = timestamp; // note the last time system in Standby
}
break;
case cmdCOOL:
//(1)don't turn cool on immediately after turning off
// unless (2) the system is already cooling or (3) the system has never run
if((timestamp>=(lastRunning + waitCycle))||isCooling||lastRunning==0){ //don't turn heat on immediately after turning off
if((timestamp<(lastRunning + fanDelay))) FAN(ON); //keep fan running temporalily if just turning off the system
else FAN(OFF);
FAN(ON); PUMP(ON); AUX(OFF); COOL(ON); EMER(OFF); isCooling = 1; /*Serial.print(" A/C");*/ tft.println("A/C On");
lastRunning = timestamp;
}
else {
/*Serial.print("<System Cool Delayed>");*/ tft.println("A/C Delayed"); lastStandby = timestamp; // note the last time system in Standby
}
break;
case cmdEMER:
FAN(ON); PUMP(OFF); AUX(OFF); COOL(OFF); EMER(ON); isHeating = 1; /*Serial.print("<EMERGENCY HEAT>");*/ tft.println("Emergency Heating");
lastRunning = timestamp;
break;
}
}
void FAN(boolean command){
if(command) digitalWrite(pinFAN,HIGH);
else digitalWrite(pinFAN,LOW);
}
void PUMP(boolean command){
if(command) digitalWrite(pinPUMP,HIGH);
else digitalWrite(pinPUMP,LOW);
}
void AUX(boolean command){
if(command) digitalWrite(pinAUX,HIGH);
else digitalWrite(pinAUX,LOW);
}
void COOL(boolean command){
if(command) digitalWrite(pinCOOL,HIGH);
else digitalWrite(pinCOOL,LOW);
}
void EMER(boolean command){
if(command) digitalWrite(pinEMER,HIGH);
else digitalWrite(pinEMER,LOW);
}
void drawTempsSet(void){
tft.setCursor(0, 20);
tft.setTextSize(1);
tft.setTextColor(ST7735_CYAN);
tft.print("Tl = ");
tft.println(Tl);
tft.setTextColor(ST7735_WHITE);
tft.print("Ts = ");
tft.println(Ts);
tft.setTextColor(ST7735_MAGENTA);
tft.print("Th = ");
tft.println(Th);
tft.println();
tft.setTextColor(ST7735_WHITE);
tft.println("Current Temp Est.");
tft.setTextSize(2);
tft.println(Traw[0]);
}
void drawClearScreen(void){
tft.fillScreen(ST7735_BLACK);
}
void drawTempSettings(void){
tft.fillRect(10, 14, 104, 7, ST7735_BLACK);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.setCursor(5, 14);
if(mode==modeHEAT){
tft.print(" Ts="); tft.print(Ts);
tft.print(" Th="); tft.print(Th);
}
if(mode==modeCOOL){
tft.print(" Tl="); tft.print(Tl);
tft.print(" Ts="); tft.print(Ts);
}
if(mode==modeAUTO){
tft.print(" Tl="); tft.print(Tl);
tft.print(" Th="); tft.print(Th);
}
//CURRENT TEMP AREA
tft.setCursor(0, 30);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.println("Current Temp:");
}
void drawTemp(void){
tft.fillRect(0, 40, 75, 15, ST7735_BLACK);
tft.setCursor(0, 40);
tft.setTextSize(2);
tft.setTextColor(ST7735_WHITE);
tft.print(T);
}
void drawMode(void){
//TOP BAR with MODES
tft.fillRect(0,0,128,13, ST7735_BLUE);
tft.setCursor(0, 3);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.print(" HEAT COOL AUTO");
delay(10);
}
void drawModeSelection(void){
//draw a blue box where mode is inactive and a yellow one where active
if(mode==modeHEAT) tft.drawRect(8,1,31,11,ST7735_YELLOW);
if(mode!=modeHEAT) tft.drawRect(8,1,31,11,ST7735_BLUE);
delay(10);
if(mode==modeCOOL) tft.drawRect(50,1,32,11,ST7735_YELLOW);
if(mode!=modeCOOL) tft.drawRect(50,1,32,11,ST7735_BLUE);
delay(10);
if(mode==modeAUTO) tft.drawRect(92,1,31,11,ST7735_YELLOW);
if(mode!=modeAUTO) tft.drawRect(92,1,31,11,ST7735_BLUE);
delay(10);
}
void drawTempBar(void){
#define BARWIDTH 108
//Determin min and max temps for plot. Lowest temp - 2deg up to highest temp+ 2 degrees
int minTemp; int maxTemp;
if(mode==modeHEAT) minTemp = (min(Ts, T) - 2);
else minTemp = (min(Tl, T) - 2);
if(mode==modeCOOL) maxTemp = (max(Ts, T) +2);
else maxTemp = (max(Th, T) + 2);
int TCtr = 10 + (T-minTemp)*BARWIDTH/(maxTemp-minTemp);
int TsCtr = 10 + (Ts-minTemp)*BARWIDTH/(maxTemp-minTemp);
int TlCtr = 10 + (Tl-minTemp)*BARWIDTH/(maxTemp-minTemp);
int ThCtr = 10 + (Th-minTemp)*BARWIDTH/(maxTemp-minTemp);
int TminCtr = 10;
int TmaxCtr = 10 + BARWIDTH;
tft.fillRect(3, 60, 122, 7, ST7735_BLACK); //background for upper temps
tft.fillRect(10, 70, BARWIDTH, 10, ST7735_BLUE); //temp bar
tft.fillRect(3, 83, 122, 7, ST7735_BLACK); //background for lower temps
//draw ticks for each degree
for(int degmark = minTemp; degmark<=maxTemp; degmark++){
tft.drawLine(10+ (degmark-minTemp)*BARWIDTH/(maxTemp-minTemp), 70, 10 + (degmark-minTemp)*BARWIDTH/(maxTemp-minTemp), 79, ST7735_GREEN); // line at degmark
}
//Draw in Min Temp
tft.setCursor(TminCtr - 5, 60);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.print(int(minTemp));
//Draw in Max Temp
tft.setCursor(TmaxCtr-5, 60);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.print(int(maxTemp));
tft.drawLine(10,80,BARWIDTH+10,80,ST7735_GREEN); //line below Tl/Ts/Th markers
if(mode!=modeAUTO){ //AUTO does not need Ts drawn in
//Write in Ts
tft.setCursor(TsCtr-5 , 60);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.print(int(Ts));
//Draw the Ts marker
tft.fillTriangle(TsCtr, 74, TsCtr - 2, 69, TsCtr + 2, 69, ST7735_WHITE);
delay(0); //it seems to need this to prevent it from crashing
}
else {
//Write in Tl
tft.setCursor(TlCtr-5 , 60);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.print(int(Tl));
//Draw the Tl marker
tft.fillTriangle(TlCtr, 74, TlCtr - 2, 69, TlCtr + 2, 69, ST7735_WHITE);
delay(0); //it seems to need this to prevent it from crashing
//Write in Th
tft.setCursor(ThCtr-5 , 60);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.print(int(Th));
//Draw the Ts marker
tft.fillTriangle(ThCtr, 74, ThCtr - 2, 69, ThCtr + 2, 69, ST7735_WHITE);
}
//Write in Current Temp
tft.setCursor(TCtr-5, 83);
tft.setTextSize(1);
tft.setTextColor(ST7735_WHITE);
tft.print(int(T));
//draw in the marker for T
tft.drawLine(10,69,BARWIDTH+10,69,ST7735_GREEN);
tft.fillTriangle(TCtr, 75, TCtr-2, 80, TCtr+2, 80, ST7735_WHITE);
}
void drawSystem(void){
tft.fillRect(0, 60, 90, 15, ST7735_RED);
tft.setCursor(0, 60);
tft.setTextSize(2);
tft.setTextColor(ST7735_WHITE);
if(digitalRead(pinFAN)){
tft.print("Fan ON");
}
if(!digitalRead(pinFAN)){
tft.print("Fan OFF");
}
}
Any tips?