Trio Power Phoenix-Contact


Google-Suche auf MEINE-SCHALTUNG.de :





Online Rechner

Chronik

Dauerkalender


Minenspiel
mit Infrarot und zwei Schrittmotoren

Minenspiel: Danger Mines

In unserem Minenspiel spielen zwei Schrittmotoren, ein IR-Empfänger mit mehreren IR‑Sendern und ein Arduino Uno die Hauptrollen. Es ist ein einfaches Geschicklichkeitsspiel, in dem vor allem Konzentration und schnelle Reaktion gefordert werden. Ein Schiff gelangte ungewollt in ein Seeminenfeld. Es gilt, bei der Weiterfahrt darauf zu achten, keine der Minen zu nah zu kommen. Sonst…
Das Minenfeld, bei uns auf einer alten Schallplatte aufgebaut, bewegt sich und zwingt das Schiff zu diversen Manövern, die notwendig sind, um den Minen auszuweichen. Das Minenfeld wird mit einem Schrittmotor bewegt. Mit einem Taster kann ein gewünschtes Spiellevel voreingestellt werden. Je höher das Level, umso schneller wird das Minenfeld bewegt. Damit wird auch automatisch der Schwierigkeitsgrad des Spiels erhöht.
In der Schallplatte befinden sich mehrere Löcher, die die Seeminen symbolisieren. Unter dem „Minenfeld“ befinden sich IR‑Sender, Leuchtdioden, die Infrarotlicht verstrahlen. Der IR-Empfänger ist an einem Arm, der sich über dem Minenfeld befindet, angebracht. Die IR-Sender, der IR-Empfänger und die Löcher sind so positioniert, dass es bei bestimmter Lage des Minenfeldes möglich ist, dass das Infrarotlicht durch ein Loch den IR-Empfänger erreicht. In diesem Fall „explodiert“ die Mine und das Schiff sinkt. Spiel verloren. Die Aufgabe des Spielers ist es natürlich, dies zu vermeiden. Ihm steht ein Potentiometer als Ruder zur Verfügung. Mit dem Potentiometer kann er den Arm mit dem IR-Empfänger bewegen. Durch Bewegungen des Armes nach links oder rechts kann er den Minen ausweichen und das Schiff retten.

Motoranschluss Minenfeld

Der erste Motor, mit dem das Minenfeld bewegt wird, ist ähnlich wie auch der zweite Motor an den Motortreiber DM420 angeschlossen. Die Aufgabe des Motortreibers ist es, das Problem der Leistung zu lösen. Das eigentliche Steuergerät, der Mikrocontroller Arduino Uno, kann alleine diese Aufgabe nicht bewältigen. Wenn seine Ausgänge zu stark belastet werden, können sie beschädigt werden. Die maximale Spannung an seinen Ausgängen beträgt lediglich 5V DC. Der Motortreiber dient in solchen Fällen wie eine Schnittstelle, die den Mikrocontroller und den Motor miteinander verbindet. Der Treiber ist an die Ausgänge PIN 11, 12 und PIN 13 des Mikrocontrollers angeschlossen. Die Ansteuerung des Motors ist in diesem Fall denkbar einfach. Das Minenfeld dreht sich stets in eine Richtung. Mit einem Taster (S2) wird das Level des Spiels eingestellt. Mit Levelwechsel wird eine andere Drehzahl des Motors eingestellt. Beim Starten des Spiels wird mit dem Ausgang D13 (Enable) der Motor gestartet.

Motoranschluss Arm

Mit dem zweiten Motor wird der Arm mit dem IR-Empfänger bewegt. Dank dieser Bewegungen kann der Spieler mit dem Schiff manövrieren und den Minen ausweichen. Vor dem Start des Spiels muss der Arm in seine Referenzposition gebracht werden. Damit die Aufgabe leicht zu bewältigen ist, wird in dem Modus eine geringe Drehzahl des Motors eingestellt. Die Referenzposition des IR-Empfängers befindet sich auf dem Außenrand des Minenfeldes.
Nach dem Spielstart wird der Arm mithilfe eines Potentiometers, das als Steuerruder fungiert, bewegt. Das Verstellen des Potentiometers nach links bewirkt eine Linksbewegung des Armes. Entsprechend bewirkt das Verstellen des Potentiometers nach rechts eine Rechtsbewegung des Armes.
Mit drei Leuchtdioden wird der aktuell voreingestellte Level angezeigt. Das Level wird mit der Taster S2 voreingestellt. Die rote Leuchtdiode leuchtet dann auf, wenn eine Mine „hochgegangen“ ist. Mit Taster S1 wird das Spiel gestartet bzw. gestoppt.

Schaltplan

