Fliegenden Teppich

Hallo
brauche mal wieder Eure Hilfe.
Der Sketch, zu meinem Fliegenden Teppich in meinem HO Mittelaltermarkt, funktioniert.
Ich möchte das Start und Landung je über einen Taster gesteuert werden, was ich auch bestimmt hinbekomme. Leider habe ich nur noch einen Taster frei, so dass der Start und die Landung über einen Taster erfolgen müssen. Dies zu programmieren, übersteigt meine Programmier Kenntnisse, das ich mir schweren Herzen zugestehen muss. Ich würde mich freuen, wenn mir jemand von euch helfen kann.

Danke im Voraus
Jürgen

volatile int Endschalterunten ;          // Gabellichtschranke unten
volatile int Endschalteroben ;           // Gabellichtschranke oben
int Relais1 = 8;                         // Relais 1 und 2 je ein Wechsler zum umpolen
int Relais2 = 9;                         // Relais 2 und 1 je ein Wechsler zum umpolen
int RelaisMotor3 = 10;                   // Relais 3 und 4 zum Motor abschalten Pin 10
int RelaisMotor4 = 16;                   // Relais 4 und 3 zum Motor abschalten Pin 11 und Pin 16 bei Micro

void setup()
{
  attachInterrupt(0, unten, FALLING);    // Pin 2 UNO und Pin 3 MICRO
  attachInterrupt(1, oben, FALLING);     // Pin 3 UNO und Pin 2 MICRO

  pinMode(Relais1, OUTPUT);
  pinMode(Relais2, OUTPUT);
  pinMode(RelaisMotor3, OUTPUT);
  pinMode(RelaisMotor4, OUTPUT);
}

void loop()
{
  // Teppich Richtung nach oben

  digitalWrite(Relais1, HIGH);               // Richtung oben HIGH = AUS Pin 4
  digitalWrite(Relais2, HIGH);               // Richtung oben HIGH = AUS Pin 5

  digitalWrite(RelaisMotor3, LOW);           // Motor = EIN = LOW Pin 6
  digitalWrite(RelaisMotor4, LOW);           // Motor = EIN = LOW Pin 7

  delay(10000);                              // Wert zum testen

  // Teppich Richtung nach unten

  digitalWrite(Relais1, LOW);               // Richtung unten LOW = EIN
  digitalWrite(Relais2, LOW);               // Richtung unten LOW = EIN

  digitalWrite(RelaisMotor3, LOW);          // Motor = EIN
  digitalWrite(RelaisMotor4, LOW);          // Motor = EIN

  delay(10000);                              // Wert zum testen
}

void unten()
{
  Endschalterunten = !Endschalterunten;
  digitalWrite(RelaisMotor3, HIGH);         // Motor = AUS
  digitalWrite(RelaisMotor4, HIGH);         // Motor = AUS
}

void oben()
{
  Endschalteroben = !Endschalteroben;
  digitalWrite(RelaisMotor3, HIGH);         // Motor = AUS
  digitalWrite(RelaisMotor4, HIGH);         // Motor = AUS
}

schau dir das Beispiel

Digital / State change detection

in der IDE an. Was macht das: es liest einen Taster aus und bei jeder Betätigung passiert was anderes: die LED schaltet ein, oder die LED schaltet aus.

Ähnliches brauchst du.
Übrigens, die Verwendung von Interrupts zum auslesen der Buttons / Endschalter braucht es auch nicht.

Hallo
teile dein Projekt in Codeteile=Funktionen nach dem EVA-Prinzip auf.
E=Eingabe ->> Taster entprellen
V=Verarbeitung ->> Schrittkette {Unten,UntenOben,Open,OpenUnten};
A=Ausgabe ->> motor(aus); motor(rauf); motor(runter);
Alle diese angedachten Funktionen lassen sich einzeln programmieren, testen und dannach zum Gesamtprojekt zusammenlöten.

Hallo,

