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)18,535
Arduino Conversion of an EM Pinball Machine

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Arduino Mega
×1
MAX7219 LED display
×1
WS2812 LEDs
×1
IRL540N MOSFET
×1
Molex connectors
×1

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
1 project • 39 followers

Comments