Schaltplan



Aufbau der Testschaltung

Minenfeld mit Minen

Minenfeld

IR-Empfänger

"Schiff" mit dem IR-Empfänger

IR-Sender

IR-Sender

Steuerruder

Steuerruder

Steuerelemente

Steuerelemente und Anzeigen

Schrittmotor

Schrittmotor

Motortreiber

Motortreiber

DIP-Schalter Arm

Einstellung der DIP-Schalter Treiber beweglicher Arm

DIP-Schalter Minenfeld

Einstellung der DIP-Schalter Treiber Minenfeld

Testschaltung komplett

Testschaltung komplett

Programm

// *******************************************************************************************
// Minenspiel mit Infrarot und Schrittmotoren
// Arduino UNO
// Arduino IDE Version 2.3.8
// *******************************************************************************************
                                                 // Anschluss-Pins Minenfeld
int Motor_Minenfeld_PUL = 11;                    // Treiber DM420: Pulse Anschluss
int Motor_Minenfeld_DIR = 12;                    // Treiber DM420: Drehrichtung
int Motor_Minenfeld_ENBL = 13;                   // Treiber DM420: Freigabe
                                                 // Anschluss-Pins beweglicher Arm
int Motor_Arm_PUL = 2;                           // Treiber DM420: Pulse Anschluss
int Motor_Arm_DIR = 3;                           // Treiber DM420: Drehrichtung
int Motor_Arm_ENBL = 4;                          // Treiber DM420: Freigabe

int Taster_Spiel_Start = 9;                      // Pin 9 - Taster Start/Stop
int Taster_Spiel_Level = 8;                      // Pin 8 - Leveleinstellung
int Spiel_Level = 1;                             // Spiellevel aktuell
int Spiel_Status;                                // Status (0-Stop, 1-Auto  2-Mine getroffen)

int Pulslaenge;                                  // Verzögerung

int LED_Level_1 = A0;                            // Pin LED weiß
int LED_Level_2 = A1;                            // Pin LED blau
int LED_Level_3 = A2;                            // Pin LED gelb
int LED_Mine_getroffen = A3;                     // Pin LED rot
int Poti = A4;                                   // Pin Steuerruder
int IR_Sensor = A5;                              // PIN IR-Empfänger

int Poti_Altwert;                                // Analogwert
bool Arm_Bewegen;                                // Arm Bewegungsfreigabe
int Arm_Position;                                // Arm aktuelle Position
int Potisitionswert_Max = 78;                    // Arm Bewegungsradius Max.

// *******************************************************************************************
void setup() {
  
    pinMode (Motor_Minenfeld_PUL, OUTPUT);       // PUL-Pin als Ausgang
    pinMode (Motor_Minenfeld_DIR, OUTPUT);       // DIR-Pin als Ausgang
    pinMode (Motor_Minenfeld_ENBL, OUTPUT);      // ENBL-Pin als Ausgang
    digitalWrite (Motor_Minenfeld_DIR, HIGH);    // Motordrehrichtung Vorbelegung

    pinMode (Motor_Arm_PUL, OUTPUT);             // PUL-Pin als Ausgang
    pinMode (Motor_Arm_DIR, OUTPUT);             // DIR-Pin als Ausgang
    pinMode (Motor_Arm_ENBL, OUTPUT);            // ENBL-Pin als Ausgang    
    
    pinMode (Taster_Spiel_Start, INPUT_PULLUP);  // Eingang
    pinMode (Taster_Spiel_Level, INPUT_PULLUP);  // Eingang

    pinMode (LED_Level_1, OUTPUT);               // Status LED Level 1
    pinMode (LED_Level_2, OUTPUT);               // Status LED Level 2
    pinMode (LED_Level_3, OUTPUT);               // Status LED Level 3
    pinMode (LED_Mine_getroffen, OUTPUT);        // Status LED Mine angefahren

    Poti_Altwert = analogRead (A4);              // Poti Position aktuell
    digitalWrite (Motor_Arm_ENBL, HIGH);         // Motor Arm Freigabe
}

// *******************************************************************************************
void Level_Umschaltung () {                      // Level-Bestimmung mit Taster S2

    if (digitalRead (Taster_Spiel_Level) == LOW) {
        Spiel_Level++;
        delay (150);
    }    
    if (Spiel_Level > 3) {
        Spiel_Level = 1;
    }
    digitalWrite (LED_Level_1, LOW);
    digitalWrite (LED_Level_2, LOW);
    digitalWrite (LED_Level_3, LOW);
    switch (Spiel_Level) {
        case 1: { 
            Pulslaenge = 10000;
            digitalWrite (LED_Level_1, HIGH);
            break;
        }
        case 2: { 
            Pulslaenge = 6000;
            digitalWrite (LED_Level_2, HIGH);
            break;
        }
        case 3: { 
            Pulslaenge = 3000;  
            digitalWrite (LED_Level_3, HIGH);
            break; 
        }
    }
}

