Frogger1108
Published © GPL3+

Arduino Conversion of an EM Pinball Machine

Conversion of an old pinball playfield to an Arduino-driven, fully working pinball machine.

AdvancedShowcase (no instructions)17,806
Arduino Conversion of an EM Pinball Machine

Things used in this project

Story

Read more

Code

Arduino controlled Pinball Machine Code

Arduino
Allows the Arduino to control the game play of a home made pinball machine. Controls lights, sensors, voltage to coils, scoring, etc.
#include <Wire.h> 
#include "LedControl.h" 
#include <EEPROMex.h>
//////////////////LED/////////////////////
#include <FastLED.h>
#define NUM_LEDS 38
#define NUM_LEDS2 14
#define DATA_PIN 8
#define DATA_PIN2 9
#define BRIGHTNESS          255
CRGB leds[NUM_LEDS];
CRGB ledsbig[NUM_LEDS2];

//////////////////LED/////////////////////

LedControl lc=LedControl(7,5,6,2);


//Variables
int Balls = 1;  //Number of Balls
int MaxBalls = 5; //Number of Maxballs
int Milli = 50; //Delay 1
int MilliRoll = 100; //Delay 2
int Milli_Bumper = 30; //Delay for Bumpers
int Oncepergame = 0;
int Skillshot_active = 0;  //Activates the Skillshot
int Skillshot1_active = 0;
int Skillshot2_active = 0;
int Skillshot3_active = 0;
int PlayMusicOnce = 0;
int randNumber;   //Random Number for the Skillshot
unsigned long previousMillis_Skillshot = 0;
const long interval_skillshot = 10000;   //The Skillshot is active for 10 seconds once the ball is in play
int Ball_active = 0;


int AttractMode = 0;
int Torpedo1_primer =1;
int Torpedo2_primer =1;
int Torpedo3_primer =1;

int Torpedo1_active =0;
int Torpedo2_active =0;
int Torpedo3_active =0;

int Vari_Bonus_active =0;
int Vari_top_bottom = 0;  //Target recognition starts at the top (position 5) to the bottom (position 1). Highest positions is cored and locks the rest.
//Mosfet Variables//////////////////////////////////////////////////////////////////////////////////////
const long interval = 50;           // interval at which to trigger bumper solenoids (milliseconds)
const long interval_vari_activate = 500;           // interval after which to activate the vari target coil (milliseconds)
const long interval_vari_deactivate = 1200;           // interval after which to deactivate the vari target coil (milliseconds)
unsigned long  Solenoid_TimeTemp;
unsigned long  Solenoid_FireTime;
unsigned long previousMillis = 0;
unsigned long previousMillis_vari_activate = 0;
unsigned long previousMillis_vari_deactivate = 0;
unsigned long currentMillis = 0;

unsigned long previousMillis_cap = 0;
const long interval_grace_cap = 900;           // interval at which the captive Balls can't be triggered again after the first trigger

unsigned long VariTargetBurnTime = 0;             //Burn Timers to protect the solenoids from stuck switches
unsigned long BumperBurnTime = 0;
unsigned long KickoutBurnTime = 0;
unsigned long ReleaseBurnTime = 0;
unsigned long SolenoidOnFireTime = 1800;
unsigned long VariTargetBurnTimeBase;
unsigned long BumperBurnTimeBase;
unsigned long KickoutBurnTimeBase;
unsigned long ReleaseBurnTimeBase;




int MosfetState = LOW;    
int Kickout_Trigger = 0;
int Bumper_Trigger = 0;
int Vari_Trigger = 2;
int BallRelease_Trigger = 0;

//Variables to avoid ghosting//////////////////////////////////////////////////////////////////////////////////////
int Rollover_Lane1_int_last = LOW;
int Rollover_Lane2_int_last = LOW;
int Rollover_Lane3_int_last = LOW;

int CaptiveBall1_int_last = LOW;
int CaptiveBall2_int_last = LOW;
int CaptiveBall3_int_last = LOW;

int Outlanes_Links_Rechts_int_last = LOW;
int Sidelanes_Left1_int_last = LOW;
int Sidelanes_Right2_int_last = LOW;

int Target_Low_int_last = LOW;
int Target_High_int_last = LOW;
int Target_Vari1_int_last = LOW;
int Target_Vari2_int_last = LOW;
int Target_Vari3_int_last = LOW;
int Target_Vari4_int_last = LOW;
int Target_Vari5_int_last = LOW;
int VariTarget_int_last = LOW;
int Kickout_int_last = LOW;
int Rollunder_int_last = LOW;
int BallRelease_int_last = LOW;
int Bumper_int_last = LOW;
int Bumper_shockproof = 0;
int Ballinplay_int_last = LOW;
int Slingshots_Left_Right_Up_int_last = LOW;
int Rubberband123_int_last = LOW;

//Attract Mode/////////////////////////////////////////////////////////////
int AttatchInteruptOnce = 0;

//volatile int AttractMode = 0;
int Attractcounter1 = 0;
int Attractcounter2 = 0;
int Attractcounter3 = 0;
int Attractcounter4 = 0;
int Attractdelay1 = 800;
int Attractdelay2 = 400;
int Startplay_A = 0;
int Startplay_ACTIVE = 0;

//Attract Mode/////////////////////////////////////////////////////////////

//Score and Scoredisplay//////////////////////////////////////////////////////////////////////////////////////

int adress = 0;   //Adress for saved Highscore
 long HighScore = EEPROM.readLong(adress);
long Score = 0;
long Bonus;           //Bonus points
long Bonus_temp = 0;  //Bonus counter
long Bonus_fix = 0;  //Bonus --> Ships sunk
int DoubleBonus = 0;
int Ships_sunk = 0;
int Ships_allive = 10;
int Max_Bonus_multiplier = (Ships_allive-Ships_sunk);
int Torpedo_Bonus = 0; //(0-10)
int Bonus_Counter = 0;
int Bonus_low_target = 0;
int Kickout_Bonus = 0;
int VariTorpedo1 = 0;
int VariTorpedo2 = 0;
int VariTorpedo3 = 0;

int num0;
int num1;
int num2;
int num3;
int num4;
int num5;
int num6;
int num7;
int Highnum0;
int Highnum1;
int Highnum2;
int Highnum3;
int Highnum4;
int Highnum5;
int Highnum6;
int Highnum7;


int loopnumber =0;

//PINS 50,51,52,53 reserved//////////////////////////////////////////////////////////////////////////////////////

int Rollover_Lane1 = 44; 
int Rollover_Lane2 = 42; 
int Rollover_Lane3 = 40; 
int CaptiveBall1 = 49; 
int CaptiveBall2 = 48; 
int CaptiveBall3 = 46; 
int Grace_Trigger = 0;   //Grace Trigger for the Captive Balls


int Outlanes_Links_Rechts = 47;
int Sidelanes_Left1 = 43;
int Sidelanes_Right2 = 45;
int Target_Low = 26; 
int Target_High = 28; 
int Target_Vari1 = 31; 
int Target_Vari2 = 29; 
int Target_Vari3 = 27; 
int Target_Vari4 = 25; 
int Target_Vari5 = 30; 
int Spinner = 32;
int Rollunder = 34;
int Ballinplay = 36;
int Slingshots_Left_Right_Up = 33;
int Rubberband123 = 38;
int Kickout = 37;
int Bumper = 35;
int VariTarget = 24;
int BallRelease = 39;


//Pins activate Solenoids when High!//////////////////////////////////////////////////////////////////////////////////////
const int solenoidPin_Kickout = A15;
const int solenoidPin_Bumper = A14;
const int solenoidPin_VariTarget = A13;
const int solenoidPin_BallRelease = A12;

