Project showcase

Arduino Conversion of an EM Pinball Machine © GPL3+

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

  • 997 views
  • 0 comments
  • 10 respects

Components and supplies

A000066 iso both
Arduino UNO & Genuino UNO
×1
Ardgen mega
Arduino Mega 2560 & Genuino Mega 2560
×1
MAX7219 LED display
×1
WS2812 LEDs
×1
IRL540N MOSFET
×1

About this project

Arduino Controlled Pinball Machine

This is my second restoration project of an old pinball playfield. I explored the basics of controlling a pinball machine with an Arduino on my first attempt which worked fine, however I learned a lot during the build of my first machine and wanted to improve my second one with the things I had learned. If you want to read up on the basics check out my first project, in this one I will focus more on specific details I have been asked about and which will simplify the progress considerably.

The Cabinet

This time I bought an old, empty pinball cabinet to house my playfield. As before, I didn’t use the head since I didn’t need it and I didn’t have a back glass anyway. I might install it one day just for the looks if time allows.

Getting Started

This is what I had to begin with. An old playfield of a Recel pinball machine named “Underwater."

As you can see, the playfield is complete with plastics and all the coils and mechanisms were still present. The rest was missing however, this included all of the lamps, wiring, and EM mechanisms. Somebody had begun stripping the playfield and cutting away some parts but thankfully stopped before removing critical stuff. I completely disassembled the playfield and components and cleaned them, bought and applied new rubbers and springs and re-soldered broken wires to the coils and sensors.

Pinball Mechanisms and Components

A pinball game usually consists of a core set of components and mechanisms which you need to address and include in your project. Each of them has to be handled differently in regard to the Arduino.

Connections

Regardless of the specific component, all have to be connected to the Arduino somehow. In pinball machines, connections are usually all soldered on the component and then fed into a control board via Molex connectors. While this is probably the best method if you want connections that are shock proof and last “forever”, they are also a pain to apply if you don’t exactly know the layout of your wiring beforehand and which lengths you need. To simplify the process, I soldered a short wire to each component and attached crimp connections to the ends. This allows me to connect any wire to any component, combine multiple wires easily and makes the construction of the wiring harness very easy. Some people say that crimp connections are not good since they can shake loose due to the mechanical stress of a pinball machine. While this might be true in some cases, I never noticed a loose connection in any one of my 2 machines. The connections are so tight that you sometimes have to use pliers to pull them apart. Therefore I tend to recommend using crimp connectors.

Sensors

Sensors can be of varying types depending on the specific part, but generally it’s a kind of switch which sends a signal once it is triggered by the ball. Most common are leaf switches, rollover switches and micro switches. These will be the main source of inputs coming into our Arduino. Since they are simple switches, they can be handled by the Arduino as any push button or trigger switch would be. The wiring of these is covered in hundreds of tutorials; basically you attach one end of the sensor to ground and the other one to an Arduino pin. For this project I used the internal pull-up resistors of the Arduino, therefore you only need 2 wires for each sensor.

Lights

Since all the lights were missing I had to come up with a solution. I didn’t want to use individual LEDs like in my last project since it was quite a lot of work and used up a lot of pins (and I was too lazy to construct a matrix or use shift registers). Luckily, there is a far superior solution which is cheap, uses only 1 pin and is extremely easy to work with, WS2812B LEDs.

I bought a string of 50 WS2812B LEDs for 8 bucks, cut them to length and installed them directly under the playfield. You can control the entire strip with one pin using the Fast.Led library. The installation under the playfield is very easy since I used paperclips which each hold an LED in place and are screwed to the playfield. The paperclips have to be coated to avoid shorts on the LEDs! I did the same with the general illumination, this time I used a string of 50 WS2811 LED bulbs which are addressed and secured the same way.

In total I have about 60 LEDs mounted beneath the playfield, all are individually addressable and use only 2 pins on the Arduino. This makes turning the different lights on and off very easy and you can also implement nice colour changing effects if the ball hits a target.

Arduino controlled WS2812 LED in a pop bumper

They are powered by a separate 5V power supply. You can see them in action in this short demonstration clip of the “attract”mode which is simply using a script from the Fast.Led library.

Arduino controlled attract mode for Underwater pinball

Flippers, Pop Bumpers, and Slingshots

This details the wiring and control process. I have a more detailed explanation about the functions of each part in my previous project description.

