DC-Car Strassenkreuzung

Antworten
Benutzeravatar
e69-fan
Beiträge: 282
Registriert: Mi 20. Jan 2021, 10:32
Wohnort: Murnau am Staffelsee

DC-Car Strassenkreuzung

Beitrag von e69-fan »

Hallo Franz,

ich habe mal wie besprochen den Sketch um ein Relais erweitert und I2C-Display angelegt.

Wie Du bereits angemerkt hast - Kippschalter sind suboptimal. Also habe ich diesen Sketch erweitert.

Code: Alles auswählen

/*  Dateiname: "DC-Car_Kreuzung_00"

     Demo zum Anschluß mehrerer Weichen, realisiert mit objektorientierter Programmierung (OOP)
     Anstelle von Funktionen und Feldern werden Methoden und Strukturen verwendet.
     Die Methoden sehen so aus, als seien sie für eine Weiche geschrieben,
     tatsächlich können aber bis zu 16 Weichen, begrenzt durch die Bibliothek, verwendet werden,
     wenn die Pins wie beim Mega2560 ausreichen.
     Beim Drücken des Tasters geht die LED aus, der Servo bewegt die Zunge mit eingestellter Geschwindigkeit
     in die andere Position, die LED für die neue Position geht an, der Servo wird nach einer Sekunde ausgeschaltet.

     Ausgaben auf den seriellen Monitor dienen nur der Veranschaulichung und können entfernt werden.
     
     optionale Infoausgabe an LCD-Display 20x4   // A4 =SDA; A5 =SCL; 5V Plus; Masse
*/
// ------------------------------------------------------------------------------------------------------------------------- //

#include <MobaTools.h>
const byte ZUNGENGESCHWINDIGKEIT = 30;  // 10 entspricht 1,7 Sekunden

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 20 chars and 4 line display

// ------------------------------------------------------------------------------------------------------------------------- //
class Weiche {
    const byte tasterPin;       // Pin für den Taster
    const byte ledGeradePin;    // Pin für die LED Zustand gerade
    const byte ledAbzweigPin;   // Pin für die LED Zustand Anzweig
    const byte servoPin;        // Pin für den Weichenservo
    const byte winkelG;         // Winkel für die Geradenstellung
    const byte winkelA;         // Winkel für die Abzweigtellung
    const bool grundStellung;   // Grundstellung beim Einschalten: 0=gerade, 1=Abzweig
    bool tasterAlt, tasterAkt;  // Tasterzustände alt und aktuell
    const byte relais;          // Umschaltrelelais für DC-Car Stopstelle
    // ------------------------------------------------------------------------------------------------------------------------- //
    MoToServo weichenServo;     // Objekt der Bibliothek
    // ------------------------------------------------------------------------------------------------------------------------- //
  public:
    Weiche (const byte tasterPin,  const byte ledGeradePin,  const byte ledAbzweigPin,  const byte servoPin, const byte winkelG, const byte winkelA, const bool grundStellung, const byte relais)
      : tasterPin(tasterPin),  ledGeradePin(ledGeradePin),  ledAbzweigPin(ledAbzweigPin),  servoPin(servoPin), winkelG(winkelG), winkelA(winkelA), grundStellung(grundStellung), tasterAlt(0), tasterAkt(0), relais(relais), weichenServo() {}

    // ------------------------------------------------------------------------------------------------------------------------- //
    void init() {

      pinMode(tasterPin, INPUT_PULLUP);               // Taster schaltet nach GND
      pinMode(ledGeradePin, OUTPUT);
      pinMode(ledAbzweigPin, OUTPUT);
      pinMode(relais, OUTPUT);

      weichenServo.attach(servoPin, true);            // Pin für den Weichenservo und Abschalten nach einer Sekunde
      weichenServo.setSpeed(ZUNGENGESCHWINDIGKEIT);   // Weichenzungengeschwindigkeit

      if (grundStellung) {
        weichenServo.write(winkelA);                  // definierten Anfangswinkel anfahren

      } else {

        weichenServo.write(winkelG);                  // definierten Anfangswinkel anfahren
      }
    }
    // ------------------------------------------------------------------------------------------------------------------------- //
    void stellen() {
      tasterAlt = tasterAkt;
      tasterAkt = digitalRead(tasterPin);

      if (weichenServo.moving() == 0) {
        byte winkel = weichenServo.read();

        if (winkel == winkelG) digitalWrite(ledGeradePin, HIGH);
        if (winkel == winkelG) digitalWrite(relais, HIGH);

        if (winkel == winkelA) digitalWrite(ledAbzweigPin, HIGH);
        if (winkel == winkelA) digitalWrite(relais, LOW);

        if (tasterAlt && !tasterAkt) {

          // ------------------------------------------------------------------------------------------------------ //
          Serial.print(F("Pin ")); Serial.print(tasterPin);
          // ------------------------------------------------------------------------------------------------------ //

          if (winkel == winkelG) {

            // ------------------------------------------------------------------------------------------------------ //
            Serial.print(F("\tWeiche Pin ")); Serial.print(servoPin); Serial.println(F(" abbiegen"));
            // ------------------------------------------------------------------------------------------------------ //

            digitalWrite(ledGeradePin, LOW);
            weichenServo.write(winkelA);

          } else {

            // ------------------------------------------------------------------------------------------------------ //
            Serial.print(F("\tWeiche Pin ")); Serial.print(servoPin); Serial.println(F(" gerade"));
            // ------------------------------------------------------------------------------------------------------ //

            digitalWrite(ledAbzweigPin, LOW);
            weichenServo.write(winkelG);
          }
        }
      }
    }
};