void setup()
{
randomSeed(analogRead(0));
/////////////LEDS///////////////////
 FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
 FastLED.addLeds<NEOPIXEL, DATA_PIN2>(ledsbig, NUM_LEDS2);
 FastLED.setBrightness(BRIGHTNESS);

/////General Illumination
ledsbig[0] = CHSV(70, 165, 255);// 
ledsbig[1] = CHSV(70, 0, 255);// 
ledsbig[2] = CHSV(70, 0, 255);// 
ledsbig[3] = CHSV(70, 205, 255);// 
ledsbig[4] = CHSV(70, 205, 255);// 
ledsbig[5] = CHSV(70, 205, 0);//   
ledsbig[6] = CHSV(70, 205, 255);// 
ledsbig[7] = CHSV(70, 205, 255);// 
ledsbig[8] = CHSV(70, 205, 255);//
ledsbig[9] = CHSV(70, 205, 255);// 
ledsbig[10] = CHSV(70, 205, 0);// 
ledsbig[11] = CHSV(70, 205, 255);// 
ledsbig[12] = CHSV(70, 205, 255);// 
ledsbig[13] = CHSV(70, 205, 255);// 
leds[37] = CHSV(150, 0, 255); //Bumper
 FastLED.show();
/////General Illuminsation


/////////////LEDS///////////////////
  
// Inputs
pinMode(Rollover_Lane1,INPUT_PULLUP);  //Rollover Lanes
pinMode(Rollover_Lane2,INPUT_PULLUP);  //Rollover Lanes
pinMode(Rollover_Lane3,INPUT_PULLUP);  //Rollover Lanes
pinMode(CaptiveBall1,INPUT_PULLUP);  //Captive Balls
pinMode(CaptiveBall2,INPUT_PULLUP);  //Captive Balls
pinMode(CaptiveBall3,INPUT_PULLUP);  //Captive Balls
pinMode(Outlanes_Links_Rechts,INPUT_PULLUP);  //Outlanes
pinMode(Sidelanes_Left1,INPUT_PULLUP);  //Sidelanes
pinMode(Sidelanes_Right2,INPUT_PULLUP);  //Sidelanes

pinMode(Target_Low,INPUT_PULLUP);  //Targets
pinMode(Target_High,INPUT_PULLUP);  //Targets
pinMode(Target_Vari1,INPUT_PULLUP);  //Vari_Target
pinMode(Target_Vari2,INPUT_PULLUP);  //Vari_Target
pinMode(Target_Vari3,INPUT_PULLUP);  //Vari_Target
pinMode(Target_Vari4,INPUT_PULLUP);  //Vari_Target
pinMode(Target_Vari5,INPUT_PULLUP);  //Vari_Target

pinMode(Slingshots_Left_Right_Up,INPUT_PULLUP);  //Spinner
pinMode(Rubberband123,INPUT_PULLUP);  //Spinner

pinMode(Spinner,INPUT_PULLUP);  //Spinner
pinMode(Rollunder,INPUT_PULLUP);  //Rollunder

pinMode(Ballinplay,INPUT_PULLUP);  //Ballinplay
pinMode(VariTarget,INPUT_PULLUP);  //VariTarget Control if hit
pinMode(BallRelease,INPUT_PULLUP);  //BallRelease Switch
pinMode(Bumper,INPUT_PULLUP);  //Bumper
pinMode(Kickout,INPUT_PULLUP);  //Bumper

pinMode(3, INPUT_PULLUP);  //Interrupt
//Outputs used to activate Solenoids//////////////////////////////////////////////////////////////////////////////////////
pinMode(solenoidPin_Kickout, OUTPUT);
pinMode(solenoidPin_Bumper, OUTPUT);
pinMode(solenoidPin_VariTarget, OUTPUT);
pinMode(solenoidPin_BallRelease, OUTPUT);

//deactivate all Solenoids just in case
digitalWrite(solenoidPin_Kickout, LOW); 
digitalWrite(solenoidPin_Bumper, LOW); 
digitalWrite(solenoidPin_VariTarget, LOW); 
digitalWrite(solenoidPin_BallRelease, LOW); 

Serial.begin(9600);
// Initialize the MAX7219 
//Serial.write("14CORE TEST CODE FOR LED MAX7219 LED TUBE\n");
lc.shutdown(0,false); // To Enable the Display 
lc.setIntensity(0,1); // To set the brightness level (0 is min, 15 is max) 
lc.clearDisplay(0); // To Clear the display register 
lc.shutdown(1,false); // To Enable the Display 
lc.setIntensity(1,1); // To set the brightness level (0 is min, 15 is max) 
lc.clearDisplay(1); // To Clear the display register 
//Serial.write("Solenoid Test   ");
//Serial.write(A13);
//Serial.write("\n");

}          //END SETUP


/////////////////////////////////////////////MAIN/////////////////////////////////////////////////////////////
void loop()
{


//EIFR = bit (INTF2);



if (AttractMode == 0) {


ATTRACT();

  
  } //END ATTRACT

if (AttractMode == 1)  {
//detachInterrupt(1);
//detachInterrupt (digitalPinToInterrupt (3)); 
//AttatchInteruptOnce = 0;   //Prevent the interrupt during the game


if (Startplay_ACTIVE == 0){

 for(int i = 0; i < NUM_LEDS; i++) {      //Turn off all the lights from the Attract mode
 leds[i] = CHSV(1, 255, 0); FastLED.show(); 
 };

    Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(9);              // sends x 
    Wire.endTransmission();    // stop transmitting

  
Serial.print("Startplay_ACTIVE\n");
    Startplay_ACTIVE = 1;
    ResetGame();
    Kickout_ball();
}

//Serial.print("MosfetChecks\n");
unsigned long currentMillis = millis();       //Starting Time
detectCollision();                              //Collision and Switch detection
control_lights();                              //Lights
check_conditions();                            //Checks for Bonuses

/////////////////////////////////////////////////////////////////////Timed Soneloid Triggers running in Main Loop///////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////MOSFET !///////////////////////////////////////////////////////////////////////////////////////////////

int difference = currentMillis - previousMillis;
int difference_vari_activate = currentMillis - previousMillis_vari_activate;
int difference_vari_deactivate = currentMillis - previousMillis_vari_deactivate;


 if ((difference >= interval)and (Bumper_Trigger == 1)) {
   previousMillis = currentMillis; 
  Bumper_Trigger = 0;
 digitalWrite(solenoidPin_Bumper, LOW);  //Bumper Solenoid deactivated
 Serial.print("Bumper de-activated \n");
 delay (10);
 
 }

if ((difference >= interval)and (Kickout_Trigger == 1)) {
   previousMillis = currentMillis; 
  Kickout_Trigger = 0;
 digitalWrite(solenoidPin_Kickout, LOW);  //Kickout Solenoid deactivated
 }

 if ((difference_vari_activate >= interval_vari_activate)and (Vari_Trigger == 0)) {
 previousMillis_vari_activate = currentMillis; 
 
 digitalWrite(solenoidPin_VariTarget, HIGH);  //Vari Solenoid activated
 Vari_Trigger = 1;
 Serial.write("vari Activated\n");
 
 }


 if ((difference_vari_deactivate >= interval_vari_deactivate)and (Vari_Trigger == 1)) {
 previousMillis_vari_deactivate = currentMillis; 
 Vari_Trigger = 2;
 digitalWrite(solenoidPin_VariTarget, LOW);  //Vari Solenoid deactivated
 Serial.write("vari automatic release-deactivated\n");
 
 Target_Vari5_int_last = LOW;   //Reset at this position to prevent counting the hits more than once. Only after coil reset a new
 Target_Vari4_int_last = LOW;   //Varit Hit will be registered.
 Target_Vari3_int_last = LOW;
 Target_Vari2_int_last = LOW;
 Target_Vari1_int_last = LOW;
 }


////////////////////////////////////////////////////////////////MOSFET End !////////////////////////////////////////////////////////

/////////////Timed Events_______Grace and Skill/////////////////////////////
int difference_grace = currentMillis - previousMillis_cap;

if ((difference_grace >= interval_grace_cap)and (Grace_Trigger == 1)) {
 previousMillis_cap = currentMillis; 
 Grace_Trigger = 0;
 
 }

int difference_skill = currentMillis - previousMillis_Skillshot;

if ((difference_skill >= interval_skillshot) and (Skillshot_active == 1) and (Ball_active == 1)) {
 Skillshot_active = 0;
 Ball_active = 0;
 Skillshot1_active = 0;
 Skillshot2_active = 0;
 Skillshot3_active = 0;
 
 }


/////////////Timed Events_______Grace and Skill/////////////////////////////



////////////////////////////////////////////////////////////////Solenoid Burn protection////////////////////////////////////////////////////////
if ((digitalRead(solenoidPin_VariTarget) == LOW) ){
  VariTargetBurnTime = 0;
  VariTargetBurnTimeBase = millis();
}
else if ((digitalRead(solenoidPin_VariTarget) == HIGH) ){
  VariTargetBurnTime = VariTargetBurnTime + (millis() - VariTargetBurnTimeBase); 
  VariTargetBurnTimeBase = millis();
}
if ((digitalRead(solenoidPin_Bumper) == LOW) ){
  BumperBurnTime = 0; 
  BumperBurnTimeBase = millis();
}
else if ((digitalRead(solenoidPin_Bumper) == HIGH) ){
  BumperBurnTime = BumperBurnTime  + (millis() - BumperBurnTimeBase); 
  BumperBurnTimeBase = millis();
}
if ((digitalRead(solenoidPin_Kickout) == LOW) ){
  KickoutBurnTime = 0; 
  KickoutBurnTimeBase = millis(); 
}
else if ((digitalRead(solenoidPin_Kickout) == HIGH) ){
  KickoutBurnTime = KickoutBurnTime + (millis() - KickoutBurnTimeBase); 
  KickoutBurnTimeBase = millis(); 
}
if ((digitalRead(solenoidPin_BallRelease) == LOW) ){
  ReleaseBurnTime = 0; 
  ReleaseBurnTimeBase = millis();
}
else if ((digitalRead(solenoidPin_BallRelease) == HIGH) ){
  ReleaseBurnTime = ReleaseBurnTime + (millis() - ReleaseBurnTimeBase); 
   ReleaseBurnTimeBase = millis();
}

//Serial.print("BumperBurnTime is ");Serial.print(BumperBurnTime);Serial.print("\n");

if ((VariTargetBurnTime > SolenoidOnFireTime) || (BumperBurnTime > SolenoidOnFireTime) || (KickoutBurnTime > SolenoidOnFireTime) || (ReleaseBurnTime > SolenoidOnFireTime)){
  digitalWrite(solenoidPin_VariTarget, LOW);  //Vari Solenoid deactivated
  digitalWrite(solenoidPin_Bumper, LOW);  //Vari Solenoid deactivated
  digitalWrite(solenoidPin_Kickout, LOW);  //Vari Solenoid deactivated
  digitalWrite(solenoidPin_BallRelease, LOW);  //Vari Solenoid deactivated
  
  while(1){
    //Endless Loop. Prevents the re-activation of a solenoid due to a stuck switch. All solenoids have to be de-activated to be on the safe side.
  Serial.print("Burnprotection ");Serial.print(VariTargetBurnTime);Serial.print(BumperBurnTime);Serial.print(KickoutBurnTime);Serial.print(ReleaseBurnTime);Serial.print("\n");
  
  }
}



////////////////////////////////////////////////////////////////Solenoid Burn protection END////////////////////////////////////////////////////////
}
}
//////////////////Main END//////////voids//////////////////////////////////////////////////////////////////////////////////////

