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