Weiche weichen[] = {
  
// tasterPin,   ledGeradePin,  ledAbzweigPin,  servoPin, winkelG,  winkelA, Grundstellung,  relais
  {A1,          2,             3,              8,        110,      80,      0,              11},             // jede Zeile entspricht einer Weiche
  {A2,          4,             5,              9,        100,      70,      0,              12},
  {A3,          6,             7,              10,       100,      70,      0,              13}
};

// ------------------------------------------------------------------------------------------------------------------------- //
void setup() {

  {
    lcd.init();                      // initialize the lcd
    
    // Print a message to the LCD.
    
    lcd.backlight();
    lcd.setCursor(0, 0);

  }

  Serial.begin(9600);
  Serial.println(F("Strassenkreuzung"));

  for (Weiche &w : weichen) w.init();
}

// ------------------------------------------------------------------------------------------------------------------------- //
void loop() {
  for (Weiche &w : weichen) w.stellen();
}
Schau doch Bitte mal darüber und gib Bescheid.

Danke
Grüße aus der Heimat der E69
Benutzeravatar
Admin
Administrator
Beiträge: 1196
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: DC-Car Strassenkreuzung

Beitrag von Admin »

Kannst du mir mal das Programm vor deiner "Erweiterung" geben? Da gibts ein Problem mit den Klammern.

Franz
Benutzeravatar
e69-fan
Beiträge: 282
Registriert: Mi 20. Jan 2021, 10:32
Wohnort: Murnau am Staffelsee

Re: DC-Car Strassenkreuzung

Beitrag von e69-fan »

Hallo Franz,


Code: Alles auswählen

[code]
/*  Dateiname: "DC-Car_Kreuzung_00"

     Demo zum Anschluß mehrerer Weichen, realisiert mit objektorientierter Programmierung (OOP)
     Anstelle von Funktionen und Feldern werden Methoden und Strukturen verwendet.
     Die Methoden sehen so aus, als seien sie für eine Weiche geschrieben,
     tatsächlich können aber bis zu 16 Weichen, begrenzt durch die Bibliothek, verwendet werden,
     wenn die Pins wie beim Mega2560 ausreichen.
     Beim Drücken des Tasters geht die LED aus, der Servo bewegt die Zunge mit eingestellter Geschwindigkeit
     in die andere Position, die LED für die neue Position geht an, der Servo wird nach einer Sekunde ausgeschaltet.

     Ausgaben auf den seriellen Monitor dienen nur der Veranschaulichung und können entfernt werden.
     
     optionale Infoausgabe an LCD-Display 20x4   // A4 =SDA; A5 =SCL; 5V Plus; Masse
*/
// ------------------------------------------------------------------------------------------------------------------------- //

#include <MobaTools.h>
const byte ZUNGENGESCHWINDIGKEIT = 30;  // 10 entspricht 1,7 Sekunden

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 20 chars and 4 line display

// ------------------------------------------------------------------------------------------------------------------------- //
class Weiche {
    const byte tasterPin;       // Pin für den Taster
    const byte ledGeradePin;    // Pin für die LED Zustand gerade
    const byte ledAbzweigPin;   // Pin für die LED Zustand Anzweig
    const byte servoPin;        // Pin für den Weichenservo
    const byte winkelG;         // Winkel für die Geradenstellung
    const byte winkelA;         // Winkel für die Abzweigtellung
    const bool grundStellung;   // Grundstellung beim Einschalten: 0=gerade, 1=Abzweig
    bool tasterAlt, tasterAkt;  // Tasterzustände alt und aktuell
    const byte relais;          // Umschaltrelelais für DC-Car Stopstelle
    // ------------------------------------------------------------------------------------------------------------------------- //
    MoToServo weichenServo;     // Objekt der Bibliothek
    // ------------------------------------------------------------------------------------------------------------------------- //
  public:
    Weiche (const byte tasterPin,  const byte ledGeradePin,  const byte ledAbzweigPin,  const byte servoPin, const byte winkelG, const byte winkelA, const bool grundStellung, const byte relais)
      : tasterPin(tasterPin),  ledGeradePin(ledGeradePin),  ledAbzweigPin(ledAbzweigPin),  servoPin(servoPin), winkelG(winkelG), winkelA(winkelA), grundStellung(grundStellung), tasterAlt(0), tasterAkt(0), relais(relais), weichenServo() {}