/////////Routine for setting Lights//////////////////////////////
void control_lights(){
  ////////////////Activated Lights////////////////
if (Torpedo1_active == 1){
  leds[17] = CHSV(50, 0, 255);
 }
if (Torpedo2_active == 1){
  leds[16] = CHSV(50, 0, 255);
 }
if (Torpedo3_active == 1){
  leds[15] = CHSV(50, 0, 255);
 }
if (Torpedo1_active == 0){
  leds[17] = CHSV(50, 0, 0);
 }
if (Torpedo2_active == 0){
  leds[16] = CHSV(50, 0, 0);
 }
if (Torpedo3_active == 0){
  leds[15] = CHSV(50, 0, 0);
 }
if (Torpedo1_primer == 1){
   leds[0] = CHSV(155, 255, 255);
   leds[18] = CHSV(150, 255, 255);
    
    if ( (Skillshot1_active == 1) and (Skillshot_active == 1)) {                 //Turn red when Skillshot is active
    leds[0] = CHSV(255, 255, 255);
  }
 
 
 }
if (Torpedo1_primer == 0){
   leds[0] = CHSV(155, 255, 0);
   leds[18] = CHSV(150, 255, 0);
      
 }
if (Torpedo2_primer == 1){
   leds[1] = CHSV(155, 255, 255);
   leds[23] = CHSV(150, 255, 255); //lane2
   
   if ( (Skillshot2_active == 1) and (Skillshot_active == 1)) {                 //Turn red when Skillshot is active
    leds[1] = CHSV(255, 255, 255);
  }
   
 }
if (Torpedo2_primer == 0){
   leds[1] = CHSV(155, 255, 0);
   leds[23] = CHSV(150, 255, 0); //lane2
 }
if (Torpedo3_primer == 1){
   leds[2] = CHSV(155, 255, 255);
   if ( (Skillshot3_active == 1) and (Skillshot_active == 1)) {                      //Turn red when Skillshot is active
    leds[2] = CHSV(255, 255, 255);
   }
   }
if (Torpedo3_primer == 0){
   leds[2] = CHSV(155, 255, 0);
 }
if (Vari_Bonus_active == 1){
   leds[21] = CHSV(50, 0, 255);  //vari
   ledsbig[5] = CHSV(70, 205, 255);//   VariBonus?`??
 }
if (Vari_Bonus_active == 0){
   leds[21] = CHSV(50, 0, 0);  //vari
   ledsbig[5] = CHSV(70, 205, 0);//   VariBonus?`??
 }  
if (Bonus_low_target == 1){
  leds[22] = CHSV(50, 1, 255);  //targetlow
 }
if (Bonus_low_target == 0){
   leds[22] = CHSV(50, 1, 0);  //targetlow
 } 

for (int t=24; t<36;t++){  //Turns off all ship lights. They are subsequently re-lit according to the Bonus and Ship Sunk scores
 leds[t] = CHSV(50, 1, 0);  //
}
if (Bonus_temp > 0){
  if (Bonus_temp == 1){
    leds[33] = CHSV(50, 1, 255); //10k
  }
  if (Bonus_temp == 2){
   leds[31] = CHSV(50, 1, 255); //20k
  }
 if (Bonus_temp == 3){
    leds[34] = CHSV(50, 1, 255); //30k 
  }
 if (Bonus_temp == 4){
   leds[30] = CHSV(50, 1, 255); //40k
  }
 if (Bonus_temp == 5){
  leds[35] = CHSV(50, 1, 255); //50k
  }
  if (Bonus_temp == 6){
  leds[29] = CHSV(50, 1, 255); //60k
  }
 if (Bonus_temp == 7){
 leds[27] = CHSV(50, 1, 255);  //70k
  }
 if (Bonus_temp == 8){
  leds[28] = CHSV(50, 1, 255); //80k
  }
 if (Bonus_temp == 9){
 leds[26] = CHSV(50, 1, 255);   //90k
  }
if (Bonus_temp == 10){
    leds[25] = CHSV(50, 1, 255);  //100k
  }
}
  
if (Ships_sunk > 0){
  if (Ships_sunk == 1){
    leds[25] = CHSV(50, 1, 255);  //100k
  }
  if (Ships_sunk == 2){
    leds[25] = CHSV(50, 1, 255);  //100k
    leds[26] = CHSV(50, 1, 255);   //90k
  }
  if (Ships_sunk == 3){
    leds[25] = CHSV(50, 1, 255);  //100k
    leds[26] = CHSV(50, 1, 255);   //90k
    leds[28] = CHSV(50, 1, 255); //80k
  }
  if (Ships_sunk == 4){
    leds[25] = CHSV(50, 1, 255);  //100k
    leds[26] = CHSV(50, 1, 255);   //90k
    leds[28] = CHSV(50, 1, 255); //80k
    leds[27] = CHSV(50, 1, 255);  //70k
  }
 if (Ships_sunk == 5){
    leds[25] = CHSV(50, 1, 255);  //100k
    leds[26] = CHSV(50, 1, 255);   //90k
    leds[28] = CHSV(50, 1, 255); //80k
    leds[27] = CHSV(50, 1, 255);  //70k
    leds[29] = CHSV(50, 1, 255); //60k
  }
 if (Ships_sunk == 6){
    leds[25] = CHSV(50, 1, 255);  //100k
    leds[26] = CHSV(50, 1, 255);   //90k
    leds[28] = CHSV(50, 1, 255); //80k
    leds[27] = CHSV(50, 1, 255);  //70k
    leds[29] = CHSV(50, 1, 255); //60k
    leds[35] = CHSV(50, 1, 255); //50k
  }
 if (Ships_sunk == 7){
    leds[25] = CHSV(50, 1, 255);  //100k
    leds[26] = CHSV(50, 1, 255);   //90k
    leds[28] = CHSV(50, 1, 255); //80k
    leds[27] = CHSV(50, 1, 255);  //70k
    leds[29] = CHSV(50, 1, 255); //60k
    leds[35] = CHSV(50, 1, 255); //50k
    leds[30] = CHSV(50, 1, 255); //40k
  }
 if (Ships_sunk == 8){
    leds[25] = CHSV(50, 1, 255);  //100k
    leds[26] = CHSV(50, 1, 255);   //90k
    leds[28] = CHSV(50, 1, 255); //80k
    leds[27] = CHSV(50, 1, 255);  //70k
    leds[29] = CHSV(50, 1, 255); //60k
    leds[35] = CHSV(50, 1, 255); //50k
    leds[30] = CHSV(50, 1, 255); //40k
    leds[34] = CHSV(50, 1, 255); //30k 
  }
  if (Ships_sunk == 9){
    leds[25] = CHSV(50, 1, 255);  //100k
    leds[26] = CHSV(50, 1, 255);   //90k
    leds[28] = CHSV(50, 1, 255); //80k
    leds[27] = CHSV(50, 1, 255);  //70k
    leds[29] = CHSV(50, 1, 255); //60k
    leds[35] = CHSV(50, 1, 255); //50k
    leds[30] = CHSV(50, 1, 255); //40k
    leds[34] = CHSV(50, 1, 255); //30k 
    leds[31] = CHSV(50, 1, 255); //20k
  }
if (Ships_sunk == 10){
    leds[25] = CHSV(50, 1, 255);  //100k
    leds[26] = CHSV(50, 1, 255);   //90k
    leds[28] = CHSV(50, 1, 255); //80k
    leds[27] = CHSV(50, 1, 255);  //70k
    leds[29] = CHSV(50, 1, 255); //60k
    leds[35] = CHSV(50, 1, 255); //50k
    leds[30] = CHSV(50, 1, 255); //40k
    leds[34] = CHSV(50, 1, 255); //30k 
    leds[31] = CHSV(50, 1, 255); //20k
    leds[33] = CHSV(50, 1, 255); //10k
  }
}
for (int t=3; t<14;t++){  //Turns off all torpedo lights. They are subsequently re-lit according to the Torpedo scores
 leds[t] = CHSV(50, 1, 0);  //
}
if (Torpedo_Bonus > 0){
  int Torpedolight = Torpedo_Bonus + 3;
  leds[Torpedolight] = CHSV(25, 1, 255);
}
if (DoubleBonus == 1){
leds[32] = CHSV(230, 255, 255); //DoubleBonus
}

if (Kickout_Bonus == 1){
  ledsbig[10] = CHSV(70, 205, 255);// ExtraBall?
}

////////////////Activated Lights////////////////


  FastLED.show(); 
}


