RTCLib and touch screen on arduino uno for aquarium project

Hello,
I'm trying to make a led switch for an aquarium. I'm using an arduino UNO and MCU friend 2.4" TFT Touch screen. The touch screen use ST7783 and i'm using for my project the following library :

-Adafruit_GFX
-UTFTGLUE
-SPI
-MCUFRIEND_kbv
-RTClib
-Wire

It's not my first project but i used to use URTouch library wich is unfortunately not working with my screen. Furthermore, it's my first project with a touch screen.
My goal is to drive a MOFSET with my arduino to switch on and off LED lights on my aquarium. MOFSET is to make it like sunset and moonset.

I'm having trouble with the touch part. I use it to program the rise up hour and the differents paramterers. I would like to detect if i touch this area to change the parameters.

A second little problem is that i'm not able to whrite hour with 2 digits .... If Someone can help me it would be nice. Here is my actual code inspired by exemples on MCUFRIEND Library :

#include <Adafruit_GFX.h>
#include <UTFTGLUE.h>
#include <SPI.h>
#include <MCUFRIEND_kbv.h>
#include <RTClib.h>
#include <Wire.h>
#include <avr/pgmspace.h>
MCUFRIEND_kbv tft;         

RTC_DS1307 rtc;

#include <TouchScreen.h>
#define YP A1   
#define YM 7    
#define XM A2   
#define XP 6    
UTFTGLUE myGLCD(0x7781, A2, A1, A3, A4, A0);

extern uint8_t BigFont[];
extern uint8_t Grotesk16x32[];
extern uint8_t SixteenSegment16x24[];
extern uint8_t SmallFont[]; 

// 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

uint32_t cx, cy;
uint32_t rx[8], ry[8];
int32_t clx, crx, cty, cby;
float px, py;
int dispx, dispy, text_y_center, swapxy;
uint32_t calx, caly, cals;
char buf[13];

#define TOUCH_ORIENTATION  LANDSCAPE

TouchScreen myTouch(XP, YP, XM, YM, 300);
TSPoint tp;  

void readResistiveTouch(void)
{
    tp = myTouch.getPoint();
    pinMode(YP, OUTPUT);      
    pinMode(XM, OUTPUT);
    digitalWrite(YP, HIGH);   
    digitalWrite(XM, HIGH);
}


bool ISPRESSED(void)
{
    int count = 0;
    bool state, oldstate;
    while (count < 10) {
        readResistiveTouch();
        state = tp.z > 20 && tp.z < 1000;
        if (state == oldstate) count++;
        else count = 0;
        oldstate = state;
        delay(5);
    }
    return oldstate;
}

void drawBoutons(int x, int y)
{
    myGLCD.setColor(0,255,0);
    myGLCD.drawRect(x,y+20,x+40,y-23);
    myGLCD.drawRect(x+60,y+20,x+100,y-23);
    myGLCD.drawLine(x+10,y-2,x+30,y-2);
    myGLCD.drawLine(x+70,y-2,x+90,y-2);
    myGLCD.drawLine(x+20,y+7,x+20,y-10);
}

void startup()
{
    myGLCD.fillScr(0,0,0);
    drawBoutons(200,33);
    drawBoutons(200,83);
    drawBoutons(200,133);
    drawBoutons(200,183);  
}

void get_heure(int h, int m, int s){
  DateTime now= rtc.now();
  m=int(now.minute());
  h=int(now.hour());
  s=int(now.second());
  myGLCD.printNumI(h, 140, 230, 2, '0');
  myGLCD.print(":", 155, 230);
  myGLCD.printNumI(m, 170, 230, 2, '0');
  
}

void temps_parametres(){
  long lsh,lsm,csh,csm,llh,llm,clh,clm;
  lsh=17;
  lsm=0;
  csh=22;
  csm=0;
  llh=0;
  llm=0;
  clh=2;
  clm=30;
  myGLCD.printNumI(lsh,140,30, 2, '0');
  myGLCD.printNumI(lsm,170,30, 2, '0');
  
  myGLCD.printNumI(csh,140,80, 2, '0');
  myGLCD.printNumI(csm,170,80, 2, '0');
  
  myGLCD.printNumI(llh,140,130, 2, '0');
  myGLCD.printNumI(llm,170,130, 2, '0');
  
  myGLCD.printNumI(clh,140,180, 2, '0');
  myGLCD.printNumI(clm,170,180, 2, '0'); 
}


