/*
Pseudocode:
1. Define constants for button and LED pin assignments.
2. Define initial and low ammo counts for three weapon profiles (Assault Rifle, Shotgun, Sniper).
3. Define variables to keep track of current ammo counts for each weapon profile.
4. Define variables to store the current weapon profile and the last states of the buttons.
5. Define variables to manage time delays for switching profiles and shooting.
6. Setup:
1. Configure button pins as inputs.
2. Configure LED pins as outputs.
3. Initialize serial communication.
4. Call functions to update the profile and ammo status.
7. Loop:
1. Read the states of the buttons.
2. Handle button 1 press to change profiles:
a. Check if the button state has changed and enough time has passed since the last switch.
b. If button 1 is pressed, update the profile and reset the last switch time.
3. Handle button 2 press to shoot:
a. Check if the button state has changed.
b. If button 2 is pressed, call the shoot function.
4. Handle button 3 press to reload:
a. Check if the button state has changed.
b. If button 3 is pressed, call the reload function.
8. Define the shoot function:
1. Get the current ammo count for the active profile.
2. If there is ammo left, simulate a bullet shot, decrease the ammo count, and update the ammo status.
3. If there is no ammo, print a message indicating the weapon is out of ammo.
9. Define the updateProfile function:
1. Print the active profile.
2. Set the RGB LED color based on the active profile.
3. Update the ammo status.
10. Define the updateAmmoStatus function:
1. Get the low ammo threshold and current ammo count for the active profile.
2. If ammo is below the threshold, turn on the green LED; otherwise, turn it off.
3. Print the current ammo count.
11. Define the reload function:
1. Reset the ammo count to the initial value for the active profile.
2. Print a reload message and update the ammo status.
12. Define the getCurrentAmmo function:
1. Return a pointer to the current ammo variable based on the active profile.
13. Define the setRGBColor function:
1. Set the RGB LED color by writing the provided red, green, and blue values to the respective pins.
*/
#include <Arduino.h>
// Define constants for button and LED pin assignments.
#define BUTTON1 23
#define BUTTON2 19
#define BUTTON3 22
#define RX_PIN 10
#define TX_PIN 9
#define LED1 0 // Red LED
#define LED2 2 // Green LED
#define RGB_RED 4
#define RGB_GREEN 16
#define RGB_BLUE 17
// Define initial ammo counts for each weapon profile
const int ammoAssaultRifleInitial = 30;
const int ammoShotgunInitial = 10;
const int ammoSniperInitial = 5;
// Define low ammo thresholds for each profile
const int lowAmmoThresholdAssaultRifle = 5;
const int lowAmmoThresholdShotgun = 3;
const int lowAmmoThresholdSniper = 2;
// Define variables to keep track of current ammo counts for each weapon profile
int currentAmmoAssaultRifle = ammoAssaultRifleInitial;
int currentAmmoShotgun = ammoShotgunInitial;
int currentAmmoSniper = ammoSniperInitial;
// Define variables to store the current weapon profile and the last states of the buttons
int profile = 1; // 1: Assault Rifle, 2: Shotgun, 3: Sniper
bool button1LastState = LOW;
bool button2LastState = LOW;
bool button3LastState = LOW;
// Define variables to manage time delays for switching profiles and shooting
unsigned long lastSwitchTime = 0; // Last time the weapon was switched
unsigned long switchDelay = 500; // Delay for weapon switching (in milliseconds)
unsigned long lastShootTime = 0; // Last time a shot was fired
unsigned long shootDelay = 100; // Delay between shots for Assault Rifle (in milliseconds)
// Function declarations
void updateProfile();
void updateAmmoStatus();
void shoot();
void reload();
int* getCurrentAmmo();
void setRGBColor(int red, int green, int blue);
// Setup function: configure pins and initialize communication
void setup() {
pinMode(BUTTON1, INPUT);
pinMode(BUTTON2, INPUT);
pinMode(BUTTON3, INPUT);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(RGB_RED, OUTPUT);
pinMode(RGB_GREEN, OUTPUT);
pinMode(RGB_BLUE, OUTPUT);
Serial.begin(115200);
Serial.println("ESP32 started.");
updateProfile();
updateAmmoStatus();
}
// Loop function: handle button presses and update states
void loop() {
unsigned long currentTime = millis();
// Read the current state of the buttons
bool button1State = digitalRead(BUTTON1);
bool button2State = digitalRead(BUTTON2);
bool button3State = digitalRead(BUTTON3);
// Handle Button 1 for changing profiles
if (button1State != button1LastState) {
if (button1State == HIGH && currentTime - lastSwitchTime >= switchDelay) {
// Button 1 was pressed and enough time has passed since the last switch
profile = (profile % 3) + 1;
updateProfile();
lastSwitchTime = currentTime; // Update last switch time
}
delay(50); // Simple debounce delay
}
button1LastState = button1State;
// Handle Button 2 for shooting
if (button2State != button2LastState) {
if (button2State == HIGH) {
// Button 2 was pressed
shoot();
}
delay(50); // Simple debounce delay
}
button2LastState = button2State;
// Handle Button 3 for reloading
if (button3State != button3LastState) {
if (button3State == HIGH) {
// Button 3 was pressed
reload();
}
delay(50); // Simple debounce delay
}
button3LastState = button3State;
}
// Define the shoot function
void shoot() {
int *currentAmmo = getCurrentAmmo();
if (*currentAmmo > 0) {
digitalWrite(LED1, HIGH);
Serial.print("Bullet shot from ");
switch (profile) {
case 1:
Serial.println("Assault Rifle");
break;
case 2:
Serial.println("Shotgun");
break;
case 3:
Serial.println("Sniper");
break;
}
delay(100); // Simulate bullet shot delay
digitalWrite(LED1, LOW);
(*currentAmmo)--;
updateAmmoStatus();
} else {
switch (profile) {
case 1:
Serial.print("Assault Rifle ");
break;
case 2:
Serial.print("Shotgun ");
break;
case 3:
Serial.print("Sniper ");
break;
}
Serial.println("out of ammo");
}
}
// Define the updateProfile function
void updateProfile() {
switch (profile) {
case 1:
Serial.println("ASSAULT RIFLE ACTIVATED");
setRGBColor(0, 0, 0); // WHITE
break;
case 2:
Serial.println("SHOTGUN ACTIVATED");
setRGBColor(255, 255, 0); // YELLOW
break;
case 3:
Serial.println("SNIPER ACTIVATED");
setRGBColor(0, 0, 255); // BLUE
break;
}
updateAmmoStatus();
}
// Define the updateAmmoStatus function
void updateAmmoStatus() {
int lowAmmoThreshold;
int currentAmmo = *getCurrentAmmo();
switch (profile) {
case 1:
lowAmmoThreshold = lowAmmoThresholdAssaultRifle;
break;
case 2:
lowAmmoThreshold = lowAmmoThresholdShotgun;
break;
case 3:
lowAmmoThreshold = lowAmmoThresholdSniper;
break;
}
if (currentAmmo <= lowAmmoThreshold) {
digitalWrite(LED2, HIGH); // Turn on GREEN LED when ammo is low
} else {
digitalWrite(LED2, LOW); // Turn off GREEN LED otherwise
}
Serial.print("Ammo: ");
Serial.println(currentAmmo);
}
// Define the reload function
void reload() {
switch (profile) {
case 1:
currentAmmoAssaultRifle = ammoAssaultRifleInitial;
break;
case 2:
currentAmmoShotgun = ammoShotgunInitial;
break;
case 3:
currentAmmoSniper = ammoSniperInitial;
break;
}
Serial.println("Gun reloaded");
updateAmmoStatus();
}
// Define the getCurrentAmmo function
int* getCurrentAmmo() {
switch (profile) {
case 1:
return ¤tAmmoAssaultRifle;
case 2:
return ¤tAmmoShotgun;
case 3:
return ¤tAmmoSniper;
}
return nullptr; // This should never be reached
}
// Define the setRGBColor function
void setRGBColor(int red, int green, int blue) {
analogWrite(RGB_RED, red);
analogWrite(RGB_GREEN, green);
analogWrite(RGB_BLUE, blue);
}