//Main Routine for detecting Conditions//////////////////////////////////////////////////////////////////////////////////////
void check_conditions(){


if ((VariTorpedo1 == 1)&&(VariTorpedo2 == 1)&&(VariTorpedo3 == 1)&&(Vari_Bonus_active == 0)){          //Activation of VariBonus
  
  allTorpedosactive();
}

if ((VariTorpedo1 == 1)&&(VariTorpedo2 == 1)&&(VariTorpedo3 == 1)&&(Kickout_Bonus == 0) && (DoubleBonus == 1)&& (Oncepergame == 0)){
  Kickout_Bonus = 1;  //Allows for Extra Ball
  Oncepergame = 1; //Only one extra Ball per game
  Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(15);              // sends x 
    Wire.endTransmission();    // stop transmitting
}


}
//Main Routine for detecting Conditions//////////////////////////////////////////////////////////////////////////////////////

//Main Routine for detecting Events and Scoring////////////////////////////////////////////////////////////////////////

void detectCollision(){   
//Serial.print("Collision Check\n");
//Definition of Sensor Reads
int Rollover_Lane1_int = digitalRead(Rollover_Lane1);  //Variable for Rollover Lanes
int Rollover_Lane2_int = digitalRead(Rollover_Lane2);  //Variable for Rollover Lanes
int Rollover_Lane3_int = digitalRead(Rollover_Lane3);  //Variable for Rollover Lanes

int CaptiveBall1_int = digitalRead(CaptiveBall1);  //Variable for CaptiveBalls
int CaptiveBall2_int = digitalRead(CaptiveBall2);  //Variable for CaptiveBalls
int CaptiveBall3_int = digitalRead(CaptiveBall3);  //Variable for CaptiveBalls

int Outlanes_Links_Rechts_int = digitalRead(Outlanes_Links_Rechts);  //Variable for Outlanes Links Rechts
int Sidelanes_Left1_int = digitalRead(Sidelanes_Left1);  //Variable for Sidelanes Left
int Sidelanes_Right2_int = digitalRead(Sidelanes_Right2);  //Variable for Sidelanes rigth

int Target_Low_int = digitalRead(Target_Low);  //Variable for Target_Low
int Target_High_int = digitalRead(Target_High);  //Variable for Target_High
int Target_Vari1_int = digitalRead(Target_Vari1);  //Variable for Target_Vari1
int Target_Vari2_int = digitalRead(Target_Vari2);  //Variable for Target_Vari1
int Target_Vari3_int = digitalRead(Target_Vari3);  //Variable for Target_Vari1
int Target_Vari4_int = digitalRead(Target_Vari4);  //Variable for Target_Vari1
int Target_Vari5_int = digitalRead(Target_Vari5);  //Variable for Target_Vari1

int Spinner_int = digitalRead(Spinner);  //Variable for Spinner
int Rollunder_int = digitalRead(Rollunder);  //Variable for Rollunder

int Ballinplay_int = digitalRead(Ballinplay);  //Variable for Ballinplay Switch
int Slingshots_Left_Right_Up_int = digitalRead(Slingshots_Left_Right_Up);  //Variable for Slingshots
int Rubberband123_int = digitalRead(Rubberband123);  //Variable for Rubberband123
int Kickout_int = digitalRead(Kickout);  //Variable for Kickout Switch
int Bumper_int = digitalRead(Bumper);  //Variable for Bumper Switch
int VariTarget_int = digitalRead(VariTarget);  //Variable for VariTarget Switch
int BallRelease_int = digitalRead(BallRelease);  //Variable for BallRelease Switch

int Startbutton = digitalRead(3);  //Variable for Startbutton

//End of Definition of Sensor Reads End//////////////////////////////////////////////////////////////////////////////////////

//Definition of Events upon activating a Sensor//////////////////////////////////////////////////////////////////////////////////////

//Switches 1-3//////////////////////////////////////////////////////////////////////////////////////

if ((Ballinplay_int == LOW) && (Ballinplay_int_last == LOW)  && (Skillshot_active == 1)){      //Ball in Play and Skillshot is active
  Ballinplay_int_last = HIGH;
  Skillshot_Timer();
  Ball_active = 1;
}
else if ((Ballinplay_int == HIGH) && (Ballinplay_int_last == HIGH)  ){    //Ball in Play  released
 Ballinplay_int_last = LOW; 
delay (150);
}

if ((Rollover_Lane1_int == LOW) && (Rollover_Lane1_int_last == LOW)  ){      //Rollover_Lane1 triggered

Rollover_Lane1_event();   //Events triggered
Rollover_Lane1_int_last = HIGH;
Serial.print("Rollover1\n"); 
delay (MilliRoll);
}
else if ((Rollover_Lane1_int == HIGH) && (Rollover_Lane1_int_last == HIGH)  ){    //Rollover_Lane1 released
 Rollover_Lane1_int_last = LOW; 
delay (MilliRoll);
}

if ((Rollover_Lane2_int == LOW) && (Rollover_Lane2_int_last == LOW)  ){      //Rollover_Lane2 triggered

Rollover_Lane2_event();   //Events triggered
Rollover_Lane2_int_last = HIGH;
Serial.print("Rollover2\n"); 
delay (MilliRoll);
}
else if ((Rollover_Lane2_int == HIGH) && (Rollover_Lane2_int_last == HIGH)  ){    //Rollover_Lane2 released
 Rollover_Lane2_int_last = LOW; 
delay (MilliRoll);
}
if ((Rollover_Lane3_int == LOW) && (Rollover_Lane3_int_last == LOW)  ){      //Rollover_Lane3 triggered

Rollover_Lane3_event();   //Events triggered
Rollover_Lane3_int_last = HIGH;
Serial.print("Rollover3\n"); 
delay (MilliRoll);
}
else if ((Rollover_Lane3_int == HIGH) && (Rollover_Lane3_int_last == HIGH)  ){    //Rollover_Lane3 released
 Rollover_Lane3_int_last = LOW; 
delay (MilliRoll);
}

//End of Switches 1-3 //////////////////////////////////////////////////////////////////////////////////////

//CaptiveBalls 1-3//////////////////////////////////////////////////////////////////////////////////////
if ((CaptiveBall1_int == LOW) && (CaptiveBall1_int_last == LOW) && (Grace_Trigger == 0) ){      //CaptiveBall1_int triggered Grace_Trigger prevents double Activation by captive Balls
Grace_Trigger = 1 ;
CaptiveBall1_int_last = HIGH;
    Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(10);              // sends x 
    Wire.endTransmission();    // stop transmitting

CaptiveBall1_event();   //Events triggered
Serial.print("Captive1\n"); 
delay (MilliRoll);
}
else if ((CaptiveBall1_int == HIGH) && (CaptiveBall1_int_last == HIGH)  ){    //CaptiveBall1_int released
 CaptiveBall1_int_last = LOW;
 Serial.print("Captive1 released\n"); 
delay (MilliRoll);
}

if ((CaptiveBall2_int == LOW) && (CaptiveBall2_int_last == LOW) && (Grace_Trigger == 0) ){      //CaptiveBall2_int triggered
Grace_Trigger = 1 ;
    Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(10);              // sends x 
    Wire.endTransmission();    // stop transmitting

CaptiveBall2_event();   //Events triggered
CaptiveBall2_int_last = HIGH;
Serial.print("Captive2\n"); 
delay (MilliRoll);
}
else if ((CaptiveBall2_int == HIGH) && (CaptiveBall2_int_last == HIGH)  ){    //CaptiveBall2_int released
 CaptiveBall2_int_last = LOW; 
  Serial.print("Captive2 released\n");
delay (MilliRoll);
}

if ((CaptiveBall3_int == LOW) && (CaptiveBall3_int_last == LOW) && (Grace_Trigger == 0) ){      //CaptiveBall3_int triggered
Grace_Trigger = 1 ;
    Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(10);              // sends x 
    Wire.endTransmission();    // stop transmitting
CaptiveBall3_event();   //Events triggered
CaptiveBall3_int_last = HIGH;
Serial.print("Captive3\n"); 
delay (MilliRoll);
}
else if ((CaptiveBall3_int == HIGH) && (CaptiveBall3_int_last == HIGH)  ){    //CaptiveBall3_int released
 CaptiveBall3_int_last = LOW;
  Serial.print("Captive3 released\n"); 
delay (MilliRoll);
}

//End of CaptiveBalls 1-3 //////////////////////////////////////////////////////////////////////////////////////

//Vari Bonus/////////////////////////////////////////////


//Vari Bonus/////////////////////////////////////////////

//Slingshot //////////////////////////////////////////////////////////////////////////////////////

if ((Slingshots_Left_Right_Up_int == LOW) && (Slingshots_Left_Right_Up_int_last == LOW)  ){      //Slingshots_Left_Right_Up_int triggered
Slingshots_Left_Right_Up_int_last = HIGH;
Slingshot_event();   //Events triggered
Serial.print("Slingshot\n"); 
Serial.print(Slingshots_Left_Right_Up_int ); 
Serial.print(Slingshots_Left_Right_Up_int_last); 
Wire.begin();Wire.beginTransmission(9); // transmit to device #9
Wire.write(2);              // sends x 
Wire.endTransmission();    // stop transmitting

}
else if ((Slingshots_Left_Right_Up_int == HIGH) && (Slingshots_Left_Right_Up_int_last == HIGH)  ){    //Slingshots_Left_Right_Up_int released
 Slingshots_Left_Right_Up_int_last = LOW; 
 delay (20);  //possibly too long for Bumper
}

//End of Slingshot //////////////////////////////////////////////////////////////////////////////////////

//Spinner////////////////////////////////////////////////////////////////////////
if ((digitalRead(Spinner) == LOW) ){
 Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(3);              // sends x 
    Wire.endTransmission();    // stop transmitting
Spinnerf();
Serial.print("Spinner1\n"); 
}
//End of Spinner////////////////////////////////////////////////////////////////////////

//Rollunder////////////////////////////////////////////////////////////////////////
if ((Rollunder_int == LOW) && (Rollunder_int_last == LOW)  ){   //Rollunder is triggered
Rollunder_int_last = HIGH;
 Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(5);              // sends x 
    Wire.endTransmission();    // stop transmitting
Rollunderf();
Serial.print("Rollunder\n");
delay (MilliRoll); 
}
else if ((Rollunder_int == HIGH) && (Rollunder_int_last == HIGH)  ){    //Rollunder released
 Rollunder_int_last = LOW; 
 Serial.print("Rollunder released\n");
 delay (MilliRoll);

}
//End of Rollunder////////////////////////////////////////////////////////////////////////

//Rubberbands //////////////////////////////////////////////////////////////////////////////////////

if ((Rubberband123_int == LOW) && (Rubberband123_int_last == LOW)  ){      //Rubberband123 triggered
 Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(14);              // sends x 
    Wire.endTransmission();    // stop transmitting
Rubberband123_event();   //Events triggered
Rubberband123_int_last = HIGH;
Serial.print("Rubber\n"); 
delay (MilliRoll);
}
else if ((Rubberband123_int == HIGH) && (Rubberband123_int_last == HIGH)  ){    //Rubberband123 released
 Rubberband123_int_last = LOW; 
 
delay (MilliRoll);
}
//End of Rubberbands //////////////////////////////////////////////////////////////////////////////////////

//Sidelanes 1 and 2 //////////////////////////////////////////////////////////////////////////////////////

if ((Sidelanes_Left1_int == LOW) && (Sidelanes_Left1_int_last == LOW)  ){      //Sidelanes_Left1_int triggered
Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(11);              // sends x 
    Wire.endTransmission();    // stop transmitting
Sidelane1_event();   //Events triggered
Sidelanes_Left1_int_last = HIGH;
Serial.print("Side1\n"); 
}
else if ((Sidelanes_Left1_int == HIGH) && (Sidelanes_Left1_int_last == HIGH)  ){    //Sidelanes_Left1_int released
 Sidelanes_Left1_int_last = LOW; 
 
delay (MilliRoll);
}

//////////
if ((Sidelanes_Right2_int == LOW) && (Sidelanes_Right2_int_last == LOW)  ){      //Sidelanes_Right2_int triggered
Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(11);              // sends x 
    Wire.endTransmission();    // stop transmitting
Sidelane2_event();   //Events triggered
Sidelanes_Right2_int_last = HIGH;
Serial.print("Side2\n"); 
}
else if ((Sidelanes_Right2_int == HIGH) && (Sidelanes_Right2_int_last == HIGH)  ){    //Sidelanes_Right2_int released
 Sidelanes_Right2_int_last = LOW; 
 
delay (MilliRoll);
}

//End of Sidelanes //////////////////////////////////////////////////////////////////////////////////////

//Outlanes 1 and 2 //////////////////////////////////////////////////////////////////////////////////////

if ((Outlanes_Links_Rechts_int == LOW) && (Outlanes_Links_Rechts_int == LOW)  ){      //Outlanes_Links_Rechts_intt triggered
    Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(11);              // sends x 
    Wire.endTransmission();    // stop transmitting
Outlanes_Links_Rechts_int_last = HIGH;
Outlane_event();   //Events triggered
Serial.print("Outlanes\n"); 
}
else if ((Outlanes_Links_Rechts_int == HIGH) && (Outlanes_Links_Rechts_int_last == HIGH)  ){    //Outlanes_Links_Rechts_int released
 Outlanes_Links_Rechts_int_last = LOW; 
 
delay (MilliRoll);
}

// Target Routine////////////////////////////////////////////////////////////////////////////////////


if ((Target_Low_int == LOW) && (Target_Low_int_last == LOW)  ){      //Low Target hit
Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(4);              // sends x 
    Wire.endTransmission();    // stop transmitting
Target_low_event();
Target_Low_int_last = HIGH;
 delay (MilliRoll); 
 Serial.print("Target_low\n"); 
}

else if ((Target_Low_int == HIGH) && (Target_Low_int_last  == HIGH)  ){ //Target released
 Target_Low_int_last = LOW;
 delay (MilliRoll); 
}

if ((Target_High_int == LOW) && (Target_High_int_last == LOW)  ){      //Low Target hit
Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(4);              // sends x 
    Wire.endTransmission();    // stop transmitting
Target_High_event();
Target_High_int_last = HIGH;
 delay (MilliRoll); 
 Serial.print("Target_High\n"); 
}

else if ((Target_High_int == HIGH) && (Target_High_int_last  == HIGH)  ){ //Target released
 Target_High_int_last = LOW;
 delay (MilliRoll); 
}
////////////Vari Target    The vari Target has 5 positions and a "check" switch.There has to be a tiny delay between triggering the
//check switch and the evaluation of the actual position. Testing with  50ms.
//The first postition doesn't have a different switch, if no other switch is triggered it is considered position 1.

if ((VariTarget_int == LOW) && (VariTarget_int_last == LOW)  ){      //Vari Target hit
VariTarget_int_last = HIGH;
delay (200);            //Small delay in front of the Evaluation
Target_vari_event();        //Evaluation Event for Vari Target

 
}
else if ((VariTarget_int == HIGH) && (VariTarget_int_last == HIGH)  ){ //Vari Target released
 VariTarget_int_last = LOW;
 delay (MilliRoll); 
}

////////////Vari Target    

// End of Target Routine ////////////////////////////////////////////////////////////////////////////////////

//Solenoids

if ((Bumper_int == LOW)  && (Bumper_int_last == LOW)){   //Bumper has been triggered
Bumper_int_last = HIGH;
Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(1);              // sends x 
    Wire.endTransmission();    // stop transmitting
Serial.print("Bumper Event triggered \n");
Bumper_Event();
 
}
else if ((Bumper_int == HIGH) && (Bumper_int_last  == HIGH)  ){ //bumper released
 
 Serial.print("Bumper_int_last reseted \n");
 delay (10);

 Bumper_int_last = LOW;
}




if ((Kickout_int == LOW) && (Kickout_int_last == LOW)  ){   //Kickout has been triggered
Kickout_int_last = HIGH;
Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(5);              // sends x 
    Wire.endTransmission();    // stop transmitting
delay (1000);  //Ball rests in Kickout position, time to let it settle.



Kickout_Event();
Serial.print("Kickout\n"); 
}
else if ((Kickout_int == HIGH) && (Kickout_int_last  == HIGH)  ){ //Kickout released
 Kickout_int_last = LOW;
 delay (MilliRoll); 
}

if ((digitalRead(BallRelease) == LOW) && (BallRelease_int_last  == LOW)){
BallRelease_int_last = HIGH;
Releasef();
Serial.print("Release\n"); 
}
else if ((digitalRead(BallRelease) == HIGH) && (BallRelease_int_last  == HIGH)  ){ //BallRelease released
 BallRelease_int_last = LOW;
 delay (MilliRoll); 
}

}

