Neuaufbau meiner Modellbahngeschwindigkeitsmessung

Moin!

kürzlich hatte ich schon einmal meinen Code für meine Geschwindigkeitsmessung mit zwei Messpunkten gepostest. Der Abstand sollte über einen Poti eingestellt werden.

Nun habe ich nochmal von Anfang an begonnen, dass ich irgendwie nicht weiter kam. Nun soll es so sein, dass über einen Taster zwischen dem Messmodi und dem Modus für die Streckenlängendefinition gewechselt werden soll.

Dabei habe ich festgestellt, dass nicht immer richtig auf den Taster reagiert wurde und so bin ich zu INTERRUPT gekommen.

Derzeit ist an meinem Arduino nur eine 16x2 LCD und ein Taster angeschlossen. Die Variablendefinitionen habe ich nicht alle entfernt. Vielleicht etwas unübersichtlich....

Vom Gedanken soll es eine Variable MODUS geben mit folgenden Werten:

0 ...Programmstart
-1 ... Def der Strecke
1 ... Messung

Über den Taster soll zwischen 1 und -1 gewechselt werden können und dafür habe ich die Interrupt-Funktion definiert.

Meinen aktuellen Sketch stelle ich ans Ende. Derzeit wird nur die Init angezeigt und wenn ich den Taster drücke, dann reagiert der nur einmal.

Nach meiner Auffassung müsste dieser nach jeder Betätigung doch den Wert ändern und dann auch eine Ausgabe in dem Monitor machen.

Kann mir einer weiterhelfen ?

Gruß Jan

// Lichtschranke für Zugeschwindigkeit in Verbindung mit Seriellen Monitor
//
// Einbinden der LCD-Funktionen derzeit noch inaktiv
// #include <LiquidCrystal_I2C.h>
// LiquidCrystal_I2C lcd(0x27, 16,2) // ?????
//
#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>

/*-----( Declare Constants )-----*/
/*-----( Declare objects )-----*/
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
/*-----( Declare Variables )-----*/
//NONE

unsigned long start, finished, elapsed;
int modus=-1;      // Programmstart 0 / Def der Strecke =-1 / Messung = 1
int act=0;         // Messung läuft 1 / beendet oder nicht gestartet 0
int tstatus=0;     // Tasterstatus
int T1=7;          // 1. IR #7
int T2=8;          // 2. IR #8

const byte interruptPin = 2;
volatile byte Taster = LOW;

int P1=A1;         // ANALOG für Poti
// Werteabfrage
// IR
// aktueller Status
int cT1=-1;        // Status IR 1
int cT2=-1;        // Status IR 2
// vorheriger Status
int oT1=-1;        // Status IR 1
int oT2=-1;        // Status IR 2
int maxTime=0;     // Kennung für die Zeitüberschreitung
// Poti
int cP=0;          // Wert am Poti
// Werte für die Messstrecke (1/10mm)
int Svon = 3500;    // 50 cm 
int Sbis = 4500;    // 60cm
int oDist =0;       // alter Streckenwert
char Ausgabe;

void setup() {
  // Hier fehlt die Initalisierung des LCD
  Serial.begin(9600);    // öffnen der Seriellen Schnittstelle für die Überwachung
  attachInterrupt(digitalPinToInterrupt(interruptPin), changeModus, CHANGE);
  
  lcd.begin(16,2);   // initialize the lcd for 16 chars 2 lines, turn on backlight
  lcd.setCursor(0,0); //Start at character 4 on line 0
  lcd.print("Lichtschranke");
  lcd.setCursor(0,1);
  lcd.print("bereit ...");
  delay(2000);  
  modus=-1;
  Serial.println("Setup abgeschlossen ....");  
}

