DIY Laser Maze mit Arduino

Laser in Aktion

Wer meine Projektentwicklung verfolgen möchte, kann dieses in den Phasen 1, Phase 2 und Phase 3 machen.

Mein Laser Maze (Laserlichtschranken Spiel) für den Heimgebrauch ist fertig und hat nun verschiedene Kindergeburtstage erfolgreich bewältigt.

Aufbau eines Laserturms Laser und PTC verlöten
Aufbau eines Laserturms Laser und PTC von vorne
DMX und Lazer Maze Shield von oben
DMX und Lazer Maze Shield seitlich
alternative zur eigenen Leiterplatte mit Schraubterminals
Laserpunkte ausrichten
Laserturm vorne
Laserturm hinten
Laser Irrgarten für unter 50 Euro
Lasertürme in Kübeln
Laser in Aktion
Laser und PTC mit reflektiertem Licht
Reflektionsfolie

Davon ausgehend, dass Hardware wie Lötkobel aber auch Holz oder HT-Rohr und Kabel in einem Bastelkeller vorhanden sind, lässt sich das Spiel für unter 50 Euro realisieren (zzgl. Nebenmaschine).

Benötigt werden ein Arduino zur Steuerung. Ein Arduino Starterset für Widerstände und Taster etc.. Die Laser und Empfänger sowie die Reflextionsfolie.

Für meine Version habe ich zusätzlich noch eine DMX Lampe und das zugehörige DMX Shield für Arduino. Eine Leiterplatte zum Anschrauben und Netzwerkkabel. Alles zusammen ist in einer Amazon Einkaufliste aufgeführt: https://amzn.to/339jaLL

Die Laser und Sensoren werden nahe zusammen montiert. Ich habe es an Holz gemacht, ein HT-Rohr (40mm oder größer) geht aber auch super. ein 6mm Loch für den Laser und 2x 3mm oder kleiner für die Beinchen des PTC’s. Das blaue Kabel des Lasers wird direkt mit einem Beinchen des PTC’s verbunden (Masse/ GND). Alle so verbunden Massen von den Lasern können zusammengeschlossen werden und zurück zum Arduino geführt werden. Die roten Enden der Laser sowie die andere Seite des PTC’s werden auf einzelne Adern des Netzwerkkabels gelötet. Ist habe den Laser immer auf die Vollfarbe und den zugehörigen PTC auf Farbe/weiss.

Am Arduino habe ich dieses dann entsprechend auf die PINs gelegt. Hier war das Schraubboard sehr hilfreich. Zusätzlich konnte ich hier den Schaltplan bestücken.

Aus dem StarterSet werden die 1MOhm und 10k Widerstände benötigt. Die Lichtsensoren (PTC) werden mittels der 1M Widerstände hochgelegt (pull up). Die beiden Taster mit den kleineren Werten gehen Masse (Pull Down). Als Taster eignen sich natürlich welche zum Einschrauben besser. Die aus dem StarterSet gehen natürlich auch.

Schaltplan Laser Maze

Die Laser sind auf eine gegenüberliegende Wand zu richten. Der Winkel sollte kleiner 45° sein. Dort wo der Laser auftrifft, wird ein bisschen von der Reflextionsfolie hingeklebt. Diese wirft das Licht zum Ausgangsort zurück, wo der PTC sitzt und es so wahrnimmt. Wird die Lichtschranke unterbrochen, wird dieses das dem Arduino so mitgeteilt und der schaltet den entsprechenden Laser dann aus.

Zusätzlich merkt sich der Arduino, dass ein Laser unterbrochen wurde und macht das solange, wie 3 Laser unterbrochen wurden oder das Spiel geschafft wurde und der WIN Buzzer gedrückt wurde.

Das Spiel kann in der Form jeder Zeit auch neu gestartet werden.

Dieser Code hier beinhaltet zusätzlich den Code zur Steuerung meiner DMX Lampe. Der Code mag von Lampe zu Lampe unterschiedlich sein.

#include <Conceptinetics.h>
#include <Rdm_Defines.h>
#include <Rdm_Uid.h>

/*
   Laser Maze Project 2020

   Taget 10 Laser should hit the PTC
   if PTC is hit, Laser will be deactivated
   if 3 PTC are hit, game over
   if buzzer is hit, game win

   Code on Mega 2560

*/

/* DMX Initiaslisierung */
DMX_Master dmx_master ( 8 , 2 );
// The first parameter is the number of channels that you are controlling. Note that no matter the number of channels given always 512 channels are transmitted by the master... you can only control the first 100 of them which saves you memory if you don't need to control all 512 channels.
// The second parameter is the pin assigned to control read and write operations on the shield (Data enable Read enable or any name assigned to it according to the shield you are using)

/* Initialisierung 10 Laser */
int laser0 = 30;
int laser1 = 32;
int laser2 = 34;
int laser3 = 36;
int laser4 = 38;
int laser5 = 40;
int laser6 = 42;
int laser7 = 44;
int laser8 = 46;
int laser9 = 48;