//END of Main Routine for detecting Events and Scoring//////////////////////////////////////////////////////////////////////////////////////

//void interruptstart(){      //  ISR!
//  
//    AttractMode = 1;
//    Serial.print("Interrupt Triggered\n"); 
//    detachInterrupt (digitalPinToInterrupt (3)); 
//    AttatchInteruptOnce = 0;   //Prevent the interrupt during the game
//  }




void Bumper_Event(){
  
Score = Score +100;             //Bumper awards 100 points and advances the Torpedo counter

  
previousMillis = millis(); 
digitalWrite(solenoidPin_Bumper, HIGH);   //Bumper Solenoid activated !

Serial.print("Bumper activated \n");
Serial.print('solenoidPin_Bumper'); 
Scoring();     //Show Score
Torpedos_count();
leds[37] = CHSV(random8(),255,255); //Bumper 
  FastLED.show();
delay(30);
Bumper_Trigger = 1 ;
  }

void Kickout_Event(){
Score = Score +1000;             //Kickout awards 100 pints and advances the Torpedo counter
Torpedos_count();
Scoring();     //Show Score

 
 
 if (Kickout_Bonus == 1) {   //if Kickout Bonus is active awards an active Ball
   MaxBalls +=1;
   Kickout_Bonus = 0;
    Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(15);              // sends x 
    Wire.endTransmission();    // stop transmitting
 }

  
previousMillis = millis(); 
digitalWrite(solenoidPin_Kickout, HIGH);   //Kickout Solenoid activated !
Kickout_Trigger = 1 ;
Serial.print("KICKOUT  activated \n"); 
delay(Milli_Bumper);
  
}


