Go Down

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

Acki1985

#30
Jan 01, 2019, 05:55 pm Last Edit: Jan 01, 2019, 05:57 pm by Acki1985
Jedes mal einen Schritt runterzählen wenn der Sensor vom Magneten betätigt wird. Bis die Schritte 0 sind. Die 2 Sekunden habe ich nur eingebaut, damit ich im Seriellen Monitor was sehe. Weil ja sobald ich den encoder Taster betätige die While Schleife ausgeführt wird, obwohl der Hal gar nicht betätigt ist.

postmaster-ino

Hi

Die Sache ist viel einfacher - diese 2 Sekunden wartet Er, damit der Hall-Sensor eben nur 1x erkannt wird.
NUR: Das Runterzählen der Schritte ist 'suboptimal'.
Was, wenn von Gleis 19 auf Gleis 18 gefahren werden soll?
Schritte=-1 ... und der Sketch läuft einige Runden, bis Das auf Null kommt (int geht bis -16768 runter ... nur Mal so)

Eigentlich eine schöne Aufgabe - nur hat sich der To hier schon etwas verrannt.
Der Ansatz ist stimmig, die Abarbeitung bedarf einer Verbesserung.
Aktuell wäre Es besser, Du lässt den Motor laufen, bis Dein IST-Gleis dem SOLL-Gleis entspricht - geht nur bei einer Drehscheibe und sieht Da dann auch noch blöd aus, wenn 23 Gleise nach links gedreht wird, wo eine Drehung um 1 Gleis nach Rechts gereicht hätte.

ODER: Du merkst Dir den Abstand der Positionen, stellst die Drehrichtung ein, und wartest drauf, daß diese Schrittanzahl Null wird.

MfG

PS: MALE Dir auf, was Du erreichen willst, mit möglichst kleinen Zwischenschritten

PPS: Oha . DANN habe ich mich mit dem delay(2000); vertan - Du wirst aber nicht sonderlich glücklich ohne das delay, da die While-Schleife für einen Durchlauf nicht wirklich lange braucht - die Schritte sind ruck-zuck auf Null runter gezählt - sobald der Hall-Sensor auslöst.
Du wartest hier NICHT darauf, daß der Hall-Sensor wieder sperrt, zählst also die Erkennung Mehrfach!
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

#32
Jan 01, 2019, 06:26 pm Last Edit: Jan 01, 2019, 06:28 pm by Acki1985
Ich will mich halt Schrit für Schritt ran tasten. Es soll dann auch immer der kürzere Weg genommen werden. Es muss dann so zu sagen auch noch recht oder linksdrehen entschieden werden. Zum schluss möchte ich auch mal noch langsam anfahren und bremsen. Aber bis dahin....

PS. das mit dem Hall und der Zeit stimmt. Da habe ich noch gar nicht dran gedacht.
 Mit den negativen und positiven Schritten hab ich auch noch keine Idee.

Acki1985

Quote
ODER: Du merkst Dir den Abstand der Positionen, stellst die Drehrichtung ein, und wartest drauf, daß diese Schrittanzahl Null wird.
genau so wollte ich es ja machen.

postmaster-ino

Hi

Dann ist aber die Start-Schrittzahl eher
Code: [Select]

schritte = abs(gleisNeu - gleisAlt);  //ABSOLUT, liefert negative Werte positiv zurück
if (gleisNeu<gleisAlt){
  richtung=links;
}else{
  richtung=rechts;
}

Damit kannst Du dann den Motor so lange drehen lassen (eben je nach 'richtung' links oder rechts rum), bis der HallSensor so oft 'gesehen' wurde, wie Schritte abzuwarten ist.

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

Danke dir. Funktioniert das auch wenn ich von Gleis 1 zu Gleis 23 Fahren will das sie dann links rum läuft?

Acki1985

Hallo,

Habt ihr ne Idee warum die for Schleife läuft obwohl der Hall nicht betätigt wird. Er ist über einen Pullup angeschlossen.

Code: [Select]


if ((gleisNeu != gleisAlt) && (enter == true)) {
    if (digitalRead (hal) == LOW); {
    for (schritte != 0; schritte >0; schritte-- ) {
    //if (digitalRead (hal) == LOW);{
    //schritte--;
    Serial.println("Schritte");
    Serial.println(schritte);
    delay(2000);}
    enter = false;
    gleisAlt = wertSpeichern;
}


postmaster-ino

#37
Jan 02, 2019, 06:03 pm Last Edit: Jan 02, 2019, 06:04 pm by postmaster-ino
Hi
Jupp :)
Code: [Select]
if (digitalRead (hal) == LOW);
Die IF-Abfrage ist an dem ; zuende.
Die Klammerung hat dahinter keinen höheren Sinn mehr - der Code wird ausgeführt, weil Er eben hinter der IF steht.

Entferne das ; , dann greift die Klammer wieder, wenn die Bedingung wahr ist.

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

Code: [Select]


