This is an image of our new project; a pinball machine.
These are the steam requirements for the project.
These are the machine requirements.
These are the prototype requirements.
Using wires, an Arduino, an AB cable, and an LCD, my partner and I coded the LCD screen to say "Kayla&Kate World domination".
#include <LiquidCrystal.h>
int Contrast=75;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup()
{
analogWrite(6,Contrast);
lcd.begin(16, 2);
}
void loop()
{
lcd.setCursor(0, 0);
lcd.print("Kayla&Kate");
lcd.setCursor(0, 1);
lcd.print("World domination");
}
Today we went to a pinball arcade to learn about pinball machines, what components they have, what most of them have in common, and about individual components.
Bumpers
Flippers
Ball slides
Scoreboard
Start button
LEDs
Ball guides with shooters
Launcher
On/Off button
Theme
Graphics
Sound effects
Score information sheets
When the ball runs into a bumper, it shoots the ball back into the play field at random, sometimes into other nearby pop bumpers and gives the player more points.
The flippers are controlled by two buttons on each side of the pinball machine. When the buttons are pressed, they move the flippers which shoot the ball away from the opening and saves the player from losing the game.
The start button is pressed when the player is ready to play the game. It sets the ball in its position to be launched and gets the play field ready.
A pinball launcher's purpose is to launch a pinball into play. The launcher's main component is a spring, which is compressed when the plunger is pulled, and released when it is let go. After the plunger is released, the springs are able to shoot the ball out and into the game.
Because the LEDs on the pinball machines have sensors, they activate or change colors when the ball touches them.
When the ball scores a goal, hits a target, or goes through a target, you will score points which add onto the scoreboard.
After wiring the buttons to the LCD, Arduino, and two breadboards, I coded the LCD to say "ball count" and count down from five when one button is pressed, or say "score" and count up by 500. When no buttons are being pressed, the LCD says "Pinball Madness".
#include <LiquidCrystal.h>
int Con=60;
int score_increase_button = 8;
int ball_count_button = 13;
int score = 0;
int ball_count = 5;
//connected pin
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//standard for LCD screen
void setup()
{
analogWrite(6,Con);
lcd.begin(16, 2);
pinMode(score_increase_button, INPUT_PULLUP);
pinMode(ball_count_button, INPUT_PULLUP);
}
void loop()
{
int buttonValueOne = digitalRead(score_increase_button);
int buttonValueTwo = digitalRead(ball_count_button);
//reads the value of the input which is either 1 or 0
//when it is on or off, respectively
if(buttonValueOne == LOW){
lcd.clear();
lcd.setCursor(6,0);
//placement of text, first number is x axis, second is y axis
lcd.print("score ");
score=score+500;
lcd.print(score);
delay(300);
}else{
lcd.clear();
//Title screen
lcd.setCursor(4, 0);
lcd.print("Pinball");
lcd.setCursor(5, 1);
lcd.print("Madness");
delay(300);
}
if(buttonValueTwo == LOW){
lcd.clear();
lcd.setCursor(0,0);
//placement of text, first number is x axis, second is y axis
lcd.print("ball count: ");
ball_count=ball_count-1;
lcd.print(ball_count);
delay(300);
}
}
This is a cardboard prototype of our scoreboard mount which we made on Onshape and cut out using the Glowforge.
This is the design for our scoreboard mount. We made it on Onshape and used the Glowforge to cut it out. After much trial and error, we were able to align it to fit the LCD and the four holes.
This is the final scoreboard mount. We made it out of wood using the same file from the cardboard prototype scoreboard.
When a copper wire is tightly coiled around the solenoid, an electrical current flows through the wire, creating strong magnetic field. This is a photo of our 3-D printed solenoid, which will convert electrical energy into our mechanical work.
This is the prototype of my pinball machine. After the CNC router cut out the parts, we assembled them with wood glue and screws.
This is the scoreboard screwed into the pinball machine prototype.
This is the on/off switch. I designed it on Onshape, then used the glowforge to cut it out.
This is the design of the switch mount on Onshape.
This is the switch mounted on our prototype.
This is the power source for our pinball machine. We used the band saw to cut a piece of wood in order to prevent the power source from falling out.
I am going to start designing my bumper for my Pinball Machine. In order do to this, I will have to research its components and how they come together. After I get an understanding of each component, I will have to sketch out each piece and its measurements. Then I will be able to start designing it on Onshape. After the pieces are made and assembled, I will test the bumper by using a ball and placing it on an incline like what was done in the video to the left. If the bumper doesn't shoot the ball far out enough, or there is another problem, I will have to go back to my design and fix the bumper. It will be fully complete when it can shoot the ball into the playfield without difficulty.
In this video, they explain the process of how to design and assemble a pinball machine bumper.
For my first prototype, I made one piece of the bumper on Onshape and 3D printed it.
The bumper needs a sensor in order to shoot the ball outwards, so I will have to design something that will be triggered by the ball.
To start researching, I watched the video above and observed similar bumper designs. After I fully understood how it would operate, I sketched out what the bumper would look like, and the parts I would have to design and 3D print. Above, each part of the bumper is sketched and explained.
This is the finished model of the second prototype. I used the sketches I made to design each part, and once I finished, I put it together in the assembly on Onshape, shown in the images below.
These are the 3D printed parts from the photos above. The cone is printed on the wrong side and the rods are too thin.
After I assembled the second prototype, I realized the cone was placed backwards, so I separated it for the next prototype. I also rounded the top of the bumper so it would better push the ball.
In this prototype, the rods are too thick and the cone isn't sturdy enough.
To the left is a document out teacher gave us that allows us to track our progress towards our constraints.
In this prototype, I added the last piece I needed to design and took away the rods so I could replace them with nails.
In the first 3D print, the 3D printer encountered a mechanical error, so the bumper didn't come out the way it was expected to. There were parts where there were no filament and the circular shapes were distorted.
This is the reprint of my fourth prototype. Each piece connects perfectly, but the hole where the solenoid goes is too large.
After I tried to assemble the new prototype, I realized the 3D printer didn't print the holes in the bumper correctly, so I kept the blue parts from the last prototype.
In this prototype, I changed the receptacle and added a rectangle which would go under it and make it more durable. I also made the holes where the nails go larger.
This is the third prototype of the receptical. After I sanded down the inside, I added the flexible filament underneath it to make it durable enough to trigger the solenoid.
In the white prototype, I figured out how to make the cone hollow on Onshape so I didn't have to sand out the inside.
This is the color-coded design of my mount and bumper together.
This is the mount I made to test the bumper. Using the jig saw, I cut two pieces of scrap plywood to hold another layer of plywood, which represents (and is the thickness of) the playfield.
I designed this to support the solenoid so the weight of it doesn't break the cone and flexible filament.
In this prototype, I made a better cone to replace the previous blue cone, which had broken.
This code sets up a contact switch and controls the solenoid when the contact is made with the switch
// constants won't change. They're used here to set pin numbers:
const int buttonPin = A2; // the number of the pushbutton pin
int solenoid = A3;
// variables will change:
int buttonState = 0;
void setup() {
// initialize the LED pin as an output:
pinMode(solenoid, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT_PULLUP);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == LOW) {
// close selenoid
digitalWrite(solenoid, HIGH);
} else {
// open selenoid
digitalWrite(solenoid, LOW);
}
}
This is the bumper fuly installed in the pinball machine.
The goal of this assignment was to code and wire our neopixels to respond to a button and light up in a pattern.
This is a lasercut piece I designed in Onshape that goes around the Neopixel.
// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// Released under the GPLv3 license to match the rest of the
// Adafruit NeoPixel library
const int buttonPin = A2;
int buttonState = 0;
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
// Which pin on the Arduino is connected to the NeoPixels?
#define PIN 6 // On Trinket or Gemma, suggest changing this to 1
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 8 // Popular NeoPixel ring size
// When setting up the NeoPixel library, we tell it how many pixels,
// and which pin to use to send signals. Note that for older NeoPixel
// strips you might need to change the third parameter -- see the
// strandtest example for more information on possible values.
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels
void setup() {
// These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
// Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
// END of Trinket-specific code.
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pinMode(buttonPin, INPUT_PULLUP);
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == LOW) {
pixels.clear();
for(int i=0; i<NUMPIXELS; i++) {
pixels.setPixelColor(i, pixels.Color(0, 150, 0));
pixels.show();
delay(DELAYVAL);
}
}
}
Source 1: The flipper buttons are plastic caps fitted on electrical switches that switch electricity on and off to a copper wire coil. This coil is wound on a hard plastic bobbin with an iron plunger (a solenoid). When the coil is powered on, it becomes an electromagnet pulling the iron plunger into the bobbin core. The iron plunger is connected to a linking rod which pulls a small lever attached to the flipper. When the flipper button is released, the switch cuts off the electricity to the coil, letting go of the iron plunger. A small spring on the flipper base then pulls the flipper back to the resting position.
Source 2: To avoid overheating flipper solenoids, most flippers use solenoids with two coils of wire wound together around the same core. The first coil is a high electric current/high power coil used by itself to kick the pinball up the playfield. The second coil is a much weaker, low electric current/low power coil that is really only strong enough to hold the ball behind the raised flipper. Because of the two coils wound together, flipper solenoids have three terminals instead of two as other solenoids do. The flipper assembly has a switch built into it called the End Of Stroke switch which switches the flipper from high power to low power once the flipper reaches the end of its swing. The flipper only uses high power for a fraction of a second before switching to low power - just enough time to kick the ball and no more. The flipper switches from high to low power seamlessly; most players never realize that it's happening. When the player presses the flipper button on the side of the cabinet, the flipper button switch closes, and an electric current rushes through the high-power coil and through the end of stroke and flipper button switches. Most of the electric current passes around the lower power flipper coil because the coil has a much higher electrical resistance than the switch. Once the flipper has reached the end of its swing, a small lever attached to it opens the end of stroke switch which prevents any more electric current from flowing through the switch. This forces all of the electric current flowing through the circuit to flow through both the high power and low power coils. The amount of electric current flowing through the circuit decreases because the combined resistance of the two coils is more than the resistance of the high power coil alone. With the reduced electric current flowing through the coils, the flipper is only strong enough to hold the ball, but neither coil is in danger of overheating so they can remain in this situation indefinitely.
Components needed:
Wires
(Common wire, high power wire, hold wire)
Mechanical Flipper
(Flipper Bat, rod, bushing)
Solenoid with two coils
(Bushing, coil sleeve, plunger, link)
End of stroke switch
#include <LiquidCrystal.h>
const int buttonPin = A2;
int solenoid = A3;
int buttonState = 0;
int Con=60;
int score_increase_button = 8;
int ball_count_button = 13;
int score = 0;
int ball_count = 5;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
pinMode(solenoid, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
analogWrite(6,Con);
lcd.begin(16, 2);
pinMode(score_increase_button, INPUT_PULLUP);
pinMode(ball_count_button, INPUT_PULLUP);
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == LOW) {
digitalWrite(solenoid, HIGH);
} else {
digitalWrite(solenoid, LOW);
}
int buttonValueOne = digitalRead(score_increase_button);
int buttonValueTwo = digitalRead(ball_count_button);
if(buttonValueOne == LOW){
lcd.clear();
lcd.setCursor(6,0);
lcd.print("score ");
score=score+500;
lcd.print(score);
delay(300);
}else{
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("Pinball");
lcd.setCursor(5, 1);
lcd.print("Madness");
delay(300);
}
if(buttonValueTwo == LOW){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("ball count: ");
ball_count=ball_count-1;
lcd.print(ball_count);
delay(300);
}
}
#include <LiquidCrystal.h>
int Con=60;
int score_increase_button = 8;
int ball_count_button = 13;
int score = 0;
int ball_count = 5;
//connected pin
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//standard for LCD screen
void setup()
{
analogWrite(6,Con);
lcd.begin(16, 2);
pinMode(score_increase_button, INPUT_PULLUP);
pinMode(ball_count_button, INPUT_PULLUP);
}
void loop()
{
int buttonValueOne = digitalRead(score_increase_button);
int buttonValueTwo = digitalRead(ball_count_button);
if(buttonValueOne == LOW){
lcd.clear();
lcd.setCursor(6,0);
lcd.print("score ");
score=score+500;
lcd.print(score);
delay(300);
}else{
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("Pinball");
lcd.setCursor(5, 1);
lcd.print("Madness");
delay(300);
}
if(buttonValueTwo == LOW){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("ball count: ");
ball_count=ball_count-1;
lcd.print(ball_count);
delay(300);
}
}
This is a video of the bumpers working. We are triggering the switches underneath the playfeild to show the bumpers compressing.
This is a video of all three of the bumpers working. It shows the components, the wiring, and how the contacts touch to create a switch and trigger the solenoid. The final bumpers have the 3-D printed cone to serve as a spoon/contact with the copper piece underneath. The spoon is also wrapped in copper. There are two wires in both the pieces of copper; one wire goes to ground and another goes to a pin on the ardiuno. The solenoid is wired to the mosphet and 5V on the powersource. The mosphet is also wired to ground on the powersource, 5V and ground on the breadboard, and a pin on the arduino. When the ball pushes the cone, it pushes the spoon downwards so the contacts form a switch and trigger the solenoid. When the solenoid compresses, the 3-D printed round top is pulled down which pushes the ball back out.
This is a photo of what the target looks like underneath the playfield. Each target is wired to ground on the breadboard and a pin on the arduino.
This is a video of the targets working. They trigger the neopixels and add points to the scoreboard.
This is a video of the flippers functioning.
The flippers are mechanical and when the sides are pushed in, the flippers flip and keep the ball in play.
The lancher is pulled back and the springs launch it forward, propelling the ball forward. This is a video of the launcher being pulled back and springing forward.
When the target is clicked at the top on the "T", it pushes back on the clicker which it connected to the scoreboard. When the target is triggered, it activates the neopixels to flicker.
This is a video of the targets being pressed and triggering the neopixels.
This is the back of the scoreboard. There are four wires going from the LCD to the arduino; 5V, ground, SCA, and SCL.
This is a video of the targets increasing the score on the LCD. Each target is coded to increase the score by 500.
The pinball machine was one of the most challenging projects I've worked on in engineering and at school. Since the project was over the course of the full school year, I had every class period to work on it, but there were so many trial and errors. At the end of the project, I was very happy to have completed everything but I wish I had more time to perfect certain parts. I am most proud to have completed the bumper and learn about coding in C++.