// *******************************************************************************************
void Spiel_starten () {    
                                                           // Automatik START
    if ((digitalRead (Taster_Spiel_Start) == LOW) && (Spiel_Status == 0)) {
        Spiel_Status = 1;                                  // Status Automatik
        Arm_Position = Potisitionswert_Max;                // Startwert Arm Position
        digitalWrite (Motor_Minenfeld_ENBL, HIGH);         // Minenfeld starten
        delay (250);                                       // Wartezeit
    } 
                                                           // Spiel zurücksetzen
    if ((digitalRead (Taster_Spiel_Start) == LOW) && (Spiel_Status == 3)) {
        Spiel_Status = 0;                                  // Wartezustand
        digitalWrite (LED_Mine_getroffen, LOW);            // Rote LED ausschalten
        digitalWrite (Motor_Minenfeld_ENBL, LOW);          // Minenfeld anhalten
        delay (250);                                       // Wartezeit
    }                                     
                                                           // Automatik unterbrechen
    if ((digitalRead (Taster_Spiel_Start) == LOW) && (Spiel_Status == 1)) {
        Spiel_Status = 0;                                  // Wartezustand
        digitalWrite (Motor_Minenfeld_ENBL, LOW);          // Minefeld anhalten
        delay (250);                                       // Wartezeit
    }
}

// *******************************************************************************************
void Motoren_drehen () {                         // Impulsbreite und Pulspause gleich für
                                                 // beide Motoren (Automatik)
    digitalWrite(Motor_Minenfeld_PUL,HIGH);
    if (Arm_Bewegen) {
    digitalWrite(Motor_Arm_PUL,HIGH);
    }
    delayMicroseconds(Pulslaenge);
    digitalWrite(Motor_Minenfeld_PUL,LOW);
    if (Arm_Bewegen) {
    digitalWrite(Motor_Arm_PUL,LOW);
    Arm_Bewegen = false;
    }    
    delayMicroseconds(Pulslaenge); 
}

// *******************************************************************************************
void Arm_Motor_drehen () {                       // Langsames Drehen um Referenzpunkt
                                                 // anzufahren (Spiel Aus)
    digitalWrite(Motor_Arm_PUL,HIGH);
    delay(25);
    digitalWrite(Motor_Arm_PUL,LOW);   
    delay(25);
}

// *******************************************************************************************
void loop() {

    Level_Umschaltung ();                             // Level Einstellung
    Spiel_starten ();                                 // Automatik Start

    if (Spiel_Status == 1) {                          // Automatik
        Motoren_drehen ();
    }
    
    int IR_Signal = analogRead(IR_Sensor);            // Signal vom IR-Empfänger prüfen
    if ((IR_Signal < 100) && (Spiel_Status == 1)) {   // Mine angefahren, Spiel Stop
        Spiel_Status = 3;
        digitalWrite (LED_Mine_getroffen, HIGH);      // Rote LED Ein
        digitalWrite (Motor_Minenfeld_ENBL, LOW);     // Minenfeld Stop
    }

    int Poti_Wert = analogRead (A4);                  // Poti Wert abfragen
    if (Poti_Wert > 520) {                            // Arm wird bewegt nach rechts
        Arm_Position++;
        if (Arm_Position > Potisitionswert_Max) {     // Bewegung nur im zugelassenen Abschnitt
            Arm_Position = Potisitionswert_Max;
        } else {
            digitalWrite (Motor_Arm_DIR, HIGH);
            Arm_Bewegen = true;
        }
        if (Spiel_Status == 0) {                      // Referenzpunkt langsam anfahren (Recht)
            digitalWrite (Motor_Arm_DIR, HIGH);
            Arm_Motor_drehen ();
        }
    } 

    if (Poti_Wert < 470) {                            // Arm wird bewegt nach links
        Arm_Position--;
        if (Arm_Position < 0) {
            Arm_Position = 0;
        } else {
            digitalWrite (Motor_Arm_DIR, LOW);
            Arm_Bewegen = true;
        }
        if (Spiel_Status == 0) {                      // Referenzpunkt langsam anfahren (Links)
            digitalWrite (Motor_Arm_DIR, LOW);
            Arm_Motor_drehen ();
        }
    }
}

// *******************************************************************************************
 

Kurzvideo

Kurzvideo


Weitere Themen:


Google-Suche auf MEINE-SCHALTUNG.de :


Home Impressum Datenschutz