Need help with adding offset function for temperature and humidity on TFT touch screen ST7789

Hello Arduino community,

I'm currently working on a project where I'm using a TFT touch screen (ST7789) with an Arduino to monitor temperature and humidity. I'm using the AHTX0 sensor for temperature and humidity measurements.

I've managed to modify a sample code originally designed for the DHT11 sensor to work with the AHTX0 sensor. The code allows the user to input temperature and humidity set points via the touch screen.

However, I've encountered a roadblock when trying to add an offset function, allowing users to set offsets for temperature and humidity using numeric keypad. I want users to be able to adjust the measured values by a certain offset value to account for any discrepancies in the sensor readings or environmental factors.

I've tried to integrate this offset function into my existing code, but I'm still at a beginner stage and struggling to get it working properly. Whenever I attempt to add the offset functionality, the code doesn't behave as expected.

Here's the sample code originally designed for the DHT11 sensor :

// IMPORTANT: Adafruit_TFTLCD LIBRARY MUST BE SPECIFICALLY
// CONFIGURED FOR EITHER THE TFT SHIELD OR THE BREAKOUT BOARD.
// SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h FOR SETUP.
//Technical support:goodtft@163.com

#include <Adafruit_GFX.h>
#include <Adafruit_TFTLCD.h>
#include <TouchScreen.h>
#include <Adafruit_AHTX0.h>
#include <MCUFRIEND_kbv.h>
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <Adafruit_Sensor.h>
#include <SPI.h>
#include <Wire.h>
MCUFRIEND_kbv tft;


#include "DHT.h"

#define DHTPIN 40     // what digital pin we're connected to

// Uncomment whatever type you're using!
#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

DHT dht(DHTPIN, DHTTYPE);


//const int XP=7,XM=A1,YP=A2,YM=6; //240x320 ID=0x9325
const int XP=8,XM=A2,YP=A3,YM=9; //240x320 ID=0x7789
const int TS_LEFT=921,TS_RT=100,TS_TOP=904,TS_BOT=80;


//const int TS_LEFT=89,TS_RT=946,TS_TOP=94,TS_BOT=883;
//const int TS_LEFT=134,TS_RT=930,TS_TOP=946,TS_BOT=71;


// Assign human-readable names to some common 16-bit color values:
#define  BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
#define NAVY        0x000F      /*   0,   0, 128 */
#define DARKGREEN   0x03E0      /*   0, 128,   0 */
#define DARKCYAN    0x03EF      /*   0, 128, 128 */
#define MAROON      0x7800      /* 128,   0,   0 */
#define PURPLE      0x780F      /* 128,   0, 128 */
#define OLIVE       0x7BE0      /* 128, 128,   0 */
#define LIGHTGREY   0xC618      /* 192, 192, 192 */
#define DARKGREY    0x7BEF      /* 128, 128, 128 */
#define BLUEGREEN   0x07E0      /*   0, 255,   0 */
#define ORANGE      0xFD20      /* 255, 165,   0 */
#define GREENYELLOW 0xAFE5      /* 173, 255,  47 */
#define PINK        0xF81F

/******************* UI details */
#define BUTTON_X 40
#define BUTTON_Y 100
#define BUTTON_W 60
#define BUTTON_H 30
#define BUTTON_SPACING_X 20
#define BUTTON_SPACING_Y 20
#define BUTTON_TEXTSIZE 2

// text box where numbers go
#define TEXT_X 10
#define TEXT_Y 10
#define TEXT_W 220
#define TEXT_H 50
#define TEXT_TSIZE 3
#define TEXT_TCOLOR MAGENTA
// the data (phone #) we store in the textfield
#define TEXT_LEN 12
char textfield[TEXT_LEN+1] = "";
uint8_t textfield_i=0;

#define MINPRESSURE 10
#define MAXPRESSURE 1000


#define TS_MINX 920
#define TS_MINY 940
#define TS_MAXX 150
#define TS_MAXY 120
// We have a status line for like, is FONA working
#define STATUS_X 65
#define STATUS_Y 10



//Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 100);
// If using the shield, all control and data lines are fixed, and
// a simpler declaration can optionally be used:
// Adafruit_TFTLCD tft;

Adafruit_GFX_Button buttons[15];
Adafruit_GFX_Button settingsButton;
Adafruit_GFX_Button backHomeButton;
/* create 15 buttons, in classic candybar phone style */
char buttonlabels[15][5] = {"Ent.", "Clr.", "Esc.", "1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#" };
uint16_t buttoncolors[15] = {DARKGREEN, DARKGREY, RED, 
                             BLUE, BLUE, BLUE, 
                             BLUE, BLUE, BLUE, 
                             BLUE, BLUE, BLUE, 
                             ORANGE, BLUE, ORANGE};