void Target_vari_event(){ //Evaluates which position has been hit in on the Vari Target/////////////////////////////////////////////////////////////

int Target_Vari1_int = digitalRead(Target_Vari1);  //Variable for Target_Vari2
int Target_Vari2_int = digitalRead(Target_Vari2);  //Variable for Target_Vari3
int Target_Vari3_int = digitalRead(Target_Vari3);  //Variable for Target_Vari4
int Target_Vari4_int = digitalRead(Target_Vari4);  //Variable for Target_Vari5
int Target_Vari5_int = digitalRead(Target_Vari5);  //Variable for Target_Vari X //Not Used ! Position 5 on the target is too far back to score.
Vari_top_bottom = 0;
delay(50);

Serial.print("Vari activated. Beginning Evaluation "); 
Serial.print("Vari_top_bottom is"); Serial.print(Vari_top_bottom);Serial.print(" The Readout for 12345 is: ");  Serial.print(Target_Vari1_int); Serial.print(Target_Vari2_int); Serial.print(Target_Vari3_int); Serial.print(Target_Vari4_int); Serial.print(Target_Vari5_int); 

if ((Target_Vari4_int == LOW) && (Target_Vari4_int_last == LOW) && (Vari_top_bottom == 0) ){      //Vari Target position 5 hit
  Target_Vari4_int_last == HIGH;
  if (Vari_Bonus_active == 0) {   //if Vari Bonus is active awards additional Bonuses
  Score = Score +5000;
  Scoring(); 
  }
  else if (Vari_Bonus_active == 1){
     Score = Score +50000; 
       for (int u=0; u<5;u++){
       Bonus_count(); 
       }

       Torpedo1_active = 0;   //Deactivating the torpedos after VariBonus has been claimed
       Torpedo2_active = 0;
       Torpedo3_active = 0;
       VariTorpedo1 = 0;
       VariTorpedo2 = 0;
       VariTorpedo3 = 0;
       Vari_Bonus_active = 0;
       Torpedo1_primer = 1;   //and activating the primers again
       Torpedo2_primer = 1;
       Torpedo3_primer = 1;
  }
Vari_top_bottom = 1;      //locks the rest of the detection
Serial.print("Vari 5 activated\n"); 
}


if ((Target_Vari3_int == LOW) && (Target_Vari3_int_last == LOW) && (Vari_top_bottom == 0) ){      //Vari Target position 4 hit
  Target_Vari3_int_last == HIGH;
  if (Vari_Bonus_active == 0) {   //if Vari Bonus is active awards additional Bonuses
  Score = Score +4000; 
  Scoring();
  }
  else if (Vari_Bonus_active == 1){
     
       for (int u=0; u<4;u++){
       Bonus_count(); 
       }

       Torpedo1_active = 0;   //Deactivating the torpedos after VariBonus has been claimed
       Torpedo2_active = 0;
       Torpedo3_active = 0;
        VariTorpedo1 = 0;
       VariTorpedo2 = 0;
       VariTorpedo3 = 0;
       Vari_Bonus_active = 0;
       Torpedo1_primer = 1;   //and activating the primers again
       Torpedo2_primer = 1;
       Torpedo3_primer = 1;
  }
Vari_top_bottom = 1;      //locks the rest of the detection
Serial.print("Vari 4 activated\n"); 
}


if ((Target_Vari2_int == LOW) && (Target_Vari2_int_last == LOW) && (Vari_top_bottom == 0) ){      //Vari Target position 3 hit
  Target_Vari2_int_last == HIGH;
  if (Vari_Bonus_active == 0) {   //if Vari Bonus is active awards additional Bonuses
  Score = Score +3000; 
  Scoring();
  }
  else if (Vari_Bonus_active == 1){
     
       for (int u=0; u<3;u++){
       Bonus_count(); 
       }

       Torpedo1_active = 0;   //Deactivating the torpedos after VariBonus has been claimed
       Torpedo2_active = 0;
       Torpedo3_active = 0;
        VariTorpedo1 = 0;
       VariTorpedo2 = 0;
       VariTorpedo3 = 0;
       Vari_Bonus_active = 0;
       Torpedo1_primer = 1;   //and activating the primers again
       Torpedo2_primer = 1;
       Torpedo3_primer = 1;
  }
Vari_top_bottom = 1;      //locks the rest of the detection
Serial.print("Vari 3 activated\n"); 
}


if ((Target_Vari1_int == LOW) && (Target_Vari1_int_last == LOW) && (Vari_top_bottom == 0) ){      //Vari Target position 2 hit
  Target_Vari1_int_last == HIGH;
  if (Vari_Bonus_active == 0) {   //if Vari Bonus is active awards additional Bonuses
  Score = Score +2000; 
  Scoring();
  }
  else if (Vari_Bonus_active == 1){
     
       for (int u=0; u<2;u++){
       Bonus_count(); 
       }

       Torpedo1_active = 0;   //Deactivating the torpedos after VariBonus has been claimed
       Torpedo2_active = 0;
       Torpedo3_active = 0;
        VariTorpedo1 = 0;
       VariTorpedo2 = 0;
       VariTorpedo3 = 0;
       Vari_Bonus_active = 0;
       Torpedo1_primer = 1;   //and activating the primers again
       Torpedo2_primer = 1;
       Torpedo3_primer = 1;
  }
Vari_top_bottom = 1;      //locks the rest of the detection
Serial.print("Vari 2 activated\n"); 
}

else if (Vari_top_bottom == 0) {    //if nothing else is hit = Position 1
  
   if (Vari_Bonus_active == 0) {   //if Vari Bonus is active awards additional Bonuses
  Score = Score +1000; 
 Scoring();
  }
  else if (Vari_Bonus_active == 1){
     
       for (int u=0; u<1;u++){
       Bonus_count(); 
       }

       Torpedo1_active = 0;   //Deactivating the torpedos after VariBonus has been claimed
       Torpedo2_active = 0;
       Torpedo3_active = 0;
        VariTorpedo1 = 0;
       VariTorpedo2 = 0;
       VariTorpedo3 = 0;
       Vari_Bonus_active = 0;
       Torpedo1_primer = 1;   //and activating the primers again
       Torpedo2_primer = 1;
       Torpedo3_primer = 1;
  }
Vari_top_bottom = 1;      //locks the rest of the detection
Serial.print("Vari 1 activated\n"); 
}



previousMillis_vari_activate = millis(); 
previousMillis_vari_deactivate = millis(); 
Vari_Trigger = 0;
//Serial.print("Vari activated\n"); 
//delay (400); //test           Delay is too long. VariCoil has to be activated by TimedEvent.
//digitalWrite(solenoidPin_VariTarget, HIGH);   //Vari Target Solenoid activated !  
//Vari_Trigger = 1;

delay(Milli_Bumper);
}// End of Evaluation which position has been hit in on the Vari Target/////////////////////////////////////////////////////////////
  



//End of Solenoid Events

//Detailed Events//////////////////////////////////////////////////////////////////////////////////////


void Spinnerf(){
Score = Score +100;
Scoring();     //Show Score
delay(50);
}

void Rollunderf() {
Score = Score +5000;
Bonus_count(); 
Scoring();     //Show Score
delay(50);
}

void Rubberband123_event (){
Torpedos_count();
}