void loop() {
  
  // Meldung beim Starten des Programmes
  if (modus==0) {
    //lcd.clear();
    lcd.setCursor(0,0); //Start at character 4 on line 0
    lcd.print("Lichtschranke");
    Serial.println("Lichtschranke bereit");
    lcd.setCursor(0,1); //Start at character 4 on line 0
    lcd.print("bereit ...");
    modus=-1; // zuerst die Strecke definieren
  }
  
  // Definition der Strecke
  if (modus==-1) {
    lcd.setCursor(0,1); //Start at character 4 on line 0
    lcd.print("Definition");
    
  } else {   // durchführen der Messung   
    lcd.setCursor(0,1); //Start at character 4 on line 0
    lcd.print("Messung");
  }
}

// Modus-Wechsel
void changeModus(){
  //Serial.println("++++ INTERRUPT +++++");
  modus=modus*-1;
  Serial.println(modus);
  lcd.clear();
}

Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *). Nicht in Quote-Tags.

Sinnvolle Einrückungen steigern die Lesbarkeit ungemein. +T in der IDE hilft Dir dabei.

Im allgemeinen sagt man: Wenn man für einen handbetätigten Schalter/Taster einen Interrupt braucht, sollte man sein Konzept überdenken.

Gruß Tommy

Hi

Bitte ändere Das in Code-Tags (Das ist ein Quote).

Was glaubst Du, macht Dein Sketch bis jetzt?
Was denkst Du passiert, wenn modus==0 ist und der Interrupt auslöst?
Wann denkst Du, wird jeweils ein Interrupt ausgelöst?

Meiner Meinung nach bist Du mit millis() und einer 08/15-State-Maschine besser aufgehoben.
Auch musst Du nicht in JEDEM loop()-Durchlauf das Display komplett beschreiben - Aktualisieren genügt - und Das auch nur, wenn's was zum Aktualisieren gibt.

MfG

Moin!

Tommy56:
Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *). Nicht in Quote-Tags.

Hatte in der Formatierungsliste geschaut und da irgendwie das Code-Tag nicht gefunden. Jetzt editiert!

Im allgemeinen sagt man: Wenn man für einen handbetätigten Schalter/Taster einen Interrupt braucht, sollte man sein Konzept überdenken.

Gruß Tommy

Bin ja noch Einsteiger und hatte diese Erscheinung. Daraufhin einen anderen "fachkundigen" gefragt und der hatte mir das mit dem Interrupt für solche Fälle empfohlen. Nun kann es sein, dass er längere Codes meint als ich.

Jan

postmaster-ino:
Hi

Bitte ändere Das in Code-Tags (Das ist ein Quote).

Was glaubst Du, macht Dein Sketch bis jetzt?
Was denkst Du passiert, wenn modus==0 ist und der Interrupt auslöst?
Wann denkst Du, wird jeweils ein Interrupt ausgelöst?

Nach der Anzeige, dass das Programm gestartet ist (Modus=0; könnte noch in das Setup verschoben werden) wird mit dem Taster der Modus-Wert geändert. Das soll dann im nächsten Schritt die Entscheidungsgrundlage, ob in Funktionen für die Zeitmessung oder die Messstreckendefinition gewechselt wird, bilden.

postmaster-ino:
Meiner Meinung nach bist Du mit millis() und einer 08/15-State-Maschine besser aufgehoben.
Auch musst Du nicht in JEDEM loop()-Durchlauf das Display komplett beschreiben - Aktualisieren genügt - und Das auch nur, wenn's was zum Aktualisieren gibt.

MfG

postmaster-ino:
Bitte ändere Das in Code-Tags (Das ist ein Quote).

Was glaubst Du, macht Dein Sketch bis jetzt?
Was denkst Du passiert, wenn modus==0 ist und der Interrupt auslöst?
Wann denkst Du, wird jeweils ein Interrupt ausgelöst?

Meiner Meinung nach bist Du mit millis() und einer 08/15-State-Maschine besser aufgehoben.
Auch musst Du nicht in JEDEM loop()-Durchlauf das Display komplett beschreiben - Aktualisieren genügt - und Das auch nur, wenn's was zum Aktualisieren gibt.

