Steuerung Bahnübergang mit LED

Hallo zusammen,

ich bin noch ziemlich am Anfang, was den Arduino angeht.
Ich habe schon einige Dinge mit tutorials selbst gemacht, z.B. eine CO2 Ampel mit einem MH-Z19B und einem Oled Display.

Nun möchte ich einen Bahnübergang programmieren.
Die Programmierung des Servos hat soweit alles geklappt und funktioniert auch.
Alles wird momentan mit 2 Tastern (später 2 Reed Sensoren) gesteuert.
Taster 1 stellt die Schranke hoch, Taster 2 runter.
Nun soll aber Taster 2 auch noch ein blinklicht steuern, welches durch Taster 1 wieder ausgeschaltet wird.
Hier habe ich ein Problem!!! Die LED blinkt immer nur, solange ich den Taster gedrückt halte, sobald ich ihn loslasse bleibt die LED im letzten zustand stehen.
Später soll es auch mal soweit gehen, dass ich die Position des Servos mit einbeziehe, so dass der Zug aus beiden Richtungen die Anlage steuern kann, soweit bin ich aber noch nicht.
Mein Letzter Versuch sah so aus:

#include <Servo.h>

int taster1 = 8;
int taster2 = 9;
int LED = 10;
int tasterstatus1, tasterstatus2;
Servo Serv;

boolean lastButtonState;
boolean blinkState;

void blinken(){
boolean buttonState = digitalRead(taster1);
if (buttonState!=lastButtonState && buttonState==HIGH) blinkState=!blinkState;
lastButtonState=buttonState;
if (blinkState)
{
digitalWrite(LED,(millis()/1000)%2);
}
else
{
digitalWrite(LED,LOW);
}
delay(5);
}

void blinkenaus() {
digitalWrite(LED, LOW);
}

void setup() {
pinMode(taster1, INPUT);
pinMode(taster2, INPUT);
pinMode(LED, OUTPUT);
Serv.attach(5);
}

void loop() {
pinMode(taster1, INPUT_PULLUP);
pinMode(taster2, INPUT_PULLUP);
tasterstatus1 = digitalRead(taster1);
tasterstatus2 = digitalRead(taster2);

if (tasterstatus1 == 0) {
Serv.write(97);
blinkenaus();
}
if (tasterstatus2 == 0) {
Serv.write(0);
blinken();
}

}

Ich hoffe, es kann mir jemand bei meinem Problem Helfen.

Vielen Dank und ein schönes Wochenende.

Viele Grüße
Matthias

Hallo
Dein Sketch brauch einen Timer, der für einen Zeitraum X, d.h. die Schranke bewegt sich, den Blinker einschaltet und danach wieder ausschaltet.
Als Basis für einen Timer eignet sich, mit einen Modifikationen, das BlinkWithOutDelay Beispiel aus dem IDE.

Setzte doch den blinkState mit beim Tasterdruck. Und führe dann in der blinken Funktion nur das Leuchten der LED aus, wenn blinkState wahr ist.

#include <Servo.h>

int taster1 = 8;
int taster2 = 9;
int LED = 10;
int tasterstatus1, tasterstatus2;
Servo Serv;

boolean blinkState;

void blinken() {
  if (blinkState && millis() % 1000 > 500)
  {
    digitalWrite(LED, HIGH);
  }
  else
  {
    digitalWrite(LED, LOW);
  }
}