void Rollover_Lane1_event(){  //The Rollovers each give 1000 points and activate the Torpedos for the captured balls.
if (Torpedo1_primer == 1){  
  Torpedo1_active =1;
  Torpedo1_primer =0;
   
if ((Skillshot1_active == 1) and (Skillshot_active == 1)) {       //Check for Skillshot
  Score = Score +5000;
  Skillshot1_active = 0;
  Skillshot_active = 0;
    Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(13);              // sends x 
    Wire.endTransmission();    // stop transmitting
}
   


}
    Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(11);              // sends x 
    Wire.endTransmission();    // stop transmitting
Score = Score +1000;
Scoring();     //Show Score
delay(Milli);
}

void Rollover_Lane2_event(){    //The Rollovers each give 1000 points and activate the Torpedos for the captured balls.
if (Torpedo2_primer == 1){
  Torpedo2_active =1;
  Torpedo2_primer =0;
   
 if ((Skillshot2_active == 1) and (Skillshot_active == 1)) {       //Check for Skillshot
  Score = Score +5000;
  Skillshot2_active = 0;
  Skillshot_active = 0;
    Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(13);              // sends x 
    Wire.endTransmission();    // stop transmitting
}
}
 Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(11);              // sends x 
    Wire.endTransmission();    // stop transmitting
Score = Score +1000;
Scoring();     //Show Score
delay(Milli);
}
void Rollover_Lane3_event(){    //The Rollovers each give 1000 points and activate the Torpedos for the captured balls.
if (Torpedo3_primer == 1){
  Torpedo3_active =1;
  Torpedo3_primer =0;
   
 if ((Skillshot3_active == 1) and (Skillshot_active == 1)) {       //Check for Skillshot
  Score = Score +5000;
  Skillshot3_active = 0;
  Skillshot_active = 0;
    Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(13);              // sends x 
    Wire.endTransmission();    // stop transmitting
}
}
 Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(11);              // sends x 
    Wire.endTransmission();    // stop transmitting
Score = Score +1000;
Scoring();     //Show Score
delay(Milli);
}

void Skillshot_Timer(){    //Timer for the activation of the skillshot

previousMillis_Skillshot = millis(); 

                        
}





void CaptiveBall1_event(){    //The captured balls each give 500 points. If the Torpedos are activated they award 5000 points
                             // and advance the Bonuscounter.
 if (Torpedo1_active == 1){
  Score = Score +5000;
  Bonus_count() ;
  Scoring();     //Show Score
  VariTorpedo1 = 1;
}      
else if (Torpedo1_active == 0){
  Score = Score +500;
  Scoring();     //Show Score
} 
previousMillis_cap = millis(); 

                        
}
void CaptiveBall2_event(){    //The captured balls each give 500 points. If the Torpedos are activated they award 5000 points
                              // and advance the Bonuscounter.
 if (Torpedo2_active == 1){
  Score = Score +5000;
  Bonus_count() ;
  Scoring();     //Show Score
  VariTorpedo2 = 1;
}      
else if (Torpedo2_active == 0){
  Score = Score +500;
  Scoring();     //Show Score
} 
previousMillis_cap = millis();                         
}

void CaptiveBall3_event(){    //The captured balls each give 500 points. If the Torpedos are activated they award 5000 points
                              // and advance the Bonuscounter.
 if (Torpedo3_active == 1){
  Score = Score +5000;
  Bonus_count() ;
  Scoring();     //Show Score
  VariTorpedo3 = 1;
}      
else if (Torpedo3_active == 0){
  Score = Score +500;
  Scoring();     //Show Score
} 
previousMillis_cap = millis();                         
}

void allTorpedosactive(){    //activates the Vari Bonus 
   Vari_Bonus_active =1;
}

void Sidelane1_event(){ //The Sidelanes each give 1000 points and activate the Torpedos 1 and 2 for the captured balls.
 if (Torpedo1_primer == 1){
  Torpedo1_active =1;
  Torpedo1_primer =0;
  if ((Skillshot1_active == 1) and (Skillshot_active == 1)) {       //Check for Skillshot
  Skillshot1_active = 0;
  Skillshot_active = 0;
}
}
Score = Score +1000;
Scoring();     //Show Score
delay(Milli); 
}

void Sidelane2_event(){ //The Sidelanes each give 1000 points and activate the Torpedos 1 and 2 for the captured balls.
 if (Torpedo2_primer == 1){
  Torpedo2_active =1;
  Torpedo2_primer =0;
  if ((Skillshot2_active == 1)and (Skillshot_active == 1)) {       //Check for Skillshot
  Score = Score +5000;
  Skillshot2_active = 0;
  Skillshot_active = 0;
}
}
Score = Score +1000;
Scoring();     //Show Score
delay(Milli); 
}

void Outlane_event() {  //Each Outlane awards 10000 points.
Score = Score +10000;
Scoring();     //Show Score
 delay(250);  
}

void Slingshot_event() {  //Each Slingshot bounce awards 100 points.
Score = Score +100;
Torpedos_count();
Scoring();     //Show Score
  delay(Milli); 
}

void Target_High_event(){      //The high target awards 10000 points and avtivates the Bonus for the lower Target
Torpedos_count();
Bonus_low_target=1;
Score = Score +10000;
Scoring();     //Show Score
delay(Milli); 
}

void Target_low_event(){      //The low target awards 10000 points or 50000 points if the Bonus for the lower Target is active
if (Bonus_low_target == 0) {
    Score = Score +10000;
}
else if (Bonus_low_target == 1) {
  Bonus_low_target =0;
  Score = Score +50000;
       Torpedo1_active = 0;   //Deactivating the torpedos after Bonus has been claimed
       Torpedo2_active = 0;
       Torpedo3_active = 0;
       VariTorpedo1 = 0;
       VariTorpedo2 = 0;
       VariTorpedo3 = 0;
   //    Vari_Bonus_active = 0;  Too harsh?
       Torpedo1_primer = 1;   //and activating the primers again
       Torpedo2_primer = 1;
       Torpedo3_primer = 1;
}


Scoring();     //Show Score
delay(Milli); 
}

void Torpedos_count(){ //Increases the Torpedo Bonus "Clock" by 1 and calls "Bonus_count" upon reaching 10 Torpedos.
Torpedo_Bonus +=1;
if (Torpedo_Bonus == 11) {
  Torpedo_Bonus =0;
  Bonus_count();
}
}

void Bonus_count() {        //Increases the Bonus Counter by 1 and calculates Sunk Ships
Max_Bonus_multiplier = (Ships_allive-Ships_sunk);
    Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(8);              // sends x 
    Wire.endTransmission();    // stop transmitting
if (Max_Bonus_multiplier > -11){   //Do this until all Ships are sunk
if (Bonus_temp < (Ships_allive-1)){
  Bonus_temp +=1;                   //Count up the Bonus Counter
}
else if (Bonus_temp == (Ships_allive-1)){
  Bonus_fix +=1;
  Ships_allive -=1;                 //Set the Bonus Counter to Zero and increase the number of Sunk ships.
  Ships_sunk +=1;                   //Use this later to calculate Bonus Score, each sunken ship adds (11000 - 1000x N) Points
  Bonus_temp = 0;                   //to the normal Bonus Score of (Bonus_temp x 10000).
}
}
if (Max_Bonus_multiplier < -10){  //all ships sunk, super Bonus awarded.

if (DoubleBonus == 0){
  DoubleBonus = 1;
}
   
}
  
}

void Bonus_add() {                //Calculates and adds the Bonuspoints to the Score

if (Ships_sunk >=1) {
  for (int i = 0; i <= Ships_sunk; i++) {
    Bonus = Bonus + (110000 - 10000*i);  
  }
}
Bonus = Bonus + (Bonus_temp*10000);

if (DoubleBonus == 1){
  Bonus = Bonus*2;
}
Score = Score + Bonus;
Bonus = 0;
Ships_sunk = 0;
Ships_allive= 10;
 }



void ResetGame() {
Score = 0;
MaxBalls = 5;
Bonus = 0;
Kickout_Bonus =0;
DoubleBonus = 0;
Torpedo_Bonus =0;
Torpedo1_primer = 1;
Torpedo2_primer = 1;
Torpedo3_primer = 1;
Ball_active = 0;
Torpedo1_active = 0;
Torpedo2_active = 0;
Torpedo3_active = 0;
Vari_Bonus_active = 0;
Bonus_low_target = 0;
int Rollover_Lane1_int_last = LOW;
int Rollover_Lane2_int_last = LOW;
int Rollover_Lane3_int_last = LOW;

int CaptiveBall1_int_last = LOW;
int CaptiveBall2_int_last = LOW;
int CaptiveBall3_int_last = LOW;

int Outlanes_Links_Rechts_int_last = LOW;
int Sidelanes_Left1_int_last = LOW;
int Sidelanes_Right2_int_last = LOW;

int Target_Low_int_last = LOW;
int Target_High_int_last = LOW;
int Target_Vari1_int_last = LOW;
int Target_Vari2_int_last = LOW;
int Target_Vari3_int_last = LOW;
int Target_Vari4_int_last = LOW;
int Target_Vari5_int_last = LOW;
int VariTarget_int_last = LOW;
int Kickout_int_last = LOW;

int Ballinplay_int_last = LOW;
int Slingshots_Left_Right_Up_int_last = LOW;
int Rubberband123_int_last = LOW;
control_lights();

for (int t=24; t<34;t++){  //Turn off all the "sunk" lights
 leds[t] = CHSV(50, 1, 0);  //
}
for (int t=3; t<12;t++){  //Turns off all torpedo lights. They are subsequently re-lit according to the Torpedo scores
 leds[t] = CHSV(50, 1, 0);  //
}


Scoring();
delay (100);  

}