For the Arduino, all components using solenoids are the same. A solenoid is a coil of wire which is magnetized when current is applied. The Arduino can’t interact directly with them since they need a lot of current, in my case 24V, many modern coils use 40-50V. In a pinball game, a solenoid is used to translate electricity into mechanical motion. This is done by using the magnetic effect to have the coil pull in a metal rod (plunger) which is connected to a part you want to be moving. You can basically separate you solenoids in 2 groups, the ones you trigger directly and the ones you want the Arduino to trigger.

In my case, I had 2 flippers and 3 slingshots I wanted to trigger directly and 1 popbumper, one kickout, a Vari-Target and the ball release which needed to be triggered by the Arduino.

If you trigger a solenoid directly you simply have to close a switch which completes the circuit. Current flows and the solenoid is activated. This allows for fast and responsive action by the slingshots and flippers. The Arduino therefore isn’t aware of them; points for activating the slingshots are awarded by a switch which is triggered by the slingshot motion.

The other solenoids rely on precise timing when to activate and need computer control.This is done by MOSFETS (metal–oxide–semiconductor field-effect transistor) since the Arduino can’t handle high voltages directly. The go-to MOSFET for many Arduino projects is the IRL540N, a logical level MOSFET (meaning you can reliably trigger them with the 5V signal from the Arduino) which can handle the current and amperage involved (and is dirt cheap if you buy the Chinese knock-offs).

I got a few questions about MOSFET wiring in my last project, so here’s a short explanation. MOSFETs have 3 pins, a GATE, DRAIN and SOURCE pin. The LR540N has the GATE on pin 1, followed by the DRAIN on pin 2 and the SOURCE on pin 3. This defines you're wiring, as the name suggests the GATE controls the flow of electricity which is the job of the Arduino, so pin 1 is connected to yourArduino pin of choice which you want to use to control the solenoid. Pin 2 isthe DRAIN which is connected to the negative side of your solenoid and the SOURCE is connected to your common ground (including your power supply for the MOSFET AND the arduino ground). The positive side of your 24v power supply is only connected to the solenoid positive side. In the diagram you can see 2 resistors. The 2 resistors serve different purposes, the one between the ground and the arduino (the "lower" one in the schematic) grounds the pin so it's not floating, use a 10K resistor. The second one between the Arduino and the Mosfet protects your Arduino pin and prevents the Mosfet from drawing too much current. Arduinos can only supply 40ma and once the Mosfet is turned"ON" it may draw more than that...or not, that is why many schematics skip that one. But since resistors are cheap and arduino pins are precious you should use one, a 470 ohm one worked fine for me.

I was talking about a positive and negative side of the solenoid. This of course doesn’t make much sense since a coil of wire has no “side”, you can apply current any way you want, the coil will always be magnetized. However, in order to protect your Arduino and your power supply you have to apply diodes on each solenoid (see picture above). A diode across the solenoid prevents the “kickback” which occurs when the coil is turned off. The magnetic field collapses, current is induced and needs to go somewhere! The diode allows the current to dissipate through the coil and not through your Arduino or power supply, preventing them from being destroyed.Don’t forget it!

In my lastproject I wired the MOSFETS directly to my coils. This is a stupid way of doing it, better do it right and build a MOSFET control board. This way you can easily connect and disconnect your solenoids to the Arduino, it’s a more compact solution and allows for the easier replacement of a bad MOSFET. I constructed this Solenoid driver board with 5 MOSFETS in about an hour, so it’s really not much work and the usage of connectors on both sides allows me to use the board in any application if I want to. The wiring is exactly the same as described above.

Now you are able to control each solenoid by putting the respective Arduino pin to HIGH, the MOSFET gate opens and current flows through the solenoid. If current flows for more than a few seconds however, you solenoid will get really hot, the insulation will melt and you end up with a burned and destroyed coil. Therefore, activation of the solenoids needs to be very strictly controlled by the Arduino. This will be covered in the code section in more detail.

Display

I used two MAX7219LED modules for displaying the scores and highscores. They are cheap and easyto use, the only problem is the length of the wiring. It needs to be rather short, so place your Arduino close to the place where the displays are and you should be fine. The score is calculated during play and starts at 0. At the end of each game, the current score is compared to the highscore. If it is higher, the highscore is replaced by the current score. This is made possible by the EEPROM in the Arduino. You can permanently store up to 4096 bytes on the ATmega2560 like on a small hard drive. This way you can keep a highscore stored, even when the Arduino is turned off.

Sound

