Schrankensteuerung HO

Hallo liebe Forum Freunde,

ich habe ein Problem beim Sketch schreiben und hoffe ihr könnt mir wieder helfen.
Da ich in den letzten Jahren unregelmäßig Eure Hilfe in Anspruch genommen habe, das letzte Mal im September 2023, bin ich bei meinen Anmeldungen durcheinandergeraten.
Ich habe es zwar aufgeschrieben, finde es aber nicht mehr.
In den letzten Jahren wurde auch der Computer drei Mal gewechselt.
Bitte um Nachsicht, wenn bei der Anmeldung etwas nicht ganz stimmt.

Jetzt aber zu meinem Problem.

Bei meinem Bahnhof Modul wird die Steuerung von einem externen Steuerpult mit MCP23017 I2C IO Port Expander zum Nano unter der Anlage geführt.
Weichen, Signale und belegt Melder funktionieren einwandfrei. Jetzt, zum Schluss, kommen die Schranken dazu, die mit einem kleinen Getriebemotor angetrieben werden.
Der Sketch dazu funktioniert, aber nur die Schranke Auf. Die Schranke Zu reagiert nicht. Wenn ich Schranke Auf in Klammer setze, funktioniert Schranke Zu.

[code]
//  Modul 2 Bahnhof. Motoren mit H-Brücke L298N über I2C ansteuern
//
//  Arduino Micro als Slave
//  SDA = 2 grün, SCL = 3 gelb

int in1 = 9;
int in2 = 8;
int EndschalterAuf = 6;
int EndschalterAb = 7;

#include <Wire.h>
#define Slave1Adresse 9                       
byte a = 0;                       

void setup() {

  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(EndschalterAuf, INPUT_PULLUP);
  pinMode(EndschalterAb, INPUT_PULLUP);

  Wire.begin(Slave1Adresse);                      
  Wire.onReceive(receiveEvent);     
}

void receiveEvent(int bytes)
{
  a = Wire.read();                               
}

void loop()
{
  // Schranke Auf

  if (a == 1)                            //  Taster Schranke Auf (mcp2.digitalRead(1) == LOW)  vom Master
  {
    digitalWrite(in1, HIGH);                      // Motor 1 beginnt zu rotieren Rechts Auf
    digitalWrite(in2, LOW);
    delay(3500);                                  // Zeit um aus die Endschalter zu fahren
  }
  if (digitalRead(EndschalterAuf) == LOW)
  {
    digitalWrite(in1, LOW);                        // Motor 1 Stop
    digitalWrite(in2, LOW);                        // Motor 1 Stop
  }
  a = 0;

  // Schranke Zu

  if (a == 2)                            // Taster Schranke Zu (mcp2.digitalRead(0) == LOW)   vom Master
  {
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);                       // Motor 1 beginnt zu rotieren Links Ab
    delay(3500);                                   // Zeit um aus die Endschalter zu fahren
  }
  if (digitalRead(EndschalterAb) == LOW)
  {
    digitalWrite(in1, LOW);                        // Motor 1 Stop
    digitalWrite(in2, LOW);                        // Motor 1 Stop
  }
  a = 0;
}
[/code]

Über eine Hilfe von Euch würde ich mich freuen.
Gruß Jürgen

Naja, mit a=0 setzt du dir ja im loop() auf jeden fall deine eingänge zurück, so dass bei der Abfrage if(a == 2) a zwangsweise immer 0 ist. Auch ist die Abfrage des Endschalters zweitrangig, der Motor läuft auf jeden Fall immer 3,5 Sekunden.

Baue Dir doch serielle Ausgaben rein, damit Du siehst, was in a steht.

Gruß Tommy

Damit stellst Du Dir ein Bein, denn (a==2) kann niemals wahr werden!

Der Sinn erschließt sich mir nicht :thinking:

a soll ja im receiveEvent gesetzt werden. Das sollte man halt mit seriellen Ausgaben prüfen.

Gruß Tommy

void receiveEvent(int bytes)
{
  if (a == 0)
  { a = Wire.read(); }
}

void loop()
{
  if (a == 1)
  {
    digitalWrite(in1, HIGH);                      // Motor 1 beginnt zu rotieren Rechts Auf
    digitalWrite(in2, LOW);
    if (digitalRead(EndschalterAuf) == LOW)
    {
      digitalWrite(in1, LOW);                        // Motor 1 Stop
      digitalWrite(in2, LOW);                        // Motor 1 Stop
      a = 0;
    }
  }
  else if (a == 2)
  {
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);                       // Motor 1 beginnt zu rotieren Links Ab
    if (digitalRead(EndschalterAb) == LOW)
    {
      digitalWrite(in1, LOW);                        // Motor 1 Stop
      digitalWrite(in2, LOW);                        // Motor 1 Stop
      a = 0;   
     }
  }
}
1 Like

Ne Ne, schau mal nochmal hin. @agmue liegt schon richtig.

Doch.
Genau nachdem a==0 gesetzt wurde und das .event einsetzt :slight_smile:

Wenn a==0 (also zurückgesetzt ist) soll ein neues a über Wire eingelesen werden.
Was verstehst Du daran nicht?
Ob da das Richtige drin steht, soll ja der TO mit seriellen Ausgaben prüfen.

