Cycle 16 numbers

how would I cycle through 16 numbers?
My screen currently prints the number of the touch grid I press,
what I want is touch button 1 “UP” to cycle up through the numbers 1-16
and touch button 3 “DOWN” to cycle down through the numbers 1-16

#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include "XPT2046_touch.h"
#include <SPI.h>
#include <Fonts/FreeMonoBoldOblique12pt7b.h>;

// For the Adafruit shield, these are the default.
#define TFT_DC PB9
#define TFT_CS PB8

#define CS_PIN  PB6  // Chip Select pin
#define LINES     4
#define COLUMNS   3
  

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
SPIClass mySPI(1); //Create an SPI instance on SPI1 port.
XPT2046_touch ts(CS_PIN, mySPI); // Chip Select pin, SPI port

uint16_t xy[2];

void setup() {

   tft.begin();
   ts.begin(); //Begin TouchScreen.
   ts.setButtonsNumber(COLUMNS, LINES); //Divide the Touch screen area into 4 columns and 2 lines and make them act as buttons. 
  
    tft.fillScreen(ILI9341_BLACK);
    tft.setRotation(0);
   // tft.drawRoundRect(20, 20, 20, 20, 20, 20);
    //   tft.drawRoundRect(50, 50, 50, 50, 50, 50);
    tft.fillRoundRect(170, 10, 78, 60, 8, 0xCA00);
    tft.fillRoundRect(170, 90, 78, 60, 8, 0x968B);
    tft.fillRoundRect(170, 170, 78, 60, 8, 0xCA00);
    tft.setFont(&FreeMonoBoldOblique12pt7b);
    tft.setCursor(25, 300);
    tft.setTextColor(ILI9341_GREEN);
   
  
    tft.setTextColor(ILI9341_BLACK);
    tft.setCursor(175, 50);
    tft.print("UP");

    tft.setTextColor(ILI9341_BLACK);
    tft.setCursor(175, 130);
    tft.print("SAVE");

    tft.setTextColor(ILI9341_BLACK);
    tft.setCursor(175, 200);
    tft.print("DOWN");
   
}

void loop() {


if(ts.read_XY(xy)){ //If the touch screen is preesed, read the X,Y coordinates and print them on tft screen
     uint8_t buttonNumber = ts.getButtonNumber();
    //if(buttonNumber > 0)

            tft.fillRect(0, 150, 90, 60, ILI9341_BLACK);
           tft.setTextColor(ILI9341_GREEN);
           tft.setTextSize(2);
            tft.setCursor(10, 200);
            tft.print(buttonNumber);
           // delay(250);
            }

  }

More details please.

Should the UP button increment the number by 1 or print all 16 numbers ? (I assume the first) What should happen when the number reaches 16 ? Should it stop there or roll over to 1 ?

Same questions in reverse for the DOWN key

You need to detect when a button press occurs and whether it has changed since the previous button detected. If it has then the button has become pressed and act on it.

Determine which button has become pressed, add or subtract one from the total, if the number limit has been exceeded then either add or subtract 1 from it to bring it back into range or roll the number over to its lower or upper value

yes increment the number by 1
And rollover back to 1 after 16

Have a look at the "State change" example to see the difference between "a button is pressed" (= a state) and "a button becoming pressed" (= an event). And if you want easy, use a library like Bounce2.

the code in my loop already knows when I press a button
I need to find a way to use button press 1 or 3 to cycle up or down 16 numbers

the code in my loop already knows when I press a button

I am not familiar with the XPT2046_touch library. Where did you get it from ?

Does the read_XY() function tell you when a button is pressed or when a button becomes pressed ?

I'm using this Library with a stm32 bluepill board, it was the only touch library I could get working with my display and board

I'm not sure of the difference between "is pressed or when a button becomes pressed"
but when I touch the "UP" button, (buttonNumber) becomes the number 1
the library example sends it to the serial monitor, I've sent it to my display instead

so I some how need (buttonNumber) if its number 1, to increase a counter of 1-16
and if (buttonNumber) is 3, to decrease the counter of 1-16
and then print the counter number not the (buttonNumber) which my code currently does

septillion:
Have a look at the "State change" example to see the difference between "a button is pressed" (= a state) and "a button becoming pressed" (= an event). And if you want easy, use a library like Bounce2.

// Variables will change:
int buttonPushCounter = 0; // counter for the number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button

this looks like what I need, thanks for that

Thanks for the link!

Leetut:
I'm not sure of the difference between "is pressed or when a button becomes pressed"

What is your native language?