I used a MP3 shield board based on the VS1053Bfor the sound. In my last project I realized that it was a bad choice since the processing time and resulting delay is too high for some pinball actions. Since it’s so cheap I simply put it on another Arduino (UNO) and controlled this “Music-Arduino”from my main one using the WIRE library. This way you have no delays on the main Arduino and can play any sound effect you like.

Arduino and Coding

Since I used smart LEDs, the WIRE library for the music and the MAX7219 as the displayI only needed 7 pins (and ground) for these peripherals. The solenoid driverboard needed 4 pins (one for each solenoid). The rest is used by the switches on the playfield, in total I have 35 inputs (give or take) which I grouped using pin headers. This way you can easily connect them to the Arduino and you reduce the cable mess inside the machine.

The Arduino is the brain behind everything, it determines when switches are activated, it turns lights on or off accordingly, it keeps track of the scoring, it displays the score and ball number, activates the energy and keeps track of the game logic.

I tried to keep the code simple and clean (and failed in most cases…again) using separate functions (void) for nearly everything. Besides the simple in/out relations between signals (if target is hit, turn of light A, turn on light B, set condition X to 1, etc..) there is some game logic involved. I tried to recreate the original game logic as well as I could, but you are free to do what you want and delivers a good gaming experience.

Solenoid Timing

This hasbeen discussed a few times in my last project, how do I activate and de-activate the solenoids without using delay()? You can’t use delay since the Arduino must never stop receiving signals from the playfield. Therefore, we are using the millis function. If you want to learn more about millis, simply lookup the examples of blinking a LED without delay, it’s the most common examplefor the Arduino. Basically, you activate the coil at some point in your game and note the system time of activation. Then you have a routine checking the difference between your activation time and the current system time. If the time exceeds a certain threshold, the routine deactivates the coil. I used 50 milliseconds for the bop bumper, othersolenoids will have to be activated for longer periods of time. I also implemented a check for stuck switches which would keep a coil activated for too long by triggering it over and over again. If a solenoid pin is high, another millis timer is started. This way I can check for how long each pin has been high. If the time exceeds a certain threshold (e.g. 2 seconds) all pins are set low and the entire program is shut down to prevent another activation.

Power Supply

To powerthe machine, I use 3 different power supplies. Two 24 volt power supplies for the solenoids and a 5V power supply to power the Arduino and the lights.

EMI (Electromagnetic Interference)

I didn’t think I would be troubled by EMI since I’m working with “only” 24V, but the Arduino sometimes is fickle and doesn’t like it. You have to keep EMI in mind if you are experiencing strange problems like signals triggering by themselves. This happened to me afew times, the culprits were the arcing switches from the solenoids which are triggered directly by shorting the circuit. To prevent this, I installed RC-snubbers on the contacts which helped a lot with false signals. A RC-Snubber is simply a resistor and a capacitor in series across the terminal of the respective switch. I was too lazy to calculate the appropriate values and used the “rule of thumb” values, 100ohm and 0.1uF.

Another source of EMI can be ground bounce. You can in theory put all grounds together wherever you want as long as they are connected. I learned the hard way that connecting the grounds from the solenoids and the sensors on the playfield wherever they cross is not a good idea and leads to false signals sometimes. I ended up using a separate ground wire for the solenoids and sensors and connected them at one point on the power supply which worked fine.

Summary

I hope I could be of some help if you are interested in a similar project. It was a lot of work, and you will undoubtedly discover obstacles and challenges on the way. However, it was (and is) a lot of fun and is definitely a worthwhile project if you like pinball. The techniques used in this project can be applied to any number of other projects as well. Most projects need some sort of display like the MAX7219. Learning how to use the WS2812 LEDs is extremely useful and can produce great effects with very little effort. The usage of MOSFETs is somethingthat should be learned by most Arduino users anyway since it expands the possibilitiesof the Arduino to interact with other devices and allows it to control basically any device.

Last but not least, two short gameplay videos of the machine so you can see the Arduino in action.

Code

Arduino controlled Pinball Machine CodeArduino
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); } }

Comments

Similar projects you might like

Arduino Bluetooth Basic Tutorial

by Mayoogh Girish

  • 454,652 views
  • 42 comments
  • 236 respects

Home Automation Using Raspberry Pi 2 And Windows 10 IoT

Project tutorial by Anurag S. Vasanwala

  • 285,498 views
  • 95 comments
  • 671 respects

Security Access Using RFID Reader

by Aritro Mukherjee

  • 229,353 views
  • 38 comments
  • 236 respects

OpenCat

Project in progress by Team Petoi

  • 195,939 views
  • 154 comments
  • 1,361 respects
Add projectSign up / Login