du solltest die Interrupt Verarbeitung weg lassen und das ohne lösen. Du benötigst eine Flankerkennung für den Taster und eine bool Zustandsmerker "nachoben", der bei jedem Tastendruck den Zustand wechselt. true/false./true usw. true bedeutet nach oben, dann dreht der Motor bist der obere Endschalter erreicht ist. Wenn Du jetzt wieder auf den Taster drückst wird der Merker "nachoben" auf false gesetzt das bedeutet runterfahren. Motor dreht bis zum Endschalter.

Wenn Du magst kannst Du auch eine Schrittkette(Ablaufsteuerung ) mit 4 Zuständen nehmen. Warteauf_heben, hochfahren_bis_ES,wartenauf_senken, runterfahren_bis_ES.

Heinz

trixi2000:
... Leider habe ich nur noch einen Taster frei, so dass der Start und die Landung über einen Taster erfolgen müssen. ...

Sieh Dir das hier an. Damit kann man lange und kurze Tastenbetätigungen unterschiedlich behandeln.

Gruß

Gregor

Hallo,

wie sieht es aus, ist dein Teppich schon weggeflogen, oder hat er noch Startprobleme ?
Für diese simple Aufgabe brauchst du keine extra Library oder zusätzliche Variable.

Du fragst nur deinen Taster und den Endschalter ab, das reicht.
Wenn dein Endschalter aktiv LOW liefert und die Taster HIGH, dann kann es so aussehen:
Pseudocode:

If (taster && !schalter_unten)
{fahre hoch}

oder

if (taster && !schalter_oben)
{fahre runter}

Zusätzliche musst du natürlich noch weiterhin deine Endschalter auswerten, damit der Teppich rechtzeitig gestoppt wird.

Hallo
Seht es nicht als unhöflich an, wenn ich mich erst jetzt wieder melde.

Ich hatte schon immer Schwierigkeiten mich hier anzumelden und in letzter Zeit war es eine Glücksache wenn ich eine Verbindung zustande bekam.
Mit dem neuen Layout geht es jetzt wieder besser, habe aber auch eine Weile gebraucht, bis ich damit klar kam. In meinem Alter wird es halt immer schwieriger, was Neues zu lernen.
Die Idee mit dem Taster war keine gute Lösung und ich habe mich entschlossen, den „Fliegenden Teppich“ dauernd in einer endlosen Schleife zu bewegen. Den Sketch, den ich geschrieben habe funktioniert, nur weiß ich nicht wie man eine Pause einlegt wenn er oben und unten angekommen ist.
Über eine Hilfe wäre ich euch sehr dankbar.
Gruß Jürgen

int Endschalterunten = 2;                // Gabellichtschranke unten
int Endschalteroben = 3;                 // Gabellichtschranke oben
int Relais1 = 4;                         // Relais 1 und 2 je ein Wechsler zum umpolen
int Relais2 = 5;                         // Relais 2 und 1 je ein Wechsler zum umpolen
int RelaisMotor3 = 10;                   // Relais 3 und 4 zum Motor abschalten Pin 10
int RelaisMotor4 = 11;                   // Relais 4 und 3 zum Motor abschalten Pin 11 und Pin 16 bei Micro

void setup()
{
  pinMode(Relais1, OUTPUT);
  pinMode(Relais2, OUTPUT);
  pinMode(RelaisMotor3, OUTPUT);
  pinMode(RelaisMotor4, OUTPUT);
  pinMode(Endschalterunten, INPUT_PULLUP);
  pinMode(Endschalteroben, INPUT_PULLUP);

  // Teppich nach oben wenn Teppich unten ist
  if ( digitalRead(Endschalterunten) == LOW &&  digitalRead(Endschalteroben) == HIGH)
  {
    digitalWrite(Relais1, HIGH);           // nach oben
    digitalWrite(Relais2, HIGH);           // nach oben
    digitalWrite(RelaisMotor3, LOW);       // Motor ein
    digitalWrite(RelaisMotor4, LOW);       // Motor ein
  }
  // Teppich nach unten wenn Teppich oben ist
  if ( digitalRead(Endschalterunten) == HIGH &&  digitalRead(Endschalteroben) == LOW)
  {
    digitalWrite(Relais1, LOW);            // nach unten
    digitalWrite(Relais2, LOW);            // nach unten
    digitalWrite(RelaisMotor3, LOW);       // Motor ein
    digitalWrite(RelaisMotor4, LOW);       // Motor ein
  }
  // Teppich nach unten wenn Teppich in Mitte ist
  if ( digitalRead(Endschalterunten) == HIGH && digitalRead(Endschalteroben) == HIGH)  
  {
    digitalWrite(Relais1, LOW);            // nach unten
    digitalWrite(Relais2, LOW);            // nach unten
    digitalWrite(RelaisMotor3, LOW);        // Motor ein
    digitalWrite(RelaisMotor4, LOW);        // Motor ein
  }
}