    // ------------------------------------------------------------------------------------------------------------------------- //
    void init() {

      pinMode(tasterPin, INPUT_PULLUP);               // Taster schaltet nach GND
      pinMode(ledGeradePin, OUTPUT);
      pinMode(ledAbzweigPin, OUTPUT);
      pinMode(relais, OUTPUT);

      weichenServo.attach(servoPin, true);            // Pin für den Weichenservo und Abschalten nach einer Sekunde
      weichenServo.setSpeed(ZUNGENGESCHWINDIGKEIT);   // Weichenzungengeschwindigkeit

      if (grundStellung) {
        weichenServo.write(winkelA);                  // definierten Anfangswinkel anfahren

      } else {

        weichenServo.write(winkelG);                  // definierten Anfangswinkel anfahren
      }
    }
    // ------------------------------------------------------------------------------------------------------------------------- //
    void stellen() {
      tasterAlt = tasterAkt;
      tasterAkt = digitalRead(tasterPin);

      if (weichenServo.moving() == 0) {
        byte winkel = weichenServo.read();

        if (winkel == winkelG) digitalWrite(ledGeradePin, HIGH);
        if (winkel == winkelG) digitalWrite(relais, HIGH);

        if (winkel == winkelA) digitalWrite(ledAbzweigPin, HIGH);
        if (winkel == winkelA) digitalWrite(relais, LOW);

        if (tasterAlt && !tasterAkt) {

          // ------------------------------------------------------------------------------------------------------ //
          Serial.print(F("Pin ")); Serial.print(tasterPin);
          // ------------------------------------------------------------------------------------------------------ //

          if (winkel == winkelG) {

            // ------------------------------------------------------------------------------------------------------ //
            Serial.print(F("\tWeiche Pin ")); Serial.print(servoPin); Serial.println(F(" abbiegen"));
            // ------------------------------------------------------------------------------------------------------ //

            digitalWrite(ledGeradePin, LOW);
            weichenServo.write(winkelA);

          } else {

            // ------------------------------------------------------------------------------------------------------ //
            Serial.print(F("\tWeiche Pin ")); Serial.print(servoPin); Serial.println(F(" gerade"));
            // ------------------------------------------------------------------------------------------------------ //

            digitalWrite(ledAbzweigPin, LOW);
            weichenServo.write(winkelG);
          }
        }
      }
    }
};

Weiche weichen[] = {
  
// tasterPin,   ledGeradePin,  ledAbzweigPin,  servoPin, winkelG,  winkelA, Grundstellung,  relais
  {A1,          2,             3,              8,        110,      80,      0,              11},             // jede Zeile entspricht einer Weiche
  {A2,          4,             5,              9,        100,      70,      0,              12},
  {A3,          6,             7,              10,       100,      70,      0,              13}
};

// ------------------------------------------------------------------------------------------------------------------------- //
void setup() {

  {
    lcd.init();                      // initialize the lcd
    
    // Print a message to the LCD.
    
    lcd.backlight();
    lcd.setCursor(0, 0);

  }

  Serial.begin(9600);
  Serial.println(F("Strassenkreuzung"));

  for (Weiche &w : weichen) w.init();
}

// ------------------------------------------------------------------------------------------------------------------------- //
void loop() {
  for (Weiche &w : weichen) w.stellen();
}

Falsch waren die Leerzeichen beim LCD-Diplay
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 20 chars and 4 line display

Jetzt meckert er nicht mehr.



Am Bedienfeld will ich DUO-Led verbauen. Jeweils eine Anode an einen Ausgansgangspin vom Arduino. Wo soll ich den Vorwiderstand für die LED anschließen? 1 Widerstand an gemeinsamer Kathode oder jeweils 1 Widerstand an jeweiliger Anode. Es ist immer nur eine Anode geschalten.
DUO Led.jpg
DUO Led.jpg (16.06 KiB) 620 mal betrachtet
Grüße aus der Heimat der E69
Benutzeravatar
Admin
Administrator
Beiträge: 1196
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: DC-Car Strassenkreuzung

Beitrag von Admin »

"Am Bedienfeld will ich DUO-Led verbauen. Jeweils eine Anode an einen Ausgansgangspin vom Arduino. Wo soll ich den Vorwiderstand für die LED anschließen? 1 Widerstand an gemeinsamer Kathode oder jeweils 1 Widerstand an jeweiliger Anode. Es ist immer nur eine Anode geschalten."

Wenn immer nur eine der beiden leuchtet, reicht der Widerstand am gemeinsammen Pin.

Franz
Antworten

Zurück zu „Hardware / Schaltungstechnik“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste