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!