/* Initialisierung 10 PTCs */
int ptc0 = 31;
int ptc1 = 33;
int ptc2 = 35;
int ptc3 = 37;
int ptc4 = 39;
int ptc5 = 41;
int ptc6 = 43;
int ptc7 = 45;
int ptc8 = 47;
int ptc9 = 49;

/* Initalisierung Starter und Buzzer */
int gstart = 27;
int buzzer = 26;

// variable to store the read value
int r_ptc0 = 0;
int r_ptc1 = 0;
int r_ptc2 = 0;
int r_ptc3 = 0;
int r_ptc4 = 0;
int r_ptc5 = 0;
int r_ptc6 = 0;
int r_ptc7 = 0;
int r_ptc8 = 0;
int r_ptc9 = 0;
int r_gstart = 0;
int r_buzzer = 0;

// Game variable
int gcount = 0;
int l0count = 0;
int l1count = 0;
int l2count = 0;
int l3count = 0;
int l4count = 0;
int l5count = 0;
int l6count = 0;
int l7count = 0;
int l8count = 0;
int l9count = 0;
int game_limit = 3; // game is lost after x hits
int game_active = 0; // 0 = game inactive, 1 = game active

void setup() {
  // setup
  // sets the digital pin as output
  pinMode(laser0, OUTPUT);
  pinMode(laser1, OUTPUT);
  pinMode(laser2, OUTPUT);
  pinMode(laser3, OUTPUT);
  pinMode(laser4, OUTPUT);
  pinMode(laser5, OUTPUT);
  pinMode(laser6, OUTPUT);
  pinMode(laser7, OUTPUT);
  pinMode(laser8, OUTPUT);
  pinMode(laser9, OUTPUT);

  // sets the digital pin as input
  pinMode(ptc0, INPUT);
  pinMode(ptc1, INPUT);
  pinMode(ptc2, INPUT);
  pinMode(ptc3, INPUT);
  pinMode(ptc4, INPUT);
  pinMode(ptc5, INPUT);
  pinMode(ptc6, INPUT);
  pinMode(ptc7, INPUT);
  pinMode(ptc8, INPUT);
  pinMode(ptc9, INPUT);

  // set Input for Gamecontroll
  pinMode(gstart, INPUT);
  pinMode(buzzer, INPUT);

  // start DMX Master
  dmx_master.enable ();
  dmx_master.setChannelValue ( 1, 110 );
  dmx_master.setChannelValue ( 3, 255 );
}

void loop() {
  // (re-)start the game
  r_gstart = digitalRead(gstart);
  if (r_gstart == HIGH) {
    // Game start code is in a function
    game_start();
    game_active = 1;
  }
  // check if buzzer is hit
  r_buzzer = digitalRead(buzzer);
  if (r_buzzer == HIGH) {
    // Game Win code is in a function
    game_win();
    game_active = 0;
  }
  if (game_active == 1) {
    // Check if Laser is hit
    r_ptc0 = digitalRead(ptc0); // read PIN
    if (r_ptc0 == HIGH) {
      // if laser is hit, turn off for safty and gameplay
      digitalWrite(laser0, LOW);
      // Store the information, that the laser is hit
      l0count = 1;
    }
    r_ptc1 = digitalRead(ptc1);
    if (r_ptc1 == HIGH) {
      digitalWrite(laser1, LOW);
      l1count = 1;
    }
    r_ptc2 = digitalRead(ptc2);
    if (r_ptc2 == HIGH) {
      digitalWrite(laser2, LOW);
      l2count = 1;
    }
    r_ptc3 = digitalRead(ptc3);
    if (r_ptc3 == HIGH) {
      digitalWrite(laser3, LOW);
      l3count = 1;
    }
    r_ptc4 = digitalRead(ptc4);
    if (r_ptc4 == HIGH) {
      digitalWrite(laser4, LOW);
      l4count = 1;
    }
    r_ptc5 = digitalRead(ptc5);
    if (r_ptc5 == HIGH) {
      digitalWrite(laser5, LOW);
      l5count = 1;
    }
    r_ptc6 = digitalRead(ptc6);
    if (r_ptc6 == HIGH) {
      digitalWrite(laser6, LOW);
      l6count = 1;
    }
    r_ptc7 = digitalRead(ptc7);
    if (r_ptc7 == HIGH) {
      digitalWrite(laser7, LOW);
      l7count = 1;
    }
    r_ptc8 = digitalRead(ptc8);
    if (r_ptc8 == HIGH) {
      digitalWrite(laser8, LOW);
      l8count = 1;
    }
    r_ptc9 = digitalRead(ptc9);
    if (r_ptc9 == HIGH) {
      digitalWrite(laser9, LOW);
      l9count = 1;
    }
  }

  // check how many lasers are hit
  gcount = l0count + l1count + l2count + l3count + l4count + l5count + l6count + l7count + l8count + l9count;
  if (gcount >= game_limit) {
    // game lost action is in a function
    game_lost();
    game_active = 0;
  }
}

