Using STMPE610 gpio pin

Anybody using the gpio3 port on a stmpe610? I am using the adafruit library but they do not have that built in. Looks like they can send registers with it but this is a little over my head.

This might help

Particularly pages 42ff

I have looked at that but a little unsure on what to send. I know one of the addresses is 0x10 but do i put in the value to send 0x3 for the gpio3 or do i just put 3.

First you need the direction register (0x13) for the respective pin set to OUTPUT and then you’d set the bit representing the GPIO you want. For GPIO3 this would be 0b00001000 which translates to 0x08 :wink:
0x03 would set GPIO0 and GPIO1 (0b00000011).

Thanks for you guidance. Guess I am going to have to lean a little binary things.

Hi, if you are using the the adafruit library which is available on Particle WEB IDE you can use touch.writeRegister8() function.
So in setup you will need to add:

touch.writeRegister8(STMPE_GPIO_DIR, 0x08); //sets GPIO3 as output

and in your loop you can call:

touch.writeRegister8(STMPE_GPIO_SET_PIN, 0x08); // set GPIO3 HIGH
touch.writeRegister8(STMPE_GPIO_CLR_PIN, 0x08); //set GPIO3 LOW

I guess that something like this should set GPIO3 HIGH when touched and GPIO3 LOW when is not touched ( modified “touchtest.ino”)

/******************/

void setup() { 
  Serial.begin(9600);
  Serial.println("Adafruit STMPE610 example");
  Serial.flush();

  // if using hardware SPI on an Uno #10 must be an output, remove line
  // if using software SPI or I2C
  //pinMode(10, OUTPUT);

  // If using I2C you can select the I2C address (there are two options) by calling
  // touch.begin(0x41), the default, or touch.begin(0x44) if A0 is tied to 3.3V
  // If no address is passed, 0x41 is used
  if (! touch.begin()) {
    Serial.println("STMPE not found!");
    while(1);
  }
  Serial.println("Waiting for touch sense");
  touch.writeRegister8(STMPE_GPIO_DIR, 0x08); //sets GPIO3 as output 
}

void loop() {
  uint16_t x, y;
  uint8_t z;
  if (touch.touched()) {
    // read x & y & z;
    touch.writeRegister8(STMPE_GPIO_SET_PIN, 0x08); // set GPIO3 HIGH
    while (! touch.bufferEmpty()) {
      Serial.print(touch.bufferSize());
      touch.readData(&x, &y, &z);
      Serial.print("->("); 
      Serial.print(x); Serial.print(", "); 
      Serial.print(y); Serial.print(", "); 
      Serial.print(z);
      Serial.println(")");
    }
    touch.writeRegister8(STMPE_INT_STA, 0xFF); // reset all ints
  }else{
      touch.writeRegister8(STMPE_GPIO_CLR_PIN, 0x08); //set GPIO3 LOW
  }
  delay(10);
  
}

I sent 0x17 first . It only stays on while touched. I tried moving it to a button but it just pulsed it once.

gpio3 is connected to a backlight control.

You sent 0x17 (= 0b00010111) where to?
Without telling us the register there is little informational value to that statement :wink:

We also don’t know anything about the rest of your code and how you have initialized the chip at all.

Sorry I sent x08 to 0x17 register.

I repeat my “request”: What does your code look like?
If you used @dreamER’s code the behaviour you described is exactly what one would expect due to this

BTW, as a short hint with regards to bit manipulation, if you want to keep your code a bit more dynamic/maintainable you could replace your hardcoded 0x08 for GPIO3 with this

  uint8_t bits;
  uint8_t bitNumber = 3;
  // set a specific bit
  bits = 1 << bitNumber;  // shift a single bit x places to the left 
1 Like

I copied in dreamer code and yes the screen stays on while I hold the touch down. I did have to add the register 17 in setup to make that work.

I have additional code that when a button is pressed it should send the on when one is pressed and off when another is pressed. The buttons work fine because right now they are turning a neopixel on and off.

void setup() {
  Wire.begin();
  keyboard.begin();
  keyboard.setBacklight(0.5f);
  
  pixels.begin();
  pixels.setBrightness(30);
  

  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(ILI9341_BLACK);
  screenClear();
  if (! ts.begin()) {
    tft.println("STMPE not found!");
    while(1);
  }
  ts.writeRegister8(0x17, 0x08);
  //ts.writeRegister8(0x13, 0x08);
  //ts.writeRegister8(0x10, 0x08);
  ts.writeRegister8(STMPE_GPIO_SET_PIN, 0x08); // set GPIO3 HIGH
}