MfG

Das ist sicherlich noch ausbaufähig und kann vereinfacht werden.

Gruß Jan

Serial.println und lcd.xxx haben in einer Interruptroutine nichts zu suchen.

Dein Modus ist int. wenn Du kleiner als 256 bleibst, ist byte besser, da das elementar gelesen werden kann. modus sollte volatile sein, aber wie bereits gesagt: Du brauchst keinen Interrupt.

Gruß Tommy

Moin!

volatile .... hatte ich vergessen.

Serial.println und lcd.xxx haben in einer Interruptroutine nichts zu suchen.

War auch nur für die ersten Schritte - bekannt das es sonst zu lange dauert.

Werde mal weiter um- und aufbauen. Dann schrittweise posten für Kritiken.

Vielleicht unterstütz Ihr mich bei meinem ersten Projekt.

Jan

Warum willst Du partout am Interrupt für den Taster festhalten?

Zeige uns doch mal die Lösung ohne Interrupt. Evtl. finden wir Deinen Fehler.
Auch mit Interrupt musst Du den Taster entprellen. Das vermisse ich noch. Ich vermute, das war auch Dein Fehler in der anderen Realisierung.

Gruß Tommy

Hi!

werde ich morgen mal Posten - ist allerdings etwas länger und unübersichlicher, weil alles darin enthalten ist.

Entprellen - habe da mal gehört, dass dafür Kondensatoren erforderlich sind ?!? Die habe ich noch nicht und weiss auch nicht welche.

Aber jetzt haue ich mich erst einmal aufs Ohr.

Jan

Zum Entprellen brauchst du keine Kondensatoren.
Google mal nach Bounce2 oder Debounce .
Geht alles per Software.

Hi

Auf Entprellen wollte ich auch hinaus - jetzt schlägt der Interrupt zig Mal zu, wenn Du den Taster drückst, da Dessen Kontakte - äh - prellen.
Dabei ist es völlig zufällig, ob Du dabei den Zustand negierst, oder nicht - also, ob dieses Prellen 'gerade' Mal auftritt, oder nicht.

MfG

Moin!

ich habe eben nochmal darüber nachgedacht warum ich den Interrupt verwende.

Es ist nicht das prellen, warum ich den jetzt verwendet habe. Es ist vielmehr, dass nicht immer jedes betätigen des Tasters korrekt erfasst wurde.

Aber jetzt ist wirklich Nachtruhe und morgen poste ich den Code vor dem Interrupt.

Jan

Dann ist Dein Codeaufbau falsch. So schnell kannst Du bei einem sauberen Code mit den Fingern nicht sein. Prellen wirkt nach außen manches Mal auch wie nicht erkannt.

Gruß Tommy

Hi

Wenn die Erkennung EINES Taster per Pollen nicht zuverlässig funktioniert, dauert Deine loop() zu lang.

  • delay() rauswerfen und durch millis() ersetzen (siehe Nachtwächter, blink_without_delay in der IDE, ...)
  • nicht in jedem Durchlauf ALLES erledigen - nur, was gerade nötig ist - z.B. das Display muß nicht 1000 Mal die Sekunde den gleichen Text aufgedrückt bekommen
  • ...

MfG

Moin!

hier der Code - auch auf die Gefahr hin, dass Ihr mich jetzt zerreizt:

// Lichtschranke für Zugeschwindigkeit in Verbindung mit Seriellen Monitor
//
// Einbinden der LCD-Funktionen derzeit noch inaktiv
// #include <LiquidCrystal_I2C.h>
// LiquidCrystal_I2C lcd(0x27, 16,2) // ?????
//
#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>

/*-----( Declare Constants )-----*/
/*-----( Declare objects )-----*/
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
/*-----( Declare Variables )-----*/
//NONE

