Unerklärliche Statusveränderung

Hallo, ich komme nicht weiter. In meiner Loop passiert etwas mir unerklärliches, was ich auch durch Analyse mit SerialMonitor nicht durchschauen kann. Ich hoffe, jemand sieht meinen Fehler...

Nach Programmupload. läuft im setup, alles wie es soll. Ich betätige während der 2 Sekunden, die die Led leuchtet den Touchbutton2 und der entsprechende Betriebsmodus (2) wird ausgewählt. Alles im SerialMonitor zu sehen.

Aber in der Loop: zunächst alles gut: ich betätige Touch1, kurz danach Touch2 und die Funktion voltMess() wird absolviert und das Ergebnis in showVolt ausgegeben (= die Led blinkt 5mal da das Board ja am USB hängt, somit ist volle Voltstärke gegeben) . Ebenfalls im Monitor zur Kontrolle ausgegeben (voltCounter).

Nun das Problem: Da ich meine Finger unverändert auf den Touchbuttons lasse, müsste das alles immer wieder durtchlaufen bius ich loslasse. Aber es läuft nur noch einmal durch, dann schaltet irgendwas den Status der Tochbuttons (statTouch1 bzw. 2) um.

Da hab ich gleich 2 Fragezeichen in der Stirn: 1. Warum laüft es nicht immer wieder ab bis zum Loslassen? Bzw Was schaltet den Status wieder auf 0 (wie im Monitor zu sehen) obwohl die Finger konsequent auf den Buttons bleiben (Wackler sind auszuschließen, da das Phänomen immer exakt gleich ist, schon den halben Tag lang)?
und 2. Wenn es schon stoppt, warum wiederholt es den Vorgang immerhin einmal, warum ist nicht nach dem ersten Durchgang Schluß?

Hier der Code (darunter dann die Ausgabe des SerialMonitor):

const int Mot = D6;  // VibrMotor
const int stark = 255;
const int mittel = 200;
const int leicht = 150;  // Vibrationsstärke
const int tacet = 0;     // Vibrationsstärke 0 = no Vibration
bool statMot = true;

int statBeat;

const int Led = D10;
bool statLed;

const int Touch1 = D7, Touch2 = D8;
bool statTouch1, statTouch2;
bool tchWait1, tchWait2;
long tchWaitNow1, tchWaitNow2;
long tchWaitStore1, tchWaitStore2;
int touchDelay = 2000;  // in ms zur Entprellung und Two-Touchkombi

int sec = 1000;  // in ms
int interval;
long past, present;

float volKorr = 0.18;  // Wert durch Testung ermittelt (bq)
int voltCounter;       // hier als Anzahl Pulse für Batterie-Voltage

int Modus;  // 0 = Reciever (default), 1 = Metronom, 2 = Charge, 3 wäre noch mögl. (noch nicht definiert)

// nur debug
int count;