bool numericScreenOn = false;
bool numericScreenInit = false;
bool homeScreenOn = true;
bool homeScreenInit = false;
bool settingsScreenOn = false;
bool settingsScreenInit = false;
bool numericScreenOnTemperature = false;
bool numericScreenOnHumidity = false;
String serialTemp;
String oldData = "";
String temperatureSP="0";
String humiditySP="0";

bool heaterOn = false;
bool fanOn = false;

void setup(void) {

  dht.begin();
  Serial.begin(9600);
  Serial.println(F("TFT LCD test"));

#ifdef USE_ADAFRUIT_SHIELD_PINOUT
  Serial.println(F("Using Adafruit 2.4\" TFT Arduino Shield Pinout"));
#else
  Serial.println(F("Using Adafruit 2.4\" TFT Breakout Board Pinout"));
#endif

  Serial.print("TFT size is "); Serial.print(tft.width()); Serial.print("x"); Serial.println(tft.height());

  tft.reset();

  uint16_t identifier = tft.readID();
  if(identifier==0x0101)
      identifier=0x9341;
  
  if(identifier == 0x9325) {
    Serial.println(F("Found ILI9325 LCD driver"));
  } else if(identifier == 0x4535) {
    Serial.println(F("Found LGDP4535 LCD driver"));
  }else if(identifier == 0x9328) {
    Serial.println(F("Found ILI9328 LCD driver"));
  } else if(identifier == 0x7789) {
    Serial.println(F("Found HX8347G LCD driver"));
  } else if(identifier == 0x9341) {
    Serial.println(F("Found ILI9341 LCD driver"));
  } else if(identifier == 0x8357) {
    Serial.println(F("Found HX8357D LCD driver"));
  } else {
    Serial.print(F("Unknown LCD driver chip: "));
    Serial.println(identifier, HEX);
    Serial.println(F("If using the Adafruit 2.4\" TFT Arduino shield, the line:"));
    Serial.println(F("  #define USE_ADAFRUIT_SHIELD_PINOUT"));
    Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));
    Serial.println(F("If using the breakout board, it should NOT be #defined!"));
    Serial.println(F("Also if using the breakout, double-check that all wiring"));
    Serial.println(F("matches the tutorial."));
    return;
  }

  tft.begin(identifier);
  
  

 
}
// Print something in the mini status bar with either flashstring
void status(const __FlashStringHelper *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(WHITE);
  tft.setTextSize(1);
  tft.print(msg);
}
// or charstring
void status(char *msg) {
  tft.fillRect(STATUS_X, STATUS_Y, 240, 8, BLACK);
  tft.setCursor(STATUS_X, STATUS_Y);
  tft.setTextColor(WHITE);
  tft.setTextSize(1);
  tft.print(msg);
}

void NumericKeyboardScreen(TSPoint p){
  if (!numericScreenInit){
        tft.fillScreen(BLACK);
      
      // create buttons
      for (uint8_t row=0; row<5; row++) {
        for (uint8_t col=0; col<3; col++) {
          buttons[col + row*3].initButton(&tft, BUTTON_X+col*(BUTTON_W+BUTTON_SPACING_X), 
                     BUTTON_Y+row*(BUTTON_H+BUTTON_SPACING_Y),    // x, y, w, h, outline, fill, text
                      BUTTON_W, BUTTON_H, WHITE, buttoncolors[col+row*3], WHITE,
                      buttonlabels[col + row*3], BUTTON_TEXTSIZE); 
          buttons[col + row*3].drawButton();
        }
      }
      
      // create 'text field'
      tft.drawRect(TEXT_X, TEXT_Y, TEXT_W, TEXT_H, WHITE);
      numericScreenInit = true;
    }

  // go thru all the buttons, checking if they were pressed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].contains(p.x, p.y)) {
      //Serial.print("Pressing: "); Serial.println(b);
      buttons[b].press(true);  // tell the button it is pressed
    } else {
      buttons[b].press(false);  // tell the button it is NOT pressed
    }
  }

  // now we can ask the buttons if their state has changed
  for (uint8_t b=0; b<15; b++) {
    if (buttons[b].justReleased()) {
      // Serial.print("Released: "); Serial.println(b);
      buttons[b].drawButton();  // draw normal
    }
    
    if (buttons[b].justPressed()) {
        buttons[b].drawButton(true);  // draw invert!
        
        // if a numberpad button, append the relevant # to the textfield
        if (b >= 3) {
          if (textfield_i < TEXT_LEN) {
            textfield[textfield_i] = buttonlabels[b][0];
            textfield_i++;
      textfield[textfield_i] = 0; // zero terminate
            
           // fona.playDTMF(buttonlabels[b][0]);
          }
        }

        // clr button! delete char
        if (b == 1) {
          
          textfield[textfield_i] = 0;
          if (textfield > 0) {
            textfield_i--;
            textfield[textfield_i] = ' ';
          }
        }

        // update the current text field
        Serial.println(textfield);
        tft.setCursor(TEXT_X + 2, TEXT_Y+10);
        tft.setTextColor(TEXT_TCOLOR, BLACK);
        tft.setTextSize(TEXT_TSIZE);
        tft.print(textfield);

        // Esc. Button
        if (b == 2) {
          //status(F("Hanging up"));
          //fona.hangUp();
          if(numericScreenOnTemperature){
            //temperatureSP = textfield;
            settingsScreenOn = true;
            settingsScreenInit = false;
            numericScreenOnTemperature = false;
            }

            if(numericScreenOnHumidity){
            //temperatureSP = textfield;
            settingsScreenOn = true;
            settingsScreenInit = false;
            numericScreenOnHumidity = false;
            }

            for(int i=0; i<=12;i++){
              textfield[i] = ' ';
            }
            textfield_i = 0;
        }
        // Enter Button
        if (b == 0) {
          //status(F("Calling"));
          //Serial.print("Calling "); Serial.print(textfield);
          if(numericScreenOnTemperature){
            temperatureSP = textfield;
            settingsScreenOn = true;
            settingsScreenInit = false;
            numericScreenOnTemperature = false;
            }

           if(numericScreenOnHumidity){
            humiditySP = textfield;
            settingsScreenOn = true;
            settingsScreenInit = false;
            numericScreenOnHumidity = false;
            }

          for(int i=0; i<=12;i++){
              textfield[i] = ' ';
            }
            textfield_i = 0;
            
          
          //fona.callPhone(textfield);
          //temperatureSP,settingsScreenOn,settingsScreenInit
        }
        
      delay(100); // UI debouncing
    }
  }
  
  }