void Scoring(){
  ScoreCalc();
  ScoreDisplay();     //Show Score 
  Serial.print("Score:  "); 
  Serial.print(Score); 
  Serial.print("\n"); 
}

void ScoreCalc()
{

num0 = (Score / 1) % 10;
num1 = (Score / 10) % 10;
num2 = (Score / 100) % 10;
num3 = (Score / 1000) % 10;
num4 = (Score / 10000) % 10;  
num5 = (Score / 100000) % 10;  
num6 = (Score / 1000000) % 10;  
num7 = (Score / 10000000) % 10; 
}

void ScoreDisplay()
{

lc.clearDisplay(0); // To Clear the display register 

if (num7 != -1){
lc.setDigit(0,7,num7, false); // To Place a 0 in the column 8
}
if (num6 != -1){
lc.setDigit(0,6,num6, false); // To Place a 0 in the column 7
}
if (num5 != -1){
lc.setDigit(0,5,num5, false); // To Place a 0 in the column 6
}
if (num4 != -1){
lc.setDigit(0,4,num4, false); // To Place a 0 in the column 5
}
if (num3 != -1){
lc.setDigit(0,3,num3, false); // To Place a 0 in the column 4
}
if (num2 != -1){
lc.setDigit(0,2,num2, false); // To Place a 0 in the column 3
}
if (num1 != -1){
lc.setDigit(0,1,num1, false); // To Place a 0 in the column 2
}

if (num0 != -1){
lc.setDigit(0,0,num0, false); // To Place a 0 in the column 1
}

}

void HighScoring(){
  HighScore = EEPROM.readLong(adress);
  HighScoreCalc();
  HighScoreDisplay();     //Show Score 
  Serial.print("HighScore:  "); 
  Serial.print(HighScore); 
  Serial.print("\n"); 
}

void HighScoreCalc()
{

Highnum0 = (HighScore / 1) % 10;
Highnum1 = (HighScore / 10) % 10;
Highnum2 = (HighScore / 100) % 10;
Highnum3 = (HighScore / 1000) % 10;
Highnum4 = (HighScore / 10000) % 10;  
Highnum5 = (HighScore / 100000) % 10;  
Highnum6 = (HighScore / 1000000) % 10;  
Highnum7 = (HighScore / 10000000) % 10; 
}

void HighScoreDisplay()
{

lc.clearDisplay(1); // To Clear the display register 

if (num7 != -1){
lc.setDigit(1,7,Highnum7, false); // To Place a 0 in the column 8
}
if (num6 != -1){
lc.setDigit(1,6,Highnum6, false); // To Place a 0 in the column 7
}
if (num5 != -1){
lc.setDigit(1,5,Highnum5, false); // To Place a 0 in the column 6
}
if (num4 != -1){
lc.setDigit(1,4,Highnum4, false); // To Place a 0 in the column 5
}
if (num3 != -1){
lc.setDigit(1,3,Highnum3, false); // To Place a 0 in the column 4
}
if (num2 != -1){
lc.setDigit(1,2,Highnum2, false); // To Place a 0 in the column 3
}
if (num1 != -1){
lc.setDigit(1,1,Highnum1, false); // To Place a 0 in the column 2
}

if (num0 != -1){
lc.setDigit(1,0,Highnum0, false); // To Place a 0 in the column 1
}

}




void Kickout_ball() { //Kicks out the ball into the shooter lane. Activates and deactivates the solenoid
Ball_active = 0;
Skillshot_active = 1;   //Skillshot activated
Skillshot1_active = 0;
Skillshot2_active = 0;
Skillshot3_active = 0;
 
int randNumber = random(1,4);

if (randNumber == 1){
  Skillshot1_active = 1;   //Skillshot activated
}
if (randNumber == 2){
  Skillshot2_active = 1;   //Skillshot activated
}
if (randNumber == 3){
  Skillshot3_active = 1;   //Skillshot activated
}

digitalWrite(solenoidPin_BallRelease, HIGH);
delay (100);    //TEST
digitalWrite(solenoidPin_BallRelease,LOW);
delay (400);  
}

void Releasef()
{
 if (Balls <MaxBalls){
  Balls +=1;
   Serial.print("Ball Lost");  
  Ball_Lost();
 }

else if (Balls >=MaxBalls){
  Serial.print("Game Over");  
  Game_Over();
 }
}

void Ball_Lost() {

Ball_active = 0;
Skillshot_active = 0;   
Skillshot1_active = 0;
Skillshot2_active = 0;
Skillshot3_active = 0;

Bonus_add();
Scoring();

previousMillis = millis(); 
delay(1000);
Kickout_ball();

Bonus = 0;
Kickout_Bonus =0;
DoubleBonus = 0;
Torpedo_Bonus =0;
Bonus_temp = 0;
Ships_sunk = 0;
Torpedo1_primer = 1;
Torpedo2_primer = 1;
Torpedo3_primer = 1;

Torpedo1_active = 0;
Torpedo2_active = 0;
Torpedo3_active = 0;
Vari_Bonus_active =0;
Vari_Bonus_active = 0;
Bonus_low_target = 0;

control_lights();    
delay (100);  
}

void Game_Over(){
    Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(7);              // sends x 
    Wire.endTransmission();    // stop transmitting
Bonus_add();
Scoring();
MaxBalls = 5;
Balls = 1;
Oncepergame = 0;
Ball_active = 0;
Skillshot_active = 0;
Skillshot1_active = 0;
Skillshot2_active = 0;
Skillshot3_active = 0;
  if (Score > HighScore){
  HighScore = Score;
  EEPROM.writeLong(adress, HighScore);
  }
HighScoring();
delay (1000);  
Bonus = 0;
Kickout_Bonus =0;
DoubleBonus = 0;
Torpedo_Bonus =0;
Torpedo1_primer = 1;
Torpedo2_primer = 1;
Torpedo3_primer = 1;
Bonus_temp = 0;
Ships_sunk = 0;
Torpedo1_active = 0;
Torpedo2_active = 0;
Torpedo3_active = 0;
Vari_Bonus_active =0;
Bonus_low_target = 0;
Startplay_ACTIVE = 0;
AttractMode = 0;
Score = 0;
PlayMusicOnce = 0;
delay (1000);  
ATTRACT();

}

void ATTRACT (){
 
//  if (AttatchInteruptOnce == 0) {
//  AttatchInteruptOnce = 1;
//  EIFR = 2;
//  EIFR = bit (INTF1);
//  delay(200);
//  EIFR = bit (INTF1);
//  attachInterrupt(digitalPinToInterrupt (3), interruptstart, FALLING); //PIN 3
//Serial.print("Interrupt attatched\n");  
//  }
if (PlayMusicOnce == 0) {
  PlayMusicOnce = 1;

    Wire.begin();Wire.beginTransmission(9); // transmit to device #9
    Wire.write(12);              // sends x 
    Wire.endTransmission();    // stop transmitting

}
  while (AttractMode == 0) {
  HighScoring();
      
  Serial.print("Attract Mode");  
  static uint8_t hue = 0;
  for(int i = 0; i < NUM_LEDS; i++) {
     if (AttractMode == 1)  {break;};
    // Set the i'th led to red 
    leds[i] = CHSV(hue++, 255, 255);
    // Show the leds
    FastLED.show(); 
    // now that we've shown the leds, reset the i'th led to black
    // leds[i] = CRGB::Black;
    fadeall();
    // Wait a little bit before we loop around and do it again
    if ((digitalRead(3) == LOW) ){
     AttractMode = 1; 
    }
    delay(30);
     if (AttractMode == 1)  {break;};
  }
  for(int i = (NUM_LEDS)-1; i >= 0; i--) {
     if (AttractMode == 1)  {break;};
    // Set the i'th led to red 
    leds[i] = CHSV(hue++, 255, 255);
    // Show the leds
    FastLED.show();
    // now that we've shown the leds, reset the i'th led to black
    // leds[i] = CRGB::Black;
    fadeall();
    // Wait a little bit before we loop around and do it again
    if ((digitalRead(3) == LOW) ){
     AttractMode = 1; 
    }
    delay(30);
     if (AttractMode == 1)  {break;};
  }
  if ((digitalRead(3) == LOW) ){
     AttractMode = 1; 
    }

  //delay(Attractdelay1);
  if (AttractMode == 1)  {break;};
  }
}

void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(250); } }

Credits

Frogger1108

Frogger1108

1 project • 37 followers

Comments