simple textile touchfield 1 x 7 x 1

This example demostrates a pretty simple 1,5dimensional textile matrix piped to Processing via direct serial connection. The matrix is based on the ESP32 touchpins (9!) which values are interpolated by a simple smooth function on the microcontroller.

This example shows how to utilize a simple textile matrix to get something like a touchpad control. The matrix might be much more detailed for sure, but this comes with a lot of complications in production and durability. So let’s keep it simple and sustainable somehow.

ESP32 Code

This code smoothly reads out all touchpins with a custom class. Check out for previous posts – we will publish it properly in the future :=)

// ----------------------------------
// -------MAIN LOOP -----------------
// ----------------------------------

// get all the defaultly available capacitive touchpins ( GPIO on ESP32 )
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();
  

  // print all values directly to console or for visualization in PROCESSING
   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);
  
}

Processing Code

Keep in mind = This code is a early, uncleaned, pin-hardcoded proof of concept. Check for learning is pretty welcome!

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;


Serial myPort;

int pad = 30;

void setup () {
  size(400, 400);        // window size

  ellipseMode(CENTER);
  rectMode(CENTER);

  // println(Serial.list());
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 9600);
  myPort.bufferUntil('\n');


  myPort.write('s');
  textAlign(CENTER,CENTER);
}




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]);
}

int padx = 60;
int pady = 30;
int ifw = 150;
int ifh = 24;

float yu = height/2-100+pady*4.3 ;

void draw() {

  background(222);

  strokeWeight(1);
  stroke(22);
  // left sidebar ----------
  fill(t4_val*5);
  rect(width/2 - ifw/1.7, height/2, 12, 200 );

  // right sidebar ----------
  fill(t2_val*5);
  rect(width/2 + ifw/1.7, height/2, 12, 200 );

  // bar 1 ----------
  fill(t1_val*5);
  rect(width/2, pady+yu, ifw, ifh );
  
  fill(0);
  text(t1_val,width/2, pady+yu);
  
  

  // bar 2 ----------
  fill(t3_val*5);
  rect(width/2, pady*2+yu, ifw, ifh );
  
   fill(0);
  text(t3_val,width/2, pady*2+yu);
  

  // bar 3 ----------
  fill(t5_val*5);
  rect(width/2, pady*3+yu, ifw, ifh );
  
   fill(0);
  text(t5_val,width/2, pady*3+yu);
  

  // bar 4 ----------
  fill(t9_val*5);
  rect(width/2, pady*4+yu, ifw, ifh );
  fill(0);
  text(t9_val,width/2, pady*4+yu);

  // bar 5 ----------
  fill(t8_val*5);
  rect(width/2, pady*5+yu, ifw, ifh );
  fill(0);
  text(t8_val,width/2, pady*5+yu);


  // bar 6 ----------
  fill(t7_val*5);
  rect(width/2, pady*6+yu, ifw, ifh );
  fill(0);
  text(t7_val,width/2, pady*6+yu);

  // bar 7 ----------
  fill(t6_val*5);
  rect(width/2, pady*7+yu, ifw, ifh );
  
  fill(0);
  text(t6_val,width/2, pady*7+yu);

 
 float tap_amount = (tick+tickx) ;
 noFill();
 stroke(255,22,22);
 strokeWeight(1+( tap_amount)*3);
 ellipse(width/2+spos.x*50,spos.y*200+100,111,111);
 
  calcSingleCursor();
 
}

PVector spos = new PVector();
PVector tpos = new PVector();
int tickx = 0;
int tick = 0;
void calcSingleCursor(){

  float midy = 0;
  
  float midx = 0;
   tickx = 0;
   
   tick = 0;
 
 
 
 if( t4_val < 30){
    midx += -1; tickx++;
  }
  
  if( t2_val < 30){
    midx += 1; tickx++;
  }
 
 if(tickx > 0){
   midx /= float(tickx);
   tpos.x = midx;
 }else{
  tpos.x *=.9;
  }
 

 
 
 // OPERATE Y AXIS! ------------------
 
 if( t1_val < 30){
    midy += 0; tick++;
  }
 
 if( t3_val < 30){
    midy += 0.143; tick++;
  }
  
  if( t5_val < 30){
    midy += 0.286; tick++;
  }

  if( t9_val < 30){
    midy += .5; tick++;
  }
  
   if( t8_val < 30){
    midy += 0.643; tick++;
  }
  
   if( t7_val < 30){
    midy += 0.786; tick++;
  }
  
  
   if( t6_val < 30){
    midy += 1.; tick++;
  }
 
 
  midy /= float(tick);
 
  
  if(tick>0){
    tpos.y= midy;
  }

  spos = PVector.lerp(spos,tpos,.2);
  
}