To the left is the brief for our new Pinball Project. The first page is a sample diagram of what a typical pinball machine would look like. The second page gave us a list of general requirements for our functional prototype. The third page gives us the requirements for our final Pinball machine. The final slide gives us an overview of the skills we will develop in this project.
My partner and I wired and coded our Arduino to our LCD screen to where we could display messages. We did this with our own research and had no teacher instruction or assistance.
Here is our scoreboard, an LCD screen, working and responding to buttons. One button adds 500 to a score, and another is the signal for losing a ball and it will decrease the score associated with the number of balls.
These are stationed throughout the pinball machine to bounce the ball around in an un predictable manner
There are two flippers at the button that guard the final hole. they are player controlled and used to keep the ball from falling down.
This starts the game. It is often spring loaded and will launch the ball into the game after being pulled back.
These lights light up the machine and add effects. The lights can also contribute to the theme of the pinball machine.
This is the switch that turns the entire machine on and off. It usually is put in a place where an unknowing player wouldn't accidentally flip it.
This is our mount for the LCD scoreboard. Getting the holes to fit with the screws required a lot of frustrating trial and error. After many failed attempts we finally got the perfect placement for the holes, allowing the screws to properly secure the LCD.
This is our 3D printed solenoid. I 3D printed the top green part while my partner George printed the bottom. We then secured the pieces together with epoxy. It is used in several components of our pinball machine. Its intended purpose is to let a metal rod slide through it. The solenoid gets very hot so that is why we had to make it heat resistant with the epoxy.
I am going to start designing the pop bumper for our pinball machine. In order to do this, I first did some research on pop bumpers. The video to the left, goes through the process of making a pop bumper stating at 9:09. I'll then go through the idea development phase where I brainstorm Ideas based on my research for the bumper. Next I will build and design prototypes in CAD and fabricate them into real life. Next, I'll test the product and after what will probably be a few iterations, I will hopefully get it. It will be finished when it works just as a bumper from a pinball machine, able to cast away balls when they are near it. It is then that it will be ready for the pin ball machine.
Today we assembled all our fabricated pieces to create the body of our prototype pinball machine. We took pieces that we previously glued together, and then used screws to assemble the remaining pieces.
We took our previously designed scoreboard mount and attached it to the prototype body. Now we have our LCD scoreboard mounted to the prototype body.
This is the same thing we did with the LCD scoreboard but now with the power switch. We took our power switch mount and attached it to our body after cutting the hole for it to fit in. The next step will be hooking the switch up to our power supply.
My partner and I installed our power supply. We screwed a piece of wood in so it will hold the power supply in place. We had to cut and make the brace ourselves. It was a bit tricky because of the length of the screws we had available to us, but we got it in the end.
My partner and I wired our power supply to our switch. We wired the power source to the previously installed power switch. We made sure that the power was turned off to be safe and wired all things needed. We can now plug the machine into the wall and turn it on and off with the switch.
This was different than what we usually do. In this assignment we conducted an experiment to answer the question of what factors will produce the most effective and powerful solenoid. We went around testing our classmates solenoids and gathered data. After completing this assignment we were then eligible to get our premade solenoid.
The brief consists of making a pop bumper with the constraints to the left. This will help guide me exactly what is expected for the pop bumper. It also ensures quality for the final product of the pop bumper.
This is the same research I conducted back with the bumper research. I went back to the video this time paying especially more attention to the bumper and how they conducted it.
This is when I applied what I learned in my research to find out how I will build the bumper. It was during this stage that I figured out the design that I would build. I drew my first sketch of the prototype I would be building
This is my first iteration. It consists of the ramp that will fall down and shove the ball out once it is triggered. It is built as a ramp that will be connected to the solenoid and it is the solenoid that will bring the ramp down.
My first iteration was only the ramp that comes down. There fore it had no way of being activated or even attaching to the solenoid. That is why in my next iteration I designed a way of connecting it to the solenoid and started on a way to activate it. As you can see there has been many changes with how a will connect it to the selenoid.
Here I have 3D printed what I had designed with on-shape. The piece that has the two rods sticking up will attach to the solenoid and the ramp. The ramp now has holes to connect to the shafts that are attached to the solenoid.
For this next iteration I entered CAD and made some changes. I made the ramp a bit larger, added a slope to the spike so it can better move the trigger, and made the piece that attaches to the solenoid a bit thicker and stronger. I also made the beams that would be used separate from the other pieces.
This is the printed version of the CAD shown before. This was actually a failed print, but I could still use it as a prototype. I swapped the columns for screws so they would be stronger. However the spike failed, so I couldn't include it in the iteration.
This is the successful re-print of the failed print. I changed the screws which were a bit awkward for smooth bolts so they would work better. I also included the spike now that is has it's slope on the top an the spike and the spike itself is printed properly.
This is the first version of the receiver. This is the piece that the spike will push to the side and trigger the solenoid. The view there is actually upside-down so that it will print correctly. I plan on attaching it to a flexible piece of plastic allowing it to move.
This is the first printed prototype of the spike receiver modeled above. It will be attached to a flexible piece of plastic while leting the receiver bend and connect to contacts. That is how the solenoid will be triggered. the first thing I notice is that it is much too thick and there are a few other things I will have to adjust for in the next iteration.
Here we used a google sheet to track exactly what constraints our prototypes currently meet. While I have made progress I clearly still have a lot to do.
The previous version of the spike receiver which will be used for triggering the solenoid was too large, and thick. The ramp in the middle was also too steep so the spike would rub against it and not slide. This new iteration I made the ramp more shallow, and slimmed the entire thing down so I can fit inside of the poles. My next step will be mounting it to a piece of plywood and working of the contacts.
This was the first iteration of the mount I will use to mount the solenoid. While it was a failed print and a couldn't actually use it, it still enabled me to make some changes in the next version. For Example, I could tell that it was too thick so I made the next version a bit thinner.
This iteration applies the newly printed Solenoid mount and the piece of wood I'm testing my bumper on. I have also worked on the mount that the receiver will sit on. I still haven't fully attached the pieces to the wood. However, the functioning solenoid mount and the properly drilled holes are both big steps toward a functioning model.
Here is the updated constraint tracking document. While it still has many red, with the steps I'm currently taking, I am setting myself up to get many at once.
This iteration I fully mounted by Arduino and its mounted onto the new model. The previous model was made with poorly attached wood and the piece which the Arduino attaches to wasn't long enough. This new design fixes all those problems and is much sturdier.
This was the Onshape CAD model for the receiver and contact mount. AS you can see above, the piece that holds the receiver is just a few pieces of wood taped together. This CAD model will be the 3D printed version of that which I can rely on.
This iteration implements the 3D modeled receiver mount I designed above. The mount is now much better and reliable than the wood and tape the previous version of this was made of.
It this iteration I tested all the wiring and code. I hooked up all the necessary wires and code hooking it up to an LED light to test.
In this twelfth iteration, I connected the bumper and pinball machine power source to the wiring and code. I now have something very close to a functioning model. All I have to complete is the triggering mechanism for the pinball.
This piece is responsible for holding the receiver and the contact points and mounting them to the pinball model. This first iteration I made this out of wood and carved out a notch with the Dremel.
This is the next iteration of the receiver mount is the white piece that I 3D printed. I designed it with Onshape. It is much better than the previous design made of wood and the measurements are much more precise.
This Iteration applies what the previous iterations have been working on, mounting the receiver onto the model. It was a very meticulous process due to the precision needed to mount the receiver at the perfect distance. Now the ball, or in this case a pencil, can trigger the solenoid from above, underneath the bumper hood.
For this almost final iteration, I made a small change, to the spike which helps the triggering mechanism Instead of it getting caught, with this mostly empty I designed a platform so the ball won't get caught. I also lowered the pitch of the ramp so the ball can roll onto it easier. Th photo shows both the new and old iterations to show exactly what changed.
Here is the bumper installed in my pinball machine. It is installed and fully functional with the exception to the balls which will be replaced with larger and heavier ones that will trigger the solenoid batter and the top which throughout the project I've kept off so I can better access the different parts of my bumper
I coded and wired a Neopixel LED strip to be changed by a button press. We will use this on the inside of the pinball machine for looks and aesthetics.
I designed and laser cut a housing for the Neopixel strip seen in the Neopixel triggered by button. It was very tricky because the measurements had to be very precise and the LEDs were not exactly even.
This is my research for how I will construct the flippers of the pinball machine. This version connects the flipper to the back of the solenoid with gets pulled back. The part is then used to move the flipper around an axis flipping it.
The second source is just a picture but it shows a design where the solenoid pushes the flipper directly, this seems like the most simple design but it may be tricky because of it.
The final design is part of a pinball machine changed for two players however, the mechanics are the same. It has the flippers triggered not by a solenoid but by two pieces of wood sticking out the side which the player hits with their hands. White this design would write reliable due to the lack of electronics it is not the design we will go with for that reason.
This is where I combine the code of the bumper and the target into one set of codes. I also connected the bumper to the LCD screen so the score will go up when the bumper is triggered. I included the Neopixel code into this aswell. That way we can have all the code nessisary for the pinball machine on the one Arduino Uno.
// constants won't change. They're used here to set pin numbers:
const int buttonPinS = A2; // the number of the pushbutton pin
int solenoid = A3;
// variables will change:
int buttonState = 0;
#include <LiquidCrystal.h>
int Con =60;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int buttonPin = 8;
int buttonPin2 = 7;
int score = 0;
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define PIN_NEO_PIXEL A0 // Arduino pin that connects to NeoPixel
#define NUM_PIXELS 5 // The number of LEDs (pixels) on NeoPixel
int buttonStateNeo = 0;
const int buttonPinNeo = A1;
Adafruit_NeoPixel NeoPixel(NUM_PIXELS, PIN_NEO_PIXEL, NEO_GRB + NEO_KHZ800);
void setup() {
// initialize the LED pin as an output:
pinMode(solenoid, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPinS, INPUT_PULLUP);
analogWrite(6, Con);
lcd.begin(16, 2);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(buttonPin2, INPUT_PULLUP);
NeoPixel.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pinMode(buttonPinNeo, INPUT_PULLUP);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPinS);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == LOW) {
// close selenoid
digitalWrite(solenoid, HIGH);
score = score + 100;
delay (300);
} else {
// open selenoid
digitalWrite(solenoid, LOW);
}
// Read the value of the input. It can either be 1 or 0
int buttonValue = digitalRead(buttonPin);
int buttonValue2 = digitalRead(buttonPin2);
if (buttonValue == LOW){
score = score + 100;
delay (300);
}
if (buttonValue2 == LOW){
score = score -100;
delay(300);
}
lcd.setCursor(0, 0);
lcd.print("score = ");
lcd.print(score);
lcd.setCursor(0,1);
lcd.print("balls left ");
lcd.print("balls");
lcd.setCursor(0, 2);
NeoPixel.clear();
buttonStateNeo = digitalRead(buttonPinNeo);
for (int pixel = 0; pixel < NUM_PIXELS; pixel++) {
}
NeoPixel.clear();
if (buttonStateNeo == LOW) {
for (int pixel = 0; pixel < NUM_PIXELS; pixel++) {
NeoPixel.setPixelColor(pixel, NeoPixel.Color(255, 0, 0));}
NeoPixel.show();
} else {
for (int pixel = 0; pixel < NUM_PIXELS; pixel++) {
NeoPixel.setPixelColor(pixel, NeoPixel.Color(0, 255, 0));}
NeoPixel.show();
}
}
The final pinball machine was showcased at our school's Fine Arts fair. As said in the video, there are bumpers, targets, flippers, ball reset, Neopixel LEDs, a scoreboard, and a launcher. All electrical components are coded and wired together on an Arduino Uno underneath the board.
The making of this component was very difficult and there were many major changes. I even ended up changing the final design of it during the making of this final product. The bumper consists of two contact points, one underneath and another on the ramp which pushes the ball down. The metal ball rolls into the bumper, and since the ball is metal it connects the contact points on the top and bottom triggering the solenoid. The solenoid is mounted underneath the board by a 3D-printed piece I designed in OnShape. The solenoid is connected to a piece that has metal rods sticking up through the board. these metal rods are also attached to the ramp which pushes the ball out when the solenoid is triggered. When the bumper is triggered, the score also increases.
This part of the project was largely done by my partner, George Christy. He went through the design process by designing the entire target in OnShape and laser-cutting the prototypes and the final product. It is essentially a casing for a button where a paddle sticks up through the board and can be hit by the ball. It screws in through the bottom of the board and has two wires which acct as the button wires coming out of it. When its hit, the score increases.
These components are the only player input in the entire game. They were largely designed by my partner George Christy. They flip over kicking the ball out back into the playing field. they are powered by a solenoid underneath the board. These two pieces on the top and bottom are connected by a wooden dowel and move in sync. the solenoid flips the bottom piece and the top moves in sync.
This scoreboard is positioned at the top of the machine above the board. It shows the number of balls the player has left, along with the score. The score increases by 100 each time a target or bumper is hit, and the ball's left number goes down every time the player losses the ball. Originally it was very tricky with many wires involved however we later got a new LCD display which only took four wires making it much easier.
These were our Neopixel LED strips which we had six of. They were scattered all over the machine. While we originally thought they would be easy, they actually proved very difficult. This was because of the location of where they were, the number of wires required for them, and the power required for them. Firstly each LED had three wires which leads to a total of 18 additional wires for these LEDs. There was also the issue of where they were. since most of them were at the opposite end of the Arduino the wires had to be long. Also, the LEDs required so much power the 5V output from the Arduino couldn't support them so we had to get another source of outside power. However, after all the issues the LEDs worked as intended which was to flash blue whenever the player scored.
This was our launcher. The launcher was what started the game. You would put the ball into it and it would launch the ball into action once pulled back. This was another deceptively difficult component. This was because of the movement of it and the stress the body comes under. There were several iterations we went through as some of our prototypes couldn't handle the stress. In the end, though, we ended up having a great launcher that worked consistently.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Changed these parameters to match our LCD - Mr. Ayers
int buttonPinT1 = 2;
int buttonPinT2 = 3;
int buttonPinT3 = 4;
int buttonPinballs = 7;
const int buttonPinS1 = 5;
const int buttonPinS2 = 6;
int solenoid1 = 8;
int solenoid2 = 9;
const int buttonPinSFlip3 = 10;
const int buttonPinSFlip4 = 11;
int solenoidFlip3 = 12;
int solenoidFlip4 = 13;
//int score = 0; // a regular int overflows at 16384. A long counts up to over 2 billion
long score = 0;
int balls = 5;
int solenoidState1 = 0;
int solenoidState2 = 0;
int solenoidStateFlip3 = 0;
int solenoidStateFlip4 = 0;
//led things--------
#include <PinballOutputHandler.h>
OutputHandler outputHandler;
#define NUM_STRIPS 6
Adafruit_NeoPixel pixels[NUM_STRIPS] = {
// Initialize the strips with the number of LEDS, pin number, and init parameters.
// Replace the pin numbers with the pins you are using for your neopixel strips
Adafruit_NeoPixel(5, A0, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(5, A1, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(5, A2, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(5, A3, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(5, 1, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(5, 0, NEO_GRB + NEO_KHZ800)
};
// An array to hold output handlers that correspond to the strips
NeoPixelHandler *handlers[NUM_STRIPS]; // to hold handlers that can control 6 strips
NeoPixelColor red(150, 0, 0);
NeoPixelColor blue(0, 25, 250);
int buttonValueLED = 0;
void setup()
{
////Serial.begin(9600);
// analogWrite(6, Con);
lcd.init(); // This line was missing from Alexander's first program -Mr. Ayers
lcd.init(); // I don't know why the example calls this twice - Mr. Ayers
//lcd.backlight();
lcd.begin(16, 2);
pinMode(buttonPinT1, INPUT_PULLUP);
pinMode(buttonPinT2, INPUT_PULLUP);
pinMode(buttonPinT3, INPUT_PULLUP);
pinMode(buttonPinballs, INPUT_PULLUP);
pinMode(buttonPinS1, INPUT_PULLUP);
pinMode(buttonPinS2, INPUT_PULLUP);
pinMode(solenoid1, OUTPUT);
pinMode(solenoid2, OUTPUT);
pinMode(buttonPinSFlip3, INPUT_PULLUP);
pinMode(buttonPinSFlip4, INPUT_PULLUP);
pinMode(solenoidFlip3, OUTPUT);
pinMode(solenoidFlip4, OUTPUT);
for (int i = 0; i < NUM_STRIPS; i++) {
handlers[i] = outputHandler.add(pixels[i]);
pixels[i].setBrightness(25);
}
}
void loop()
{
//Serial.println("printing score");
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("score: ");
lcd.print(score);
lcd.setCursor(0, 1);
lcd.print("balls left: ");
lcd.print(balls);
lcd.setCursor(0, 2);
// Read the value of the input. It can either be 1 or 0
int buttonValueT1 = digitalRead(buttonPinT1);
int buttonValueT2 = digitalRead(buttonPinT2);
int buttonValueT3 = digitalRead(buttonPinT3);
int buttonValueS1 = digitalRead(buttonPinS1);
int buttonValueS2 = digitalRead(buttonPinS2);
int buttonValueballs = digitalRead(buttonPinballs);
int buttonValueSFlip3 = digitalRead(buttonPinSFlip3);
int buttonValueSFlip4 = digitalRead(buttonPinSFlip4);
if (buttonValueT1 == LOW) {
//Serial.println("T1 hit");
score = score + 100;
delay (300);
}
if (buttonValueT2 == LOW) {
//Serial.println("T2 hit");
score = score + 100;
delay (300);
}
if (buttonValueT3 == LOW) {
//Serial.println("T3 hit");
score = score + 100;
delay (300);
}
if (buttonValueS1 == LOW) {
//Serial.println("S1 hit");
score = score + 100;
delay (300);
}
if (buttonValueS2 == LOW) {
//Serial.println("S2 hit");
score = score + 100;
delay (300);
}
if (buttonValueballs == LOW) {
//Serial.println("ball hit");
balls = balls - 1;
delay (300);
}
//Bumper Solenoids---------------------------------
if (buttonValueS1 == LOW) {
digitalWrite(solenoid1, HIGH);
delay(750);
digitalWrite(solenoid1, LOW);
} else {
digitalWrite(solenoid1, LOW);
}
if (buttonValueS2 == LOW) {
digitalWrite(solenoid2, HIGH);
delay(750);
digitalWrite(solenoid2, LOW);
} else {
digitalWrite(solenoid2, LOW);
}
//Flipper Solenoids--------------------------------------
if (buttonValueSFlip3 == LOW) {
digitalWrite(solenoidFlip3, HIGH);
} else {
digitalWrite(solenoidFlip3, LOW);
}
if (buttonValueSFlip4 == LOW) {
digitalWrite(solenoidFlip4, HIGH);
} else {
digitalWrite(solenoidFlip4, LOW);
}
//led code---------------------------------------
if (buttonValueT1 == LOW) {
handlers[0]->blink(blue, 150, 3);
handlers[1]->blink(blue, 150, 3);
handlers[2]->blink(blue, 150, 3);
handlers[3]->blink(blue, 150, 3);
handlers[4]->blink(blue, 150, 3);
handlers[5]->blink(blue, 150, 3);
}
if (buttonValueT2 == LOW) {
handlers[0]->blink(blue, 150, 3);
handlers[1]->blink(blue, 150, 3);
handlers[2]->blink(blue, 150, 3);
handlers[3]->blink(blue, 150, 3);
handlers[4]->blink(blue, 150, 3);
handlers[5]->blink(blue, 150, 3);
}
if (buttonValueT3 == LOW) {
handlers[0]->blink(blue, 150, 3);
handlers[1]->blink(blue, 150, 3);
handlers[2]->blink(blue, 150, 3);
handlers[3]->blink(blue, 150, 3);
handlers[4]->blink(blue, 150, 3);
handlers[5]->blink(blue, 150, 3);
}
if (buttonValueS1 == LOW) {
handlers[0]->blink(blue, 150, 3);
handlers[1]->blink(blue, 150, 3);
handlers[2]->blink(blue, 150, 3);
handlers[3]->blink(blue, 150, 3);
handlers[4]->blink(blue, 150, 3);
handlers[5]->blink(blue, 150, 3);
}
if (buttonValueS2 == LOW) {
handlers[0]->blink(blue, 150, 3);
handlers[1]->blink(blue, 150, 3);
handlers[2]->blink(blue, 150, 3);
handlers[3]->blink(blue, 150, 3);
handlers[4]->blink(blue, 150, 3);
handlers[5]->blink(blue, 150, 3);
}
// Call the output Handler every time you go through the main loop.
outputHandler.handleAll();
}
This project really hasn't compared to anything we've ever done in school before. It was so large in scale and required so many moving parts it really was like nothing else. the coding and electronics to the CAD required are truly like nothing else I've ever done. The scale however could be comparable to the interior restoration of my family's 1983 Toyota Sunrader camper, however, that was a very different project in that it was more construction oriented, while this had many small intricate parts and had a large code aspect to it.
Completing this project may have been one of my most proud moments, especially considering the final grade I ended up with. The months of work and the time outside of school hours dedicated to this project are nothing like anything I've done previously, and finishing the project just gave me a sense of overwhelming joy.
Something I'm most proud of would be the entire final machine. I know I'm kind of just saying the entire thing, but the way the final product came out, was just so incredible and cohesive with the appearance, the mechanics, and the overall completion of it. Everything just worked exactly how it needed to and showing it during the Fine Arts Fair was one of my proudest moments.