if ((gleisNeu != gleisAlt) && (enter == true)) {
    if (digitalRead (hal) == LOW) {
    for (schritte != 0; schritte >0; schritte-- ) {
    //if (digitalRead (hal) == LOW);{
    //schritte--;
    Serial.println("Schritte");
    Serial.println(schritte);
    delay(2000);}
    enter = false;
    gleisAlt = wertSpeichern;
}



hm... Funktionirt aber trotzdem nicht. Der code rast jetzt durch und wenn ich den Hall einmal betätige läuft die Schleife wieder automatisch. Aber sie soll jedesmal wenn der Hall betätigt wird jedesmal die Variable schritte um 1 runter zählen.

postmaster-ino

Hi

Du wartest, bis der ein neues Gleis gewählt wurde und Enter gedrückt wurde
Jetzt wartest Du darauf, daß der Hall-Sensor LOW zeigt
Jetzt Startest Du eine Schleife, Die alle 2 Sekunden einen Wert runter zählt.

Ich denke, der Sketch macht genau Das, was Du geschrieben hast.
Mit ziemlicher Sicherheit aber nicht Das, was Du willst.

Du willst:
- den Hall-Sensor IMMER abfragen - direkt in der loop
- den Motor starten, wenn eine Fahrt gestartet wird (und der Abstand !=0 ist)
- den Motor stoppen, wenn der Abstand ==0 ist
- die Schritte (um 1) herunterzählen, wenn der Hall-Sensor von HIGH nach LOW wechselt
... die loop() wird tausend Mal die Sekunde durchrannt und trotzdem wird nur dann auf etwas reagiert, wenn's dafür 'an der Zeit ist'.

Ob der Motor nach dem letzten Hall-Impuls noch weiterlaufen muß, bis die Gleise übereinander stehen - kA - wenn nicht, müsste man einen Schritt vorher mit der Bremsrampe beginnen.

Das lässt sich wunderbar in eine State-Maschine einbauen.
Dazu hat combie bereite eine Liste hier im Forum - solltest Du Dir ansehen.

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

Quote
[
Du willst:
- den Hall-Sensor IMMER abfragen - direkt in der loop
Nein der Hall soll nur abgefragt werden, wenn die Bühne dreht und der Motor läuft
Quote
- den Motor starten, wenn eine Fahrt gestartet wird (und der Abstand !=0 ist)
Ja genau
Quote
- den Motor stoppen, wenn der Abstand ==0 ist
ja genau
Quote
- die Schritte (um 1) herunterzählen, wenn der Hall-Sensor von HIGH nach LOW wechselt
Stimmt auch

Wenn die Schritte abgelaufen sind kann, kann man über den Drehencoder erst das nächste Zielgleis wählen.


... die loop() wird tausend Mal die Sekunde durchrannt und trotzdem wird nur dann auf etwas reagiert, wenn's dafür 'an der Zeit ist

postmaster-ino

Hi

Was stört Dich daran, daß der Hall-Sensor abgefragt wird, wenn die Bühne Sich nicht dreht?
Ohne Drehung wird auch keine Flanke kommen, Die man auswerten könnte - und ausgewertet wird eh nur, wenn der Motor drehen soll.
Code: [Select]

Motor = stop ;// Drehrichtung des Motor bei Start auf STOP (oder ggf. Referenz-Fahrt)
...
setup(){
//Motor-Pin auf OUT, Hall-Pin auf IN, ...
}
...
loop(){
  //... Encoder auswerten und 'Soll' hoch/runter zählen
  static boolean flanke=false;
  static boolean hallalt=false;
  boolean hallneu=digitalRead(hall_pin);
  if (hallalt==true && hallneu==false){
     flanke=true;
  }else{
     flanke=false;
  }
  hallalt=hallneu;
  Wenn (Motor!=stop && Flanke=true){
    schritt--;
  }
  Wenn (schritt==0 && Motor!=stop){
    Motor=stop;
  }
  Wenn (Enter=gedrückt && Soll != Ist && Motor==stop){
     byte linksrum=abs(Soll-Ist);
     byte rechtsrum=abs(Ist-Soll);
     Wenn (linksrum <= rechtsrum){
        schritte=linksrum;
     }else{
        schritte=rechtsrum;
     }
  }
  if (motor==stop && schritte!=0){
     if (schritte==linksrum){
        Motor=links;
     }else{
        Motor=rechts;
     }
  }
}

So in der Art würde ich's versuchen.

Das Zielgleis kann IMMER eingestellt werden.
Eine neue Fahrt kann nur gestartet werden, wenn die Bühne nicht dreht, dann wird das eingestellte Gleis als Ziel übernommen (bzw. die Schritte dahin berechnet und der Motor gestartet).
Während der Motor fährt, werden bei fallender Flanke jeweils ein Schritt abgezogen.
Bei Schritt auf Null wird der Motor angehalten.
Es wird jeweils in die Richtung der kürzeren Entfernung gestartet.
Man kann, sobald die Bühne läuft, problemlos ein neues Zielgleis anwählen, die Übernahme geht aber erst, wenn die vorherige Fahrt beendet wurde.

Man kann einige der Abfragen kombinieren - so ist Es nicht wirklich nötig, in mehreren auf einander folgenden IF-Abfragen 'Motor==stop' abzufragen - Das könnte man in einer IF erschlagen und in Deren Körper die anderen IFs verarbeiten.

Man kann den Motor auch in ein switch-case einsetzen und dort z.B. die Referenz-Fahrt abfrühstücken, bei stop die Fahrt starten, sofern Soll!=Ziel und Enter gedrückt sowie bei links/rechts prüfen, ob wir bereits am Ziel sind (= Motor stoppen) bzw. die Flanke des Hal-Sensor auswerten.
= State-Maschine

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

Das mit der Statemachine verstehe ich nicht. Wie soll mir das bei meinem Projekt helfen?

Acki1985

Oder besser gesagt womit fange ich da in meinem Projekt an?

Acki1985


Go Up