void loop(void) {
  uint16_t x, y;
  uint8_t z;
  if (ts.touched()) {
    // read x & y & z;
    ts.writeRegister8(STMPE_GPIO_SET_PIN, 0x08); // set GPIO3 HIGH
    while (! ts.bufferEmpty()) {
      Serial.print(ts.bufferSize());
      ts.readData(&x, &y, &z);
      tft.print("->("); 
      tft.print(x); tft.print(", "); 
      tft.print(y); tft.print(", "); 
      tft.print(z);
      tft.println(")");
    }
    ts.writeRegister8(STMPE_INT_STA, 0xFF); // reset all ints
  }else{
      ts.writeRegister8(STMPE_GPIO_CLR_PIN, 0x08); //set GPIO3 LOW
  }
  delay(10);
  
  if (keyboard.keyCount()) {
    const BBQ10Keyboard::KeyEvent key = keyboard.keyEvent();
    if (key.state == BBQ10Keyboard::StateRelease) {
      if (key.key == KEY_BTN_RIGHT2){
        tft.print(txtBuf);
        Particle.publish("blackberry",txtBuf,PRIVATE);
      }
      else if( key.key == KEY_BTN_LEFT1){
          keyleft1();
      }
      else if( key.key == KEY_BTN_LEFT2){
          keyleft2();
      }
      else if( key.key == KEY_BTN_RIGHT1){
          keyright1();
      }
      else if( key.key == KEY_BTN_CR){
          tft.print("\n");
      }
      else {
         tft.print(key.key);
         strncat(txtBuf,&key.key,sizeof(key.key));
      }  
  }
}

void keyleft2(void){
  pixels.clear();
  pixels.show();
  //ts.writeRegister8(STMPE_GPIO_SET_PIN, 0x08);
  //ts.writeRegister8(0x17,0x0F);
  ts.writeRegister8(STMPE_GPIO_SET_PIN, 0x08); // set GPIO3 HIGH    
}

void keyright1(void){
  pixels.setPixelColor(0, pixels.Color(128,0,0));
  pixels.show();
  ts.writeRegister8(STMPE_GPIO_CLR_PIN, 0x08); //set GPIO3 LOW
}

You should still set the STMPE_GPIO_DIR (0x13) register and instead of 0x17 it is better style to use the definition STMPE_GPIO_ALT_FUNCT to make it easier to read the code.

Also while(1); is not a good idea on Particle devices as it will break the cloud connection.
Rather use while(1) Particle.process();.

Instead of a load of if()..else if()..else you may want to consider using switch() .. case .. default

If you don’t want the GPIO to go off immediately after you released the touch screen, just wrap the respective call in some timeout logic (e.g. go off 10 seconds after the last touch).

Hi,
you can try the one below this is with 5s Timeout.
Please note that I didn’t try this, I’m not sure if my switch… case… implementation will work at all so I apologize in advance :see_no_evil: .

Also I do not understand why you have to call
ts.writeRegister8(STMPE_GPIO_ALT_FUNCT, 0x08);
in setup to make tings working as manual says on pg.44:

GPIO_ALT_FUNCT
Description: Alternate function register. "‘0’ sets the corresponding pin to function as
touchscreen/ADC, and ‘1’ sets it into GPIO mode.

On power-up reset, all GPIOs are set as input.

So from my perespective calling ts.writeRegister8(STMPE_GPIO_DIR, 0x08) in setup should be enough.

Code:

unsigned long TimeOut = 5000;
unsigned long Tstart = 0;
unsigned long Telapsed = 0;

uint8_t GPIO_3;
uint8_t bitNumber = 3;

bool keys_controll = false;

void setup() {
  Wire.begin();
  keyboard.begin();
  keyboard.setBacklight(0.5f);
  
  pixels.begin();
  pixels.setBrightness(30);
  

  tft.begin();
  tft.setRotation(1);
  tft.fillScreen(ILI9341_BLACK);
  screenClear();
  if (! ts.begin()) {
    tft.println("STMPE not found!");
    while(1) Particle.process();
  }
  GPIO_3 = 1 << bitNumber;
  ts.writeRegister8(STMPE_GPIO_ALT_FUNCT, GPIO_3);
  ts.writeRegister8(STMPE_GPIO_DIR, GPIO_3); //sets GPIO3 as output 
  //ts.writeRegister8(STMPE_GPIO_SET_PIN, GPIO_3); // set GPIO3 HIGH
}

void loop(void) {
  uint16_t x, y;
  uint8_t z;
  if (ts.touched()) {
    // read x & y & z;
    ts.writeRegister8(STMPE_GPIO_SET_PIN, GPIO_3); // set GPIO3 HIGH
    
    while (! ts.bufferEmpty()) {
      Serial.print(ts.bufferSize());
      ts.readData(&x, &y, &z);
      tft.print("->("); 
      tft.print(x); tft.print(", "); 
      tft.print(y); tft.print(", "); 
      tft.print(z);
      tft.println(")");
    }
    Tstart = millis();
    ts.writeRegister8(STMPE_INT_STA, 0xFF); // reset all ints
  }else{
      if(! keys_controll){
      Telapsed = millis() - Tstart;
         if(Telapsed >= TimeOut){
              ts.writeRegister8(STMPE_GPIO_CLR_PIN, GPIO_3);
     }
  }
}
  delay(10);

if (keyboard.keyCount()) {
    const BBQ10Keyboard::KeyEvent key = keyboard.keyEvent();
    if (key.state == BBQ10Keyboard::StateRelease) {
    switch (key.key){
        case KEY_BTN_RIGHT1: {
            keyright1();
            break;    
        }
        case KEY_BTN_RIGHT2: {
            tft.print(txtBuf);
            Particle.publish("blackberry",txtBuf,PRIVATE);
            break;
        }
        case KEY_BTN_LEFT1: {
            keyleft1();
            break;
        }
        case KEY_BTN_LEFT2: {
            keyleft1();
            break;
        }  
        case KEY_BTN_CR: {
            tft.print("\n");
        }
        default: {
            tft.print(key.key);
            strncat(txtBuf,&key.key,sizeof(key.key));      
       }
   }
  }
 }
}

void keyleft2(void){
  pixels.clear();
  pixels.show();
  //ts.writeRegister8(STMPE_GPIO_SET_PIN, 0x08);
  //ts.writeRegister8(0x17,0x0F);
  ts.writeRegister8(STMPE_GPIO_SET_PIN, GPIO_3); // set GPIO3 HIGH 
  keys_controll = true;   
}

void keyright1(void){
  pixels.setPixelColor(0, pixels.Color(128,0,0));
  pixels.show();
  ts.writeRegister8(STMPE_GPIO_CLR_PIN, GPIO_3); //set GPIO3 LOW
  keys_controll = false; 
}

I havnt not tried the switch statement yet. The backlight control works good now.

Thanks for all your help.

1 Like