void loop()
{
  // Teppich nach oben
  if ( digitalRead(Endschalterunten) == LOW &&  digitalRead(Endschalteroben) == HIGH)
  {
    digitalWrite(Relais1, HIGH);           // nach oben
    digitalWrite(Relais2, HIGH);           // nach oben
    digitalWrite(RelaisMotor3, LOW);       // Motor ein
    digitalWrite(RelaisMotor4, LOW);       // Motor ein 
  }
  // Teppich nach unten
  if ( digitalRead(Endschalterunten) == HIGH &&  digitalRead(Endschalteroben) == LOW)
  {
    digitalWrite(Relais1, LOW);            // nach unten
    digitalWrite(Relais2, LOW);            // nach unten
    digitalWrite(RelaisMotor3, LOW);       // Motor ein
    digitalWrite(RelaisMotor4, LOW);       // Motor ein
  }
}

Und warum war das keine gut Lösung ?

Erst wollte ich den „Fliegenden Teppich“ manuell über einen Taster ein- und aus schalten.
Da ich mich mehr um die Steuerung des Bahnverkehrs kümmern möchte, ist mir das dauernde betätigen des Tasters störend, zumal weitere Aktionen, wie Karussell und mein kleines Riesenrad, in einem separaten Sketch in Bewegung sind.

dann lies dir mal die Zufallsfunktion durch

https://www.arduino.cc/reference/de/language/functions/random-numbers/random/

und starte halt deinen Teppich “zufällig” und nimm den Taster nur mehr für eine “aber jetzt will ich wirklich den Teppich fliegen lassen”.

Oder du nimmst einen Timer (SimpleTimer, Intervall) der gezielt alle Minuten den Teppich fliegen lässt. Geht natürlich auch über eine Steuerung mit der Funktion “millis()”.

Ich empfehle Dir hauptsächlich zwei Dinge:

  1. Die Benutzung einer Schrittkette (=endlicher Automat, =finite state machine), bei mir gerne mittels switch/case realisiert. Für mich war das der Aha-Effekt, als ich mit Arduino anfing.
  2. Die Programmbibliothek MobaTools erledigt viele Dinge sehr elegant, beispielsweise Zeitabläufe. Sie kann mittels IDE installiert werden. Der Autor ist hier im Forum aktiv.

Ein Vorschlag, getestet mit UNO und LEDs:

#include <MobaTools.h>
MoToTimer Wartezeit;
int Endschalterunten = 2;                // Gabellichtschranke unten
int Endschalteroben = 3;                 // Gabellichtschranke oben
int Relais1 = 4;                         // Relais 1 und 2 je ein Wechsler zum umpolen
int Relais2 = 5;                         // Relais 2 und 1 je ein Wechsler zum umpolen
int RelaisMotor3 = 10;                   // Relais 3 und 4 zum Motor abschalten Pin 10
int RelaisMotor4 = 11;                   // Relais 4 und 3 zum Motor abschalten Pin 11 und Pin 16 bei Micro

void setup()
{
  pinMode(Relais1, OUTPUT);
  pinMode(Relais2, OUTPUT);
  pinMode(RelaisMotor3, OUTPUT);
  pinMode(RelaisMotor4, OUTPUT);
  pinMode(Endschalterunten, INPUT_PULLUP);
  pinMode(Endschalteroben, INPUT_PULLUP);
}