void setup() {
    digitalWrite(A0, HIGH);
    pinMode(A0, OUTPUT);
    myGLCD.InitLCD(TOUCH_ORIENTATION);
    myGLCD.clrScr();
    dispx = myGLCD.getDisplayXSize();
    dispy = myGLCD.getDisplayYSize();
    startup();
    myGLCD.setColor(255,255,255);
    myGLCD.setFont(Grotesk16x32);
    myGLCD.print("Leve Soleil : ",20,30);
    myGLCD.print(":", 155,30);
    myGLCD.print("Couche Soleil : ",20,80);
    myGLCD.print(":", 155,80);
    myGLCD.print("Leve Lune : ",20,130);
    myGLCD.print(":",155,130);
    myGLCD.print("Couche Lune : ", 20,180);
    myGLCD.print(":", 155,180);
    myGLCD.setColor(255,0,255);
    
    rtc.begin();
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}

void loop() {
        
    while (true) {}
}
void readResistiveTouch(void)
{
    tp = myTouch.getPoint();
    pinMode(YP, OUTPUT);     
    pinMode(XM, OUTPUT);
    digitalWrite(YP, HIGH);   
    digitalWrite(XM, HIGH);
}

Why do you need to set the mode of the pins every time this function is called? Why do you need to set the pins HIGH?

    int count = 0;
    bool state, oldstate;
    while (count < 10) {
        readResistiveTouch();
        state = tp.z > 20 && tp.z < 1000;
        if (state == oldstate) count++;

Local variables are NOT initialized, unless you do it.

What is the point of comparing state, that you have assigned a known value to, to some garbage left over from who knows when?

Local variables MUST always be initialized.

void loop() {
       
    while (true) {}
}

Why is there an infinite loop inside an infinite loop()?

Hello,
Thanks for your reply.
For the 2 first questions : This functions has been taken from Example included in MCUFRIEND.kbv library (TOuch screen calbiration) . I have tryed to understand the code of this example and i took the functions which seems to be usefull.

For the main void it's actually empty with only an infinite loop. I haven't done yet the touch detection void so i didn't fill it.

If you want i can write the exemple code i have tryed to understand.

The point is i'm actually blind in touch screen programing.

How do you read touch screen information to detect click on displayed button?

How do you read touch screen information to detect click on displayed button?

Isn't that what readResistiveTouch() is supposed to do?

What, exactly, IS a TSPoint? Doesn't it define if the screen IS being touched? Doesn't it define where the screen is being touched, if it is being touched?

I can NOT believe that the library didn't come with examples to cover something so basic.

Ok so if i say tp=readResistiveTouch(), then i will have 3 datas : tp.x , tp.y, tp.z and i should only use them for if conditions?

baracuda33:
Ok so if i say tp=readResistiveTouch(), then i will have 3 datas : tp.x , tp.y, tp.z and i should only use them for if conditions?

If that is the data that it returns, you can use them for any purpose you desire, including but not limited to if conditions.

Ok so if i say tp=readResistiveTouch(), then i will have

an error, because readResistiveTouch() is defined to return nothing.

Ok so i have to use :
tp = myTouch.getPoint() but then what is resistivetouch() for? i don't understand why he sets some pins high and other low. It's extracted from the calibration exemple on MCU library

Ok so i have to use :
tp = myTouch.getPoint() but then what is resistivetouch() for?

It's your code. Why did you write it that way? If you have a function called neverUsedForAnything(), would you hesitate to delete it?

If you don't understand code you are stealing/borrowing, stop stealing code.

The point is that i don't understand MCUlibrary and i don't know how to use URtouch from rinkydinky or how to use TFT screen. I have opened the calibration code from MCU and pick up things that can be applied in my case. But i don't understand everything especialy all the things i call at the beginning of the code (do i use everything?). I have some problems using mcufriend functions like to print num with 2 digits (to have time on screen according to RTC).... And to change font. I need help to understand how does this thing work

baracuda33:
The point is that i don't understand MCUlibrary and i don't know how to use URtouch from rinkydinky or how to use TFT screen. I have opened the calibration code from MCU and pick up things that can be applied in my case. But i don't understand everything especialy all the things i call at the beginning of the code (do i use everything?). I have some problems using mcufriend functions like to print num with 2 digits (to have time on screen according to RTC).... And to change font. I need help to understand how does this thing work

The normal path to understanding is study. You have to quit this and work on some simpler projects and get them to work first. Otherwise it won't be possible to absorb what you're learning. Just as in math, where you can't begin with calculus.

The only other problem that I can think of, that you might be having, is difficulty in attaining the realization that you need to exhaustively mine the documentation.

Yea, i'm not a real beginner since i have done few programs on arduino, but i still have some miss understading on few points. For now i have problems on MCU library that i can't solve and this make me bad. For exemple for the 2 digits it seems to be defined in the mcu lib but when i call it it doesn't work....

baracuda33:
Yea, i'm not a real beginner since i have done few programs on arduino, but i still have some miss understading on few points. For now i have problems on MCU library that i can't solve and this make me bad. For exemple for the 2 digits it seems to be defined in the mcu lib but when i call it it doesn't work....

What did the library documentation and examples tell you? Also, "doesn't work" is not a sufficiently detailed report for anyone to give you any help.

Ok So :
I understand that by calling function : myTouch.getPoint() like :
tp=myTouch.getPoint() i can get x y and z coordonate by using : tp.x, tp.y and tp.z

The main issue i have about the two digit is :
in my function i use :

myGLCD.printNumI(h,170,30, 2, '0');

h is an int wich is define as :

  DateTime now= rtc.now();
int h=int(now.hour())

The point is that is for exemple i remove the RTC and just write h=1, the lcd will display 1 and not 01. I don't understand because when i look into the lib i found :

	void printNumI(long num, int x, int y, int length=0, char filler=' ') {
		 char buf[16]; ltoa(num, buf, 10); 
		 settextcursor(buf, x, y); MCUFRIEND_kbv::print(buf);}

And my loop with touch screen not working :

void temps_parametres(){
  
  startup();
  int a=0;
  myGLCD.print("Leve Soleil : ",20,30);
  myGLCD.print(":", 155,30);
  myGLCD.print("Couche Soleil : ",20,80);
  myGLCD.print(":", 155,80);
  myGLCD.print("Leve Lune : ",20,130);
  myGLCD.print(":",155,130);
  myGLCD.print("Couche Lune : ", 20,180);
  myGLCD.print(":", 155,180);
  myGLCD.printNumI(lsh,140,30, 2, '0');
  myGLCD.printNumI(lsm,170,30, 2, '0');
  
  myGLCD.printNumI(csh,140,80, 2, '0');
  myGLCD.printNumI(csm,170,80, 2, '0');
  
  myGLCD.printNumI(llh,140,130, 2, '0');
  myGLCD.printNumI(llm,170,130, 2, '0');
  
  myGLCD.printNumI(clh,140,180, 2, '0');
  myGLCD.printNumI(clm,170,180, 2, '0');
  do
  {
  tp = myTouch.getPoint();
  if (tp.x<=240 && tp.x>=200 && tp.y<=50 && tp.y>=10)
    {
      if(lsm==59){
        if(lsh==23)
          {lsh=0;
           lsm=0;
          }
        else{lsh=lsh+1;}
      }
      else{lsm=lsm+1;}
     myGLCD.printNumI(lsh,140,30, 2, '0');
     myGLCD.printNumI(lsm,170,30, 2, '0');           
    }
  if (tp.x<=240 && tp.x>=200 && tp.y<=100 && tp.y>=60)
    {
      if(csm==59){
        if(csh==23)
          {csh=0;
           csm=0;
          }
        else{csh=csh+1;}
      }
      else{csm=csm+1;}
      myGLCD.printNumI(csh,140,80, 2, '0');
      myGLCD.printNumI(csm,170,80, 2, '0');   
    }
  if (tp.x<=240 && tp.x>=200 && tp.y<=150 && tp.y>=110)
    {
      if(llm==59){
        if(llh==23)
          {llh=0;
           llm=0;
          }
        else{llh=llh+1;}
      }
      else{llm=llm+1;}
     myGLCD.printNumI(llh,140,130, 2, '0');
     myGLCD.printNumI(llm,170,130, 2, '0');  
    }
  if (tp.x<=160 && tp.x>=0 && tp.y<=200 && tp.y>=160)
    {
      if(clm==59){
        if(clh==23)
          {clh=0;
           clm=0;
          }
        else{clh=clh+1;}
      }
      else{clm=clm+1;}
      myGLCD.printNumI(clh,140,180, 2, '0');
      myGLCD.printNumI(clm,170,180, 2, '0');   
    }     
  if (tp.x<=300 && tp.x>=260 && tp.y<=50 && tp.y>=10)
    {
      if(lsm==0){
        if(lsh==0)
          {lsh=23;
           lsm=59;
          }
        else{lsh=lsh-1;lsm=59;}
      }
      else{lsm=lsm-1;}
     myGLCD.printNumI(lsh,140,30, 2, '0');
     myGLCD.printNumI(lsm,170,30, 2, '0');               
    }
  if (tp.x<=300 && tp.x>=260 && tp.y<=100 && tp.y>=60)
    {
      if(csm==0){
        if(csh==0)
          {csh=23;
           csm=59;
          }
        else{csh=csh-1;csm=59;}
      }
      else{csm=csm-1;}
      myGLCD.printNumI(csh,140,80, 2, '0');
      myGLCD.printNumI(csm,170,80, 2, '0');               
    }
  if (tp.x<=300 && tp.x>=260 && tp.y<=150 && tp.y>=110)
    {
      if(llm==0){
        if(llh==0)
          {llh=23;
           llm=59;
          }
        else{llh=llh-1;llm=59;}
      }
      else{llm=llm-1;}
     myGLCD.printNumI(llh,140,130, 2, '0');
     myGLCD.printNumI(llm,170,130, 2, '0'); 
    }
  if (tp.x<=300 && tp.x>=260 && tp.y<=200 && tp.y>=160)
    {
      if(clm==0){
        if(clh==0)
          {clh=23;
           clm=59;
          }
        else{clh=clh-1;clm=59;}
      }
      else{clm=clm-1;}               
    }
    myGLCD.printNumI(clh,140,180, 2, '0');
    myGLCD.printNumI(clm,170,180, 2, '0');   
       
  if (tp.x<=220 && tp.x>=100 && tp.y<=260 && tp.y>=210){a=1;}
  }while (a=!1);
}

I used the same coordonates as the display code (for exemple last if is on a button build as     myGLCD.fillRect(100,210,220,260);

Numbers are usually printed without leading zeroes. Otherwise, how would a print routine know how many zeroes to print? :slight_smile: If the number is less than 10, print a 0 first.

baracuda33:
And my loop with touch screen not working :

Again, you say "not working"? Do you understand that we are not mind readers?

Yes sorry :confused: i can send it on arduino but if i click everyhere nothing happen. To try to understand a bit how touch screen works i have made a quick program but the results seems weird :

#include <Adafruit_GFX.h>
#include <UTFTGLUE.h>
#include <SPI.h>
#include <MCUFRIEND_kbv.h>
#include <RTClib.h>
#include <Wire.h>
#include <avr/pgmspace.h>
MCUFRIEND_kbv tft;       

RTC_DS1307 rtc;

#include <TouchScreen.h>
#define YP A1   
#define YM 7    
#define XM A2   
#define XP 6    
UTFTGLUE myGLCD(0x7781, A2, A1, A3, A4, A0);
#define TOUCH_ORIENTATION  LANDSCAPE

TouchScreen myTouch(XP, YP, XM, YM, 300);
TSPoint tp;  
int dispx, dispy;

void setup() {
    myGLCD.InitLCD(TOUCH_ORIENTATION);
    myGLCD.clrScr();
    dispx = myGLCD.getDisplayXSize();
    dispy = myGLCD.getDisplayYSize();
    myGLCD.setColor(0,0,0);
    myGLCD.fillRect(0,dispx,0,dispy);
    Serial.begin(9600);

}

void loop() {
    tp = myTouch.getPoint();
    Serial.print(tp.x);
    Serial.print('\n');
    Serial.print(tp.y);
    Serial.print('\n');
    Serial.print(tp.z);
    Serial.print('\n');
    Serial.print(1); 
    Serial.print('\n');
    delay(1000);

}

Each 1 sec serial monitoring give me values of x, y and z. Without clicking, i have a tp.Z=0 but tp.x=259-272 (mooving arround 260), and tp.y=680-684 (mooving around 680).

If i click on left top then right top then right bottom and then left bottom (in landscape usb on the left) i get :

tp.x =210
tp.y= 250

tp.x=870
tp.y=230

tp.x=860
tp.y=900

tp.x=200
tp.y=900

So i guess that's why my first attempt wasn't working, because i used pixel position and not toutch screen levels.

Can i correct this value to match the pixels ones easily or not?

Can i correct this value to match the pixels ones easily or not?

Why do you assume that the values are not in pixels?

Add Serial.print() statements to setup(). Print the values (with identifiers) of dispx and dispy.

How do those values relate to the values you see when you touch the 4 corners?

Does the value of tp.z change as you touch and press?

You are now on the right track, with trying to understand how the library works. This is a much better approach that a shotgun attack.