Touch, Light and ESP32 on Textile

Textile prototype using touch input and direct visual feedback.

Both LED and Touch Helper Lib is needed for this in prior.

// ----------------------------------
// -------- BASIC HELPERS LED & TOUCH --------
// ----------------------------------
 
// basic lerp function
float return_lerp(float _s, int _target, int _time) {
  _s = _s + (( float(_target) - _s) / float(_time));
  return _s;
 
}
 
// --------------
// LED Object
// -------------
class aLED {
  private:
    byte pin;
    long ts = 0;
    int led_mode = 0; //0 manual / 1:sinpulse / 2:fading
 
  public:
    int brightness = 0; // current brightness
    float fade_target = 0; // where to fade?
    int fade_speed = 4;
    float pulse_speed = .004; // speed of pulse when in pulsemode
    int pulse_amplitude = 125;
 
    aLED(byte pin) {
      this->pin = pin;
      init();
    }
 
    void init() {
      pinMode(pin, OUTPUT);
    }
 
    void operateLED() {
      if (led_mode == 0) {
 
        // if in manual mode
 
      } else if (led_mode == 1) {
 
        // -----------  PULSE MODE
        brightness =  int((sin(millis() * pulse_speed) + 1) * pulse_amplitude * .5);
 
      } else if (led_mode == 2) {
 
        // -----------  FADING MODE
        brightness = int(return_lerp(brightness, fade_target, fade_speed));
 
      }
 
      analogWrite(pin, brightness);
 
    }
 
    void setMode(int _mode) {
      led_mode = _mode;
    }
 
};


class aTouch {
  private:
    bool prev_touch_state = false;
    byte pin;
    int smooth_time = 2;
    int trigger_threshold = 8;
    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);
     }
   
};


// ----------------------------------
// -------- MAIN PROGRAM  --------
// ----------------------------------
  
  
// setup the LED object  aLED namewhatever(pin);
aLED led1(19);
 
aTouch touch1(2);
aTouch touch2(4); 
 
bool holdmode = false; 
 
int hold_ticker = 0;
 
bool has_record = false;
 
float curr_pulsespeed = .1;
  
void setup() {
  
  
    
 Serial.begin(9600);
}
  
void loop() {
   
  led1.operateLED(); //operate specific LED
  touch1.readAndProcessInput();
  touch2.readAndProcessInput();  
 
 
   if( touch2.is_holded){ Serial.println("Touch2 hold very long"); holdmode = false; hold_ticker = 0; }
 
  if( touch1.is_holded){ Serial.println("Touch1 hold very long"); holdmode = true;  }
 
  if(holdmode == false){  
       
      if( touch1.on_pressed){ 
        led1.setMode(0);
        led1.brightness=255;
        led1.setMode(2);
        led1.fade_target=1;
       }
       
   
  }else{
    // -------------------
    // -------  IN HOLDMODE  -----------
    // ----------------------    
 
    hold_ticker++;
    led1.setMode(1); 
    led1.pulse_speed=.00002*float(hold_ticker);
    led1.pulse_amplitude = int(.1*hold_ticker)+2;
 
    curr_pulsespeed =.00002*float(hold_ticker);
    has_record = true;
     
     
   }
 
  if( touch1.on_released){
 
 
     if( hold_ticker == 0){
        has_record = false;
     }
 
    if(has_record ){
        led1.setMode(1);
        led1.pulse_speed = curr_pulsespeed*2.;
        led1.pulse_amplitude = 122;
       
      }else{
        led1.setMode(0);
        led1.brightness=0;
    }
     
      holdmode = false;
      hold_ticker = 0;
     
    }
    
  delay(20);
  
    
}