void HomeScreen(String temperature,String humidity,String tempSP, String humSP,bool hOn, bool fOn){
  if(!homeScreenInit){
    tft.fillScreen(BLACK); 
    settingsButton.initButton(&tft, 120,20,    // x, y, w, h, outline, fill, text
                      230,30, WHITE, DARKGREEN, WHITE,
                      "Settings", BUTTON_TEXTSIZE); 
    settingsButton.drawButton();
    tft.setCursor(10, 50);
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
    tft.print("Temp. ");
    tft.setTextColor(ORANGE);
    tft.print("(SP: "+tempSP+" C)");

    tft.setCursor(10,130);
    tft.setTextSize(2);
    tft.setTextColor(WHITE,BLACK);
    tft.print("Heater ");
    
    tft.setCursor(10, 200);
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
    tft.print("Humidity ");
    tft.setTextColor(BLUE);
    tft.print("(SP: "+humSP+"%)");

    tft.setCursor(10,280);
    tft.setTextSize(2);
    tft.setTextColor(WHITE,BLACK);
    tft.print("Fan ");
    
    homeScreenInit = true;
    }
    tft.setCursor(10,80);
    tft.setTextSize(5);
    tft.setTextColor(WHITE,BLACK);
    tft.print(temperature + " C");

    
    
    if(hOn){
      tft.drawCircle(100, 135, 10, GREEN);
      tft.fillCircle(100, 135, 10, GREEN);
      }else{
        tft.drawCircle(100, 135, 10, RED);
        tft.fillCircle(100, 135, 10, RED);}
    


    tft.setCursor(10,230);
    tft.setTextSize(5);
    tft.setTextColor(WHITE,BLACK);
    tft.print(humidity + " %");

    
    
    if(fOn){
      tft.drawCircle(100, 285, 10, GREEN);
      tft.fillCircle(100, 285, 10, GREEN);
      }else{
        tft.drawCircle(100, 285, 10, RED);
        tft.fillCircle(100, 285, 10, RED);}
    
  }

void SettingsScreen(String temp, String hum){
  if(!settingsScreenInit){
    tft.fillScreen(BLACK); 
    tft.setCursor(10, 10);
    tft.setTextColor(WHITE);
    tft.setTextSize(2);
    tft.print("Temp. Setpoint");
    tft.drawRect(10, 30, TEXT_W, TEXT_H, WHITE);
    tft.setCursor(10, 90);
    tft.print("Humidity Setpoint");
    tft.drawRect(10, 120, TEXT_W, TEXT_H, WHITE);
    
    backHomeButton.initButton(&tft, 120,300,    // x, y, w, h, outline, fill, text
                      230,30, WHITE, LIGHTGREY, WHITE,
                      "Back Home", BUTTON_TEXTSIZE); 
    backHomeButton.drawButton();
    
    settingsScreenInit = true;
    }
    tft.setCursor(TEXT_X + 2, 40);
    tft.setTextColor(TEXT_TCOLOR, BLACK);
    tft.setTextSize(TEXT_TSIZE);
    tft.print(temp);

    tft.setCursor(TEXT_X + 2, 130);
    tft.setTextColor(TEXT_TCOLOR, BLACK);
    tft.setTextSize(TEXT_TSIZE);
    tft.print(hum);
    
  
  }

