textile touch matrix 3×3

Code for Processing/Java and ESP32/C++

Both code work with the ESP32 connected via USB.

import processing.serial.*;

int t1_val = 0;
int t2_val = 0;
int t3_val = 0;

int t4_val = 0;
int t5_val = 0;
int t6_val = 0;

int t7_val = 0;
int t8_val = 0;
int t9_val = 0;

boolean t1_triggered = false;
boolean t2_triggered = false;
boolean t3_triggered = false;

boolean t4_triggered = false;
boolean t5_triggered = false;
boolean t6_triggered = false;

boolean t7_triggered = false;
boolean t8_triggered = false;
boolean t9_triggered = false;

int gridsize = 10;
int pad = 80;

Serial myPort;

void setup () {
  size(400,400);        // window size
 
 ellipseMode(CENTER);
 
  // List all the available serial ports
  println(Serial.list());
  String portName = Serial.list()[1];
  myPort = new Serial(this,portName, 9600);
  myPort.bufferUntil('\n');
  
  gridsize = int((width-pad )*.3333);
  //myPort.write('s');
  
}



void serialEvent (Serial myPort) {

  try {
   operateSerial(myPort);
  }
  catch(RuntimeException e) {
    e.printStackTrace();
  }

}


void operateSerial(Serial myport) {
  String portData = myport.readString();
  
  String[] stringData = split(portData, ',');
  
  float[] values = float(stringData);
  
 
  t1_val = int(values[0]);
  t2_val = int(values[1]);
  t3_val = int(values[2]);
  
  t4_val = int(values[3]);
  t5_val = int(values[4]);
  t6_val = int(values[5]);
  
  t7_val = int(values[6]);
  t8_val = int(values[7]);
  t9_val = int(values[8]);
   
}


void mousePressed(){

    println("CALL CONNECTION ----");
    myPort.write('s');

}

void draw(){

  noStroke();
   background(22);
    
  
  if(t1_triggered){fill(2);}else{fill(242);}
   ellipse(pad,pad, t1_val, t1_val);
  
   if(t2_triggered){fill(2);}else{fill(242);}
   ellipse(pad+gridsize,pad, t2_val, t2_val);
   
    if(t3_triggered){fill(2);}else{fill(242);}
   ellipse(pad+gridsize*2,pad, t3_val, t3_val);
   
   
     if(t4_triggered){fill(2);}else{fill(242);}
   ellipse(pad,pad+gridsize, t4_val, t4_val);
  
   if(t5_triggered){fill(2);}else{fill(242);}
   ellipse(pad+gridsize,pad+gridsize, t5_val, t5_val);
   
    if(t6_triggered){fill(2);}else{fill(242);}
   ellipse(pad+gridsize*2,pad+gridsize, t6_val, t6_val);
   
   
      if(t7_triggered){fill(2);}else{fill(242);}
   ellipse(pad,pad+gridsize*2, t7_val, t7_val);
  
   if(t8_triggered){fill(2);}else{fill(242);}
   ellipse(pad+gridsize,pad+gridsize*2, t8_val, t8_val);
   
    if(t9_triggered){fill(2);}else{fill(242);}
   ellipse(pad+gridsize*2,pad+gridsize*2, t9_val, t9_val);
  
}

// THE TOUCHFIELD OBJECT

class aTF{

   // matrix position
  int mxi = 0;
  int myi = 0;
  
  int xpos = 0;
  int ypos = 0;

  aTF(int _xi, int _yi){
  
      // save matrix position
      mxi = _xi;
      myi = _yi;
  
  }

}

C++ ESP32 main loop code

// ----------------------------------
// -------MAIN LOOP -----------------
// ----------------------------------
 
// initalize the aTouch objects : aTouch namewahtevet(yourpinnumber);
aTouch touch1(2);
aTouch touch2(4);
aTouch touch3(15);

aTouch touch4(13); 
aTouch touch5(12); 
aTouch touch6(14);

aTouch touch7(27);
aTouch touch8(33);
aTouch touch9(32);


 
void setup() {
   
   Serial.begin(9600);
   Serial.println("0,0,0,0,0,0,0,0,0");
 
}
 
void loop() {
  
  // simply read input and do some calc
  touch1.readAndProcessInput();
  touch2.readAndProcessInput();
  touch3.readAndProcessInput();
  touch4.readAndProcessInput();
  touch5.readAndProcessInput();
  touch6.readAndProcessInput();
  touch7.readAndProcessInput();
  touch8.readAndProcessInput();
  touch9.readAndProcessInput();
 
 
if (Serial.available()>0){

   Serial.print(touch1.smoothed_val);
   Serial.print(",");
   Serial.print(touch2.smoothed_val);
   Serial.print(",");
   Serial.print(touch3.smoothed_val);
   Serial.print(",");
   Serial.print(touch4.smoothed_val);
   Serial.print(",");
   Serial.print(touch5.smoothed_val);
   Serial.print(",");
   Serial.print(touch6.smoothed_val);
   Serial.print(",");
   Serial.print(touch7.smoothed_val);
   Serial.print(",");
   Serial.print(touch8.smoothed_val);
   Serial.print(",");
   Serial.println(touch9.smoothed_val);
   
}
 
  delay(20);
 
}

C++ helper function

// ----------------------------------
// ------- TRXYS TOUCH HELPERS ------
// ----------------------------------
// ( put this code PRIOR to your mainloop code or you will get nice errors :) )
 
  // simple lerp helper function
 
float return_lerp(float _s, int _target,int _time){
  
   _s = _s + (( float(_target) - _s)/float(_time));
   return _s;
    
}
 
class aTouch {
  private:
    bool prev_touch_state = false;
    byte pin;
    int smooth_time = 3;
    int trigger_threshold = 15;
    long ts = 0;
  public:
    int current_val = 0;
    int smoothed_val = 0;
    int diff_val = 0;
    bool is_triggered = false;
    bool on_pressed = false;
    bool on_released = false;
     bool is_holded = false;
    aTouch(byte pin) {
     this->pin = pin;
    }
     
 
    void readAndProcessInput() {
 
        // reset interaction states
        on_pressed = false;
        on_released = false;
         
         // directly read out values TWICE = BUGFIX for debouncing 
         current_val = touchRead(pin);
         delayMicroseconds(10);
         current_val = touchRead(pin);
 
        //calculate smoothed input values 
         smoothed_val = return_lerp(smoothed_val,current_val,smooth_time);
 
         // calc current differential sum of button
          diff_val =   smoothed_val - current_val;
 
          // check if there is a noticable difference input values
          if(  diff_val  > trigger_threshold){
 
              if(prev_touch_state == false){
                is_triggered = true;
                prev_touch_state = is_triggered;
                on_pressed = true;
                ts = millis(); // set timestamp for hold routine
             }
              
          }else if( diff_val < trigger_threshold*-.4){
 
              if(prev_touch_state == true){
                is_triggered = false;
                 prev_touch_state = is_triggered;
                 on_released = true;
              }
                 
          }
 
 
          // calculate timed holding function
           
          if( ts + 2500 < millis() && is_triggered){
 
                
              is_holded = true;
          }else{
 
              is_holded = false;
           }

       delayMicroseconds(2);
     }

};