void setup() {
 pinMode(Mot, OUTPUT);
 pinMode(Led, OUTPUT);
 pinMode(Touch1, INPUT);
 pinMode(Touch2, INPUT);
 pinMode(A0, INPUT);  // für Voltage Messung

 digitalWrite(Mot, LOW);  // evntl überflüssig ???

 dreierBlitz();
 delay(sec / 2); // zeitl. Abstand zur "Mod-ChoosingLed"

//!!!!!!!!!!!!!!!!! SERIAL !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Serial.begin(115200);
 delay(100);  // Zeit geben um Serial zum starten
 Serial.println("Setup");
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

 /////////// Mod-Choice-LED /////////////////////////////
 digitalWrite(Led, HIGH);
 delay(2000);  // jetzt Modus wählen (Touch 1 od 2 od no Touch)
 digitalWrite(Led, LOW);
 /////////////////////////////////////////////////////////

 statTouch1 = digitalRead(Touch1);
 statTouch2 = digitalRead(Touch2);
 delay(sec / 2); // zeitl. Abstand zum Beginn showCooseResult

 // delay(dauer);
 // Serial.print("Status Touch1: ");
 // Serial.println(statTouch1);
 // Serial.print("Status Touch2: ");
 // Serial.println(statTouch2);

 // Modus ermitteln & anzeigen
 //////// Reciever - Modus: 3x Blink /////////////////////
 if (statTouch1 == 0 && statTouch2 == 0) {
   Modus = 0;  // Reciever
   for (int i = 0; i < 3; i++) {
     // Serial.print("for-Loop Counter: "); Serial.println(count);
     // count = count + 1;
     digitalWrite(Led, HIGH);
     delay(sec / 8);
     digitalWrite(Led, LOW);
     delay(sec / 2);
   }
   // Serial.print("for-Loop EndCounter: "); Serial.println(count);
 }
 //////// internes Metronom - Modus: 5x Blink ////////////
 if (statTouch1 == 1 && statTouch2 == 0) {
   Modus = 1;  // internes Metronom
   for (int i = 0; i < 5; i++) {
     digitalWrite(Led, HIGH);
     delay(sec / 8);
     digitalWrite(Led, LOW);
     delay(sec / 2);
   }
 }
 //////// Lademodus: 7x Blink ////////////////////////////
 if (statTouch1 == 0 && statTouch2 == 1) {
   Modus = 2;  // Chargemode
   for (int i = 0; i < 7; i++) {
     digitalWrite(Led, HIGH);
     delay(sec / 8);
     digitalWrite(Led, LOW);
     delay(sec / 2);
   }
 }
 // Reset
 statTouch1 = 0;
 statTouch2 = 0;
 Serial.print("Modus: "); Serial.println(Modus);
 Serial.println("Reset Touch done");
}


void voltMess() {
 uint32_t Vbatt = 0;
 for (int i = 0; i < 16; i++) {
   Vbatt = Vbatt + analogReadMilliVolts(A0);  // ADC with correction
 }
 float Vbattf = 2 * Vbatt / 16 / 1000.0;  // attenuation ratio 1/2, mV --> V
 float volBatt = Vbattf + volKorr;

 // voltage counter change
 if (volBatt >= 4.1) {
   voltCounter = 5;
 }  // => voll aufgeladen
 if (volBatt >= 3.8 && volBatt < 4.1) {
   voltCounter = 4;
 }  // => fast voll
 if (volBatt >= 3.5 && volBatt < 3.8) {
   voltCounter = 3;
 }  // => mittelvoll
 if (volBatt >= 3.2 && volBatt < 3.5) {
   voltCounter = 2;
 }  // => hält noch ein wenig (wie lange?)
 if (volBatt < 3.2) {
   voltCounter = 1;
 }  // => dringend aufladen!
 // Serial.print("voltCounter (in voltMess): "); Serial.println(voltCounter);
 // Serial.println("voltMess done ! ");
}


void showVolt() {
 /* Ergebniscode: Blink 5x = Batt voll, 4x = fast voll, 3x = halbleer, 2x = bald leer, 
     Blink 1x = DRINGEND AUFLADEN !!! */

 //Serial.print("voltCounter (in showVolt): "); Serial.println(voltCounter);

 for (int i = 0; i < voltCounter; i++) {
       delay(250);
       digitalWrite(Led, HIGH);
       delay(250);
       digitalWrite(Led, LOW);
     } 
 delay(500);

 // Code für Ergebnisanzeigen-Ende: 3x kurzBlitz
 dreierBlitz();
 delay(500);
 //Serial.println("showVolt done ! ");
}


void dreierBlitz() {
 for (int y = 0; y < 3; y++) {
   delay(125);
   digitalWrite(Led, HIGH);
   delay(25);
   digitalWrite(Led, LOW);
 }
}


void action() {
 switch (statBeat) {
   case 1:
     if (statMot == true) {
       analogWrite(Mot, leicht);
     }
     if (statLed == true) {
       digitalWrite(Led, HIGH);
     }
     break;
   case 0:
     analogWrite(Mot, tacet);
     digitalWrite(Led, LOW);
     break;
   default: break;
 }
}