void setup() {
  pinMode(taster1, INPUT_PULLUP);
  pinMode(taster2, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  Serv.attach(5);
}

void loop() {
  tasterstatus1 = digitalRead(taster1);
  tasterstatus2 = digitalRead(taster2);

  if (tasterstatus1 == 0) {
    Serv.write(97);
    blinkState=false;
  }
  if (tasterstatus2 == 0) {
    Serv.write(0);
    blinkState=true;
  }
  blinken();
}

Edit: pinMode wird eigentlich nur einmalig im Setup ausgeführt. Das wiederholte aufrufen im Loop bei dir ergibt kein Sinn.

Guck mal

Vielen Dank, hat super funktioniert. :slight_smile:

Für zukünftige Projekte könnten die per Arduno-IDE installierbaren MobaTools von Nutzen sein. Diese Programmbibliothek kümmert sich um langsam bewegende Servos, Schrittmotoren, dimmende LEDs (Andreaskreuz) und ganz allgemein um Zeiten.

Der Autor ist hier im Forum aktiv.

Hallo Zusammen,

Ich bin neu hier und auch im Arduino Bereich.
Ich bin an etwas ähnlichem dran...
Bitte seid gnädig, ich schaffe damit erst seit 2 Wochen... und möchte eine Weichensteuerung (Wegesteuerung an Kreuzweiche mit 3 Taster) "läuft", sowie eine 1 Taster Schrankensteuerung (Servo hoch_runter) mit Blinkleds (Andreaskreuz) "hier hackts".
Im Start -> Schranke unten blinkt... "OK"...Taste 1x Schranke hoch blinkt aber noch... "n. OK" ... nach mehrmaligen drücken geht auch mal die LED aus nicht nachvollziehbar... dann teilweise Taste 1x Schranke runter, blinkt nicht -> noch mal Taste 1x Schranke bleibt unten aber blinkt nun auch...


#include <Servo.h>

Servo Weiche1;

Servo Weiche2;

Servo Weiche3;

Servo Weiche4;

Servo Schranke;

int Grad;

const int T_W = 53;

const int T_O = 52;

const int T_G1 = 51;

const byte T_S= 50;                 // Taster an Pin 1 und GND

const long interval = 500;               // Blinkintervall

const byte entprellzeit = 20;     // Zeitintervall der Tasterabfrage

boolean taster_gedrueckt = 0;     // Speichervariable für den Tasterzustand

boolean last_tasterzustand = 0;   // zur Erkennung der Flanke

// Leds

const int Pin_LED2_Rot = A0;         // LED Gerade an PIN A0 high

const int Pin_LED3_Gruen = A0;         // LED Gerade an PIN A0 low

const int Pin_LED6_Gruen = A1;         // LED Gerade an PIN A1 high

const int Pin_LED7_Rot = A1;         // LED Gerade an PIN A1 low

const int Pin_LED4_Rot = A2;         // LED Gerade an PIN A0 high

const int Pin_LED5_Gruen = A2;         // LED Gerade an PIN A0 low

const int Pin_LED8_Gruen = A3;         // LED Gerade an PIN A1 high

const int Pin_LED9_Rot = A3;         // LED Gerade an PIN A1 low

// Blinkleds

int ledState = LOW;                       // Led-Status

uint8_t TasterValue = 0;                  // Taster-Status

uint8_t BlinkValue = 0;                   // Blink-Status    

uint8_t status = 0;

unsigned long previousMillis = 0;        

//___________________VOID SETUP______________

void setup()

{

  pinMode(T_W, INPUT_PULLUP);

  pinMode(T_O, INPUT_PULLUP);

  pinMode(T_G1, INPUT_PULLUP);

  pinMode(T_S, INPUT_PULLUP);

 

// BlinkLed

 

  pinMode(LED_BUILTIN, OUTPUT);           // Led Pin13

// Leds definieren

  pinMode(Pin_LED3_Gruen, OUTPUT);  

  digitalWrite(Pin_LED3_Gruen, HIGH);    // Initialisieren der LED auf Grundstellung, LED Gerade leuchtet

  pinMode(Pin_LED2_Rot, OUTPUT);

  digitalWrite(Pin_LED2_Rot, LOW);     // Initialisieren der LED auf Grundstellung, LED Abzweig ist aus

  pinMode(Pin_LED5_Gruen, OUTPUT);  

  digitalWrite(Pin_LED5_Gruen, LOW);    // Initialisieren der LED auf Grundstellung, LED Gerade leuchtet

  pinMode(Pin_LED4_Rot, OUTPUT);

  digitalWrite(Pin_LED4_Rot, HIGH);     // Initialisieren der LED auf Grundstellung, LED Abzweig ist aus

  pinMode(Pin_LED6_Gruen, OUTPUT);  

  digitalWrite(Pin_LED6_Gruen, HIGH);    // Initialisieren der LED auf Grundstellung, LED Gerade leuchtet

  pinMode(Pin_LED7_Rot, OUTPUT);

  digitalWrite(Pin_LED7_Rot, LOW);     // Initialisieren der LED auf Grundstellung, LED Abzweig ist aus

  pinMode(Pin_LED8_Gruen, OUTPUT);  

  digitalWrite(Pin_LED8_Gruen, LOW);    // Initialisieren der LED auf Grundstellung, LED Gerade leuchtet

  pinMode(Pin_LED9_Rot, OUTPUT);

  digitalWrite(Pin_LED9_Rot, HIGH);     // Initialisieren der LED auf Grundstellung, LED Abzweig ist aus

}

//___________FUNKTION "schalten"________________

void schalten (Servo Weiche, int PIN, int Winkel)

{

  Weiche.attach(PIN);

  Weiche.write(Winkel);

  delay(200);

  Weiche.detach();

}

//___________FUNKTION "W1"___________________

void W1(int Stellung)                //0=gerade - 1=abbiegen

{  if(Stellung == 0)                  //Stellung gerade aus

  {

    Grad = 0;                         //Position in Grad      

  }

  if(Stellung == 1)                  //Stellung abbiegend

  {

    Grad = 90;                        //Position in Grad

  }

  schalten(Weiche1, 2, Grad);         //(Servo, Anschlusspin, Position)

}

//___________FUNKTION "W2"___________________

void W2(int Stellung)               //0=gerade - 1=abbiegen

{  if(Stellung == 0)                  //Stellung gerade aus

  {

    Grad = 0;                         //Position in Grad      

  }

    if(Stellung == 1)                  //Stellung abbiegend

  {

    Grad = 90;                        //Position in Grad

  }

  schalten(Weiche2, 3, Grad);         //(Servo, Anschlusspin, Position)

}

//___________FUNKTION "W3"___________________

void W3(int Stellung)                //0=gerade - 1=abbiegen

{  if(Stellung == 0)                  //Stellung gerade aus

  {

    Grad = 0;                         //Position in Grad      

  }

  if(Stellung == 1)                  //Stellung abbiegend

  {

    Grad = 90;                        //Position in Grad

  }

  schalten(Weiche3, 2, Grad);         //(Servo, Anschlusspin, Position)

}

//___________FUNKTION "W4"___________________

void W4(int Stellung)                //0=gerade - 1=abbiegen

{  if(Stellung == 0)                  //Stellung gerade aus

  {  

    Grad = 0;                         //Position in Grad      

  }

  if(Stellung == 1)                  //Stellung abbiegend

  {

    Grad = 90;                        //Position in Grad

  }

  schalten(Weiche4, 3, Grad);         //(Servo, Anschlusspin, Position)

}

  //___________FUNKTION "Schranke"___________________

void S(int Stellung)   //void S(int Stellung) //0=offen - 1=geschlossen

{              

  if(Stellung == 0)                  //Stellung gerade aus

  {

    Grad = 0;                         //Position in Grad      

  }

  if(Stellung == 1)                  //Stellung abbiegend

  {

    Grad = 90;                        //Position in Grad

  }

  schalten(Schranke, 4, Grad);        //(Servo, Anschlusspin, Position)

}

 

//_____________VOID LOOP______________________

void loop()

{

  while(digitalRead(T_W) == LOW)        //Start Weiche 1 zu 3

    {

      W1(1);

      digitalWrite(Pin_LED3_Gruen, HIGH);

      digitalWrite(Pin_LED8_Gruen, LOW);

      W2(0);

      digitalWrite(Pin_LED4_Rot, HIGH);

      digitalWrite(Pin_LED7_Rot, LOW);

    }

 

  while(digitalRead(T_O) == LOW)        //Start Weiche 1/2 und 3/4

    {

      W1(0);

      digitalWrite(Pin_LED3_Gruen, HIGH);

      digitalWrite(Pin_LED6_Gruen, HIGH);

      W2(0);

      digitalWrite(Pin_LED5_Gruen, LOW);

      digitalWrite(Pin_LED8_Gruen, LOW);

    }

 

  while(digitalRead(T_G1) == LOW)       //Start Weiche 3 zu 4

    {

      W2(1);

      digitalWrite(Pin_LED2_Rot, LOW);

      digitalWrite(Pin_LED9_Rot, HIGH);

      W1(0);

      digitalWrite(Pin_LED5_Gruen, LOW);

      digitalWrite(Pin_LED6_Gruen, HIGH);

    }

  while(digitalRead(T_S) == LOW)      //Start Schranke schließen

    {

      S(0);

     

    }

  while(digitalRead(T_S) == LOW)       //Start Schranke öffnen

    {

      S(1);

   

    }

 

    // Blinkled

 

  // BlinkWithoutDelay....

  unsigned long currentMillis = millis();

  if (BlinkValue == HIGH)

  {                  

    if (currentMillis - previousMillis >= interval)

    {

      previousMillis = currentMillis;

      if (ledState == LOW)

        ledState = HIGH;

      else

        ledState = LOW;

      digitalWrite(LED_BUILTIN, ledState);

    }

  }

  else

    digitalWrite(LED_BUILTIN, LOW);            

  // Ende BlinkWithoutDelay....

   

  TasterValue = digitalRead (T_S);        // Tasterstatus einlesen

  if (status != TasterValue)                 // Aenderung des Taster ?

  {

    if (TasterValue)                     // geschaltet

    {                          

      BlinkValue = !BlinkValue;                 // ...und wird gewechselt.

    }

    status = TasterValue;                       // Status merken

  }

}

ich hoffe es ist schick so... ich teste mit Wokwi

Ich hoffe ihr könnt einem Anfänger weiterhelfen.
Sagt wenn ihr noch was braucht,
mir raucht schon der KOPF.

Vielen Dank schon mal im Voraus... Steve

Sorry ich vergaß, es geht um eine Legobahn, welche mit Servos gesteuert wird.
Danke

Ein kleiner Fortschritt, nämlich dass die Schranke hoch/runter fährt, lässt sich im Wokwi-Sketch wie folgt erreichen:

 // Bei den Deklarationen oben
boolean SchrankeOben = false;

// ...

// In der loop():

  if (SchrankeOben) {
    while(digitalRead(T_S) == LOW)      //Start Schranke schließen
    {
      S(0);
      SchrankeOben = false;
    }
  } else {
    while(digitalRead(T_S) == LOW)       //Start Schranke öffnen
     {
       S(1);
       SchrankeOben = true;
    }
  }
  

Ohne die Unterscheidung der Zustände ist es Zufall, welchen der beiden

while(digitalRead(T_S) == LOW) {}

Schleifen der Controller erwischt.

Das mit dem Blinken muss ich mir noch anschauen ...

Ok, in dem u.a. aus Deinem Projekt abgeleiteten Wokwi klappt das meiste. Es gibt noch einen kleinen "Glitch": Nach dem Neustart blinken die LED beim allerersten Tastendruck während die Schranke unten bleibt. Das sollte sich noch beheben lassen:

https://wokwi.com/arduino/projects/322612732669985364

Ansonsten ist die Tastenabfrage etwas fragwürdig:

  • Tastenabfrage mit digitalread() ohne Debouncing (Entprellen) wird mit realen Tastern sehr wahrscheinlich zu äußerst merkwürdigem Verhalten führen!
  • Die Funktionen in der while-Schleife werden immer wieder (als Vielfach!) ausgeführt, solange die Taste gedrückt ist ...

Auch wenn der Sketch mit den kleinen Verbesserungen "gerettet" scheint, müssen diese Funktionen überarbeitet werden.

Muss für heute Schluss machen ... :wink:

Hallo furiossteve
Lösche die Leetzeilen, damit das Ganze lesbarer wird.
Eine while() Schleife ist eine "ungünstige" Konstruktion um Knöpfe auszulesen, da ist eine if() Abfrage besser. Die Anzahl der Wx() Funktionen läßt sich eindunsten, indem die Parameterliste angepasst wird.
Und noch viele andere Dinge, die den Sketch geschmeidiger macht.
Ich wünsche einen guten Tag und viel Spass beim Programmieren in C++.

Hallo furiossteve
Eröffne ein neues Topic.
Das Kapern von bestehenden Threads wird so gar nicht gerne gesehen.

Erst mal Danke an die Fleißigen Helfer...
Bin auf Wunsch umgezogen...

Lego Eisenbahn Schranken mit Blinklicht und Weichen steuern

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