Go Down

Topic: Drehscheibe Modellbahn mit RF24 (Read 5291 times) previous topic - next topic

Acki1985

Code: [Select]


 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?

postmaster-ino

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
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Acki1985

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.

Code: [Select]





#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

postmaster-ino

Hi
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
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Acki1985

#64
Jan 12, 2019, 10:27 pm Last Edit: Jan 12, 2019, 10:47 pm by Acki1985
Guten Abend,

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

Code: [Select]


#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

Acki1985

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?

Code: [Select]


#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(){
 
}


postmaster-ino

Hi

Na verdammt - dann brauchst Du mich ja gar nicht mehr ;)
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
Code: [Select]

#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
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Tommy56

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
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

Acki1985

Ich danke euch.

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

Code: [Select]


 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


postmaster-ino

Hi

Äh - 'maxposition' habe ich nicht deklariert :/
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
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Acki1985

#70
Jan 13, 2019, 11:43 am Last Edit: Jan 13, 2019, 11:57 am by Acki1985
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.

postmaster-ino

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
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Acki1985

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?

Acki1985

Hab mal versucht eine Refernzfahrt zu programmieren.

Code: [Select]


#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'


Tommy56

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
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

Go Up