void loop() {
 // delay(2000);
   present = millis();
   tchWaitNow1 = present;
   tchWaitNow2 = present;

   // debug ################################
   bool statTouch1old = statTouch1;
   bool statTouch2old = statTouch2;
   //########################################

   statTouch1 = digitalRead(Touch1);
   statTouch2 = digitalRead(Touch2);

   // debug #####################################
   if (statTouch1 != statTouch1old) {
     Serial.print("statTouch1: "); Serial.println(statTouch1);
   }
   if (statTouch2 != statTouch2old) {
     Serial.print("statTouch2: "); Serial.println(statTouch2);
   } //###########################################


/*  
 if (Modus == 0) { ///////// RECIEVER /////////////////////////////////////////////////

 }  //////////////////////////////////////////////////////////////////

 
 if (Modus == 1) { ///////// intern METRONOM //////////////////////////////////////////

   //======== Erzeugung Microtiming =========================
   if (present >= past + interval) {
     statBeat = statBeat + 1;
     if (statBeat == 2) {
       statBeat = 0;
     }
     action();  // statBeat 0 = Pause; statBeat 1 = Motor (& evntl Led)
     past = present;
   }  //======================================================

   //======== BeatLED ON/OFF ================================
   if (statTouch1 == true) {
     interval = sec / 4;  // Tempoänderung
     if (tchWait1 == false) {
       if (statTouch2 == true) {
         statLed = !statLed;
         tchWait1 = true;
         tchWaitStore1 = millis();
       }
     }
   }
   if (tchWaitNow1 > tchWaitStore1 + touchDelay) {
     tchWait1 = false;
   }  //======================================================

   //======== Voltage Messung ===============================
   // if (statTouch2 == true) {
   //   interval = sec / 2;  // Tempoänderung
   //   if (tchWait2 == false) {
   //     if (statTouch1 == true) {
   //       statMot = false;
   //       voltMess();  // voltage Messung wird ausgelöst
   //       showVolt();  // Ergebnis wir gezeigt
   //       tchWait2 = true;
   //       tchWaitStore2 = millis();
   //     }
   //   }
   // }
   // if (tchWaitNow2 > tchWaitStore2 + touchDelay) {
   //   tchWait2 = false;
   //   statMot = true;
   // }  //====================================================
 } /////////////////////////////////////////////////////////////////
*/
 
 if (Modus == 2) { /////////// LADEMODUS //////////////////////////////////////////////
   //statMot = false;  // eigentlich nicht nötig da kein Motor-Befehl rausgehen kann ... ???

   //??????????? Voltage Messung ????????????????????????????????????
   if (statTouch2 == true) {
     //Serial.print("statTouch2: "); Serial.println(statTouch2);
     if (tchWait2 == false) {
       //Serial.print("tchWait2_first: "); Serial.println(tchWait2);
       if (statTouch1 == true) {
         // debug ################################################
         Serial.print("statTouch1: "); Serial.println(statTouch1);
         Serial.print("statTouch2: "); Serial.println(statTouch2);
         //#######################################################
         voltMess();  // voltage Messung wird ausgelöst
         showVolt();  // Ergebnis wir gezeigt
         tchWait2 = true;
         // debug ##########################################################
         Serial.print("voltCounter: "); Serial.println(voltCounter);
         Serial.print("tchWait2_after_showVolt: "); Serial.println(tchWait2);
         //#################################################################
         tchWaitStore2 = millis();
       }
     }
   }
   if ((tchWait2 == true) && (tchWaitNow2 > tchWaitStore2 + touchDelay)) {
     tchWait2 = false;

     // debug ##########################################################
     Serial.print("tchWait2_End touchDelay: "); Serial.println(tchWait2);
     //#################################################################
   }  //???????????????????????????????????????????????????????????
 }

}

hier die SerialMonitor-Ausgabe:

