Arduino and TFT

Hi,

I am working on a project that needs to output the current letter being showed on the TFT screen. The letters are being printed through a for loop to go through each letter of the alphabet.
I need to have a button which when click it, it prints to the serial monitor the letter being showed and the problem is that I cannot make it work because it only works if the button is already being pressed when the letter changes. I've even tried using the debounce method but it still doesn't work.

I would appreciate if someone can help me find a solution to for this, for example what should I do to register the fact that the button was pressed during that particular cycle of the for loop.

Thank you

Can't see your code.

I’d guess without looking at you code that it is simply a matter of removing the delay() statement that you have put in to regulate the speed of character change on your display (use millis() instead), putting a Serial.println in the correct place, putting a button test in the right place and putting a test in to prevent multiple button presses within a short period printing the same character.

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

How have you got your button wired?

Thanks.. Tom.. :slight_smile:

I'm sorry, here's my code:

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h> // Hardware-specific library

//Colors
#define BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0
#define WHITE           0xFFFF

//CS, CD, WR, RD, RESET
Adafruit_TFTLCD tft(A3, A2, A1, A0, A4);

const int button = 10;
int buttonState; 

void setup(void) 
{
  Serial.begin(9600);
  Serial.println("Start:");
  tft.reset();
  delay(1000);
  pinMode(button, INPUT);
  tft.begin(0x9325);
}

void loop()
{
  tft.setRotation(3);
  print(); 
  delay(1000);
}
 
void print()
{
  int letterNumber = 65;
  char letter = letterNumber;

  for(int i = 0; i < 26; i++)
  {
    tft.fillScreen(BLACK);
    tft.setTextColor(WHITE);
    tft.setTextSize(20);
    tft.drawRoundRect(80, 30, 155, 180, 15, WHITE);
    tft.setCursor(110, 50);
    tft.print(letter);
    delay(2000);
    //here's where I want to the check if the button is pressed during the
    //2 delay second while the letter is being showed on TFT
    if(letter == 'Z')
    {
      tft.fillScreen(BLACK);
      tft.drawRoundRect(10, 60, 300, 100, 15, WHITE);
      tft.setCursor(30, 80);
      tft.setTextSize(9);
      tft.print("SPACE");
      delay(2000);
    }
    letter = letter + 1;
  }
}

At the moment I do not have any code for the button as I deleted it because I was testing some other options but couldn't make it work.

I have mentioned as a comment where I want to the check if the button is pressed.

Thanks

You are going to HAVE to get rid of that delay(). Look at the blink without delay example.

While the two seconds are going by that the letter is being displayed you could be doing other things, like checking the state of a switch, if you weren't burying your head in the sand by using delay().

PaulS:
You are going to HAVE to get rid of that delay(). Look at the blink without delay example.

While the two seconds are going by that the letter is being displayed you could be doing other things, like checking the state of a switch, if you weren't burying your head in the sand by using delay().

I understand that, I've been trying and because I am still a newbie using arduino I can't figure out to make it work, even following the logic of that example.

Would it be something like this:

void loop() {

  int letterNumber = 65;
  char letter = letterNumber;

  for(int i = 0; i < 26; i++)
  {
    tft.fillScreen(BLACK);
    tft.setTextColor(WHITE);
    tft.setTextSize(20);
    tft.drawRoundRect(80, 30, 155, 180, 15, WHITE);
    tft.setCursor(110, 50);
    tft.print(letter);
    buttonState = digitalRead(button);
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      // save the last time the button was pressed
      previousMillis = currentMillis;
      if(buttonState = HIGH){
        Serial.println(letter);
        buttonState = LOW;
      }
    }
    if(letter == 'Z')
    {
      tft.fillScreen(BLACK);
      tft.drawRoundRect(10, 60, 300, 100, 15, WHITE);
      tft.setCursor(30, 80);
      tft.setTextSize(9);
      tft.print("SPACE");
    }
    letter = letter + 1;
  }
  
}

Would it be something like this:

No. For several reasons.

On any given pass through loop(), it might, or might not, be time to display the next letter. Obviously, to me at least, you can NOT use a for loop to define the next letter to display.

Write a function to display a letter. That function should take one argument - the letter to display.

Use the blink without delay technique to determine if it is time to call that function again. If it is, call it, and increment the letter to show next time (resetting to A as needed). Of course, you'll also reset lastTimeLetterDisplayed to the current "time", too (as obtained from millis()).

On EVERY pass through loop(), you will check for a switch press. If the switch has become (NOT is) pressed, send the letter currently being displayed (not the value in the variable to use next time) to the serial port.

This might be a problem:

      if(buttonState = HIGH){

Also, why waste memory on letterNumber ; you never use it.

PaulS:
No. For several reasons.

On any given pass through loop(), it might, or might not, be time to display the next letter. Obviously, to me at least, you can NOT use a for loop to define the next letter to display.

Write a function to display a letter. That function should take one argument - the letter to display.

Use the blink without delay technique to determine if it is time to call that function again. If it is, call it, and increment the letter to show next time (resetting to A as needed). Of course, you'll also reset lastTimeLetterDisplayed to the current "time", too (as obtained from millis()).

On EVERY pass through loop(), you will check for a switch press. If the switch has become (NOT is) pressed, send the letter currently being displayed (not the value in the variable to use next time) to the serial port.

Thank you for your answer. Totally makes sense, but how do I exactly check if the button was pressed, can you help me on that?