unsigned long start, finished, elapsed;
int modus=-1;      // Programmstart 0 / Def der Strecke =-1 / Messung = 1
int act=0;         // Messung läuft 1 / beendet oder nicht gestartet 0
int tstatus=0;     // Tasterstatus
int T1=7;          // 1. IR #7
int T2=8;          // 2. IR #8
int T3=9;          // 1. Taster für Modi-Wechsel
int P1=A1;         // ANALOG für Poti
// Werteabfrage
// IR
// aktueller Status
int cT1=-1;        // Status IR 1
int cT2=-1;        // Status IR 2
// vorheriger Status
int oT1=-1;        // Status IR 1
int oT2=-1;        // Status IR 2
int maxTime=0;     // Kennung für die Zeitüberschreitung
// Poti
int cP=0;          // Wert am Poti
// Werte für die Messstrecke (1/10mm)
int Svon = 3500;    // 50 cm 
int Sbis = 4500;    // 60cm
int oDist =0;       // alter Streckenwert
char text[5];

void setup() {
  // Hier fehlt die Initalisierung des LCD
  Serial.begin(9600);    // öffnen der Seriellen Schnittstelle für die Überwachung
  pinMode(T1,INPUT);     // EINGANGSpin für den IR-#1
  pinMode(T2,INPUT);     // EINGANGSpin für den IR-#2
  pinMode(T3,INPUT);     // EINGANGSpin für den Taster
  
  lcd.begin(16,2);   // initialize the lcd for 16 chars 2 lines, turn on backlight
  lcd.setCursor(0,0); //Start at character 4 on line 0
  lcd.print("Lichtschranke");
  lcd.setCursor(0,1);
  lcd.print("aktiv ...");
  delay(2000);  
  
}

void loop() {
  
  // Meldung beim Starten des Programmes
  if (modus==0) {
    //lcd.clear();
    lcd.setCursor(0,0); //Start at character 4 on line 0
    lcd.print("Lichtschranke");
    lcd.setCursor(0,1); //Start at character 4 on line 0
    lcd.print("bereit ...");
    Serial.println("Programm gestartet");
    //lcd.begin(16,2);   // initialize the lcd for 16 chars 2 lines, turn on backlight
    delay(5000);
    modus=-1; // zuerst die Strecke definieren
    lcd.clear();
  }

  // Abfrage des Tasters für Modus
  if (digitalRead(T3)==HIGH){
    modus=modus*-1;
    lcd.clear();
  }

Serial.println(modus);
  
  // Definition der Strecke
  if (modus==-1) {
    //lcd.clear();
    lcd.setCursor(0,0); //Start at character 4 on line 0
    lcd.print("Referenzlaenge:");
    lcd.setCursor(0,1); //Start at character 4 on line 0
    lcd.print("Widerstand ausgelesen");
    Serial.println("Programm gestartet");
    //lcd.begin(16,2);   // initialize the lcd for 16 chars 2 lines, turn on backlight
    
  } else {   // durchführen der Messung   
    if (act==0){  // beobachten IR 1
    lcd.setCursor(0,0); //Start at character 4 on line 0
    lcd.print("Start durchfahren");

    cT1=digitalRead(T1); // Auslesen IR - #1
    if (cT1==LOW){
      start=millis();
      lcd.setCursor(0,0); //Start at character 4 on line 0
      lcd.print("Messung aktiv ");

      sprintf(text,"%02d",calTime());
      lcd.setCursor(0,1); //Start at character 4 on line 0
      lcd.print("                ");
      lcd.setCursor(0,1); //Start at character 4 on line 0
      lcd.print(text);
  
      
      //lcd.setCursor(0,1); //Start at character 4 on line 0
      //lcd.print("erwarte Ziel ...");
      Serial.println("gestartet ...");
      act=1;
      maxTime=0;
     }
    }// beobachten IR 1

  
  if (act==1){ // beobachten IR 2
    cT2=digitalRead(T2); // Auslesen IR - #2
    if (cT2==LOW && maxTime==0){
      Serial.print("act ...");
      Serial.println(act);
      if (act==1){
        lcd.setCursor(0,0); //Start at character 4 on line 0
        lcd.print("Zeitmessung erfolgt");
        lcd.setCursor(0,1); //Start at character 4 on line 0
        lcd.print("Auswertung läuft ...");
        delay(1000);
   //     showResult();
        act=0; // damit wird die Messung als beendet erklärt
//      }else{
//        Serial.println("ungültiger Messwert!");
      }
    } else {
      if (calTime()>10.0 && maxTime<1){
        Serial.println("** Zeitüberschreitung **");
        maxTime=1; // Zeitüberschreitung wurde ausgegeben
        act=0; // damit der Start wieder ausgelesen werden kann
      }
    }
  }// beobachten IR 2
    
  }
  


  

  
  writeStatus();
   
  // Status merken
  oT1=cT1;
  oT2=cT2;

 }
 