20:47:03.005 -> Setup
20:47:09.894 -> Modus: 2
20:47:09.894 -> Reset Touch done
20:47:12.901 -> statTouch2: 1
20:47:13.026 -> statTouch1: 1
20:47:13.026 -> statTouch1: 1
20:47:13.026 -> statTouch2: 1
20:47:16.950 -> voltCounter: 5
20:47:16.950 -> tchWait2_after_showVolt: 1
20:47:18.972 -> tchWait2_End touchDelay: 0
20:47:18.972 -> statTouch1: 1
20:47:18.972 -> statTouch2: 1
20:47:22.929 -> voltCounter: 5
20:47:22.929 -> tchWait2_after_showVolt: 1
20:47:22.929 -> statTouch1: 0
20:47:22.929 -> statTouch2: 0
20:47:24.922 -> tchWait2_End touchDelay: 0

DIe Fett -gedruckten beiden Zeilen kann ich mir nicht erklären. Wie kann dort der Wert 0 sein? Ich lasse die Buttons nicht los. Und selbst wenn ich wackeln würde. Das Ergebnis ist immer exakt so. Es läuft nicht manchmal 3x und manchmal nur 1x. Es ist immer 2x, es sei denn ich lasse beim 1. Mal los.

Ich kapier das nicht. Erkennt jemand den Fehler?
Das wär cool. Danke schon mal.

Beste Grüße,
bq.

Die Ladung am PIN ist aufgebraucht.

Solange hat die Ladung gehalten.

Wie ist der Button angeschlossen?

Welche Touch Sensoren hast Du?
Es gibt welche die sich immer wieder selbst Kalibrieren und wenn Du zu lange den Finger drauf hast kalibriert er sich dann eben mit Finger und gibt 0 aus.
Ich kenne das von den TYTP223 TTP223.

Im Datenblatt steht zwar: And the re-calibration period is about 4.0sec, when key has not be touched
aber mir kommt es vor als ob diese Rekalibration auch bei aktiviertem Sensor anspringt.
Grüße Uwe

[EDIT] Typencode TTP223 korrigiert Uwe[/EDIT]

1 Like

Muss mann eigentlich einen AnalogEingang als INPUT definieren? ich dachte der wird so zum digital-Eingang?
Weil i Setup ist hier

pinMode(A0, INPUT);

definiert.

Nein muß/soll man nicht.
Grüße Uwe

Ich habe die TTP223 (ohne das "Y" zwischen den Ts wie bei dir). Abert das sind wohl die selben. Dann wärte die Ursache ja gefunden...
Dann muss ich eben immer neu draufdrücken. Das ist nicht wie gewollt, aber letztlich nmur eine kleine Änderung des Projektes.

Danke für die schnelle Antwort. Ich kann ja auch noch mal prüfen, wie schnell meine Buttons sich neu kalibrieren.

Beste Grüße,
bq.

Nein nicht als Analog-Messung. Die Sensoren geben Logikpannung aus, wenn sie Berührung (Annäherung) detektieren. Sie sind entweder an oder aus. Das zeigen sie mit einer eingebauten Led an. Man kann über Lötbrücken aner invertieren oder eine "Hold"-Funktion erzeugen.

Also digitalRead() funktioniert an sich super, die Sensoren sind sehr empfindlich. Man kann recht dicke Gehäusewandung drumrum planen.

Das Y kam da irgendwie rein. :innocent:

Es gibt noch andere Touch-Sensoren (außer der TTP22x Serie) . Ich weiß nicht, ob diese anders reagieren.

Ich meine auch nicht die Sensortasten. Ich meine A0, da steht im Setup : pinMode (A0, INPUT); // für Voltage Messung
und in:

