Strange behavior with 1.8 TFT and GFX library

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
kwschnautz
 
Posts: 4
Joined: Fri Aug 12, 2011 10:54 pm

Strange behavior with 1.8 TFT and GFX library

Post by kwschnautz »

Hello,

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");
 }
} 
Some scenarios that I can't currently reproduce, but I've had happen:
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");
 }
} 
My best guess is that there is a memory allocation or addressing issue... It doesn't help that the problems aren't consistent.

Any tips?

kwschnautz
 
Posts: 4
Joined: Fri Aug 12, 2011 10:54 pm

Re: Strange behavior with 1.8 TFT and GFX library

Post by kwschnautz »

Aha! another reproducible problem:

remove (or comment out) line 358:

Code: Select all

delay(10);
and the display stays white... (although the code continues on without it...)

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");
 }
} 

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Strange behavior with 1.8 TFT and GFX library

Post by adafruit_support_mike »

First suggestion: pour your code through a prettyprinter and get proper line sequencing and indentation on it. The line that contains "Heat Pump On" looks like this:

Code: Select all

        else {FAN(ON); PUMP(ON); AUX(OFF); COOL(OFF); EMER(OFF); /*Serial.print("<HEAT>");*/ tft.println("Heat Pump On");}
Basic principle of programming: Source code is for human beings.

A CPU can't execute source directly, and while the stuff that comes out of a compiler is logically equivalent to the human readable document, the actual structure can be extremely different.

Cramming an entire block into a single line simply invites problems. I'll make a strong guess that when you reformat the code so the textual structure mirrors the logical structure, you'll find at least one or two bugs that weren't easily visible before.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”