// Berechnen des Ergebnis
void showResult(){
//  Serial.print(calTime());
  Serial.print("Dauer: ");
  Serial.print(calTime());
  Serial.println(" sek");
  lcd.clear();
  lcd.setCursor(0,0); //Start at character 4 on line 0
  lcd.print("Dauer: ... sek");
  lcd.setCursor(0,1); //Start at character 4 on line 0
  lcd.print("Speed...  km/h");
  }

float calTime(){
  unsigned long over;
  finished=millis();
  elapsed=finished - start;

//  over = elapsed % 3600000;
//  over = over % 60000;
  return (elapsed / 1000.0);
}

// Ausgabe der Statusangaben
void writeStatus(){
  // liegt eine Veränderung in den Tastern vor?
  if (oT1!=cT1 || oT2!=cT2)  {
    Serial.print(cT1);
    Serial.print(" - ");
    Serial.print(cT2);
    Serial.print(" -> ");
    Serial.println(act);
  }
}

// Definieren der Strecke für die Ausmessung in MM
void Strecke(){
  int cDist = map(analogRead(P1),0,1023,Svon,Sbis);
  int value =analogRead(P1);
}

Gruß Jan

Hallo Jan,
wenn ein Moba-Kollege ein Problem hat, muss ich mich doch auch mal zu Wort melden :wink:

Zerrissen wird hier keiner :slight_smile: . Aber dein Sketch ist schon noch eine rechte Bauruine.
Kommentare sind zwar gut und wichtig ( an einigen Stellen könnten es durchaus auch ein paar mehr sein ). Aber sie sollten auch zum Programm passen! Kommentare, die was anderes sagen als der kommentierte Code, tragen sehr zur Verwirrung bei.

Dass es keine gute Idee ist, für die Abfrage eines mechanischen Tasters einen Interrupt herzunehmen, wurde ja schon gesagt. Das ist besser im loop aufgehoben. Dass der loop dann aber nicht mit delay lange blockiert werden darf, wurde ja auch schon gesagt.
Wichtig für das Entprellen ist eigentlich nur, dass der Taster nicht zu oft abgefragt wird. Die Libs, die es dafür gibt, sind m.M. nach nur Ressourcenvernichter und überflüssig. Definier dir eine Statusvariable für den Taster. Die aktualisierst Du dann am Anfang von loop, wenn seit der letzten Aktualisierung mindestens 10ms vergangen sind. Das kann man sehr schon und einfach mit millis machen und mehr braucht es dafür nicht. Im loop wird dann nur die Statusvariable verwendet.

Aufpassen muss man, wenn mit dem Taster 'getoggelt' werden soll ( bei dir die Umschaltung von Modus zwischen -1 und 1 ). Da darfst Du nicht den statischen Zustand des Tasters abfragen. Sonst wird während der Taster gedrückt ist, ständig zwischen -1 und 1 hin- und hergeschaltet, und welcher Zustand dann beim Loslassen herrscht ist rein zufällig. Da musst Du das 'Drücken' also den Statuswechsel erkennen. Dazu musst Du dir bei jedem loop-Durchlauf auch den vorherigen Status merken, und nur wenn sich der Tasterstatus von 'nicht gedrückt' auf 'gedrückt' ändert, darfst Du den Modus umschalten.