But to rephrase it, there is a difference if you check if a button is pressed or it became (started being) pressed. If you check both a lot the first will be true A LOT while the other is only true once when you start pressing it. So if you increment a counter every time the microcontroller sees the button being pressed it will increment A LOT (because it's very fast) but you want to increment it just once.

Leetut:
so I some how need (buttonNumber) if its number 1, to increase a counter of 1-16

So no, you need to check if that number changes to 1 :wink:

Leetut:
// Variables will change:
int buttonPushCounter = 0; // counter for the number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button

this looks like what I need, thanks for that

Are you really expecting a button state of -12345? Or count to 35543? Otherwise, change the type :wink:

But yeah, a check between the current and the last/previous is indeed checking for a change.

@septillion’s reply, graphically.

                      ______________________
debounced input  _____|                     |_________________________
                       _            
becomes pressed   ____| |_____ <- on one program scan ________________
                       _____________________
is pressed  __________|                     |________________________

                      ^                     ^
gazillions of program scans

gotcha!
I’ll experiment with the suggestions thank you!

I'm getting somewhere!
this makes the counter go up 1 with each button press
but how to make it stop at 16 then go back to 1?

void loop() {


if(ts.read_XY(xy)){

      
        //If the touch screen is preesed, read the X,Y coordinates and print them on tft screen
      
     uint8_t buttonNumber = ts.getButtonNumber();
             buttonState = buttonNumber; 
             {
             
             
           // compare the buttonState to its previous state
  if (buttonState != lastButtonState) 
  
    // if the state has changed, increment the counter
     (buttonState == 1);
    
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
 
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;
  
            tft.fillRect(0, 150, 90, 60, ILI9341_BLACK);
           tft.setTextColor(ILI9341_GREEN);
           tft.setTextSize(2);
            tft.setCursor(10, 200);
            tft.print(buttonPushCounter);
            delay(250);
            }
}
  }
if (buttonPushCounter > 16)
  buttonPushCounter = 1;

Pieter

buttonPushCounter++;
if (buttonPushCounter >= 16)
  {
    buttonPushCounter = 1;  //reset count back to 1
  {

thank you!
Now I only want the number to go up when I press up, which is mapped to the Number 1 according my serial monitor,
as in, if (buttonNumber == 1) increase the counter
it currently increases the counter no matter where I press on the screen
latest code:

#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include "XPT2046_touch.h"
#include <SPI.h>
#include <Fonts/FreeMonoBoldOblique12pt7b.h>;

// For the Adafruit shield, these are the default.
#define TFT_DC PB9
#define TFT_CS PB8

#define CS_PIN  PB6  // Chip Select pin
#define LINES     4
#define COLUMNS   3
// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
SPIClass mySPI(1); //Create an SPI instance on SPI1 port.
XPT2046_touch ts(CS_PIN, mySPI); // Chip Select pin, SPI port

uint16_t xy[2];

void setup() {
 Serial.begin(9600);
   tft.begin();
   ts.begin(); //Begin TouchScreen.
   ts.setButtonsNumber(COLUMNS, LINES); //Divide the Touch screen area into 4 columns and 2 lines and make them act as buttons. 
  
    tft.fillScreen(ILI9341_BLACK);
    tft.setRotation(0);
   // tft.drawRoundRect(20, 20, 20, 20, 20, 20);
    //   tft.drawRoundRect(50, 50, 50, 50, 50, 50);
    tft.fillRoundRect(170, 10, 78, 60, 8, 0xCA00);
    tft.fillRoundRect(170, 90, 78, 60, 8, 0x968B);
    tft.fillRoundRect(170, 170, 78, 60, 8, 0xCA00);
    tft.setFont(&FreeMonoBoldOblique12pt7b);
    tft.setCursor(25, 300);
    tft.setTextColor(ILI9341_GREEN);
   
  
    tft.setTextColor(ILI9341_BLACK);
    tft.setCursor(175, 50);
    tft.print("UP");

    tft.setTextColor(ILI9341_BLACK);
    tft.setCursor(175, 130);
    tft.print("SAVE");

    tft.setTextColor(ILI9341_BLACK);
    tft.setCursor(175, 200);
    tft.print("DOWN");
    
}

void loop() {


if(ts.read_XY(xy)){

      
        //If the touch screen is preesed, read the X,Y coordinates and print them on tft screen
      
     byte buttonNumber = ts.getButtonNumber();
            // buttonState = buttonNumber; 
             
             
             
      // compare the buttonState to its previous state
  if //(buttonState != lastButtonState)      
    (buttonNumber == 1);
       Serial.println(buttonNumber);
    buttonPushCounter++;
    {
if (buttonPushCounter >= 17)
    buttonPushCounter = 1;  //reset count back to 1
  
 
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;
  
            tft.fillRect(0, 150, 90, 60, ILI9341_BLACK);
           tft.setTextColor(ILI9341_GREEN);
           tft.setTextSize(2);
            tft.setCursor(10, 200);
            tft.print(buttonPushCounter);
            delay(250);
            }


}
}

totally stuck now, tried lots of configurations

Leetut:
totally stuck now, tried lots of configurations

Let's see what you tried

Did the code in your original post work ?

Just been adding if, else, statements into various points of the last code I posted,
Can’t seem to get this bit working
Only if (buttonNumber == 1) increase the counter

tried this

  if (buttonState != lastButtonState && (buttonNumber == 1));

and this
if (buttonState != lastButtonState && buttonNumber == 1;

and this
 if (buttonState != lastButtonState);    
   buttonNumber == 1;
if (buttonState != lastButtonState && buttonNumber == 1);
  buttonCounter++;

This is equivalent to:

if (buttonState != lastButtonState && buttonNumber == 1) {
  ; // Nothing
}
buttonCounter++;

See the problem? The semicolon terminates the body of the if statement, and the next line is executed no matter what the if statement expression evaluates to.

Please look at Arduino/C++ examples to get the syntax right, and enable compiler warnings in the Arduino IDE's preferences menu (set "Compiler Warnings" to "All"), so it tells you about these kinds of bugs:

sketch.ino: In function 'void loop()':
sketch.ino:9:57: warning: suggest braces around empty body in an 'if' statement [-Wempty-body]
 if (buttonState != lastButtonState && buttonNumber == 1);
                                                         ^

Pieter