void loop()
{
  static byte schritt = 0;
  switch (schritt) {
    case 0:
      if ( digitalRead(Endschalteroben) == LOW ) {
        schritt = 2;
      } else {
        if ( !Wartezeit.running() ) {
          digitalWrite(Relais1, HIGH);           // nach oben
          digitalWrite(Relais2, HIGH);           // nach oben
          digitalWrite(RelaisMotor3, LOW);       // Motor ein
          digitalWrite(RelaisMotor4, LOW);       // Motor ein
          schritt++;
        }
      }
      break;
    case 1:
      if ( digitalRead(Endschalteroben) == LOW ) {
        digitalWrite(RelaisMotor3, HIGH);        // Motor aus
        digitalWrite(RelaisMotor4, HIGH);        // Motor aus
        Wartezeit.setTime( random(1000, 5000) );
        schritt++;
      }
      break;
    case 2:
      if ( !Wartezeit.running() ) {
        digitalWrite(Relais1, LOW);             // nach unten
        digitalWrite(Relais2, LOW);             // nach unten
        digitalWrite(RelaisMotor3, LOW);        // Motor ein
        digitalWrite(RelaisMotor4, LOW);        // Motor ein
        schritt++;
      }
      break;
    case 3:
      if ( digitalRead(Endschalterunten) == LOW ) {
        digitalWrite(RelaisMotor3, HIGH);        // Motor aus
        digitalWrite(RelaisMotor4, HIGH);        // Motor aus
        Wartezeit.setTime( random(1000, 5000) );
        schritt++;
      }
      break;
    default:
      schritt = 0;
  }
}

Hallo agmue

danke für deine Zeit und Geduld mit mir.

Mir wird mal wieder bewusst, dass ich in meinem Alter nicht über ein Anfänger Niveau heraus komme. So wie du den Sketch geschrieben hast, würde ich ihn niemals hinbekommen. So habe ich schon ein Dutzend Mal das Beispiel “Blink Without Delay ( millis ) Beispiel eines Wachmanns” durchgelesen, und bekomme es nicht in meinen Kopf hinein.
Werde den Sketch morgen auf meiner Anlage testen.

Nochmals Danke
Jürgen

Hallo Jürgen,
Du bist ja auch Mobahner :wink: . Was Schrittketten ( auch ‘Zustandsautomat’ ) und Zeitsteuerungen angeht, da hatte ich im Stummiforum mal ein Tutorial speziell für Modellbahner geschrieben. Tommy56 hat das in kompakter Form auf seiner Webseite gehostet. Und auch die Beispielsketche dazu sind dort zu finden.
Vielleicht hilft dir das ja ein wenig beim Verständnis.

Grüße
Franz-Peter

Nicht aufgeben - so alt kannst Du gar nicht sein :sunglasses:

Bitte gerne!

Am Anfang hatte ich damit auch so meine Schwierigkeiten und bin nur über viele Irrungen und Wirrungen dahin gekommen, wo ich jetzt bin, ein fortgeschrittener Anfänger. Üben, üben, üben und Fehler zulassen!

Franz-Peter ist übrigens der Autor der MobaTools.

Mein Programmvorschlag läuft blockadearm und könnte daher noch weitere Aufgaben übernehmen.

Hallo agmue
Der Sketch funktioniert einwandfrei. Konnte ihn erst heute testen.
Nochmals herzlichen Dank

Die gut geschriebenen Seiten habe ich mir schon herunter geladen. Bis ich die durchgearbeitet habe dauert es aber eine Weile.

Ich habe schon etliche einfache Bewegungen auf meiner Modellbahn Anlage mit Moba Tools realisiert und habe Hochachtung was er mit Moba Tools geleistet hat.

Bitte gerne! Hat so ein fliegender Teppich nicht auch blinkende LEDs oder einen Scheinwerfer zur nächtlichen Beleuchtung?

Da stimme ich Dir gerne zu!

Nicht nur für Modellbahner laufen sie auf einigen Arduinos, aber auch auf STM32, ESP8266 und ESP32. Bei größerem Speicherbedarf z. B. für Schriftfonts kann das interessant sein.

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