Dinge, die nur beim Programmstart ausgeführt werden sollen, gehören in setup(), das mit dem modus==0 ist unnötig.

Die lcd-Aufrufe sind zeitintensiv. Deshalb - wie schon geschrieben wurde - das LCD wirklich nur bei Bedarf aktualisieren.

Ist deine Messtrecke wirklich variabel? Bei einer festen Messtrecke kannst Du die Werte als const im Programm eintragen, und brauchst deinen speziellen 'Strecken-Definiton-Mode' gar nicht. Es macht auch keinen Sinn, die Strecke in 1/10 mm anzugeben. So genau wirst Du das gar nicht ausrichten können.

So, das mal meine ersten Gedanken dazu.

Das kleine Prijekt ist auch eine wunderbare Gelegenheit, sich mal mit dem Thema 'endlicher Automat' auseinanderzusetzen. Da gibt's auch hier im Forum Beispiele dazu.

Eine Frage noch zum Taster. Du fragst auf HIGH ab, d.h. Dein Taster schaltet nach 5V. Hast Du an dem Eingang einen Pulldownwiderstand von ca. 10 kOhm nach GND? Sonst wirkt der Eingang wie eine Antenne und fängt alles (un)mögliche ein.

Dass die delay aus dem Loop raus müssen, wurde Dir ja schon gesagt.

Gruß Tommy

Moin!

ich habe den Code einmal reduziert und auch den Interrupt herausgenommen.

Dann alles (bis auf den Kopf) reduziert. Über den Monitor lasse ich mir das Betätigen des Tasters dokumentieren.

Aber wenn ich auf den Taster drücke kommt folgendes:

1

1
++++++++++
-1
++++++++++
1
++++++++++
-1
++++++++++
1

1

Es wurde zwar einmal etwas von Bounce2 geschrieben - aber das habe ich mit meinem englisch Kenntnissen nicht verstanden.

Hier der Code:

// Lichtschranke für Zugeschwindigkeit in Verbindung mit Seriellen Monitor
//
// Einbinden der LCD-Funktionen derzeit noch inaktiv
// #include <LiquidCrystal_I2C.h>
// LiquidCrystal_I2C lcd(0x27, 16,2) // ?????
//
#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>

/*-----( Declare Constants )-----*/
/*-----( Declare objects )-----*/
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
/*-----( Declare Variables )-----*/
//NONE

unsigned long start, finished, elapsed;
int modus=-1;      // Programmstart 0 / Def der Strecke =-1 / Messung = 1
int act=0;         // Messung läuft 1 / beendet oder nicht gestartet 0
int tstatus=0;     // Tasterstatus
int T1=7;          // 1. IR #7
int T2=8;          // 2. IR #8
int T3=9;          // 1. Taster für Modi-Wechsel
int P1=A1;         // ANALOG für Poti
// Werteabfrage
// IR
// aktueller Status
int cT1=-1;        // Status IR 1
int cT2=-1;        // Status IR 2
// vorheriger Status
int oT1=-1;        // Status IR 1
int oT2=-1;        // Status IR 2
int maxTime=0;     // Kennung für die Zeitüberschreitung
// Poti
int cP=0;          // Wert am Poti
// Werte für die Messstrecke (1/10mm)
int Svon = 3500;    // 50 cm 
int Sbis = 4500;    // 60cm
int oDist =0;       // alter Streckenwert
char text[5];

