Kapazitiver Touch Sensor mit großer Kapazität

Moin, ich bin absoluter Anfänger was das Programmieren angeht, bitte seht es mir nach :).

Hardware ist ein ESP32 WROOM Dev Module.

Nun zu meinem Problem:
Ich möchte für mein Bett einen Touchsensor aus einem 1,5 meter langem Kupferstreifen bauen, welcher einfach mit einem Kabel an den GPIO 4 Pin angeschlossen ist. Dieser soll mit verschiedenen Touchrythmen dann drei verschiedene Lampen über ein Relais schalten. Der größte teil des Codes stammt dabei von Steve Hoefer, ich habe ihn dann mit meinen geringen Kenntnissen auf meine Bedürfnisse angepasst bekommen.
Das Problem ist, das der Wert der mir ausgegeben wird schon nahe oder gleich 0 ist, vermutlich da die Kapazität meines Kupferstreifens alleine schon zu groß ist. Dadurch ist es kaum möglich einen Threshold zu setzen, da dieser auch ohne Touch regelmäßig getriggered werden würde.
Wenn ich nur ein Kabel als Sensor benutze funktioniert alles einwandfrei.

Meine Frage lautet also:
Ist es möglich die dies über die Referenzspannung zu regeln? Wenn ja, wie benutze ich den touch_pad_set_voltage() Befehl, bzw. gibt es eine andere Softwareseitige Lösung?
Oder kann ich dieses Problem nur über die Hardware lösen, sprich einen Vergleichs-Kondensator oder sogar nur über einen Widerstands basierten Touch Sensor lösen?

Hier der Vollständigkeit halber noch mein Code:

#define touchPin T0

const int16_t LightL = 12;
const int16_t LightR = 13;
const int16_t LightM = 14;
const int16_t Charger = 32;

const int16_t threshold = 20;
const int16_t touchRange = 1000;
const int16_t rejectValue = 25;
const int16_t avarageRejectValue = 15;
const int16_t touchFadeTime = 300;
unsigned long startTime2;
const unsigned long interval = 30 * 1000;

const int16_t maximumtouchs = 5;
const int16_t touchComplete = 1200;

const int16_t Num_touch_Patterns = 5;

int16_t secretCode[ Num_touch_Patterns ][maximumtouchs ]= {
  {50, 100, 0, 0, 0},
  {100, 50, 0, 0, 0},
  {100, 100, 0, 0, 0},
  {100, 100, 100, 0, 0},
  {100, 50, 50, 0, 0},
};
int16_t touchReadings[maximumtouchs];
int16_t touchSensorValue = 0;

void setup() {
  pinMode(LightL, OUTPUT);
  pinMode(LightR, OUTPUT);
  pinMode(LightM, OUTPUT);
  pinMode(Charger, OUTPUT);
  pinMode(touchPin, INPUT);

  Serial.begin(9600);
  Serial.println("Program start.");


  }

void loop(){
  touchSensorValue = touchRead(touchPin);




    
    if (touchSensorValue < threshold){
    listenToSecrettouch();
    }
  



  int16_t status = digitalRead(Charger);

  if (status == HIGH) {
    if(millis() - startTime2 < interval){
    digitalWrite(Charger, LOW);
    }
    else{
    status = LOW;
    }
  }
  else{
  digitalWrite(Charger, HIGH);
  }
}

void listenToSecrettouch(){
  Serial.println("touch starting");

  int16_t i = 0;

  for (i = 0; i < maximumtouchs; i++) {
    touchReadings[i] = 0;
  }

  int16_t currenttouchNumber = 0  ;
  int16_t startTime = millis();
  int16_t now = millis();

  delay(touchFadeTime);
  do{
    touchSensorValue = touchRead(touchPin);
    if (touchSensorValue < threshold) {
      Serial.println("touch");
      Serial.print("Touch0 value is = ");
      Serial.println(touchSensorValue);
      now = millis();
      touchReadings[currenttouchNumber] = now - startTime;
      currenttouchNumber ++;
      startTime = now;
      delay(touchFadeTime);
    }
    
    now = millis();

  } while ((now - startTime < touchComplete) && (currenttouchNumber < maximumtouchs));

  int16_t validatedtouch = validatetouch();

  if (validatedtouch == 1) {
    Serial.println("Detected FIRST touch");
    doThing1();
  }

  if (validatedtouch == 2) {
    Serial.println("Detected SECOND touch");
    doThing2();    
  }

  if (validatedtouch == 3) {
    Serial.println("Detected THIRD touch");
    doThing3();
  }

  if (validatedtouch == 4) {
    Serial.println("Detected FOURTH touch");
    doThing4();
  }

  if (validatedtouch == 5) {
    Serial.println("Detected FIFTH touch");
    doThing5();
  }

  else {
    Serial.println("touch Failed");    
  }
}


void doThing1(){
  Serial.println("Turning Light 1");
  digitalWrite(LightL, !digitalRead(LightL));
}