void initAllScreens(){
  numericScreenInit = false;
  homeScreenInit = false;
  settingsScreenInit = false;
  }

  
void loop(void) {
  /*TSPoint p;
  p = ts.getPoint(); 
  */
  digitalWrite(13, HIGH);
  TSPoint p = ts.getPoint();
  digitalWrite(13, LOW);

  // if sharing pins, you'll need to fix the directions of the touchscreen pins
  //pinMode(XP, OUTPUT);
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
  //pinMode(YM, OUTPUT);

  // we have some minimum pressure we consider 'valid'
  // pressure of 0 means no pressing!
  
 // p = ts.getPoint(); 
  /*
  if (ts.bufferSize()) {
    
  } else {
    // this is our way of tracking touch 'release'!
    p.x = p.y = p.z = -1;
  }*/
  
  // Scale from ~0->4000 to tft.width using the calibration #'s
  /*
  if (p.z != -1) {
    p.x = map(p.x, TS_MINX, TS_MAXX, 0, tft.width());
    p.y = map(p.y, TS_MINY, TS_MAXY, 0, tft.height());
    Serial.print("("); Serial.print(p.x); Serial.print(", "); 
    Serial.print(p.y); Serial.print(", "); 
    Serial.print(p.z); Serial.println(") ");
  }*/
   if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
    // scale from 0->1023 to tft.width
    p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
    p.y = map(p.y, TS_MINY, TS_MAXY, tft.height(), 0);
/*
    Serial.print("("); Serial.print(p.x); Serial.print(", "); 
    Serial.print(p.y); Serial.print(", "); 
    Serial.print(p.z); Serial.println(") ");
    */
   }
  /* 
   if(Serial.available()){
    serialTemp = Serial.readString();
   }
   if(oldData!=serialTemp){
    oldData = serialTemp;
    //homeScreenOn = false;
    }
    */
    
    
    
    if(homeScreenOn){
      float h = dht.readHumidity();
      // Read temperature as Celsius (the default)
      float t = dht.readTemperature();
      if(t<temperatureSP.toFloat()){
        heaterOn = true;
        }else{
          heaterOn = false;
          }

      if(h>humiditySP.toFloat()){
        fanOn = true;
        }else{
          fanOn = false;
          }
      //initAllScreens();
      HomeScreen(String(t),String(h),temperatureSP,humiditySP,heaterOn,fanOn);
     // HomeScreen("14.5","20",temperatureSP,humiditySP);
      }

    if(settingsScreenOn){
      //initAllScreens();
      SettingsScreen(temperatureSP, humiditySP);
      }
      //Serial.println("Temp. SP "+temperatureSP+"settingsScreen "+settingsScreenOn);
    if(numericScreenOnTemperature || numericScreenOnHumidity){
      NumericKeyboardScreen(p);
      }
      
    

    //Settings Button
    if(homeScreenOn && p.x>10 && p.x<230 && p.y>0 && p.y<30 ){
      //Serial.println("Settings ON");
      settingsScreenOn = true;
      numericScreenOn = false;
      homeScreenOn = false;
      numericScreenOnTemperature = false;
      initAllScreens();
      
      }
      
    // BackHome Button
    if(settingsScreenOn && p.x>10 && p.x<230 && p.y>260 && p.y<280){
      //Serial.println("Home ON");
      numericScreenOnTemperature = false;
      settingsScreenOn = false;
      numericScreenOn = false;
      homeScreenOn = true;
      initAllScreens();
      }
      
      //Temperature TextBox
      if(settingsScreenOn && p.x>10 && p.x<230 && p.y>40 && p.y<80){
      //Serial.println("Home ON");
      numericScreenOnTemperature = true;
      numericScreenOnHumidity = false;
      settingsScreenOn = false;
      homeScreenOn = false;
      initAllScreens();
      }
      
      //Humidity TextBox
      if(settingsScreenOn && p.x>10 && p.x<230 && p.y>130 && p.y<170){
      //Serial.println("Home ON");
      numericScreenOnTemperature = false;
      numericScreenOnHumidity = true;
      settingsScreenOn = false;
      homeScreenOn = false;
      initAllScreens();
      }
    
   //NumericKeyboardScreen(p);
   //delay(300);
  
  
}

If anyone could offer guidance or assistance on how to properly implement the offset function for temperature and humidity using the same keypad on the TFT touch screen, I would greatly appreciate it.

Thank you in advance for your help!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.