void setup() {
  // Hier fehlt die Initalisierung des LCD
  Serial.begin(9600);    // öffnen der Seriellen Schnittstelle für die Überwachung
  pinMode(T1,INPUT);     // EINGANGSpin für den IR-#1
  pinMode(T2,INPUT);     // EINGANGSpin für den IR-#2
  pinMode(T3,INPUT);     // EINGANGSpin für den Taster
  
  lcd.setCursor(0,0); //Start at character 4 on line 0
  lcd.print("Lichtschranke");
  lcd.setCursor(0,1); //Start at character 4 on line 0
  lcd.print("bereit ...");
  delay(2000); 
}

void loop() {
  // Abfrage des Tasters für Modus
  //Serial.println("Taster-Abfrage");
  if (digitalRead(T3)==HIGH){
    Serial.println("++++++++++          ");
    modus=modus*-1;
  }else{
    Serial.println("          ----------");
 }

Serial.println(modus);
  
  // Definition der Strecke
  if (modus==-1) {
//    Serial.println("Streckendefinition");
  }else{
//    Serial.println("Messung");
 }
  
}//end-loop

Kann mir zumindest für diese Stelle einer schon mal weiterhelfen??

Gruß Jan

Habe jetzt erst die anderen Postings von heute gesehen! :frowning:

Hallo Jan,
das Ganze erstmal abzuspecken, und mit der Tasterabfrage zu beginnen ist ja schonmal gut. Aber hast Du dir durchgelesen, was ich geschrieben habe? Du machst in deinem Programm nichts davon - weder entprellen, noch die Flanke erkennen. So wie es jetzt ist, kann das nichts werden.

mal auf die reine Tastererkennung reduziert:

int modus=-1;      // Programmstart 0 / Def der Strecke =-1 / Messung = 1
const int T3=9;          // 1. Taster für Modi-Wechsel
bool T3State, T3oldState;
unsigned long lastAktT3;
const unsigned long prellZeit = 20;

void setup() {
  // Hier fehlt die Initalisierung des LCD
  Serial.begin(9600);    // öffnen der Seriellen Schnittstelle für die Überwachung
  pinMode(T3,INPUT);     // EINGANGSpin für den Taster
}

void loop() {
  // Abfrage des Tasters für Modus
  T3oldState = T3State;
  if ( millis() - lastAktT3 > prellZeit ) {
    lastAktT3 = millis();
    T3State = digitalRead(T3);
  }
  if (T3State && ! T3oldState){
    Serial.println("++++++++++          ");
    modus=modus*-1;
    Serial.println(modus);
  }

 
}//end-loop

Hallo Franz-Peter,

ich habe mir das jetzt gerade durchgelesen.

Ist deine Messtrecke wirklich variabel? Bei einer festen Messtrecke kannst Du die Werte als const im Programm eintragen, und brauchst deinen speziellen 'Strecken-Definiton-Mode' gar nicht. Es macht auch keinen Sinn, die Strecke in 1/10 mm anzugeben. So genau wirst Du das gar nicht ausrichten können.

hatte ich so vorgesehen, dass diese nicht verbaut ist. Außerdem möchte ich nicht ein Rechner mitschleppen. Auf den 1/10 kann man verzichten. 8)

Nebensächlich - ich wundere mich, dass in diesem Code die LCD nicht reagiert! Habe ich versehentlich etwas gelöscht was erforderlich ist? Defekt und falsch angeschlossen ist ausgeschlossen, da in einem anderen Sketch es angesprochen wird.

Was die Frage nach der Steckung betrifft habe ich meine erste Skizze mit Fritzing erstellt:

Helfen diese Angaben weiter?

Ein Beispiel für eine Geschwindigkeitsmessung habe ich gefunden - Geschwindigkeitsmessung - Deutsch - Arduino Forum. Aber das ist nicht mein Ziel ich möchte es schrittweise mir selber erarbeiten. Eine Messung ohne den Taster und die Umschaltung hat schon einmal funktioniert.

Anmerkung zum Beispiel von Franz-Peter: das würdest Du dann in eine Void legen?

Gruß Jan