-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNerfZeus.ino
208 lines (186 loc) · 5.92 KB
/
NerfZeus.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#include <LiquidCrystal.h>
#include <FastLED.h>
#define NUM_LEDS 16
#define LED_DATA_PIN 11
#define LED_POWER_PIN 10
#define MOTOR_TRIGGER_PIN 4//detects user pressing motor trigger
#define MOTOR_POWER_PIN 6//controls power sent to the motor
#define MAIN_TRIGGER_PIN 13//detects user pressing main trigger pin
#define SOLENOID_POWER_PIN 12//controls whether the solenoid is triggerable
#define IR_SENSOR_PIN A6
#define VOLTMETER_PIN A7
LiquidCrystal lcd(8, 7, 9, 3, 2, 1);
byte motorFactor = 250;//motor speed value
byte ammo;//ammo count
int shotDelay = 500;//delay between shots in milliseconds
CRGB leds[NUM_LEDS];
void setup() {
pinMode(MOTOR_POWER_PIN, OUTPUT);
pinMode(LED_POWER_PIN, OUTPUT);
pinMode(MOTOR_TRIGGER_PIN, INPUT);
pinMode(MAIN_TRIGGER_PIN, INPUT);
pinMode(SOLENOID_POWER_PIN, OUTPUT);
FastLED.setBrightness(30);
FastLED.addLeds<NEOPIXEL, LED_DATA_PIN>(leds, NUM_LEDS);
initialize();
reload();
}
void loop() {
while (digitalRead(MOTOR_TRIGGER_PIN) == HIGH) {//user pressed motor rev switch
digitalWrite(SOLENOID_POWER_PIN, HIGH);//activates solenoid
analogWrite(MOTOR_POWER_PIN, motorFactor);//enables motor
if (digitalRead(MAIN_TRIGGER_PIN) == HIGH) {
shoot();
delay(shotDelay);//delay between shots
}
}
digitalWrite(MOTOR_POWER_PIN, LOW);
updateVoltmeter();
delay(1);
}
//updates voltmeter and displays to LCD
void updateVoltmeter() {
float inputVoltage = (analogRead(VOLTMETER_PIN) * 5.0) / 1024.0;//converts the analog read output into a ratio out of 5V(analogRead(VOLTMETER_PIN) = 1024 when 5V)
float realVoltage = inputVoltage / (51.0 / 151.0);//voltage divider calculation max ~ 15V
lcd.setCursor(11, 1);
lcd.print(realVoltage);
}
//writes ammo variable value to LCD display
void updateAmmoCounter() {
if (ammo < 10) {
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(1, 1);
} else {
lcd.setCursor(0, 1);
}
lcd.print(ammo);
}
//updates strip for new ammo value
void decrimentStripLength() {
leds[12 - ammo] = CRGB::Black;
leds[13 - ammo] = CRGB::Black;
FastLED.show();
}
//resets ammo variable, updates LCD, and LED strip with this new value
void reload() {
ammo = 12;
updateAmmoCounter();
//fills LED strip
for (int i = 2; i < 14; i++) {
leds[i] = CRGB::Blue;
}
for (int i = 2; i < 8; i++) {//dims first LEDs in series
leds[i].fadeLightBy(235);
}
FastLED.show();
}
//interprets a main trigger pull
void shoot() {
ammo -= 2;//subtracts two from ammo total, IR sensor is too slow and will allow two balls beforing tripping
unsigned long start = millis();
while (analogRead(IR_SENSOR_PIN) != 0) {//while IR sensor detects no ball fired
if (millis() - start > 200 && digitalRead(MAIN_TRIGGER_PIN) == LOW) {//if no balls are fired withing 200ms and the user releases the main trigger
ammo = 0;
break;
} else if (millis() - start > 2000 && digitalRead(MAIN_TRIGGER_PIN) == HIGH) {//if the user pulls the trigger down on empty magazine for 2000ms = 2s
ammo = 0;
enterSettings();
break;
}
}
digitalWrite(SOLENOID_POWER_PIN, LOW);//disables power to the solenoid
if (ammo == 0) {
reload();
} else {
updateAmmoCounter();
decrimentStripLength();
}
}
//flashes red x amount of times
void flashRed(int repeat) {
for (repeat; repeat > 0; repeat--){
ledStripOff();
delay(100);//will be black for 100ms
for (int i = 0; i < 16; i++) {
leds[i] = CRGB::Red;
}
for (int i = 0; i < 8; i++) {//dims first LEDs in series
leds[i].fadeLightBy(200);
}
FastLED.show();
delay(10);//will be red for 10ms
}
}
//turns off the led strip
void ledStripOff() {
for (int i = 0; i < 16; i++) {
leds[i] = CRGB::Black;
}
FastLED.show();
}
//resets LED strip, LCD, and lightning bolt LED
void initialize() {
lcd.clear();
ledStripOff();
digitalWrite(LED_POWER_PIN, HIGH);
lcd.clear();
lcd.begin(16, 2);
lcd.print("Welcome, Alan");
lcd.setCursor(15, 1);
lcd.print("V");
leds[0] = CRGB::Blue;
}
//enters the settings page
void enterSettings() {
//disabling all blaster controls
digitalWrite(SOLENOID_POWER_PIN, LOW);
analogWrite(MOTOR_POWER_PIN, LOW);
digitalWrite(LED_POWER_PIN, LOW);
flashRed(5);
lcd.clear();
//prints to LCD user interface for changing shot delay and motor speed
lcd.setCursor(0, 0);
lcd.print("Motor:");
lcd.setCursor(6, 0);
lcd.print(motorFactor);
lcd.setCursor(0, 1);
lcd.print("Delay:");
lcd.setCursor(6, 1);
lcd.print(shotDelay);
//loop for user changing motor speed and delay between shots exits when user holds button for 4 seconds
unsigned long start = millis();//recording of when user presses button
boolean state = true;//true when user is changing delay between shots, false when changing motor speed
while(millis() - start < 4000) {
start = millis();//reset timer
while(digitalRead(MOTOR_TRIGGER_PIN) == HIGH && millis() - start < 4000) {//let clock run while user presses the motor trigger
delay(1);
}
if (millis() - start > 1000) {//swap user changes
state = !state;//switch state
} else if (millis() - start > 100) {
if (state) {//increment shot delay
if (shotDelay == 1000) {//max shot delay
lcd.setCursor(6, 1);
lcd.print(" ");//wipe screen, otherwise the last zero will not be overwritten when printing 100
shotDelay = 0;//reset to zero shot delay
} else {
shotDelay += 100;//increments of 100ms
}
//write change to LCD display
lcd.setCursor(6, 1);
lcd.print(shotDelay);
} else {//increment motor speed
if (motorFactor == 250) {//max motorFactor
motorFactor = 100;//reset to minimum motor speed
} else {
motorFactor += 15;//increments byte by 15
}
//write change to LCD display
lcd.setCursor(6, 0);
lcd.print(motorFactor);
}
}
}
initialize();//reset blaster with new user defined settings
}