Drehscheibe Modellbahn mit RF24

Jetzt weis ich was du meinst. Klar die 2 Sekunden macht er ja nix, weder auf nen Sensor reagieren sonst noch irgendwas anderes. Hatte am Anfang zum einlesen des Encoder Tasters vorallem schon mit millis() gearbeiteitet und baue mir dann hier mit dem Delay ne Krücke rein.

Nicht nur mit dem delay. Du prüfst auch enter und sensor nicht ab. Wenn die egal sind, kannst Du sie aus der Bedingung raus lassen, ansonsten musst Du im while deren Zustand prüfen und aktualisieren.

Gruß Tommy

 sensor = digitalRead (hal);
    if ((schritte != 0)&& (enter == true)){
      
      while ((schritte != 0) && (sensor == HIGH)) {
          startZeit = millis();
          if ((millis() - startZeit >= interval) && sensor == LOW) { 
                 
          schritte--;
          vergangeneZeit = startZeit;
          Serial.println("Schritte");
          Serial.println(schritte);
          
           Serial.println("Ziel");
          enter = false;
          gleisAlt = wertSpeichern;
       }

also so ungefähr?

Hi

Ja, die Richtung stimmt schon.
Wofür das While?
loop() kommt eh direkt wieder hier vorbei.
Du musst 'nur' gucken, ob der Hall-Sensor 'jetzt gedrückt ist' und Dir Das merken.
Und in der nächsten Zeile, ob der Hall-Sensor 'jetzt nicht gedrückt ist'.
Jeweils die aktuelle Zeit merken beim Umschalten und nach 20ms ohne weitere Umschaltung wird der Pegel stabil sein (eigentlich prellt ein elektronischer Sensor nicht, schadet aber auch nicht).

Die ganzen Einzel-Probelme

  • Gleiswahl per Zifferneingabe/per Drehencoder/per Serial
  • Entfernung und Richtungsbestimmung (bei Return)
  • starten/stoppen des Motor in die entsprechende Richtung
  • Hallsensor erkennen und schritte runter zählen
    packst Du in einzelne Funktionen.
    Deine loop() ruft dann nur noch diese Funktionen nach einander auf.
    Wenn kein neues Gleis eingegeben wurde, kommt kein Return, wird also keine (neue) Entfernung berechnet.
    Wenn wir keine Entfernung zum Ziel haben, muß der Motor nicht laufen.
    Wenn der Motor nicht läuft, werden auch keine Hall-Signale verarbeitet - es kommen schlicht Keine.

Die Probleme vereinzeln und die möglichst in möglichst kleine Einzelprobleme auch einzeln lösen.

MfG

Habe mal versucht während du den Beitrag geschrieben hast, Den codeumzuschreiben. Habe ihn aber noch nicht weiter getestet. Aber so ungefähr habe ich mir das gedacht.

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


int messungPin1 = HIGH;
int messungPin1Alt = HIGH;
byte encoderWert = 0; // -1 ( eins weniger als 0 ) == 255
const byte hal = 3;
const byte encoderPinA = 10;            // Phase A vom Drehencoder
const byte encoderPinB = 11;             // Phase B vom Drehencoder
const byte tasterEnter = 12;                   // Pin an dem der Encoder Taster angeschlossen ist
int wertSpeichern = 0;                  // gespeicherter Encoderwert
int encoderGedrueckt = 0;              // Statusspeicher ob Encodertaster betätigt wurde
int encoderTaster = HIGH;             // Taster im Encoder
int gleisAlt = 0;                     // Scheibe Position alt
int gleisNeu = 0;                     // Position welche die Scheibe anfahren soll
bool enter = false;                   // Bestätigung das der Encoder gedrückt wurde
int schritte = 0;                     // Schritte die deer Motor (Hallsensor betätigt) zurücklegen muss
int sensor = LOW;
bool start = false;

unsigned long encoderDruckzeit;       // Zeit wann der Encodertaster betätigt wurde
unsigned long entprellZeit = 200;     // Zeit die nach der betätigung eines Tasters gewartet wird
unsigned long startZeit;
unsigned long interval = 2000;
unsigned long vergangeneZeit = 0;

void setup() {
  pinMode(encoderPinA, INPUT);
  pinMode(encoderPinB, INPUT);
  pinMode(tasterEnter, INPUT);
  pinMode(hal, INPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Encoder");
  lcd.setCursor(0, 1);
  lcd.print("Test");
  delay (2000);
  lcd.clear();
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Wert");
  lcd.setCursor(0, 1);
  lcd.print(encoderWert);
}

void loop() {
  messungPin1 = digitalRead(encoderPinA);
  if ((messungPin1 == LOW) && (messungPin1Alt == HIGH)) {
    if (digitalRead(encoderPinB) == HIGH) {
      if (encoderWert < 48) encoderWert++ ;
    } else {
      if (encoderWert > 1) encoderWert-- ;
    }
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Wert");
    lcd.setCursor(0, 1);
    lcd.print(encoderWert);
  }
     encoderTaster = digitalRead(tasterEnter);
    if (encoderTaster == LOW)
    {
      encoderDruckzeit = millis();
      encoderGedrueckt = 1;
    }
    if ((millis() - encoderDruckzeit > entprellZeit) && encoderGedrueckt == 1) {
      wertSpeichern = encoderWert;
      Serial.println(wertSpeichern);
      encoderGedrueckt = 0;
      enter = true;
    }
    if (enter == true) {
      gleisNeu = wertSpeichern;
      schritte = abs (gleisNeu - gleisAlt);
      Serial.print ("benoetigte Schritte  ");
      Serial.println(schritte);
      //gleisAlt = wertSpeichern;
      Serial.println(gleisNeu);
      Serial.println(gleisAlt);
      Serial.println(enter);
    }
   sensor = digitalRead (hal);
   startZeit=millis();
    if ((schritte != 0)&& (enter == true)){
      start = true;
      if ((startZeit - vergangeneZeit >= interval) && (sensor == LOW) && (start ==true)) { 
          schritte--;
          Serial.println("Schritte");
          Serial.println(schritte);
      }
          else
          start = false;
           Serial.println("Ziel erreicht");
          enter = false;
          gleisAlt = wertSpeichern;
       }
  //    }
//    }
    //if ((schritte >12)&& (enter== true)) {
    // Serial.println("rechts");
    //enter = false;
   //  else {
  // Serial.println("links");
  //enter = false;
 // }
 // }
  messungPin1Alt = messungPin1;
   
}

Vielleicht bin ich ja jetzt auf dem richtigen weg. Werd jetzt erst mal schlafen. Bis später und vielen Dank für die bisherige Hilfe.

MfG Daniel

Hi

Acki1985:
Aber so ungefähr habe ich mir das gedacht.
....
Vielleicht bin ich ja jetzt auf dem richtigen weg. Werd jetzt erst mal schlafen....

Der Weg wird immer besser, dürfte so aber noch nicht funktionieren.
Das heimische Bettchen aufsuchen klingt nach einem sinnvollem Plan - mache ich hier auch Mal.

MfG

Guten Abend,

ich habe es jetzt mal mit Funktionen versucht zu schreiben. Meint ihr es so in der Art?

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


int messungPin1 = HIGH;
int messungPin1Alt = HIGH;
byte encoderWert = 0; // -1 ( eins weniger als 0 ) == 255
const byte hal = 3;
const byte encoderPinA = 10;            // Phase A vom Drehencoder
const byte encoderPinB = 11;             // Phase B vom Drehencoder
const byte tasterEnter = 12;                   // Pin an dem der Encoder Taster angeschlossen ist
int wertSpeichern = 0;                  // gespeicherter Encoderwert
int encoderGedrueckt = 0;              // Statusspeicher ob Encodertaster betätigt wurde
int encoderTaster = HIGH;             // Taster im Encoder
int gleisAlt = 0;                     // Scheibe Position alt
int gleisNeu = 0;                     // Position welche die Scheibe anfahren soll
bool enter = false;                   // Bestätigung das der Encoder gedrückt wurde
int schritte = 0;                     // Schritte die deer Motor (Hallsensor betätigt) zurücklegen muss
int sensor = LOW;
bool start = false;
bool ergebnis = false;

unsigned long encoderDruckzeit;       // Zeit wann der Encodertaster betätigt wurde
unsigned long entprellZeit = 200;     // Zeit die nach der betätigung eines Tasters gewartet wird
unsigned long startZeit;
unsigned long interval = 2000;
unsigned long vergangeneZeit = 0;

void setup() {
  pinMode(encoderPinA, INPUT);
  pinMode(encoderPinB, INPUT);
  pinMode(tasterEnter, INPUT);
  pinMode(hal, INPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Encoder");
  lcd.setCursor(0, 1);
  lcd.print("Test");
  delay (2000);
  lcd.clear();
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Wert");
  lcd.setCursor(0, 1);
  lcd.print(encoderWert);
}


void loop() {
  encoder_lesen();
  schritt();
  schritteZaehlen();

}

void encoder_lesen () {
  messungPin1 = digitalRead(encoderPinA);
  if ((messungPin1 == LOW) && (messungPin1Alt == HIGH)) {
    if (digitalRead(encoderPinB) == HIGH) {
      if (encoderWert < 48) encoderWert++ ;
    } else {
      if (encoderWert > 1) encoderWert-- ;
      
    }
   
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Wert");
    lcd.setCursor(0, 1);
    lcd.print(encoderWert);
}
  encoderTaster = digitalRead(tasterEnter);
    if (encoderTaster == LOW)
    {
      encoderDruckzeit = millis();
      encoderGedrueckt = 1;
    }
    if ((millis() - encoderDruckzeit > entprellZeit) && encoderGedrueckt == 1) {
      wertSpeichern = encoderWert;
      Serial.println(wertSpeichern);
      encoderGedrueckt = 0;
      enter = true;
      
    }
    messungPin1Alt = messungPin1;
}

void schritt () {
   if (enter == true) {
      gleisNeu = wertSpeichern;
      schritte = abs (gleisNeu - gleisAlt);
      Serial.print ("benoetigte Schritte  ");
      Serial.println(schritte);
      //gleisAlt = wertSpeichern;
      Serial.println(gleisNeu);
      Serial.println(gleisAlt);
      Serial.println(enter);
      enter = false;
      ergebnis =true;
    }
}

void schritteZaehlen () {
  sensor = digitalRead (hal);
   startZeit = millis();
    if ((schritte != 0)&& (ergebnis == true)){
      start = true;
      if ((startZeit - vergangeneZeit >= interval) && (sensor == LOW) && (start ==true)) { 
          vergangeneZeit = startZeit;
          schritte--;
          Serial.println("Schritte");
          Serial.println(schritte);
      }
    }
          else if (schritte == 0){
          start = false;
           Serial.println("Ziel");
          ergebnis = false;
          gleisAlt = wertSpeichern;
       }
}

Edit: Code geändert

Jetzt macht die Steuerung das was sie bis jetzt soll. Der nächste Schritt ist die Richtungsbestimmung. Kann mir da wer auf die Sprünge helfen?

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


int messungPin1 = HIGH;
int messungPin1Alt = HIGH;
byte encoderWert = 0; // -1 ( eins weniger als 0 ) == 255
const byte hal = 3;
const byte encoderPinA = 10;            // Phase A vom Drehencoder
const byte encoderPinB = 11;             // Phase B vom Drehencoder
const byte tasterEnter = 12;                   // Pin an dem der Encoder Taster angeschlossen ist
int wertSpeichern = 0;                  // gespeicherter Encoderwert
int encoderGedrueckt = 0;              // Statusspeicher ob Encodertaster betätigt wurde
int encoderTaster = HIGH;             // Taster im Encoder
int gleisAlt = 0;                     // Scheibe Position alt
int gleisNeu = 0;                     // Position welche die Scheibe anfahren soll
bool enter = false;                   // Bestätigung das der Encoder gedrückt wurde
int schritte = 0;                     // Schritte die deer Motor (Hallsensor betätigt) zurücklegen muss
int sensor = LOW;
bool start = false;
bool ergebnis = false;

unsigned long encoderDruckzeit;       // Zeit wann der Encodertaster betätigt wurde
unsigned long entprellZeit = 200;     // Zeit die nach der betätigung eines Tasters gewartet wird
unsigned long startZeit;
unsigned long interval = 2000;
unsigned long vergangeneZeit = 0;

void setup() {
  pinMode(encoderPinA, INPUT);
  pinMode(encoderPinB, INPUT);
  pinMode(tasterEnter, INPUT);
  pinMode(hal, INPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Encoder");
  lcd.setCursor(0, 1);
  lcd.print("Test");
  delay (2000);
  lcd.clear();
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Wert");
  lcd.setCursor(0, 1);
  lcd.print(encoderWert);
}


void loop() {
  encoder_lesen();
  schritt();
  schritteZaehlen();

}

void encoder_lesen () {
  messungPin1 = digitalRead(encoderPinA);
  if ((messungPin1 == LOW) && (messungPin1Alt == HIGH)) {
    if (digitalRead(encoderPinB) == HIGH) {
      if (encoderWert < 48) encoderWert++ ;
    } else {
      if (encoderWert > 1) encoderWert-- ;
      
    }
   
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Wert");
    lcd.setCursor(0, 1);
    lcd.print(encoderWert);
}
  encoderTaster = digitalRead(tasterEnter);
    if (encoderTaster == LOW)
    {
      encoderDruckzeit = millis();
      encoderGedrueckt = 1;
    }
    if ((millis() - encoderDruckzeit > entprellZeit) && encoderGedrueckt == 1) {
      wertSpeichern = encoderWert;
      Serial.println(wertSpeichern);
      encoderGedrueckt = 0;
      enter = true;
      
    }
    messungPin1Alt = messungPin1;
}

void schritt () {
   if (enter == true) {
      gleisNeu = wertSpeichern;
      schritte = abs (gleisNeu - gleisAlt);
      Serial.print ("benoetigte Schritte  ");
      Serial.println(schritte);
      //gleisAlt = wertSpeichern;
      Serial.println(gleisNeu);
      Serial.println(gleisAlt);
      Serial.println(enter);
      enter = false;
      ergebnis =true;
    }
}

void schritteZaehlen () {
  sensor = digitalRead (hal);
   startZeit = millis();
    if ((schritte != 0)&& (ergebnis == true)){
      start = true;
      if ((startZeit - vergangeneZeit >= interval) && (sensor == LOW) && (start ==true)) { 
          vergangeneZeit = startZeit;
          schritte--;
          Serial.println("Schritte");
          Serial.println(schritte);
      }
    }
          else if ((schritte == 0) && (start == true)){
          start = false;
           Serial.println("Ziel");
          ergebnis = false;
          gleisAlt = wertSpeichern;
       }
}

void best_Richtung(){
  
}

void motor(){
  
}

Hi

Na verdammt - dann brauchst Du mich ja gar nicht mehr :wink:
Habe mich Mal in Deinem Sketch probiert, ein/zwei Dinge umgebaut.
Unter Anderem sollte die Drehrichtung in die kürzere Richtung gehen.

Sketch ist UNGETESTET

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int messungPin1 = HIGH;               //Temp für Encoder-Pin
int messungPin1Alt = HIGH;            //dito, um Veränderungen erkennen zu können
byte encoderWert = 0;                 // -1 ( eins weniger als 0 ) == 255
const byte hal = 3;                   //Pin vom Hall-Sensor
const byte encoderPinA = 10;          // Phase A vom Drehencoder
const byte encoderPinB = 11;          // Phase B vom Drehencoder
const byte tasterEnter = 12;          // Pin an dem der Encoder Taster angeschlossen ist
int wertSpeichern = 0;                // gespeicherter Encoderwert
int encoderGedrueckt = 0;             // Statusspeicher ob Encodertaster betätigt wurde
int encoderTaster = HIGH;             // Taster im Encoder
int gleisAlt = 0;                     // Scheibe Position alt
int gleisNeu = 0;                     // Position welche die Scheibe anfahren soll
bool enter = false;                   // Bestätigung das der Encoder gedrückt wurde
int schritte = 0;                     // Schritte die der Motor (Hallsensor betätigt) zurücklegen muss
boolean sensor = LOW;                 // Wert des (Hall) Sensor
bool start = false;                   // Verdrehen gestartet?
bool ergebnis = false;                // Es sind Schritte vorhanden, Motor gestartet
const byte pin_motor_links = 10;      // Richtungspin an H-Brücke für Links
const byte pin_motor_rechts = 11;     // Richtungspin an H-Brücke für Rechts


unsigned long encoderDruckzeit;       // Zeit wann der Encodertaster betätigt wurde
unsigned long entprellZeit = 200;     // Zeit die nach der betätigung eines Tasters gewartet wird
unsigned long startZeit;              // Hilfsvariable für die Startzeit
unsigned long interval = 2000;
unsigned long vergangeneZeit = 0;

void setup() {
  pinMode(encoderPinA, INPUT);
  pinMode(encoderPinB, INPUT);
  pinMode(tasterEnter, INPUT);
  pinMode(hal, INPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Encoder");
  lcd.setCursor(0, 1);
  lcd.print("Test");
  delay (2000);
  lcd.clear();
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Wert");
  lcd.setCursor(0, 1);
  lcd.print(encoderWert);
}


void loop() {
  encoder_lesen();
  schritt();
  schritteZaehlen();

}

void encoder_lesen () {
  messungPin1 = digitalRead(encoderPinA);
  if ((messungPin1 == LOW) && (messungPin1Alt == HIGH)) {
    if (digitalRead(encoderPinB) == HIGH) {
      if (encoderWert < 48) encoderWert++ ;
    } else {
      if (encoderWert > 1) encoderWert-- ;
    }
    //    lcd.setCursor(0, 0);
    //    lcd.print("Wert");
    lcd.setCursor(0, 1);
    lcd.print(encoderWert);
  }
  encoderTaster = digitalRead(tasterEnter);
  if (encoderTaster == LOW)
  {
    encoderDruckzeit = millis();
    encoderGedrueckt = 1;
  } else if ((millis() - encoderDruckzeit > entprellZeit) && encoderGedrueckt == 1) {
    wertSpeichern = encoderWert;
    Serial.println(wertSpeichern);
    encoderGedrueckt = 0;
    enter = true;
  }
  messungPin1Alt = messungPin1;
}

void schritt () {
  if (enter == true) {
    gleisNeu = wertSpeichern;

    // 17 -> 3 links 14, rechts 10
    // links = abs(alt-neu)
    // rechts = 24-abs(alt-neu)

    // 3 -> 17 rechts 14, links 10
    // links = abs(alt-neu)
    // rechts = 24-abs(alt-neu)
    byte rechtsrum = abs(gleisAlt - gleisNeu);                //Weg rechts herum
    byte linksrum = maxpositionen - abs(gleisAlt - gleisNeu); //Weg links herum
    schritte = min(rechtsrum, linksrum);                      //kürzeren Weg nehmen
    Serial.print ("benoetigte Schritte  ");
    Serial.println(schritte);
    Serial.println(gleisNeu);
    Serial.println(gleisAlt);
    Serial.println(enter);
    enter = false;
    if (schritte) {   //wenn Ist = Soll, dann Nichts machen
      ergebnis = true;
      if (linksrum < rechtsrum) {             //Startrichtung des Motor
        //Motor starten links
        digitalWrite(pin_motor_links, HIGH);
      } else {
        //Motor starten rechts
        digitalWrite(pin_motor_rechts, HIGH);
      }
    }
  }
}

void schritteZaehlen () {
  sensor = digitalRead (hal);
  static boolean sensor_old = sensor;
  if (schritte != 0) {          //nur, wenn noch Schritte zu erledigen sind
    if (ergebnis == true) {     //Motor ist gestartet?
      start = true;             //Abarbeitung gestartet
      //Flanken auswerten
      //Entprellzeit beachten
      //bei HIGH-LOW Schritte runterzählen
      if (sensor == HIGH) { //Sensor in Ruhestellung
        startTeit = millis(); //Entprellung neu beginnen
      } else if (millis() - startZeit > interval) {  //Entprellzeit vorbei?
        //fallende Flanke erkannt, da wir hier eh bei == LOW sind
        schritte--;
        Serial.println("Schritte");
        Serial.println(schritte);
      }
    }
  }
  if (schritte == 0 && (start != false) { //die Schritte können in der oberen IF auf Null gegangen sein
  start = false;
  Serial.println("Ziel");
    ergebnis = false;
    gleisAlt = wertSpeichern;
    //Motor AUS
    digitalWrite(pin_motor_links, LOW);
    digitalWrite(pin_motor_rechts, LOW);
  }
}

Sichere Dir Deinen Sketch, bevor Du Meinen drüber kopierst oder Ideen daraus in Deinen einbaust!!
Nichts ist schlimmer, als ein eigenhändig zerstörter Sketch, weil man 'nur Mal schnell diese Kleinigkeit' ...
(ich spreche Da aus leidvoller Erfahrung)

MfG

Wer keine Versionsverwaltung hat, hatte keine wichtigen Quellcodes - in Abwandlung des Spruchs zu Backups.

Bei mir wird beim Compilieren gespeichert und bei jedem Speichern automatisch eine Kopie mit Zeitstempel hinten dran erzeugt. Das ist zwar nur eine minimale Versionierung, ich kann aber immer auf den alten Stand zurück.

Am Ende muss man dann mal aufräumen.

Gruß Tommy

Ich danke euch.

Kann mir mal einer das erklären was damit gemeint ist?

 byte rechtsrum = abs(gleisAlt - gleisNeu);                //Weg rechts herum
    byte linksrum = maxpositionen - abs(gleisAlt - gleisNeu); //Weg links herum
    schritte = min(rechtsrum, linksrum);                      //kürzeren Weg nehmen

Hi

Äh - 'maxposition' habe ich nicht deklariert :confused:
Darin steht (sollte stehen) die Anzahl der möglichen Positionen - also bei Dir 48 - wollte Das flexibel halten.
recht/linksrum ist der Abstand vom Start zum Ziel, wenn ich recht oder linksrum fahre.
Dein altes schritte war ja der Abstand der beiden Gleisnummern zueinander.
Gleich 43 und Gleis 2 haben '41 Gleise Anstand' - oder 7, wenn wir anders herum fahren.
Der kürzere Weg wird dann eingeschlagen.

MfG

Hallo alle zusammen. Ich komm damit nicht klar. Vielleicht kann mir das einer erklären. Eine volle Drehung sind 48 Schritte.

// 17 -> 3 links 14, rechts 10
// links = abs(alt-neu)
// rechts = 24-abs(alt-neu)

// 3 -> 17 rechts 14, links 10
// links = abs(alt-neu)
// rechts = 24-abs(alt-neu)

Wie das mit der Richtungsbestimmung funktionieren soll, das verstehe ich nicht.

Hi

Fehler Meinerseits - bei den Beispielrechnungen habe ich '24' angenommen.
Deshalb steht bei rechts auch die 24 (statt Deiner 48, Die habe ich erst rein korrigiert, nachdem der Sketch soweit beisammen war).

Annahme, wir haben 24 Positionen, dann ist von der Position 17 bis zur 24 der Abstand 7.
Da die 24 aber ebenfalls der Position Null entspricht, haben wir von dirt einen Abstand zur 3 von 3.
7 + 3 = 10.
In die andere Richtung ist's von der 17 bis zur 3 ein Abstand von 14.
10 < 14, somit wird die 10er Richtung gewählt.

Sorry für die Verwirrungen

MfG

Ah gut. Das mit dem rechts drehen habe ich verstanden. Aber wie funktioniert das mit dem links drehen?

Bietet es sich an die Richtungswahl in eine seperate Funktion zu schreiben und die dann je na Richtung aufzurufen?

Hab mal versucht eine Refernzfahrt zu programmieren.

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


int messungPin1 = HIGH;
int messungPin1Alt = HIGH;
byte encoderWert = 0; // -1 ( eins weniger als 0 ) == 255
const byte hal = 3;
const byte encoderPinA = 10;            // Phase A vom Drehencoder
const byte encoderPinB = 11;             // Phase B vom Drehencoder
const byte tasterEnter = 12;                   // Pin an dem der Encoder Taster angeschlossen ist
int wertSpeichern = 0;                  // gespeicherter Encoderwert
int encoderGedrueckt = 0;              // Statusspeicher ob Encodertaster betätigt wurde
int encoderTaster = HIGH;             // Taster im Encoder
int gleisAlt = 0;                     // Scheibe Position alt
int gleisNeu = 0;                     // Position welche die Scheibe anfahren soll
bool enter = false;                   // Bestätigung das der Encoder gedrückt wurde
int schritte = 0;                     // Schritte die deer Motor (Hallsensor betätigt) zurücklegen muss
int sensor = LOW;
bool start = false;
bool ergebnis = false;

unsigned long encoderDruckzeit;       // Zeit wann der Encodertaster betätigt wurde
unsigned long entprellZeit = 200;     // Zeit die nach der betätigung eines Tasters gewartet wird
unsigned long startZeit;
unsigned long interval = 2000;
unsigned long vergangeneZeit = 0;
bool nullStellung = false;
const byte pin_motor_links = A1;      // Richtungspin an H-Brücke für Links
const byte pin_motor_rechts = A2;     // Richtungspin an H-Brücke für Rechts
const byte sensor_referenz = A3;

void setup() {
  pinMode(sensor_referenz, INPUT);
  pinMode(pin_motor_links, OUTPUT);
  pinMode(pin_motor_rechts, OUTPUT);
  pinMode(encoderPinA, INPUT);
  pinMode(encoderPinB, INPUT);
  pinMode(tasterEnter, INPUT);
  pinMode(hal, INPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Drehscheiben-");
  lcd.setCursor(0, 1);
  lcd.print("steuerrung");
  delay (2000);
  //lcd.clear();
  //lcd.begin(16, 2);
  //lcd.setCursor(0, 0);
  //lcd.print("Wert");
  //lcd.setCursor(0, 1);
  //lcd.print(encoderWert);
}


void loop() {
  referenzFahrt();
  encoder_lesen();
  schritt();
  schritteZaehlen();

}

void referenzFahrt(){
  if ((nullStellung == false) && (sensor_referenz == LOW)) {
    lcd.clear();
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Referenzfahrt");
    lcd.setCursor(0, 1);
    lcd.print("gestartet");
    pin_motor_rechts = HIGH;
    pin_motor_links = LOW;
  }
  else {
    nullStellung = true;
    pin_motor_rechts = LOW;
    pin_motor_links = LOW;
    lcd.clear();
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Referenzfahrt");
    lcd.setCursor(0, 1);
    lcd.print("beendet");
    delay(2000);
    lcd.clear();
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Wert");
    lcd.setCursor(0, 1);
    lcd.print(encoderwert);
  }
  
}

void encoder_lesen () {
  messungPin1 = digitalRead(encoderPinA);
  if ((messungPin1 == LOW) && (messungPin1Alt == HIGH)) {
    if (digitalRead(encoderPinB) == HIGH) {
      if (encoderWert < 48) encoderWert++ ;
    } else {
      if (encoderWert > 1) encoderWert-- ;
      
    }
   
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Wert");
    lcd.setCursor(0, 1);
    lcd.print(encoderWert);
}
  encoderTaster = digitalRead(tasterEnter);
    if (encoderTaster == LOW)
    {
      encoderDruckzeit = millis();
      encoderGedrueckt = 1;
    }
    if ((millis() - encoderDruckzeit > entprellZeit) && encoderGedrueckt == 1) {
      wertSpeichern = encoderWert;
      Serial.println(wertSpeichern);
      encoderGedrueckt = 0;
      enter = true;
      
    }
    messungPin1Alt = messungPin1;
}

void schritt () {
   if (enter == true) {
      gleisNeu = wertSpeichern;
      schritte = abs (gleisNeu - gleisAlt);
      Serial.print ("benoetigte Schritte  ");
      Serial.println(schritte);
      //gleisAlt = wertSpeichern;
      Serial.println(gleisNeu);
      Serial.println(gleisAlt);
      Serial.println(enter);
      enter = false;
      ergebnis =true;
    }
}

void schritteZaehlen () {
  sensor = digitalRead (hal);
   startZeit = millis();
    if ((schritte != 0)&& (ergebnis == true)){
      start = true;
      if ((startZeit - vergangeneZeit >= interval) && (sensor == LOW) && (start ==true)) { 
          vergangeneZeit = startZeit;
          schritte--;
          Serial.println("Schritte");
          Serial.println(schritte);
      }
    }
          else if ((schritte == 0) && (start == true)){
          start = false;
           Serial.println("Ziel");
          ergebnis = false;
          gleisAlt = wertSpeichern;
       }
}

void best_Richtung(){
  
}

void motor(){
  
}

Beim überprüfen des Codes bekomme ich folgende Fehlermeldung:

Arduino: 1.8.5 (Windows 10), Board: "Arduino/Genuino Uno"

C:\Users\danie\Documents\Arduino\Drehscheibensteuerrung_mit_Funktionen\Drehscheibensteuerrung_mit_Funktionen.ino: In function 'void referenzFahrt()':

Drehscheibensteuerrung_mit_Funktionen:73: error: assignment of read-only variable 'pin_motor_rechts'

pin_motor_rechts = HIGH;

^

Drehscheibensteuerrung_mit_Funktionen:74: error: assignment of read-only variable 'pin_motor_links'

pin_motor_links = LOW;

^

Drehscheibensteuerrung_mit_Funktionen:78: error: assignment of read-only variable 'pin_motor_rechts'

pin_motor_rechts = LOW;

^

Drehscheibensteuerrung_mit_Funktionen:79: error: assignment of read-only variable 'pin_motor_links'

pin_motor_links = LOW;

^

Drehscheibensteuerrung_mit_Funktionen:92: error: 'encoderwert' was not declared in this scope

lcd.print(encoderwert);

^

exit status 1
assignment of read-only variable 'pin_motor_rechts'

Da machst Du jetzt aber ganz gewaltige Rückschritte.

Warum willst Du einem Pin (also einer Konstanten) einen Wert zuweisen?
Du willst doch den Anschluss, der durch diesen Pin bestimmt wird auf HIGH oder LOW setzen!

Grundlagen lernen: digitalWrite

Gruß Tommy

Stimmt. Habe es geändert. Wie könnte das aussehen wenn ich anstatt der Delay's millis() einsetze? Gibt es eine Möglichkeit eine globale Wartezeit für Anzeige Referenzfahrt gestartet und für Referrenzfahrt beendet?

void referenzFahrt(){
  status_sensor_referenz = digitalRead(sensor_referenz);
  if ((nullStellung == false) && (status_sensor_referenz == HIGH)) {
    lcd.clear();
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Referenzfahrt");
    lcd.setCursor(0, 1);
    lcd.print("gestartet");
    digitalWrite (pin_motor_rechts, HIGH);
    digitalWrite (pin_motor_links, LOW);
  delay(2000);
  }
  else {
Serial.println(nullStellung);
Serial.println(status_sensor_referenz);
    
    nullStellung = true;
    digitalWrite(pin_motor_rechts, LOW);
    digitalWrite(pin_motor_links, LOW);
    lcd.clear();
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Referenzfahrt");
    lcd.setCursor(0, 1);
    lcd.print("beendet");
    delay(2000);
    lcd.clear();
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Wert");
    lcd.setCursor(0, 1);
    lcd.print(encoderWert);
  }
  
}

Da kann ich Dir nur die Standardantwort geben: Schaue Dir BlinkWithoutDelay an und verstehe es. Lies dazu die Nachtwächtererklärung.
Das kann Dir keiner abnehmen, das musst Du selbst verstehen. Das brauchst Du in vielen Anwendungen.

Gruß Tommy

Jetzt habe ich es mit millis() geschrieben. Die Zeit läuft auch ab. der Text 2 Sekunden abgelaufen kommt alle 2 Sekunden. Ich habe nur das Gefühl das er die zeit nicht als Wartezeit für die LCD Anzeige nutzt. Es wird so schnell gelöscht und neu geschrieben das man kaum was erkennt. Woran liegt das. Müsste die LCD Anzeige nicht jetzt auch für 2 Sekunden stehen bleiben?

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

unsigned long aktuelleZeit;
unsigned long vergangeneZeit_A;
unsigned long interval_1 = 2000;
int messungPin1 = HIGH;
int messungPin1Alt = HIGH;
byte encoderWert = 0; // -1 ( eins weniger als 0 ) == 255
const byte hal = 3;
const byte encoderPinA = 10;            // Phase A vom Drehencoder
const byte encoderPinB = 11;             // Phase B vom Drehencoder
const byte tasterEnter = 12;                   // Pin an dem der Encoder Taster angeschlossen ist
int wertSpeichern = 0;                  // gespeicherter Encoderwert
int encoderGedrueckt = 0;              // Statusspeicher ob Encodertaster betätigt wurde
int encoderTaster = HIGH;             // Taster im Encoder
int gleisAlt = 0;                     // Scheibe Position alt
int gleisNeu = 0;                     // Position welche die Scheibe anfahren soll
bool enter = false;                   // Bestätigung das der Encoder gedrückt wurde
int schritte = 0;                     // Schritte die deer Motor (Hallsensor betätigt) zurücklegen muss
int sensor = LOW;
bool start = false;
bool ergebnis = false;

unsigned long encoderDruckzeit;       // Zeit wann der Encodertaster betätigt wurde
unsigned long entprellZeit = 200;     // Zeit die nach der betätigung eines Tasters gewartet wird
unsigned long startZeit;
unsigned long interval = 2000;
unsigned long vergangeneZeit = 0;
bool nullStellung = false;
int pin_motor_links = A1;      // Richtungspin an H-Brücke für Links
int pin_motor_rechts = A2;     // Richtungspin an H-Brücke für Rechts
const byte sensor_referenz = 2;
int status_sensor_referenz;
void setup() {
  pinMode(sensor_referenz, INPUT);
  pinMode(pin_motor_links, OUTPUT);
  pinMode(pin_motor_rechts, OUTPUT);
  pinMode(encoderPinA, INPUT);
  pinMode(encoderPinB, INPUT);
  pinMode(tasterEnter, INPUT);
  pinMode(hal, INPUT);
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Drehscheiben-");
  lcd.setCursor(0, 1);
  lcd.print("steuerrung");
  delay (2000);
  //lcd.clear();
  //lcd.begin(16, 2);
  //lcd.setCursor(0, 0);
  //lcd.print("Wert");
  //lcd.setCursor(0, 1);
  //lcd.print(encoderWert);
}


void loop() {
  referenzFahrt();
 // encoder_lesen();
  //schritt();
  //schritteZaehlen();

}

void referenzFahrt(){
  aktuelleZeit = millis();
  status_sensor_referenz = digitalRead(sensor_referenz);
  if ((nullStellung == false) && (status_sensor_referenz == HIGH)) {
    lcd.clear();
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Referenzfahrt");
    lcd.setCursor(0, 1);
    lcd.print("gestartet");
    digitalWrite (pin_motor_rechts, HIGH);
    digitalWrite (pin_motor_links, LOW);
  if (millis() - vergangeneZeit_A >= interval_1){
    Serial.println("2 Sekunden abgelaufen");
     vergangeneZeit_A = millis();
  }
  }
  else {
Serial.println(nullStellung);
Serial.println(status_sensor_referenz);
Serial.println(vergangeneZeit_A);
    
    nullStellung = true;
    digitalWrite(pin_motor_rechts, LOW);
    digitalWrite(pin_motor_links, LOW);
    lcd.clear();
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Referenzfahrt");
    lcd.setCursor(0, 1);
    lcd.print("beendet");
    delay(2000);
    lcd.clear();
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Wert");
    lcd.setCursor(0, 1);
    lcd.print(encoderWert);
  }
  
}

void encoder_lesen () {
  messungPin1 = digitalRead(encoderPinA);
  if ((messungPin1 == LOW) && (messungPin1Alt == HIGH)) {
    if (digitalRead(encoderPinB) == HIGH) {
      if (encoderWert < 48) encoderWert++ ;
    } else {
      if (encoderWert > 1) encoderWert-- ;
      
    }
   
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("Wert");
    lcd.setCursor(0, 1);
    lcd.print(encoderWert);
}
  encoderTaster = digitalRead(tasterEnter);
    if (encoderTaster == LOW)
    {
      encoderDruckzeit = millis();
      encoderGedrueckt = 1;
    }
    if ((millis() - encoderDruckzeit > entprellZeit) && encoderGedrueckt == 1) {
      wertSpeichern = encoderWert;
      Serial.println(wertSpeichern);
      encoderGedrueckt = 0;
      enter = true;
      
    }
    messungPin1Alt = messungPin1;
}

void schritt () {
   if (enter == true) {
      gleisNeu = wertSpeichern;
      schritte = abs (gleisNeu - gleisAlt);
      Serial.print ("benoetigte Schritte  ");
      Serial.println(schritte);
      //gleisAlt = wertSpeichern;
      Serial.println(gleisNeu);
      Serial.println(gleisAlt);
      Serial.println(enter);
      enter = false;
      ergebnis =true;
    }
}

void schritteZaehlen () {
  sensor = digitalRead (hal);
   startZeit = millis();
    if ((schritte != 0)&& (ergebnis == true)){
      start = true;
      if ((startZeit - vergangeneZeit >= interval) && (sensor == LOW) && (start ==true)) { 
          vergangeneZeit = startZeit;
          schritte--;
          Serial.println("Schritte");
          Serial.println(schritte);
      }
    }
          else if ((schritte == 0) && (start == true)){
          start = false;
           Serial.println("Ziel");
          ergebnis = false;
          gleisAlt = wertSpeichern;
       }
}

void best_Richtung(){
  
}

void motor(){
  
}