Projekt Laser Maze – Phase 3

DMX und Lazer Maze Shield von oben

Finale Dokumentation der Phase 2 und Erklärung was hier passiert.

Für Techniker wird der Schaltplan einleuchtend sein.

Schaltplan Laser Maze Arduino

Die Laser und die Erkennung der Laser wiederholt sich nur 10mal. und die beiden Taster sind an sich auch identisch aufgebaut.

Pull Up Widerstände and den PTC’s

Das Prinzip der Pull Up und Pull Down Widerstände ist einfach. Wenn einer der Eingangpins des Arduinos nicht auf Masse (Ground oder Low) bzw. auf +5V (Vcc oder High) liegt, kann es zu unerwünschten Effekten kommen. So mag die Spannung des Körpers ausreichen, den Microcontroller etwas erkennen zu lassen, dass es im Spiel aber nicht gibt.
Durch hochohmige Widerstände umgeht man dieses Effekt. Am Beispiel der Pull Up Widerstände an den Fotodioden erklärt es sich wie folgt:

Trifft Licht auf die Fotodiode (der Laser), so wird diese niederohmig und leitend. Es entsteht ein Spannungsteiler und die Spannung über die Fotodiode ist sehr gering und wird von dem Eingangpin als Low erkannt.
Wird der Lichtstrahl unterbrochen, dann wird die Fotodiode hochohmig und damit teilt sich die Spannung zwischem dem Pull Up Widerstand oder Fotodiode anders auf und es wird ein High erkannt.

Bei den beiden Schaltern ist das Prinzip einfach andersrum angewendet.

Mein finaler Code hat sich ein bisschen in den Ports geändert, um den Gegebenheiten auf der Leiterplatte gerecht zu werden.

#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(2000);
}

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 );
}

Der Code beinhaltet auch ein paar Steuerungsbefehle für die angeschlossene DMX Lampe. Diese Lampen haben aber keine einheitliche Steuerung. Das kann von Lampe zu Lampe unterschiedlich sein.

Die Einkaufsliste gibt es in der Phase 2.

Falls du mich unterstützen möchtest, wäre es schön, wenn du diese Amazon Seite als deine Startseite anlegst. Dadurch bekomme ich bei jedem Einkauf ein bisschen Affiliate Link Geld von Amazon und dir entsteht kein Nachteil.