void doThing2(){
  Serial.println("Turning Light 2");
  digitalWrite(LightR, !digitalRead(LightR));
}

void doThing3(){
  Serial.println("Turning Light 3");
  digitalWrite(LightM, !digitalRead(LightM));
}

void doThing4(){
  Serial.println("Everything OFF");
  digitalWrite(LightM, HIGH);
  digitalWrite(LightR, HIGH);
  digitalWrite(LightL, HIGH);
}

void doThing5(){
  Serial.println("Charging");
  digitalWrite(Charger, HIGH);
  delay(30);
  startTime2 = millis();
}


int16_t validatetouch() {
  int16_t i = 0;

  // simplest check first: Did we get the right number of touchs?
  //int16_t currenttouchCount = 0;
  int16_t secrettouchCount[2] = {0, 0};
  int16_t maxtouchinterval = 0;          			// We use this later to normalize the times.

  for (i = 0; i < maximumtouchs; i++) {
    //if (touchReadings[i] > 0){
    //  currenttouchCount++;
    //}

    for (int16_t k = 0; k < Num_touch_Patterns; k++) {
      if (secretCode[k][i] > 0) {           //todo: precalculate this.
        secrettouchCount[k]++;
      }
    }

    if (touchReadings[i] > maxtouchinterval) { 	// collect normalization data while we're looping.
      maxtouchinterval = touchReadings[i];
    }
  }

    for (i = 0; i < maximumtouchs; i++) { // Normalize the times
    touchReadings[i] = map(touchReadings[i], 0, maxtouchinterval, 0, 100);
  }

  for (int16_t code = 0; code < Num_touch_Patterns; code++) {
    bool failed = false;
    int16_t totaltimeDifferences = 0;
    int16_t timeDiff = 0;
    for (i = 0; i < maximumtouchs; i++) { // Normalize the times
      timeDiff = abs(touchReadings[i] - secretCode[code][i]);
      if (timeDiff > rejectValue) { // Individual value too far out of whack
        //return false;
        failed = true;
        break; // break out of the pattern check loop
      }
      totaltimeDifferences += timeDiff;
    }

    if (failed) continue; // try next touch code

    // It can also fail if the whole thing is too inaccurate.
    if (totaltimeDifferences / secrettouchCount[code] > avarageRejectValue) {
      //return false;
      continue; // try next touch code
    }

    // code found
    return code + 1;
  }

  // if none of the codes were found, return failure
  return 0;
}

Die touchRange funktioniert nicht, das ist mein anfänglicher Versuch gewesen die Staffelung zu ändern. Ich dachte wenn ich den Ruhezustand auf ein Value von 1000 setzen könnte dann hätte ich vielleicht mit der Angeschlossenen Kupferleiste noch 30-50 und könnte dann einen threshold bei 10 setzen, Beispielsweise.

Vielen Dank schonmal für eure Lösungsvorschläge, und wenn etwas fehlen oder Falsch formatiert sein sollte dann ändere ich das gerne noch
LG

Ich verstehe, dass Sie Zeit und Ressourcen für den Kupfer-Berührungssensor aufgewendet haben, aber erwägen Sie, einen Vibrationssensor (auch bekannt als Tap-Sensor oder Klopfsensor) für eine Eindrahtlösung zu verwenden.

Gibst Du uns eine Link/Beispiel zu einer solchen Anwendung.
Grüße Uwe

Ich weiß wie dieser Sensor verwendet wird. Wie kann man aber mit diesem Sensor einen 1,5m langen Sensor basteln?
Grüße Uwe

Ursprünglich hatte ich das mit einem Piezosensor gelöst, aber da ich das eine Licht als Nachtlicht verwenden will, möchte ich nicht doll gegen das Regal klopfen müssen. Dadurch brauche ich eine hohe Sensitivität und wodurch der Sensor leider oft falsche Signale geliefert hat.

Moin, ich habe heute festgestellt das mein Problem doch ein anderes zu sein scheint. Eins welches ich anfänglich hatte, und dachte gelöst zu haben. Und zwar ist es so, wenn ich Beispielsweise einen Threshold von 100 habe, liegt der touchValue im unberührten Zustand bei ca. 20 wenn ich den Sensor berühre unter 10. Setze ich nun den Threshold auf 10, liegt der Wert im unberührten Zustand unter 10. Sprich meine Range verstellt sich mit dem Threshold, so wie ich das verstehe. Weiß jemand was da zu tun ist? Wäre über Hilfe sehr dankbar :slight_smile:
LG

Ich hatte mal vor ettlichen Jahren Probleme mit der CapSense- Bibliothek auf einem Arduino Leonardo. Das Hauptproblem war daß ein von der Bibliothek sehr ungenauer und grob berechneter Offset und darum der relative Meßwert nicht zu gebrauchen war. Ein gleitender Offset von mir selbst berechnet funktionierte dann. Ich hatte eine Signaländerung von ca 300 bei einem Offset von ca 10000.
Ich weiß nicht ob Du ähnlche Probleme hast.
Grüße Uwe

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.