Gruß Tommy

Die Variable a wird an der falschen Stelle zurückgesetzt. @my_xy_projekt hat es richtig gemacht.

3 Likes

Erkennst Du es jetzt nachdem @my_xy_projekt es geändert hat?

Es steht das richtige drin.
Wenn der erste Teil auskommentiert wird und nur der zweite Teil läuft, reagiert die Funktion auf das gesetzte Byte.
Das Problem ist die Klammersetzung und damit das Ende der jeweiligen Funktionsblöcke.

1 Like

Hier noch eine kleine Verbesserung, sollte schonender für Motor und Schranke sein.
Noch ein kleiner Tipp an den TO zur besseren Lesbarkeit, Ausgänge besser out1, out2 benennen und nicht in1, in2

void receiveEvent(int bytes)
{
  if (a == 0)
  { a = Wire.read(); }
}

void loop()
{
  if (a == 1)
  {
    if (digitalRead(EndschalterAuf) == LOw)
    {
      digitalWrite(in1, LOW);                        // Motor 1 Stop
      digitalWrite(in2, LOW);                        // Motor 1 Stop
      a = 0;
    }
	else
	{
	  digitalWrite(in1, HIGH);                      // Motor 1 beginnt zu rotieren Rechts Auf
	  digitalWrite(in2, LOW);
	}
  }
  else if (a == 2)
  {
    if (digitalRead(EndschalterAb) == LOW)
    {
      digitalWrite(in1, LOW);                        // Motor 1 Stop
      digitalWrite(in2, LOW);                        // Motor 1 Stop
      a = 0;   
    }
	else
	{
      digitalWrite(in1, LOW);
      digitalWrite(in2, HIGH);                       // Motor 1 beginnt zu rotieren Links Ab
	}
  }
}

Was ist daran besser?
Aber Danke, dass Du meinen Fehler mit übernommen hast.

na ja, so lange z.B. a==1 ist, würde bei dir immer in1 auf jeden Fall einmal kurz auf High gesetzt, auch wenn der Endschalter betätigt ist.

Ok, Du hast Recht. Du bist besser im blind programmieren. Das liegt mir nicht so.
Das wäre aber bei der seriellen Ausgabe auch aufgefallen.

Gruß Tommy

Wenn Du das verhindern willst (Anmerkung: Wir reden über einen Getriebemotor und nicht über einen Stepper) dann ist das Konstrukt mit der Prüfung auf Endschalter HIGH besser bedient, um die Reihenfolge im Ablauf aufrecht zu erhalten.

geb ich dir recht, ich wollte nur den TO nicht ganz verwirren, er soll sein Programm ja noch in etwa wiedererkennen können :wink:

Danke für Eure Tipps und Verbesserungs Vorschläge.
Werde Morgen das ganze überarbeiten und Euch Bescheid geben.
Nochmals Danke

Hallo liebe Forum Freunde,

seit Tagen grüble ich jeden Abend über den Sketch und komme nicht zu einem brauchbaren Ergebnis.
So wie der Sketch jetzt ist, kann ich über Taster die Richtung ändern, aber die Endschalter funktionieren nicht.
Auf der Platine des L298N steht in1, in2 und habe es so übernommen.

Vielleicht kann mir doch noch jemand helfen. Ich komme nicht mehr weiter.

Danke
Gruß Jürgen

int in1 = 9;                                 //  in1 = Bezeichnung am L298N
int in2 = 8;                                 //  in2 = Bezeichnung am L298N
int EndschalterAuf = 6;
int EndschalterAb = 7;

#include <Wire.h>
#define Slave1Adresse 9
byte a = 0;

void setup() {

  pinMode(in1, OUTPUT);                         
  pinMode(in2, OUTPUT);                      
  pinMode(EndschalterAuf, INPUT_PULLUP);
  pinMode(EndschalterAb, INPUT_PULLUP);

  Wire.begin(Slave1Adresse);               // Start the I2C Bus as Slave
  Wire.onReceive(receiveEvent);            // Attach a function to trigger when something is received.
  
}

void receiveEvent(int bytes)
{
  if (a == 0)
  {
    a = Wire.read();
  }
}

void loop()
{
  if (a == 1)
  {
    if (digitalRead(EndschalterAuf) == LOW)
    {
      digitalWrite(in1, LOW);                        // Motor 1 Stop
      digitalWrite(in2, LOW);                        // Motor 1 Stop
    }
    else
    {
      digitalWrite(in1, HIGH);                      // Motor 1 beginnt zu rotieren Rechts Auf
      digitalWrite(in2, LOW);
    }
    a = 0;
  }

  if (a == 2)           //else if (a == 2)
  {
    if (digitalRead(EndschalterAb) == LOW)
    {
      digitalWrite(in1, LOW);                        // Motor 1 Stop
      digitalWrite(in2, LOW);                        // Motor 1 Stop
    }
    else
    {
      digitalWrite(in1, LOW);
      digitalWrite(in2, HIGH);                       // Motor 1 beginnt zu rotieren Links Ab
    }
    a = 0;
  }
}