Frisbee Launcher
Planning
My Fab Academy project is a Frisbee launcher that will help our school and others practice frisbee even if they are alone with accurately fast throws.
Brainstorming Process
I started brainstorming by coming up with Ideas, I also asked people around me about their problems in life and even my grandmother came up with an idea about a light bulb inserter. After thinking through the many ideas, I finally set my sight on a frisbee launcher.
Next, I drew out how I envisioned the launcher to look and work.
Finally, I planned out what I would be learning each week and what part of my final project would incorporate each week.
Description of the final goal
The goal for this frisbee launcher is to press a button and after a certain amount of time, the frisbee shooter shoots a frisbee over 50 yards to an accurate area.
How each thing will be done :
-
To shoot the frisbee, I plan to use a super fast flywheel and a wall on the other side to shoot the frisbee out and git it spin as well
-
To store the frisbees, I plan to have a column that holds the frisbees
-
To push the frisbees into the column, I will use a electronic piston to quickly push the frisbee into the fliwheel and reset before the next frisbee falls.
Extra Ideas I plan to Implement :
-
the entire thing can flip so 2 types of throws can be done
-
Moveable legs and control panel for uneven ground and flipping ability
Creating the Launcher
CADing the Launcher
part 1
I started CADing by choosing a bottom up design intent. This means that I started by creating a part and then created more and more and built upon what I had till I had a final design.
The first piece I designed was the wooden baseplate that would act as the fix part to build upon. I also decided that I would use a CNC machine cut this part out.Below is the 3D Model :
Next, I added in the curved wood area and 3D printed sliders as well.
Then, I used the mirror tool to create a baseplate for the top.
Issue #1
When cading the launcher, everything was going smoothly until I started to work on the disk holder. My idea for the holder was to make a column that would hold the frisbees un till they fall down into the launcher where they would rest on a plate to be hit by the piston. However, I quickly ran into the problem of how to attach the column and bottom plate in a way that would be sturdy yet allow the 2 pieces to be swapped around so it can fire 2 types of throws. My first idea was to use velcro but I quickly realized that the strength for the bottom piece would be questionable and not professional. I then pondered some more and realized that I could add the 2 pieces onto the screws that would hold the top and bottom baseplate together. After contemplation of any issues, I decided I would proceed with this choice.
part 2
I started this part 2 of Cading the launcher during week 7 of Fab academy. As I learned about the incredible usage of joints in week 7, I decided to get a head start on my final project by CNCing my final project during this week. However, that meant that the CNC job had to be big, which it is, and also have joints.
This is what I have at the end of my week 7 super fun modeling time!
The process of making successful joint areas
My first method I tried for making joints was to add the joints onto the straight parts of the laser cut wood and then use the extrusions to cut out same size holes for them to enter into. Then, I realized I had forgot about a major factor that could make this whole design fail.
Problem 1 - I forgot to make the tolerances! to fix this, I went into the sketch and turned the finger joints from the laser cut wood with the offset tool and made each area have the tolerance I set in a variables section.
Problem 2 - When I was adding in the joints, I decided that I wanted more room for screws if I need them in the worst case senary and for the sliding rails as well. However, things didn't edit as nicely as I hoped and I had to expand the baseplate which led to me solving a bunch of errors due to the baseplate changing.
Problem 3 - I realized that in order to make the pattern for the lasercutter's arc, I would need a flat plate so I redid all the curve and straight parts of the lasercut areas to be individual parts. Below is the pattern and piece I created for the main big curve.
Producing the frame
During week 7, I CNC'ed the plates that the frisbee shooter uses and laser cutted the arc and joint pieces on 1/8 inch wood. After I put it all together, it looked great.
CAM
To CNC a 3D or 2D object, I needed to run it through a CAM software. Within the CAM software, I assigned toolpaths to areas and lines which tell the CNC where and how to cut the wood. When using creating toolpaths, there are a few factors you need to be aware of.
Tabs
Whenever I had to cut something big out, rather than spending an our reducing the material to wood chips, I instead cut on the inside and use tabs to keep the big piece in the middle from interfering with the rest of the cut.
My Toolpath on CNC computer
CNCing the board
I used a ShotBot Alpha to CNC my final project plates which I used for this weeks assignment.
Air Cut
Before I CNCed my plates, I set the Z axis zero 1.5 inches above the board thickness and
issues encountered
go to week 7 to see my issues and how I solved them
CNCing Video and post-CNC work
After the CNC job finished, I proceeded to remove the tabs on my pieces and the brads in the wood.
Then, I went outside of the CNC room and used a dremel to ensure everything was nice.
Finally, I laser cut the joint pieces and jointed the pieces together. I purposefully left off the top so I can do the electronics, screws, ect.
Motor Research
During research, I looked for 3 main aspects. The first aspect I needed was a high RPM that would allow the disk to fly far and fast. The second aspect was the motor needed enough torque to squish the frisbee and shoot it out without getting stuck. Lastly, I wanted to get the cost as low as possible.
I looked through many different types of motors but my main issues were with cost and power supply needed. Most motors were around $150 - $200 and required 115 Volts of power. This was a little to demanding in all aspects for me so I continued looking and eventually came across this amazing motor.
the Ampflow economy E30 is a good performance low cost high RPM motor. It costs only 70 dollars, can be used at 24 volts or 48, and runs around 5600 RPM with peak horsepower at 1.1 and stall toque at 750 oz-in. This is the link to the motor Motor on amazon
MAJOR SAFETY ISSUE
This motor requires 600 Watts of power and 18 Amps of current. In other words, if I make a mistake or touch the circuit. I will die. literally, I will be electrocuted to death.
Because of this, I decided that risking my life was not worth my FAB final project.
To get around this issue, I decided to use a 3 prong plug-in spindle motor to shoot the frisbee. due to the fact it gets power from an outlet, this is a much safer option for me. I plan to test it later.
Motor Research Part 2
After testing my spindle as can be seen below, I proceeded to do more research and testing
During my research I game across this video of frisbee shooters, where the first shooter is almost exactly the same as my idea. This helped me confirm that what I am trying to do is very possible and that a super big and expensive motor is not necessarily needed to shoot the frisbee.
I found this video while I was at one of the Fab Saturday Sessions. During it, I conversed with Adrian Torres, Pablo from Fab Lab Leon, and Ricardo Marques who gave me great advice on motor drivers and design Ideas.
Midterm Review
The first thing I created was a lucid chart to plan out what I needed to do.
BOM
Name | Vendor | Quantity | Cost | Link |
---|---|---|---|---|
Motor (spindle) | At home | 1 | ||
1/2 inch plywood for main plates | In Lab | 1 | ||
1/8 inch plywood for laser cutting | In Lab | 1 | ||
TPU 3D Printer Filament | At Home | 1 | ||
PCB board | In Lab | 1 | ||
Rotary Encoder | In Lab | 1 | ||
OLED | In Lab | 1 | ||
CNC SHEILD board that goes atop an arduino with motor drivers | In Lab | 1 | ||
Wheel + D-Shaft | At Home | 1 |
Gantt Chart
Motor testing
Motor Attachment
To spin and throw the frisbee, I determined that I would need a squishy yet semi firm wheel. I also needed a wheel that I could secure in the callut of the spindle. Luckily for me, I found a 2.75 in rubber wheel that attaches to a d-shaft in my robotics parts. I figured that despite it being a bit small, the wheel would expand during high velocity causing it to be over 3 in. which is what I need.
I then brought in the wheel and had a second fortune of the spindles tightener having the same wrench size as our Ultimaker Milling machines in our lab so I was able to easily attach the d-shaft into the spindle. I will later test the wheel to see if it will stretch too much and explode or for any other problems I haven't thought of.
Safety Testing Procedure
I created a 3D holder for my spindle and got to work on printing it. I used a threaded hole provided on the spindle as well as a strong zip tie to hold the motor onto the part. Lastly, I added some clamps to prevent vibration as can be seen below.
Wheel 1 - Pre-Manufactured Rubber Wheel
The first wheel I tested was a GoBilda Rubber Gecko wheel. Below is a before and after picture
BEFORE
AFTER
To put what happened into words, the rubber part of the wheel expanded to the point of separating from the inside solid piece
Wheel 2 - Casted Silicon Wheel
The next wheel I tested was the wheel I created during molding and casting week. I was able to get a cool video of the results as well.
BEFORE
AFTER
1/4 speed replay :
This video illustrated that the wheel quickly expanded and then ripped off the screws causing a backlash to the spindle and sending the wheel flying.
Conclusion of the testing
I conclude that my spindle spins way to fast for both my wheels and my use of shooting the frisbee. This conclusion means I need to rethink the way I plan to shoot the frisbee. If I continue with my current design, I will have to buy a big expensive motor. Or, I could try a different approach to the shooting mechanism all together that won't put as much stress on one motor.
Reflecting on the current status of the Idea
Frisbee Launcher V2 - Part 1
After determining a different approach that relies less on the strength of the motor, I was recommended this video "Precision guided launcher turns noobs into pros". After I watched it, I kinda fell in love with the idea and the design but changing would mean I would have to restart. After a good amount of thought, I decided to build a mock up of both designs and see which worked the best. Go to Frisbee Launcher v2 page to see the progression of the other mockup.
Creating the Launcher - Part 2
New motor opens new opertunities
One of my teachers happened to have a strong and decently fast RC motor I could use. This brought me back to my original launcher Idea and I created a 3D printed motor mount for it on the bamboo printer. I also created a 3D printed wheel just so I could get a rough proof of concept.
Original Frisbee Launcher Idea Continued - Assembly of 1st Prototype
After I finished printing all motor parts, I started assembling all the parts onto the wood. This is how it looks without the top.
First Official Test
4 Feet!!!!!! This mock up proved that the design has the potential to work.
Upgrade Ideas / Trouble Shooting
So, I defiantly want a stronger and further throw out of my frisbee launcher. To do this, I came up with a few upgrades and future plans that I could test.
Upgrade 1 - Silicon Plastic Wheel
My first thought when I saw the weakness of the frisbee throw was that the 3D printed wheel simply did not have the grip to throw the frisbee at a high velocity. However, I also had to think about my previous silicon tests and how my wheel could explode / the hole areas expand allowing the wheel to fly off the shaft.
To solve both these problems, I came up with the idea of a silicon wheel with a 3D printed part embedded in it. the 3D printed part in this system has 2 main objectives. One, to attach the wheel to the shaft without expanding. And two, to keep the silicon from expanding to much. By putting the d-shaft shape in the middle and putting rings with holes on the outside, I hope to reign in the silicon while still getting its best qualities.
To actually create the 3D printed Silicon Wheel, I need a way to have the middle of the mold which would go with the wheel and the outside of the mold separate yet join together so there wouldn't be a leak. I also needed a way to keep the middle part centered and straight. I knew how important this would be because in previous spindle tests, the oscillations of the wheel literal threw the motor into the air.
After a bit of thinking, I created a little circle on the end of the middle 3D part and removed a slightly bigger circle on the mold itself. The tolerance makes it so that no material can get in and keeps the part upright and centered.
Sadly, the extra weight added onto the wheel by the silicon meant the wheel needed more force to spin which caused the D-Shaft in the 3D printed part to convert to a full circle meaning it would jut fall off.
Upgrade Testing Results
Sadly, the extra weight added onto the wheel by the silicon meant the wheel needed more force to spin which caused the D-Shaft in the 3D printed part to convert to a full circle meaning it would jut fall off.
I then decided to join the 2 ideas because it would fix the attachment issue.
Upgrade 2 - More Power
For having more power, I had 2 ideas in mind. The first idea is to increase the battery from 3cells to 4 cells on the 880KV motor. The second idea which I decided to try was to use a 2200KV motor. The downside of using a faster motor would mean less torque, but hopefully it will still have the torque needed
I created some 3D printed parts such as a motor mount, and a 3D printed wheel to test my theory.
Upgrade Testing Results
The installation of the faster motor went smoothly but sadly the 3D printed wheel was .5 in. too small and didn't contact the wheel. However, I decided it was still worth the effort and printed a slightly bigger new wheel.
Whelp, I printed a slightly bigger one and it still wasn't big enough so I decided to combine the 2 upgrades for time efficiency.
When the wheel touched the frisbee, the frisbee barely moved and you could hear that the 3D print had little to no friction. To solves this, like I said before, I combined upgrades 1 & 2 to get more grip with more power.
Upgrade 1 & 2 Combined (upgrade 3)
So, I combined the 2 ideas and created the wheel shown below. However, once again, I ran into problems. The first of my problems was a stupid mistake by me which was that the bottom of the silicon would hit the wood at high speeds due to the wheel being low. This would cause the entire wheel to stop. The other problem was that the wheel was too heavy, or had too much mass to spin at the fastest speed the motor spun at.
After the combo didn't work, I designed a lighter wheel that was a bit higher off the wood and started the print. In the meantime, I decided to give the 3D printed wheel another shot on the shooter. Only this time, I surrounded the wheel with velcro.
The first run I did, the velcro ended up getting torn off with a loud bang.
When I relized this was because air resistance on the small part of the wheel where there wasn't any velcro, I re-did the velcro so there were not spots for air to get trapped in.
I ran it and below are the results
It flew around 8 feet!!!!!!
After this success, I tested the friction between the velcro and the frisbee. Then I tested the friction between the Silicon wheel and the frisbee. My conclusion from these tests was that the silicon had around 2.5 times the amount of grip the velcro had. This made me super happy and makes me think the silicon version will be able to shoot the frisbee around 20 feet.
Upgrade 4 - previous version but less mass and taller
I quickly CADed up a new model and got printing.
Then I went to pour the silicon and let it sit. The final wheel is below.
At this point, I decided to do a bit of work on programming and hardware. You can find the doc. later on this page.
Upgrade Results
RIP. My only reaction. I was super confident in this design and then it proceeded to explode during testing. Below is a picture and video of the exploded wheel
Upgrade 5
My next thought for this wheel problem was that the material I was using, Moldstar Type 15 slow. This material is originally supposed to be a mold material and not really a robust casting material. Because of this, I gave a call to Reynolds Advanced Materials(Highly recommend) shop and they recommended a Urethane rubber with a shore(kinda like hardness) of 40A or 50A. However, this material cost $40 so I first scavenged through my schools materials and found a Moldstar 31T which has a shore of 30A so I decided to give it a try.
Upgrade Results
EXPLOSION!!!!!!!!!!!!!! I hate this stupid wheel, It explodes everything! Unlike my first silicon wheel explosion, this material tore off the wheel and shot shrapnel. Below is the explosion video and pictures.
Upgrade 6 (Buying materials from Reynolds)
So off I went on a 30 min drive to Reynolds to buy a material. When I arrived, I explained my project, issues, and requirements my material needed to the employee and he recommended me a Urethane Rubber Called PMC-746. He also provided a small test piece and I was happy with both it's grip and its toughness. I bought this material and started the cast.
Upgrade 6 results
After I poured the material into the wheel, I let it sit for 2 days and came back to a uncured cast. I tried poking it and it had a sticky jello consistency. I called the Reynolds to ask why it turned out like that and they didn't know where I went wrong. They recommended I throw it through an oven so I did that but the result didn't change.
I also made sure I did the correct mix ratio by creating a sample test and it still turned out bad. In conclusion, I think the material I bought is bad. I am too lazy to go back on another hour drive so I am looking at other solutions.
Upgrade 7 (Pre-Manufactured RC Wheel)
This time, I looked through the depths of amazon for an RC wheel that was 100mm, the size of the wheel I needed and found 1. I ordered it and it should arrive soon. When it does, I am going to 3D print a inside for the rubber wheel and then test it.
Upgrade 7 - 1 (Pre-Manufactured RC Wheel on 3D print)
The first upgrade I tried when the wheels arrived from amazon was to put the entire wheel with the foam still inside of it onto an axle. During my first tests, I learned that despite the wheel falling off when the motor went around 3/4 speed, it still didn't explode or break
Upgrade 7 - 2 (Cut RC wheel on 3D printed wheel)
The second upgrade I tried was to take the 3D printed wheel and put a ring of rubber formed by me cutting up a rubber wheel.
Upgrade 7 Results / Upgrade 8
Both upgrade 7-1 and 7-2 installs went great and I was super hyped to finally have a working wheel. Sadly, the 3D printed bottom broke off from the top on both of these wheels. After some thought, I came up with 3 possible solutions.
The first solution would be the order the parts in metal. The downside of this solution is that I need time to order and get the part shipped to me so that option fell off the table.
The second idea I had was longer screws to hold the wheel on. This would allow me to make the bottom plate thicker and therefore reduce the probability of the wheel breaking. The downside of this solution is that I need 2 days to get the parts ordered and I still don't know if it will work
The last Idea I had was to add a bearing at the top of the wheel. This would negate the vibrations causing less stress on the motor henceforth preventing the 3D printed part from breaking. The downside of this solution and the second one is that I need 2 days to get parts ordered and I still don't know if either will truly work.
After a bit of thought I decided to go with the third idea and built some extra parts to join the wheel with the bearing block.
I tested the upgrade and it worked!!! the frisbee flew around 8 feet and I was super happy with it. The only sad part is that I think I have hit my limit on how much distance I can get out of my small drone motor and 12v battery.
Finishing the Frame and Assembly
The first thing I did to finish the frame was to laser cut the bottom plates for the frisbee holder.
Hardware for the launcher
Main PCB Hardware
For my hardware, I decided to take a multi board approach which means making multiple boards that can attach to each other allowing for more functionality to be added in the future.
I used KiCAD to create a board that will house my bluetooth compatible RP2040 XIAO nRF. Below is the schematic, board layout, case, and finished product.
UI PCB board
After creating the main board, I proceeded to make other boards, casings and wire it all together as shown below. I also wired a ribbon wire which connects to my physical UI where the 11 wires from the OLED, Binary Encoder, and button are condensed into a nice 8 wires all inside a super nice 3D printed case that slides onto the launcher. This board also contained the pull down resistor needed for my button. Lastly, I created a user chart that says what wires are attached to what.
Power Source / Motor Hardware
The motor I ended up sticking with is an RC airplane motor which connects to a RC motor controller(ESC) that then splits into a power source, a 12v lithium battery in my case, and a servo chord for controlling the motor. This servo cord usually connects to a receiver to be controlled by the RC controller. However, in my case, I was able to take the servo chord and route it to my board. To my pleasant surprise, the ESC has a built in regulator that takes the 12v power and delivers 5v worth of power through the servo cable which let me power my entire board off of one battery.
As I said before, I created a small board that would attach back to the XIAO board I milled and added in an on switch so I could turn off the launcher without needing to unplug the battery. This board also has a servo port for the solenoid which I added in later. The fully milled and soldered board is shown below.
Solenoid Hardware
To push the frisbee into the shooter, I used a 9v solenoid connected to a mosfet board. I found the mosfet board in the lab as I was searching for a way to deliver 9v of power to my solenoid using 3.3v, what a pin on high gives out, to activate it. Basically, the mosfit board takes in my 9v power from the 9v battery and when power is put through the PWM side of the pin's, the 9v is connected to the opposite side which contains my solenoid. I glued the mosfet board to the back of the 9v battery case and then velcro'd the whole thing to the launcher
System Integration / Electrical Management
To combine all the wires, cases, and the actual physical launcher, I used velcro'd cases. These cases are mostly 3D printed with some exceptions. Then, I added velcro and also used a bit of hot glue tp attach boards to opportune places on the cases.Below is a picture of all the electrical components arranged on the bottom of my launcher.
Programming the Launcher
Thought Process
For the programming of my launcher, I used many different examples and codes from my Fab experience. I then took all the codes and integrated them into one big code. I started by adding in all the libraries and pinouts. Then I went through the codes finding parts I needed and bringing them into my program. Finally, I troubleshooted the integration issues that arose and got the code below. The codes I have referenced were my machine week project, a bit of ChatGPT motor code, and some help from friends such as Richard Shan.
Final Code With Explanation
The first part of my code is the library setups and later on the pinMode commands. I also used #define when the situation allowed because it doesn't take up memory space unlike a variable. Lastly, I also set up serial which allowed me to troubleshoot problems such as the fire button not working due to wires touching.
#include<Servo.h> // MOTOR CONTROL
#define MotorPin D2
#define Solonoid D1
Servo esc;
#include <SPI.h> //OLED STUFF
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
static const unsigned char PROGMEM logo_bmp[] =
{ 0b00000000, 0b11000000,
0b00000001, 0b11000000,
0b00000001, 0b11000000,
0b00000011, 0b11100000,
0b11110011, 0b11100000,
0b11111110, 0b11111000,
0b01111110, 0b11111111,
0b00110011, 0b10011111,
0b00011111, 0b11111100,
0b00001101, 0b01110000,
0b00011011, 0b10100000,
0b00111111, 0b11100000,
0b00111111, 0b11110000,
0b01111100, 0b11110000,
0b01110000, 0b01110000,
0b00000000, 0b00110000 }; // OLED done
#define CLK_PIN D10 // Rotary Encoder Stuff
#define DT_PIN D9
#define SW_PIN D8
int counter = 0;
int CLK_state;
int CLK_laststate;
int storedValues[2]; // Array to store the values
int buttonPressCounter = 0; // Counter for button presses
bool valstored = false;
int Distance = 1;
int Delay=1;
bool AlreadyFired = false;
// Start Button
int ButtonPin = D0;
int LightStrip = D3;
void setup() {
esc.attach(MotorPin);
pinMode(ButtonPin, INPUT);
pinMode(Solonoid, OUTPUT);
pinMode(CLK_PIN, INPUT);
pinMode(DT_PIN, INPUT);
pinMode(SW_PIN, INPUT_PULLUP);
pinMode(LightStrip, OUTPUT);
Serial.begin(9600);
// initialize OLED display with address 0x3C for 128x64
if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
while (true);
}
delay(2000); // wait for initializing
oled.clearDisplay(); // clear display
oled.setTextSize(1); // text size
oled.setTextColor(WHITE); // text color
oled.setCursor(0, 0); // position to display
oled.println("Starting Up"); // text to display
oled.display();
delay(500); // show on OLED
oled.clearDisplay();
oled.setTextSize(2);
esc.writeMicroseconds(1000);
delay(1000); // MOTOR INITAITING
}
The first part of the looped code is setup for the actual launch. It includes an array that stores both distance and delay for later use. This part also contains the OLED code for displaying said values so the user can see what value they are selecting.
void loop(){
// SETUP / GETTING UI INPUT
CLK_state = digitalRead(CLK_PIN);
if (digitalRead(SW_PIN) == LOW) {
Serial.println("Value Stored!");
oled.display();
storedValues[buttonPressCounter] = counter; // Store the current value
buttonPressCounter++; // Increment button press counter
if (buttonPressCounter >= 2) { // If pressed three times
// Print all stored values
oled.setTextSize(1);
oled.clearDisplay();
oled.setCursor(5, 10); // position to display
oled.print("Click Below To Fire");
oled.setCursor(5, 30); // position to display
oled.print("Distance : ");
Distance = (abs(storedValues[0]));
oled.print(Distance);
oled.setCursor(5, 50);
oled.print("Delay : ");
Delay = (abs(storedValues[1]));
oled.print(Delay+1);
valstored = true;
}
// Reset button press counter and clear stored values
delay(250); // Debouncing delay
}
if (CLK_state != CLK_laststate){
if (digitalRead(DT_PIN) != CLK_state) {
counter ++;
} else {
counter --;
}
CLK_laststate = CLK_state;
if (buttonPressCounter == 0){
oled.clearDisplay();
oled.setCursor(20,30);
oled.print("Distance = ");
oled.println(abs(counter));
oled.display();
} else if (buttonPressCounter == 1){
oled.clearDisplay();
oled.setCursor(20,30);
oled.print("Delay = ");
oled.println((abs(counter)+1));
oled.display();
}
Serial.print("Counter: ");
Serial.println(counter);
}
if (counter >= 9 || counter <=-9){
counter = 0;
}
The part below Activates the Shoot command I talk about in the next code snippet when the button is pressed. The reason I had to use analog read instead of digital read for the button was because I was getting different values outputted from the button due to the design so I chose analog read as my solution.
// END OF SETTING UP STUFF
int ButtonPressed = analogRead(ButtonPin);
if (ButtonPressed >= 400){
Serial.println("Fire");
delay(250); //Debounce
// FIRE THE WEOPON HERE!!!!
Shoot(abs(storedValues[0]), abs(storedValues[1]));
delay(1000);
NVIC_SystemReset();
}
}
'''
The next part of the code is a shooting function I created. This function accepts a integer distance and delay amount. Then it proceeds to use said amounts to run the motor, turn on LED's at the coolest times, and give the user enough time to run and catch the disk.
'''
void Shoot(int distance, int delayT){
int throttle = (distance*20);
int escOutput = map(throttle, 0, 180, 1000, 2000);
delay(delayT*1000);
digitalWrite(LightStrip, LOW);
esc.writeMicroseconds(escOutput);
delay(1000);
digitalWrite(LightStrip, HIGH);
delay(100);
digitalWrite(LightStrip, LOW);
digitalWrite(Solonoid, HIGH);
delay(3000);
digitalWrite(LightStrip, HIGH);
esc.writeMicroseconds(0);
}
Final Code
#include<Servo.h> // MOTOR CONTROL
#define MotorPin D2
#define Solonoid D1
Servo esc;
#include <SPI.h> //OLED STUFF
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
static const unsigned char PROGMEM logo_bmp[] =
{ 0b00000000, 0b11000000,
0b00000001, 0b11000000,
0b00000001, 0b11000000,
0b00000011, 0b11100000,
0b11110011, 0b11100000,
0b11111110, 0b11111000,
0b01111110, 0b11111111,
0b00110011, 0b10011111,
0b00011111, 0b11111100,
0b00001101, 0b01110000,
0b00011011, 0b10100000,
0b00111111, 0b11100000,
0b00111111, 0b11110000,
0b01111100, 0b11110000,
0b01110000, 0b01110000,
0b00000000, 0b00110000 }; // OLED done
#define CLK_PIN D10 // Rotary Encoder Stuff
#define DT_PIN D9
#define SW_PIN D8
int counter = 0;
int CLK_state;
int CLK_laststate;
int storedValues[2]; // Array to store the values
int buttonPressCounter = 0; // Counter for button presses
bool valstored = false;
int Distance = 1;
int Delay=1;
bool AlreadyFired = false;
// Start Button
int ButtonPin = D0;
int LightStrip = D3;
void setup() {
esc.attach(MotorPin);
pinMode(ButtonPin, INPUT);
pinMode(Solonoid, OUTPUT);
pinMode(CLK_PIN, INPUT);
pinMode(DT_PIN, INPUT);
pinMode(SW_PIN, INPUT_PULLUP);
pinMode(LightStrip, OUTPUT);
Serial.begin(9600);
// initialize OLED display with address 0x3C for 128x64
if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
while (true);
}
delay(2000); // wait for initializing
oled.clearDisplay(); // clear display
oled.setTextSize(1); // text size
oled.setTextColor(WHITE); // text color
oled.setCursor(0, 0); // position to display
oled.println("Starting Up"); // text to display
oled.display();
delay(500); // show on OLED
oled.clearDisplay();
oled.setTextSize(2);
esc.writeMicroseconds(1000);
digitalWrite(Solonoid, LOW);
delay(1000); // MOTOR INITAITING
}
void loop(){
// SETUP / GETTING UI INPUT
CLK_state = digitalRead(CLK_PIN);
if (digitalRead(SW_PIN) == LOW) {
Serial.println("Value Stored!");
oled.display();
storedValues[buttonPressCounter] = counter; // Store the current value
buttonPressCounter++; // Increment button press counter
if (buttonPressCounter >= 2) { // If pressed three times
// Print all stored values
oled.setTextSize(1);
oled.clearDisplay();
oled.setCursor(5, 10); // position to display
oled.print("Click Below To Fire");
oled.setCursor(5, 30); // position to display
oled.print("Distance : ");
Distance = (abs(storedValues[0]));
oled.print(Distance);
oled.setCursor(5, 50);
oled.print("Delay : ");
Delay = (abs(storedValues[1]));
oled.print(Delay+1);
valstored = true;
}
// Reset button press counter and clear stored values
delay(250); // Debouncing delay
}
if (CLK_state != CLK_laststate){
if (digitalRead(DT_PIN) != CLK_state) {
counter ++;
} else {
counter --;
}
CLK_laststate = CLK_state;
if (buttonPressCounter == 0){
oled.clearDisplay();
oled.setCursor(20,30);
oled.print("Distance = ");
oled.println(abs(counter));
oled.display();
} else if (buttonPressCounter == 1){
oled.clearDisplay();
oled.setCursor(20,30);
oled.print("Delay = ");
oled.println((abs(counter)+1));
oled.display();
}
Serial.print("Counter: ");
Serial.println(counter);
}
if (counter >= 9 || counter <=-9){
counter = 0;
}
// END OF SETTING UP STUFF
int ButtonPressed = analogRead(ButtonPin);
if (ButtonPressed >= 400){
Serial.println("Fire");
delay(250); //Debounce
// FIRE THE WEOPON HERE!!!!
Shoot(abs(storedValues[0]), abs(storedValues[1]));
delay(1000);
NVIC_SystemReset();
}
}
void Shoot(int distance, int delayT){
int throttle = (distance*20);
int escOutput = map(throttle, 0, 180, 1000, 2000);
delay(delayT*1000);
digitalWrite(LightStrip, LOW);
esc.writeMicroseconds(escOutput);
delay(1000);
digitalWrite(LightStrip, HIGH);
delay(100);
digitalWrite(LightStrip, LOW);
digitalWrite(Solonoid, HIGH);
delay(3000);
digitalWrite(LightStrip, HIGH);
digitalWrite(Solonoid, LOW);
esc.writeMicroseconds(0);
}
All Files
Final Launcher
I'm super happy with how my project worked out. I hoped for 15 feet and my project delivered. From molding and casting to CNCing and coding, I have grown my skill set and become more well versed in real world technologies. I have learned so many new skills and have gotten closer with all my fab buddies.