void game_start() {
  // reset game
  gcount = 0;
  l0count = 0;
  l1count = 0;
  l2count = 0;
  l3count = 0;
  l4count = 0;
  l5count = 0;
  l6count = 0;
  l7count = 0;
  l8count = 0;
  l9count = 0;

  // DMX start
  // dmx_master.setChannelValue ( channel, byte_value );
  // flash all laser 2 times and DMX
  dmx_master.setChannelValue ( 1, 0 );
  dmx_master.setChannelValue ( 2, 0 );
  digitalWrite(laser0, HIGH);
  digitalWrite(laser1, HIGH);
  digitalWrite(laser2, HIGH);
  digitalWrite(laser3, HIGH);
  digitalWrite(laser4, HIGH);
  digitalWrite(laser5, HIGH);
  digitalWrite(laser6, HIGH);
  digitalWrite(laser7, HIGH);
  digitalWrite(laser8, HIGH);
  digitalWrite(laser9, HIGH);
  delay(400);
  dmx_master.setChannelValue ( 1, 14 );
  dmx_master.setChannelValue ( 2, 75 );
  digitalWrite(laser0, LOW);
  digitalWrite(laser1, LOW);
  digitalWrite(laser2, LOW);
  digitalWrite(laser3, LOW);
  digitalWrite(laser4, LOW);
  digitalWrite(laser5, LOW);
  digitalWrite(laser6, LOW);
  digitalWrite(laser7, LOW);
  digitalWrite(laser8, LOW);
  digitalWrite(laser9, LOW);
  delay(400);
  dmx_master.setChannelValue ( 1, 0 );
  dmx_master.setChannelValue ( 2, 0 );
  digitalWrite(laser0, HIGH);
  digitalWrite(laser1, HIGH);
  digitalWrite(laser2, HIGH);
  digitalWrite(laser3, HIGH);
  digitalWrite(laser4, HIGH);
  digitalWrite(laser5, HIGH);
  digitalWrite(laser6, HIGH);
  digitalWrite(laser7, HIGH);
  digitalWrite(laser8, HIGH);
  digitalWrite(laser9, HIGH);
  delay(400);
  dmx_master.setChannelValue ( 1, 14 );
  dmx_master.setChannelValue ( 2, 75 );
  digitalWrite(laser0, LOW);
  digitalWrite(laser1, LOW);
  digitalWrite(laser2, LOW);
  digitalWrite(laser3, LOW);
  digitalWrite(laser4, LOW);
  digitalWrite(laser5, LOW);
  digitalWrite(laser6, LOW);
  digitalWrite(laser7, LOW);
  digitalWrite(laser8, LOW);
  digitalWrite(laser9, LOW);
  delay(600);
  dmx_master.setChannelValue ( 1, 0 );
  dmx_master.setChannelValue ( 2, 0 );

  // start the game all laser on
  digitalWrite(laser0, HIGH);
  digitalWrite(laser1, HIGH);
  digitalWrite(laser2, HIGH);
  digitalWrite(laser3, HIGH);
  digitalWrite(laser4, HIGH);
  digitalWrite(laser5, HIGH);
  digitalWrite(laser6, HIGH);
  digitalWrite(laser7, HIGH);
  digitalWrite(laser8, HIGH);
  digitalWrite(laser9, HIGH);
  delay(1000);
}

void game_win() {
  // gewonnen
  // all laser off
  digitalWrite(laser0, LOW);
  digitalWrite(laser1, LOW);
  digitalWrite(laser2, LOW);
  digitalWrite(laser3, LOW);
  digitalWrite(laser4, LOW);
  digitalWrite(laser5, LOW);
  digitalWrite(laser6, LOW);
  digitalWrite(laser7, LOW);
  digitalWrite(laser8, LOW);
  digitalWrite(laser9, LOW);
  // DMX win
  dmx_master.setChannelValue ( 1, 14 );
  dmx_master.setChannelValue ( 2, 55 );
}

void game_lost() {
  // verloren
  // all laser off
  digitalWrite(laser0, LOW);
  digitalWrite(laser1, LOW);
  digitalWrite(laser2, LOW);
  digitalWrite(laser3, LOW);
  digitalWrite(laser4, LOW);
  digitalWrite(laser5, LOW);
  digitalWrite(laser6, LOW);
  digitalWrite(laser7, LOW);
  digitalWrite(laser8, LOW);
  digitalWrite(laser9, LOW);
  // DMX lost
  dmx_master.setChannelValue ( 1, 14 );
  dmx_master.setChannelValue ( 2, 45 );
}

Fertig! Viel Spass

Ersten Kommentar schreiben

Antworten