void voltMess() {
 Vbatt = Vbatt + analogReadMilliVolts(A0);  // ADC with correction

also liest Du Deine MessSpannung analog an A0 ein, sagst dem Controller in Setup aber, er soll A0 als Digital-Input kofigurieren.

Ich meine auch nicht die Sensortasten. Ich meine A0, da steht im Setup : pinMode (A0, INPUT); // für Voltage Messung
und in:

void voltMess() {
 Vbatt = Vbatt + analogReadMilliVolts(A0);  // ADC with correction

also liest Du Deine MessSpannung analog an A0 ein, sagst dem Controller in Setup aber, er soll A0 als Digital-Input kofigurieren.

Jetzt verstehe ich deinen Einwand. Ja, da hab ich das wohl falsch. Seltsamerweise, hat es dennoc funktioniert, zumindest soweit ich testen konnte (mit Labornetzeil verschiedene Batteriespannung simuliert und die Messwerte noch mal mit Multimeter gegengeprüft).
Möglicherweise muss ich meinen ermittelten Korrekturwert noch mal ändern.

Jedenfalls: Danke!

gerne. ich würde jedenfalls nicht ausschliessen, dass der gelesene Wert an einem Analogeingang verfälscht wird, wenn der Eingang Controllerintern gleichzeitig als Digital-Eingang geschaltet ist. Jedoch bin ich mit dem Internen physikalischen Aufbau der Microcontroler dahingehend zuwenig vertraut, um dies mit Bestimmtheit festlegen oder behaupten zu können. Dennoch würde ich diesen Weg nicht gehen, wenn ich zumindest einigermassen stabile Messergebnisse erwarte / benötige.

Für die AVR Arduino kann ich dir GARANTIEREN, dass es keinen Unterschied macht.
Input ist die default Konfiguration eines jeden Pins.
Es wird nicht zwischen analog input oder digital input unterschieden.
Ausnahme: Nicht alle Pins sind mit dem analog Multiplexer verbunden

Selbst bei Pins mit Spezial Funktion, wie z.B. Reset, Oszillator, I2C, auch bei output Pins, ist ein analoges lesen jederzeit möglich. Belastet allerdings mit dem S&H Kondensator die Schaltung.

Ok, Danke combie, dann ist man da zumindest von der Funktion her auf der sicheren Seite. Dann ist /kann sein ein im Setup Speziel als Input deklarierterAnalog-(fähiger) Pin höchstens dahingehend etwas verwirend, weil es sugerriert, der Pin ürde als Digital Input genutzt. Hier bleibt aber noch die Frag: wenn pinns ja so oder so generell Inputs sind (beim Start/Neustart des controllers , warum definieren wir diese denn überhaupt im Setup als Eingänge ? Wäre doch eigentlich gar nicht nötig. eigentlich bräuchten wir ja nur die digital Ausgänge zu definieren, und bei den Eingängen wo benötigt, der PULLUP aktivieren.

Ja, da hast du vollkommen recht, wenn man die Welt auf die üblichen AVR Arduinos beschränkt.
So steht es auch in der Arduino Doku.

Leider ist die Welt nicht so klein. Es gibt in der Arduino Welt viele weitere µC, bei denen ist das längst nicht immer so.
Wenn man öfter den µC wechselt, kann es also Sinn manchen das generell so zu tun, also Inputs auch konsequent auf input zu setzen.

Am Rande, selbst in der AVR Welt....
z.B. auch bei SoftWire muss man dauernd zwischen input und output wechseln

Ich finde es auch der Übersichtlichkeit halber besser, wenn man auch die Eingänge deklariert, besonder bei grösseren Projekten die Viele Pins in Gebrauch haben und wenn man nen Sketch auch später mal wieder bearbeiten oder gar erweitern will/muss, wird die Einarbeitungszeit kürzer.

1 Like

Schon, aber nicht unbedingt mit dem sinnlosen Aufruf von pinMode für Analog-Eingänge.
A0 ist übrigens bereits die Definition einer Konstanten

Ja natürlich, ich war es ja auch nicht, der A0 im Setup mit pinMode aufgerufen habe, sondern ich hab ja darauf hingewiesen, dass ich das etwas ungeöhnlich finde.

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