The Aliens Legacy http://forum.alienslegacy.com/ |
|
my smartgun progress http://forum.alienslegacy.com/viewtopic.php?f=3&t=19377 |
Page 1 of 1 |
Author: | knoxvilles_joker [ Sun Feb 28, 2021 5:39 am ] |
Post subject: | my smartgun progress |
I had sourced a similar light control switch assembly to control the crybabyfx kit and added a short stunt clutch lever which is closest I can find to the actual lever but I had to mill it down to fit the matsucorp bracket. https://youtu.be/jLCYakcVmZI I also threw in the progress on my marine helmet using the spats kit. And yes those are deer antlers on them that were ethically harvested by my late grand father. |
Author: | knoxvilles_joker [ Sun Jan 21, 2024 12:38 am ] |
Post subject: | |
I am working on updating the code to include grenade sound triggering along with full/semi/burst modes. I have it set to display the modes for the moment. I still have to figure out how to redo the logic for semi/burst/full modes, or do i as the display is just cool itself. Initial logic structures made: Code: /*
CryBaby FX Kit v1.0, written by Sean Maio (outcry27@gmail.com) Designed for use with the Adafruit Pro Trinket and Adafruit audio FX board Credit and many thanks to the writers of the numerous tutorials available on both the Arduino and Adafruit websites, without which this project could never have been completed! Updated January 2024 Cobra_shipwreck adding grenade counter, second grenade display, and full/semi/burst triggering If you are using an actual motorcycle light switch assembly ( you need one with buttons: Horn, Highbeam, light, hazard, left and right signal) 1. Horn is the Fire Switch 2. High beam is the Grenade Switch 3. Hazard is the safety Switch 4. Left is Semi Auto (default is burst fire) 5. Right is Full auto 6. Light Switch is used for the Mosfet for the airsoft portion and is a manual battery disconnect for the LIPO the airsoft gun uses -Pin Map- Pro Trinket: (Micro pin noted in parenthesis) 0. Serial RX, connect to Audio FX Serial TX (on Micro labeled D1/TX/PD3) 1. Serial TX, connect to Audio FX Serial RX (on Micro labeled D0/RX/PD2) 3. Fire Switch -> GND (on Micro D3 is SCL, so use D4/PD4) 4. Safety toggle switch -> GND (on Micro use D5/PC6) 9. Muzzle LED, connect this to the GATE pin on the muzzle strobe MOSFET (on Micro use D9/PB5) 8. Grenade -> GND (on Micro D8/PB4) 7. Semi -> GND (on Micro D7/PE6) 6. Full -> GND (on Micro D6/PD7) Audio FX board: TX. Connect to Trinket Pin 2 (these cross over so this goes to RX on Micro) (disconnect while uploading via USB as this is used for USB too) RX. Connect to Trinket Pin 1 (these cross over so this goes to TX on Micro) UG. Jumper to GND to enable UART mode. (this allows direct serial triggering using the Serial.print command set(less wires used)) These are the invokations for the sound effects: Please note that the files are named specifically on the FX Sound Board to play when these are called serially. 1. This invokes the bootup sound: Serial.print("#0\n"); 2. This invokes the click sound: Serial.print("#2\n"); 3. This invokes the firing sound: Serial.print("#3\n"); 4. This invokes the Grenade sound:Serial.print("#1\n"); */ #include <Wire.h> #include <SoftwareSerial.h> #include "Adafruit_Soundboard.h" #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" // pins used for Serial communication with the audio board #define SFX_TX 1 #define SFX_RX 0 // This calls the LCD display for it to operate and it uses Digital Pins 2 and 3 for SCL/SDA on Micro, A4/A5 on Trinket Pro. SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX); Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, NULL); Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4(); // constants: const int triggerPin = 3; // the number of the firing trigger pin const int safetyPin = 4; // pin for the "safety" toggle //const int fireSoundPin = 6; // pin for the firing sound const int muzzlePin = 9; // the number of the LED pin //const int startSoundPin = 10; // pin for the "boot-up" sound //const int clickSoundPin = 11; // pin for the bolt "click" sound const int fireDelay = 50; // duration in milliseconds for each "shot" // these are the additional pins const int grenadePin = 8; // pin for the grenade sound const int fullPin = 7; // pin for fire selection mode select const int semiPin = 6; // other pin for fire selection mode select // variables: boolean safetyOn = false; int triggerState = 0; // variable for reading the trigger status int safetyState = 0; // variable for reading the safety switch status int lastTriggerState = 0; // previous state of the trigger int lastSafetyState = 0; // previous state of the safety switch int ammoCount = 299; String ammoDisp = String(ammoCount); // these are for the additional pins int grenadeCount = 6; //default grenade ammo count String grenadeDisp = String(grenadeCount); int fireSelect = 0; int lastgrenadetriggerState = 0; int grenadetriggerState = 0; int semiState = 0; int fullState = 0; boolean fullOn = false; boolean semiOn = false; int lastsemiState = 0; int lastfullState = 0; int lastburstState = 0 ; int burstState = 0; boolean burstOn = false; void setup() { // initialize the LED pin as an output: pinMode(muzzlePin, OUTPUT); // initialize the trigger and safety pins as input: pinMode(triggerPin, INPUT); pinMode(safetyPin, INPUT); // initialize the audio pins // pinMode(startSoundPin, INPUT); // pinMode(clickSoundPin, INPUT); // pinMode(fireTailSoundPin, INPUT); // pinMode(fireSoundPin, INPUT); // pinMode(triggerPin, INPUT); //duplicate // pinMode(safetyPin, INPUT); // duplicate // These are the additional pin declarations. pinMode(grenadePin, INPUT); pinMode(fullPin, INPUT); pinMode(semiPin, INPUT); // set up the audio trigger pins to give a path to GND when set to OUTPUT // this sets the initial led status to off on the muzzle strobe LEDs digitalWrite(muzzlePin, LOW); digitalWrite(triggerPin, HIGH); digitalWrite(safetyPin, HIGH); // digitalWrite(startSoundPin, LOW); // digitalWrite(clickSoundPin, LOW); // digitalWrite(fireTailSoundPin, LOW); // digitalWrite(fireSoundPin, LOW); // These are the additional button pin declarations. digitalWrite(grenadePin, HIGH); digitalWrite(fullPin, HIGH); digitalWrite(semiPin, HIGH); Serial.begin(9600); ss.begin(9600); alpha4.begin(0x70); // pass in the address alpha5.begin(0x71); delay(200); //give the audio board time to power up; otherwise bootup sound will be called before audio board is ready Serial.print("#0\n"); //this plays the bootup sound // Change this number if you change the default ammo count above to match alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '2'); alpha4.writeDigitAscii(2, '9'); alpha4.writeDigitAscii(3, '9'); alpha4.writeDisplay(); delay(500); for (int x = 4; x > 0; x--) { updateAmmoCounter(); ammoCount--; delay(50); } updateAmmoCounter(); } // this function calls the current value of ammoCount and writes it to the LED display void updateAmmoCounter() { String ammoDisp = String(ammoCount); if (ammoCount < 10) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, '0'); alpha4.writeDigitAscii(3, ammoDisp[0]); } else if (ammoCount < 100) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, ammoDisp[0]); alpha4.writeDigitAscii(3, ammoDisp[1]); } else if (ammoCount < 1000) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, ammoDisp[0]); alpha4.writeDigitAscii(2, ammoDisp[1]); alpha4.writeDigitAscii(3, ammoDisp[2]); } else if (ammoCount < 10000) { alpha4.writeDigitAscii(0, ammoDisp[0]); alpha4.writeDigitAscii(1, ammoDisp[1]); alpha4.writeDigitAscii(2, ammoDisp[2]); alpha4.writeDigitAscii(3, ammoDisp[3]); } alpha4.writeDisplay(); } //int ammoCount = 299; //String ammoDisp = String(ammoCount); // these are for the additional pins //int grenadeCount = 6; //default grenade ammo count //String grenadeDisp = String(grenadeCount); // alpha5.begin(0x71); void updateGrenadeCounter() { String grenadeDisp = String(grenadeCount); if (grenadeCount < 10) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, '0'); alpha5.writeDigitAscii(3, ammoDisp[0]); } else if (grenadeCount < 100) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, ammoDisp[0]); alpha5.writeDigitAscii(3, ammoDisp[1]); } else if (grenadeCount < 1000) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, ammoDisp[0]); alpha5.writeDigitAscii(2, ammoDisp[1]); alpha5.writeDigitAscii(3, ammoDisp[2]); } else if (grenadeCount < 10000) { alpha5.writeDigitAscii(0, ammoDisp[0]); alpha5.writeDigitAscii(1, ammoDisp[1]); alpha5.writeDigitAscii(2, ammoDisp[2]); alpha5.writeDigitAscii(3, ammoDisp[3]); } alpha5.writeDisplay(); } void setSafe() { safetyOn = true; alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); } void setArm() { safetyOn = false; alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(300); updateAmmoCounter(); } // pinMode(semiPin, INPUT); //const int fullPin = 7; // pin for fire selection mode select //const int semiPin = 6; // other pin for fire selection mode select //int semiState = 0; //int fullState = 0; //int safetyState = 0; //boolean safetyOn = false; //boolean fullOn = false; //boolean semiOn = false; void setSemi() { semiOn = false; alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(300); updateAmmoCounter(); } void setFull() { semiOn = false; alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(300); updateAmmoCounter(); } void setBrst() { burstOn = false; alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(300); updateAmmoCounter(); } //const int fullPin = 7; // pin for fire selection mode select //const int semiPin = 6; // other pin for fire selection mode select //int safetyState = 0; // variable for reading the safety switch status // pinMode(fullPin, INPUT); // pinMode(semiPin, INPUT); //int semiState = 0; //int fullState = 0; // --MAIN LOOP STARTS HERE-- void loop() { safetyState = digitalRead(safetyPin); semiState = digitalRead(semiPin); fullState = digitalRead(fullPin); //int lastgrenadetriggerState = 0; //int grenadetriggerState = 0' //const int grenadePin = 8; // pin for the grenade sound //const int fullPin = 7; // pin for fire selection mode select //const int semiPin = 6; // other pin for fire selection mode select //int grenadeCount = 6; //default grenade ammo count //String grenadeDisp = String(grenadeCount); //setFull(); //setSemi(); //int lastburstState = 0 ; //int burstState = 0; //boolean burstOn = false; grenadetriggerState = digitalRead(grenadePin); if (grenadetriggerState != lastgrenadetriggerState){ if (grenadetriggerState == HIGH) { } // this can be used to add a grenade flash using a declared pin later. the ethernet cable has no spare pins currently. while (grenadetriggerState == LOW) { Serial.print("#1\n"); grenadetriggerState = digitalRead(grenadePin); return; } if (grenadeCount <= 0) { grenadetriggerState = digitalRead(grenadePin); return; } if (grenadeCount > 0) { Serial.print("#3\n"); grenadeCount--; updateGrenadeCounter(); delay(10); delay(39); grenadetriggerState = digitalRead(grenadePin); if (grenadetriggerState == HIGH) { Serial.print("q\n"); } if (grenadeCount == 0){ Serial.print("q\n"); delay(10); Serial.print("#2\n"); } } else { return; } } lastgrenadetriggerState = grenadetriggerState; //const int fullPin = 7; // pin for fire selection mode select //const int semiPin = 6; // other pin for fire selection mode select //int safetyState = 0; // variable for reading the safety switch status // pinMode(fullPin, INPUT); // pinMode(semiPin, INPUT); //int semiState = 0; //int fullState = 0; // safetyState = digitalRead(safetyPin); //semiState = digitalRead(semiPin); // fullState = digitalRead(fullPin); //int lastsemiState = 0; //int lastfullState = 0; //boolean fullOn = false; //boolean semiOn = false; if (safetyState != lastSafetyState) { if (safetyState == LOW) { if (safetyOn == false) { setSafe(); } else if (safetyOn == true) { setArm(); } } } if (semiState != lastsemiState) { if (semiState == LOW) { if (semiOn == false) { setBrst(); } else if (semiOn == true) { setSemi(); } } } if (fullState != lastfullState) { if (fullState == LOW) { if (fullOn == false) { setBrst(); } else if (fullOn == true) { setFull(); } } } triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } while (triggerState == LOW) { if (safetyOn == true) { Serial.print("#2\n"); triggerState = digitalRead(triggerPin); return; } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); return; } if (safetyOn == false) { if (ammoCount > 0) { Serial.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(39); triggerState = digitalRead(triggerPin); if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } if (ammoCount == 0){ digitalWrite(muzzlePin, LOW); Serial.print("q\n"); delay(10); Serial.print("#2\n"); } } } else { return; } } lastTriggerState = triggerState; } lastSafetyState = safetyState; lastfullState = fullState lastsemiState = semiState } |
Author: | metalalien [ Tue Jan 23, 2024 6:10 am ] |
Post subject: | |
I don't know what all that means but the pics in the video are very cool! |
Author: | knoxvilles_joker [ Wed Jan 24, 2024 4:11 am ] |
Post subject: | Re: |
metalalien wrote: I don't know what all that means but the pics in the video are very cool! Basically in addition to the base safety and fire function. It can fire in groups of three, full auto(current setting), or semi auto(one trigger pull one round)(the three modes require a logic redo), but for now those functions are just a snazzy display. Plus I am adding a grenade trigger function. This makes the setup more universal so if folks want to make a pulse rifle with sounds, they can do so. |
Author: | metalalien [ Fri Jan 26, 2024 3:01 am ] |
Post subject: | Re: Re: |
knoxvilles_joker wrote: metalalien wrote: I don't know what all that means but the pics in the video are very cool! Basically in addition to the base safety and fire function. It can fire in groups of three, full auto(current setting), or semi auto(one trigger pull one round)(the three modes require a logic redo), but for now those functions are just a snazzy display. Plus I am adding a grenade trigger function. This makes the setup more universal so if folks want to make a pulse rifle with sounds, they can do so. Very cool! Glad you understand all that! ![]() |
Author: | 88reaper88 [ Fri Jan 26, 2024 8:47 pm ] |
Post subject: | |
Wouldn’t it be easier to buy an airsoft mosfet and wire the sound function to it instead of a motor? |
Author: | knoxvilles_joker [ Mon Jan 29, 2024 1:19 am ] |
Post subject: | Re: |
88reaper88 wrote: Wouldn’t it be easier to buy an airsoft mosfet and wire the sound function to it instead of a motor? I have one as part of the setup as well |
Author: | knoxvilles_joker [ Mon Mar 04, 2024 11:11 am ] |
Post subject: | Re: my smartgun progress |
Did some work on it and fixed some syntax errors: Code: /*
CryBaby FX Kit v1.0, written by Sean Maio (outcry27@gmail.com) Designed for use with the Adafruit Pro Trinket and Adafruit audio FX board Credit and many thanks to the writers of the numerous tutorials available on both the Arduino and Adafruit websites, without which this project could never have been completed! Updated January 2024 Cobra_shipwreck adding grenade counter, second grenade display, and full/semi/burst triggering If you are using an actual motorcycle light switch assembly ( you need one with buttons: Horn, Highbeam, light, hazard, left and right signal) 1. Horn is the Fire Switch 2. High beam is the Grenade Switch 3. Hazard is the safety Switch 4. Left is Semi Auto (default is burst fire) 5. Right is Full auto 6. Light Switch is used for the Mosfet for the airsoft portion and is a manual battery disconnect for the LIPO the airsoft gun uses -Pin Map- Pro Trinket: (Micro pin noted in parenthesis) 0. Serial RX, connect to Audio FX Serial TX (on Micro labeled D1/TX/PD3) 1. Serial TX, connect to Audio FX Serial RX (on Micro labeled D0/RX/PD2) 3. Fire Switch -> GND (on Micro D3 is SCL, so use D4/PD4) 4. Safety toggle switch -> GND (on Micro use D5/PC6) 9. Muzzle LED, connect this to the GATE pin on the muzzle strobe MOSFET (on Micro use D9/PB5) 8. Grenade -> GND (on Micro D8/PB4) 7. Semi -> GND (on Micro D7/PE6) 6. Full -> GND (on Micro D6/PD7) Audio FX board: TX. Connect to Trinket Pin 2 (these cross over so this goes to RX on Micro) (disconnect while uploading via USB as this is used for USB too) RX. Connect to Trinket Pin 1 (these cross over so this goes to TX on Micro) UG. Jumper to GND to enable UART mode. (this allows direct serial triggering using the Serial.print command set(less wires used)) These are the invokations for the sound effects: Please note that the files are named specifically on the FX Sound Board to play when these are called serially. 1. This invokes the bootup sound: Serial.print("#0\n"); 2. This invokes the click sound: Serial.print("#2\n"); 3. This invokes the firing sound: Serial.print("#3\n"); 4. This invokes the Grenade sound:Serial.print("#1\n"); */ #include <Wire.h> #include <SoftwareSerial.h> #include "Adafruit_Soundboard.h" #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" // pins used for Serial communication with the audio board #define SFX_TX 1 #define SFX_RX 0 // This calls the LCD display for it to operate and it uses Digital Pins 2 and 3 for SCL/SDA on Micro, A4/A5 on Trinket Pro. SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX); Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, NULL); Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4(); Adafruit_AlphaNum4 alpha5 = Adafruit_AlphaNum4(); // constants: const int triggerPin = 5; // the number of the firing trigger pin const int safetyPin = 4; // pin for the "safety" toggle const int fireSoundPin = 8; // pin for the firing sound const int muzzlePin = 9; // the number of the LED pin const int startSoundPin = 9; // pin for the "boot-up" sound const int clickSoundPin = 4; // pin for the bolt "click" sound const int grenadeSoundPin = 5; const int fireDelay = 50; // duration in milliseconds for each "shot" // these are the additional pins const int grenadePin = 8; // pin for the grenade sound const int fullPin = 7; // pin for fire selection mode select const int semiPin = 6; // other pin for fire selection mode select // variables: boolean safetyOn = false; int triggerState = 0; // variable for reading the trigger status int safetyState = 0; // variable for reading the safety switch status int lastTriggerState = 0; // previous state of the trigger int lastSafetyState = 0; // previous state of the safety switch int ammoCount = 299; String ammoDisp = String(ammoCount); // these are for the additional pins int grenadeCount = 6; //default grenade ammo count String grenadeDisp = String(grenadeCount); int fireSelect = 0; int lastgrenadetriggerState = 0; int grenadetriggerState = 0; int semiState = 0; int fullState = 0; boolean fullOn = false; boolean semiOn = false; int lastsemiState = 0; int lastfullState = 0; int lastburstState = 0 ; int burstState = 0; boolean burstOn = false; void setup() { // initialize the LED pin as an output: pinMode(muzzlePin, OUTPUT); // initialize the trigger and safety pins as input: pinMode(triggerPin, INPUT); pinMode(safetyPin, INPUT); // initialize the audio pins pinMode(startSoundPin, INPUT); pinMode(clickSoundPin, INPUT); // pinMode(fireTailSoundPin, INPUT); pinMode(fireSoundPin, INPUT); pinMode(grenadeSoundPin, INPUT); // pinMode(triggerPin, INPUT); //duplicate // pinMode(safetyPin, INPUT); // duplicate // These are the additional pin declarations. pinMode(grenadePin, INPUT); pinMode(fullPin, INPUT); pinMode(semiPin, INPUT); // set up the audio trigger pins to give a path to GND when set to OUTPUT // this sets the initial led status to off on the muzzle strobe LEDs digitalWrite(muzzlePin, LOW); digitalWrite(triggerPin, HIGH); digitalWrite(safetyPin, HIGH); // These are the additional button pin declarations. digitalWrite(grenadePin, HIGH); digitalWrite(fullPin, HIGH); digitalWrite(semiPin, HIGH); Serial.begin(9600); ss.begin(9600); alpha4.begin(0x70); // pass in the address alpha5.begin(0x71); delay(200); //give the audio board time to power up; otherwise bootup sound will be called before audio board is ready Serial.print("#11\n"); //this plays the bootup sound // Change this number if you change the default ammo count above to match alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '2'); alpha4.writeDigitAscii(2, '9'); alpha4.writeDigitAscii(3, '9'); alpha4.writeDisplay(); delay(500); for (int x = 4; x > 0; x--) { updateAmmoCounter(); ammoCount--; delay(50); } updateAmmoCounter(); } // this function calls the current value of ammoCount and writes it to the LED display void updateAmmoCounter() { String ammoDisp = String(ammoCount); if (ammoCount < 10) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, '0'); alpha4.writeDigitAscii(3, ammoDisp[0]); } else if (ammoCount < 100) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, ammoDisp[0]); alpha4.writeDigitAscii(3, ammoDisp[1]); } else if (ammoCount < 1000) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, ammoDisp[0]); alpha4.writeDigitAscii(2, ammoDisp[1]); alpha4.writeDigitAscii(3, ammoDisp[2]); } else if (ammoCount < 10000) { alpha4.writeDigitAscii(0, ammoDisp[0]); alpha4.writeDigitAscii(1, ammoDisp[1]); alpha4.writeDigitAscii(2, ammoDisp[2]); alpha4.writeDigitAscii(3, ammoDisp[3]); } alpha4.writeDisplay(); } void updateGrenadeCounter() { String grenadeDisp = String(grenadeCount); if (grenadeCount < 10) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, '0'); alpha5.writeDigitAscii(3, ammoDisp[0]); } else if (grenadeCount < 100) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, ammoDisp[0]); alpha5.writeDigitAscii(3, ammoDisp[1]); } else if (grenadeCount < 1000) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, ammoDisp[0]); alpha5.writeDigitAscii(2, ammoDisp[1]); alpha5.writeDigitAscii(3, ammoDisp[2]); } else if (grenadeCount < 10000) { alpha5.writeDigitAscii(0, ammoDisp[0]); alpha5.writeDigitAscii(1, ammoDisp[1]); alpha5.writeDigitAscii(2, ammoDisp[2]); alpha5.writeDigitAscii(3, ammoDisp[3]); } alpha5.writeDisplay(); } void setSafe() { safetyOn = true; alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); } void setArm() { safetyOn = false; alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(300); updateAmmoCounter(); } void setSemi() { semiOn = false; alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(300); updateAmmoCounter(); } void setFull() { semiOn = false; alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(300); updateAmmoCounter(); } void setBrst() { burstOn = false; alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(300); updateAmmoCounter(); } // --MAIN LOOP STARTS HERE-- void loop() { grenadetriggerState = digitalRead(grenadePin); if (grenadetriggerState != lastgrenadetriggerState){ if (grenadetriggerState == HIGH) { } // this can be used to add a grenade flash using a declared pin later. the ethernet cable has no spare pins currently. while (grenadetriggerState == LOW) { Serial.print("#10\n"); grenadetriggerState = digitalRead(grenadePin); return; } if (grenadeCount <= 0) { grenadetriggerState = digitalRead(grenadePin); return; } if (grenadeCount > 0) { Serial.print("#10\n"); grenadeCount--; updateGrenadeCounter(); delay(5000); delay(39); grenadetriggerState = digitalRead(grenadePin); if (grenadetriggerState == HIGH) { Serial.print("q\n"); } if (grenadeCount == 0){ Serial.print("q\n"); delay(10); Serial.print("#12\n"); } } else { return; } lastgrenadetriggerState = grenadetriggerState; } safetyState = digitalRead(safetyPin); if (safetyState != lastSafetyState) { if (safetyState == LOW) { if (safetyOn == false) { setSafe(); } else if (safetyOn == true) { setArm(); } } } semiState = digitalRead(semiPin); if (semiState != lastsemiState) { if (semiState == LOW) { if (semiOn == true) { setBrst(); } else if (semiOn == false) { setSemi(); } }} fullState = digitalRead(fullPin); if (fullState != lastfullState) { if (fullState == LOW) { if (fullOn == true) { setBrst(); } else if (fullOn == false) { setFull(); } } } if (semiOn == true && fullOn == true){setBrst();} lastSafetyState = safetyState; lastsemiState = semiState; lastfullState = fullState; triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } while (triggerState == LOW) { if (safetyOn == true) { Serial.print("#12\n"); triggerState = digitalRead(triggerPin); return; } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); return; } if (safetyOn == false) { if (ammoCount > 0) { Serial.print("#13\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(39); triggerState = digitalRead(triggerPin); if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } if (ammoCount == 0){ digitalWrite(muzzlePin, LOW); Serial.print("q\n"); delay(10); Serial.print("#12\n"); } } } else { return; } } lastTriggerState = triggerState; } } |
Author: | knoxvilles_joker [ Sun Mar 10, 2024 5:50 am ] |
Post subject: | Re: my smartgun progress |
OK, got things working with the arduino micro. After I had a wiring malfunction, after I had a short, after I had miswired a couple of things. After I had some misformatted files. I just have some counter logic to work through at the moment but it is a rough work. Code: /*
CryBaby FX Kit v1.0, written by Sean Maio (outcry27@gmail.com) Designed for use with the Adafruit Pro Trinket and Adafruit audio FX board Credit and many thanks to the writers of the numerous tutorials available on both the Arduino and Adafruit websites, without which this project could never have been completed! Updated January 2024 Cobra_shipwreck adding grenade counter, second grenade display and counter, and full/semi/burst triggering If you are using an actual motorcycle light switch assembly ( you need one with buttons: Horn, Highbeam, light, hazard, left and right signal) 1. Horn is the Fire Switch 2. High beam is the Grenade Switch 3. Hazard is the safety Switch 4. Left is Semi Auto (default is burst fire) 5. Right is Full auto 6. Light Switch is used for the Mosfet for the airsoft portion and is a manual battery disconnect for the LIPO the airsoft gun uses -Pin Map- Pro Trinket: (Micro pin noted in parenthesis) 0. Serial RX, connect to Audio FX Serial TX (on Micro labeled D1/TX/PD3) 1. Serial TX, connect to Audio FX Serial RX (on Micro labeled D0/RX/PD2) 3. Fire Switch -> GND (on Micro D3 is SCL, so use D4/PD4) 4. Safety toggle switch -> GND (on Micro use D5/PC6) 9. Muzzle LED, connect this to the GATE pin on the muzzle strobe MOSFET (on Micro use D9/PB5) 8. Grenade -> GND (on Micro D8/PB4) 7. Semi -> GND (on Micro D7/PE6) 6. Full -> GND (on Micro D6/PD7) DigitalRead is used to detect momentary button presses a value of HIGH means pressed, a value of LOW means not pressed. Please note on the arduino Micro the UART(serial) has to be called using Serial1.blah. Due to the design there is not an easy way to test things with the serial monitor. Audio FX board: TX. Connect to Trinket Pin 2 (these cross over so this goes to RX on Micro) (disconnect while uploading via USB as this is used for USB too) RX. Connect to Trinket Pin 1 (these cross over so this goes to TX on Micro) UG. Jumper to GND to enable UART mode. (this allows direct serial triggering using the Serial.print command set(less wires used)) These are the invokations for the sound effects: Please note that the files are named specifically on the FX Sound Board to play when these are called serially. 1. This invokes the bootup sound: Serial.print("#2\n"); 2. This invokes the click sound: Serial.print("#1\n"); 3. This invokes the firing sound: Serial.print("#3\n"); 4. This invokes the Grenade sound:Serial.print("#0\n"); Also note that the files have to be 16-bit signed PCM at 22khz mono wav files. No other settings will work or play. Ogg files will not work as they cause a delay on looping sounds like the fire sfx. */ #include <Wire.h> #include <SoftwareSerial.h> #include "Adafruit_Soundboard.h" #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" // pins used for Serial communication with the audio board #define SFX_TX 1 #define SFX_RX 0 // This calls the LCD display for it to operate and it uses Digital Pins 2 and 3 for SCL/SDA on Micro, A4/A5 on Trinket Pro. SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX); Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, NULL); Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4(); //this is for the mg rounds Adafruit_AlphaNum4 alpha5 = Adafruit_AlphaNum4(); //this is for the grenade rounds // constants: const int triggerPin = 5; // the number of the firing trigger pin const int safetyPin = 4; // pin for the "safety" toggle const int fireSoundPin = 8; // pin for the firing sound const int muzzlePin = 9; // the number of the LED pin const int startSoundPin = 9; // pin for the "boot-up" sound const int clickSoundPin = 4; // pin for the bolt "click" sound const int grenadeSoundPin = 5; const int fireDelay = 50; // duration in milliseconds for each "shot" // these are the additional pins const int grenadePin = 8; // pin for the grenade sound const int fullPin = 7; // pin for fire selection mode select const int semiPin = 6; // other pin for fire selection mode select // variables: boolean safetyOn = false; int triggerState = 0; // variable for reading the trigger status int safetyState = 0; // variable for reading the safety switch status int lastTriggerState = 0; // previous state of the trigger int lastSafetyState = 0; // previous state of the safety switch int ammoCount = 299; String ammoDisp = String(ammoCount); // these are for the additional pins int grenadeCount = 200; //default grenade ammo count String grenadeDisp = String(grenadeCount); int fireSelect = 0; int lastgrenadetriggerState = 0; int grenadetriggerState = 0; int semiState = 0; int fullState = 0; boolean fullOn = false; boolean semiOn = false; int lastsemiState = 0; int lastfullState = 0; int lastburstState = 0 ; int burstState = 0; boolean burstOn = false; void setup() { // initialize the LED pin as an output: pinMode(muzzlePin, OUTPUT); // initialize the trigger and safety pins as input: pinMode(triggerPin, INPUT); pinMode(safetyPin, INPUT); // initialize the audio pins pinMode(startSoundPin, INPUT); pinMode(clickSoundPin, INPUT); // pinMode(fireTailSoundPin, INPUT); pinMode(fireSoundPin, INPUT); pinMode(grenadeSoundPin, INPUT); // pinMode(triggerPin, INPUT); //duplicate // pinMode(safetyPin, INPUT); // duplicate // These are the additional pin declarations. pinMode(grenadePin, INPUT); pinMode(fullPin, INPUT); pinMode(semiPin, INPUT); // set up the audio trigger pins to give a path to GND when set to OUTPUT // this sets the initial led status to off on the muzzle strobe LEDs digitalWrite(muzzlePin, LOW); digitalWrite(triggerPin, HIGH); digitalWrite(safetyPin, HIGH); // These are the additional button pin declarations. digitalWrite(grenadePin, HIGH); digitalWrite(fullPin, HIGH); digitalWrite(semiPin, HIGH); Serial.begin(9600); Serial1.begin(9600); ss.begin(9600); alpha4.begin(0x70); // pass in the address alpha5.begin(0x71); delay(200); //give the audio board time to power up; otherwise bootup sound will be called before audio board is ready Serial1.print("#2\n"); //this plays the bootup sound // Change this number if you change the default ammo count above to match alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '2'); alpha4.writeDigitAscii(2, '9'); alpha4.writeDigitAscii(3, '9'); alpha4.writeDisplay(); alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '1'); alpha5.writeDigitAscii(2, '9'); alpha5.writeDigitAscii(3, '9'); alpha5.writeDisplay(); delay(500); // these are the round load effects for (int x = 4; x > 0; x--) { updateAmmoCounter(); ammoCount--; delay(50); } updateAmmoCounter(); for (int x = 1; x > 0; x--) { updateGrenadeCounter(); grenadeCount--; delay(50); } updateGrenadeCounter(); } // this function calls the current value of ammoCount and writes it to the LED display void updateAmmoCounter() { String ammoDisp = String(ammoCount); if (ammoCount < 10) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, '0'); alpha4.writeDigitAscii(3, ammoDisp[0]); } else if (ammoCount < 100) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, ammoDisp[0]); alpha4.writeDigitAscii(3, ammoDisp[1]); } else if (ammoCount < 1000) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, ammoDisp[0]); alpha4.writeDigitAscii(2, ammoDisp[1]); alpha4.writeDigitAscii(3, ammoDisp[2]); } else if (ammoCount < 10000) { alpha4.writeDigitAscii(0, ammoDisp[0]); alpha4.writeDigitAscii(1, ammoDisp[1]); alpha4.writeDigitAscii(2, ammoDisp[2]); alpha4.writeDigitAscii(3, ammoDisp[3]); } alpha4.writeDisplay(); } // this displays and writes the grenade ammo count void updateGrenadeCounter() { String grenadeDisp = String(grenadeCount); if (grenadeCount < 10) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, '0'); alpha5.writeDigitAscii(3, grenadeDisp[0]); } else if (grenadeCount < 100) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, grenadeDisp[0]); alpha5.writeDigitAscii(3, grenadeDisp[1]); } else if (grenadeCount < 1000) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, grenadeDisp[0]); alpha5.writeDigitAscii(2, grenadeDisp[1]); alpha5.writeDigitAscii(3, grenadeDisp[2]); } else if (grenadeCount < 10000) { alpha5.writeDigitAscii(0, grenadeDisp[0]); alpha5.writeDigitAscii(1, grenadeDisp[1]); alpha5.writeDigitAscii(2, grenadeDisp[2]); alpha5.writeDigitAscii(3, grenadeDisp[3]); } alpha5.writeDisplay(); } void setSafe() { safetyOn = true; alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); } void setArm() { safetyOn = false; alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(300); updateAmmoCounter(); } void setSemi() { semiOn = false; alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(300); updateAmmoCounter(); } void setFull() { semiOn = false; alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(300); updateAmmoCounter(); } void setBrst() { burstOn = false; alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(300); updateAmmoCounter(); } // --MAIN LOOP STARTS HERE-- void loop() { // grenade trigger section grenadetriggerState = digitalRead(grenadePin); if (grenadetriggerState != lastgrenadetriggerState){ if (grenadetriggerState == HIGH) { } // this can be used to add a grenade flash using a declared pin later. the ethernet cable has no spare pins currently. It would be something along these lines: digitalWrite(muzzlePin, LOW); // while (grenadetriggerState == LOW) { Serial1.print("#0\n"); grenadetriggerState = digitalRead(grenadePin); return; } if (grenadetriggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); grenadetriggerState = digitalRead(grenadePin); } // if (grenadeCount <= 0) { grenadetriggerState = digitalRead(grenadePin); return; if (grenadeCount <= 0) { grenadetriggerState = digitalRead(grenadePin); if (if safetyon == false && grenadeCount > 0) { Serial1.print("#0\n"); grenadeCount--; updateGrenadeCounter(); delay(5000); delay(39); grenadetriggerState = digitalRead(grenadePin);} // if (grenadeCount > 0) { Serial1.print("#0\n"); grenadeCount--; updateGrenadeCounter(); delay(5000); // delay(39); grenadetriggerState = digitalRead(grenadePin); if (if safetyon == false && grenadeCount == 0) { Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } if (if safetyon == false && grenadetriggerState == HIGH) { Serial1.print("q\n"); } // if (grenadeCount == 0){ Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } } // } // else { return; } // } lastgrenadetriggerState = grenadetriggerState; } // end grenade trigger section // begin safety pin and firemode selection section safetyState = digitalRead(safetyPin); if (safetyState != lastSafetyState) { if (safetyState == LOW) { if (safetyOn == false) { setSafe(); } else if (safetyOn == true) { setArm(); } } } semiState = digitalRead(semiPin); if (semiState != lastsemiState) { if (semiState == LOW) { if (semiOn == true) { setBrst(); } else if (semiOn == false) { setSemi(); } }} fullState = digitalRead(fullPin); if (fullState != lastfullState) { if (fullState == LOW) { if (fullOn == true) { setBrst(); } else if (fullOn == false) { setFull(); } } } if (semiOn == true && fullOn == true){setBrst();} lastSafetyState = safetyState; lastsemiState = semiState; lastfullState = fullState; // end safety pin and firemode selection section triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } // while (triggerState == LOW) { if (safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); return; } if (triggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); } // if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); return; } if (safetyOn == false && ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(39); triggerState = digitalRead(triggerPin); } // if (safetyOn == false) { // if (ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(39); triggerState = digitalRead(triggerPin); if (safetyOn == false && ammoCount == 0 ){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } if (safetyOn == false && triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } // if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } // if (ammoCount == 0){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } // } // } // else { return; } } lastTriggerState = triggerState; } } |
Author: | knoxvilles_joker [ Sun Mar 10, 2024 10:14 am ] |
Post subject: | Re: my smartgun progress |
OK, grenade counter works. grenade and fire sounds work. Still have to work on logic piece for full, semi, burst. Question I have for group is should I modify code to make for burst and semi or is it just cool to have it pop up full, semi, burst? Code: /*
CryBaby FX Kit v1.0, written by Sean Maio (outcry27@gmail.com) Designed for use with the Adafruit Pro Trinket and Adafruit audio FX board Credit and many thanks to the writers of the numerous tutorials available on both the Arduino and Adafruit websites, without which this project could never have been completed! Updated January 2024 Cobra_shipwreck adding grenade counter, second grenade display and counter, and full/semi/burst triggering If you are using an actual motorcycle light switch assembly ( you need one with buttons: Horn, Highbeam, light, hazard, left and right signal) 1. Horn is the Fire Switch 2. High beam is the Grenade Switch 3. Hazard is the safety Switch 4. Left is Semi Auto (default is burst fire) 5. Right is Full auto 6. Light Switch is used for the Mosfet for the airsoft portion and is a manual battery disconnect for the LIPO the airsoft gun uses -Pin Map- Pro Trinket: (Micro pin noted in parenthesis) 0. Serial RX, connect to Audio FX Serial TX (on Micro labeled D1/TX/PD3) 1. Serial TX, connect to Audio FX Serial RX (on Micro labeled D0/RX/PD2) 3. Fire Switch -> GND (on Micro D3 is SCL, so use D4/PD4) 4. Safety toggle switch -> GND (on Micro use D5/PC6) 9. Muzzle LED, connect this to the GATE pin on the muzzle strobe MOSFET (on Micro use D9/PB5) 8. Grenade -> GND (on Micro D8/PB4) 7. Semi -> GND (on Micro D7/PE6) 6. Full -> GND (on Micro D6/PD7) DigitalRead is used to detect momentary button presses a value of HIGH means pressed, a value of LOW means not pressed. Please note on the arduino Micro the UART(serial) has to be called using Serial1.blah. Due to the design there is not an easy way to test things with the serial monitor. Audio FX board: TX. Connect to Trinket Pin 2 (these cross over so this goes to RX on Micro) (disconnect while uploading via USB as this is used for USB too) RX. Connect to Trinket Pin 1 (these cross over so this goes to TX on Micro) UG. Jumper to GND to enable UART mode. (this allows direct serial triggering using the Serial.print command set(less wires used)) These are the invokations for the sound effects: Please note that the files are named specifically on the FX Sound Board to play when these are called serially. 1. This invokes the bootup sound: Serial.print("#2\n"); 2. This invokes the click sound: Serial.print("#1\n"); 3. This invokes the firing sound: Serial.print("#3\n"); 4. This invokes the Grenade sound:Serial.print("#0\n"); Also note that the files have to be 16-bit signed PCM at 22khz mono wav files. No other settings will work or play. Ogg files will not work as they cause a delay on looping sounds like the fire sfx. */ #include <Wire.h> #include <SoftwareSerial.h> #include "Adafruit_Soundboard.h" #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" // pins used for Serial communication with the audio board #define SFX_TX 1 #define SFX_RX 0 // This calls the LCD display for it to operate and it uses Digital Pins 2 and 3 for SCL/SDA on Micro, A4/A5 on Trinket Pro. SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX); Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, NULL); Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4(); //this is for the mg rounds Adafruit_AlphaNum4 alpha5 = Adafruit_AlphaNum4(); //this is for the grenade rounds // constants: const int triggerPin = 5; // the number of the firing trigger pin const int safetyPin = 4; // pin for the "safety" toggle const int fireSoundPin = 8; // pin for the firing sound const int muzzlePin = 9; // the number of the LED pin const int startSoundPin = 9; // pin for the "boot-up" sound const int clickSoundPin = 4; // pin for the bolt "click" sound const int grenadeSoundPin = 5; const int fireDelay = 50; // duration in milliseconds for each "shot" // these are the additional pins const int grenadePin = 8; // pin for the grenade sound const int fullPin = 7; // pin for fire selection mode select const int semiPin = 6; // other pin for fire selection mode select // variables: boolean safetyOn = false; int triggerState = 0; // variable for reading the trigger status int safetyState = 0; // variable for reading the safety switch status int lastTriggerState = 0; // previous state of the trigger int lastSafetyState = 0; // previous state of the safety switch int ammoCount = 299; String ammoDisp = String(ammoCount); // these are for the additional pins int grenadeCount = 200; //default grenade ammo count String grenadeDisp = String(grenadeCount); int fireSelect = 0; int lastgrenadetriggerState = 0; int grenadetriggerState = 0; int semiState = 0; int fullState = 0; boolean fullOn = false; boolean semiOn = false; int lastsemiState = 0; int lastfullState = 0; int lastburstState = 0 ; int burstState = 0; boolean burstOn = false; void setup() { // initialize the LED pin as an output: pinMode(muzzlePin, OUTPUT); // initialize the trigger and safety pins as input: pinMode(triggerPin, INPUT); pinMode(safetyPin, INPUT); // initialize the audio pins pinMode(startSoundPin, INPUT); pinMode(clickSoundPin, INPUT); // pinMode(fireTailSoundPin, INPUT); pinMode(fireSoundPin, INPUT); pinMode(grenadeSoundPin, INPUT); // pinMode(triggerPin, INPUT); //duplicate // pinMode(safetyPin, INPUT); // duplicate // These are the additional pin declarations. pinMode(grenadePin, INPUT); pinMode(fullPin, INPUT); pinMode(semiPin, INPUT); // set up the audio trigger pins to give a path to GND when set to OUTPUT // this sets the initial led status to off on the muzzle strobe LEDs digitalWrite(muzzlePin, LOW); digitalWrite(triggerPin, HIGH); digitalWrite(safetyPin, HIGH); // These are the additional button pin declarations. digitalWrite(grenadePin, HIGH); digitalWrite(fullPin, HIGH); digitalWrite(semiPin, HIGH); Serial.begin(9600); Serial1.begin(9600); ss.begin(9600); alpha4.begin(0x70); // pass in the address alpha5.begin(0x71); delay(200); //give the audio board time to power up; otherwise bootup sound will be called before audio board is ready Serial1.print("#2\n"); //this plays the bootup sound // Change this number if you change the default ammo count above to match alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '2'); alpha4.writeDigitAscii(2, '9'); alpha4.writeDigitAscii(3, '9'); alpha4.writeDisplay(); alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '1'); alpha5.writeDigitAscii(2, '9'); alpha5.writeDigitAscii(3, '9'); alpha5.writeDisplay(); delay(100); // these are the round load effects for (int x = 4; x > 0; x--) { updateAmmoCounter(); ammoCount--; delay(50); } updateAmmoCounter(); for (int x = 1; x > 0; x--) { updateGrenadeCounter(); grenadeCount--; delay(50); } updateGrenadeCounter(); } // this function calls the current value of ammoCount and writes it to the LED display void updateAmmoCounter() { String ammoDisp = String(ammoCount); if (ammoCount < 10) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, '0'); alpha4.writeDigitAscii(3, ammoDisp[0]); } else if (ammoCount < 100) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, ammoDisp[0]); alpha4.writeDigitAscii(3, ammoDisp[1]); } else if (ammoCount < 1000) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, ammoDisp[0]); alpha4.writeDigitAscii(2, ammoDisp[1]); alpha4.writeDigitAscii(3, ammoDisp[2]); } else if (ammoCount < 10000) { alpha4.writeDigitAscii(0, ammoDisp[0]); alpha4.writeDigitAscii(1, ammoDisp[1]); alpha4.writeDigitAscii(2, ammoDisp[2]); alpha4.writeDigitAscii(3, ammoDisp[3]); } alpha4.writeDisplay(); } // this displays and writes the grenade ammo count void updateGrenadeCounter() { String grenadeDisp = String(grenadeCount); if (grenadeCount < 10) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, '0'); alpha5.writeDigitAscii(3, grenadeDisp[0]); } else if (grenadeCount < 100) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, grenadeDisp[0]); alpha5.writeDigitAscii(3, grenadeDisp[1]); } else if (grenadeCount < 1000) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, grenadeDisp[0]); alpha5.writeDigitAscii(2, grenadeDisp[1]); alpha5.writeDigitAscii(3, grenadeDisp[2]); } else if (grenadeCount < 10000) { alpha5.writeDigitAscii(0, grenadeDisp[0]); alpha5.writeDigitAscii(1, grenadeDisp[1]); alpha5.writeDigitAscii(2, grenadeDisp[2]); alpha5.writeDigitAscii(3, grenadeDisp[3]); } alpha5.writeDisplay(); } void setSafe() { safetyOn = true; alpha4.clear(); alpha4.writeDisplay(); delay(40); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); delay(40); alpha4.clear(); alpha4.writeDisplay(); delay(40); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); } void setArm() { safetyOn = false; alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setSemi() { semiOn = false; alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setFull() { semiOn = false; alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setBrst() { burstOn = true; alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } // --MAIN LOOP STARTS HERE-- void loop() { // begin safety pin and firemode selection section safetyState = digitalRead(safetyPin); if (safetyState != lastSafetyState) { if (safetyState == LOW) { if (safetyOn == false) { setSafe(); } else if (safetyOn == true) { setArm(); } } } semiState = digitalRead(semiPin); if (semiState != lastsemiState) { if (semiState == LOW) { if (semiOn == true) { setBrst(); } else if (semiOn == false) { setSemi(); } }} fullState = digitalRead(fullPin); if (fullState != lastfullState) { if (fullState == LOW) { if (fullOn == true) { setBrst(); } else if (fullOn == false) { setFull(); } } } if (semiOn == true && fullOn == true){setBrst();} lastSafetyState = safetyState; lastsemiState = semiState; lastfullState = fullState; // end safety pin and firemode selection section // grenade trigger section grenadetriggerState = digitalRead(grenadePin); if (grenadetriggerState != lastgrenadetriggerState){ if (grenadetriggerState == HIGH) { } // this can be used to add a grenade flash using a declared pin later. the ethernet cable has no spare pins currently. It would be something along these lines: digitalWrite(muzzlePin, LOW); if (grenadetriggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); grenadetriggerState = digitalRead(grenadePin); } if (grenadeCount <= 0) { grenadetriggerState = digitalRead(grenadePin); } if (safetyOn == false && grenadeCount > 0) { Serial1.print("#0\n"); grenadeCount--; updateGrenadeCounter(); delay(4000); grenadetriggerState = digitalRead(grenadePin);} if (safetyOn == false && grenadeCount == 0) { Serial1.print("q\n"); Serial1.print("#1\n"); } if (safetyOn == false && grenadetriggerState == HIGH) { Serial1.print("q\n"); } lastgrenadetriggerState = grenadetriggerState; } // end grenade trigger section triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } while (triggerState == LOW) { if (safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); return; } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); return; } if (safetyOn == false) { if (ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(39); triggerState = digitalRead(triggerPin); if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } if (ammoCount == 0){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } } } else { return; } } lastTriggerState = triggerState; } } |
Author: | knoxvilles_joker [ Sun Mar 10, 2024 10:34 am ] |
Post subject: | Re: my smartgun progress |
OK, I think this might fix the full/semi/burst fire select modes: Code: fullbuttonCount = 0;
semibuttonCount = 0; safetyState = digitalRead(safetyPin); if (safetyState != lastSafetyState) { if (safetyState == LOW) { if (safetyOn == false) { setSafe(); } else if (safetyOn == true) { setArm(); } } } semiState = digitalRead(semiPin); if (semiState != lastsemiState) { if (semiState == LOW) { if (semiOn == true) { setBrst(); } else if (semiOn == false) { fullbuttonCount++ } }} fullState = digitalRead(fullPin); if (fullState != lastfullState) { if (fullState == LOW) { if (fullOn == true) { setBrst(); } else if (fullOn == false) { semibuttonCount++; } } } if (semibuttonCount == 1){setBrst();} if (semibuttonCount == 2){setSemi();} if (semibuttonCount == 3){setFull();} if (fullbuttonCount == 1){setBrst();} if (fullbuttonCount == 2){setSemi();} if (fullbuttonCount == 3){setFull();} lastSafetyState = safetyState; lastsemiState = semiState; lastfullState = fullState; |
Author: | knoxvilles_joker [ Sun Mar 10, 2024 11:19 am ] |
Post subject: | Re: my smartgun progress |
OK, got the burst,semi.full display to work. Code: /*
CryBaby FX Kit v1.0, written by Sean Maio (outcry27@gmail.com) Designed for use with the Adafruit Pro Trinket and Adafruit audio FX board Credit and many thanks to the writers of the numerous tutorials available on both the Arduino and Adafruit websites, without which this project could never have been completed! Updated January 2024 Cobra_shipwreck adding grenade counter, second grenade display and counter, and full/semi/burst triggering Please be advised screw terminal or directly soldered wires are the best way to connect things. Jumper wires are problematic. And jumper wires are known to be problematic due to intermittant connection issues and strain issues worsen things. It is recommended that you have spare parts for things due to con wear and board altering shorts. If you are using an actual motorcycle light switch assembly ( you need one with buttons: Horn, Highbeam, light, hazard, left and right signal) 1. Horn is the Fire Switch 2. High beam is the Grenade Switch 3. Hazard is the safety Switch 4. Left is Semi Auto (default is burst fire) 5. Right is Full auto 6. Light Switch is used for the Mosfet for the airsoft portion and is a manual battery disconnect for the LIPO the airsoft gun uses -Pin Map- Pro Trinket: (Micro pin noted in parenthesis) 0. Serial RX, connect to Audio FX Serial TX (on Micro labeled D1/TX/PD3) 1. Serial TX, connect to Audio FX Serial RX (on Micro labeled D0/RX/PD2) 3. Fire Switch -> GND (on Micro D3 is SCL, so use D4/PD4) 4. Safety toggle switch -> GND (on Micro use D5/PC6) 9. Muzzle LED, connect this to the GATE pin on the muzzle strobe MOSFET (on Micro use D9/PB5) 8. Grenade -> GND (on Micro D8/PB4) 7. Semi -> GND (on Micro D7/PE6) 6. Full -> GND (on Micro D6/PD7) DigitalRead is used to detect momentary button presses a value of HIGH means pressed, a value of LOW means not pressed. Please note Please note on the arduino Micro the UART(serial) has to be called using Serial1.blah. Due to the design there is not an easy way to test things with the serial monitor. The Arduino Micro uses the same chip as the Leonardo so if you use that board it wll have the same issue as well. And UART on the micro can only be used on the tx/rx pins, it will not work on any other pins. Audio FX board: TX. Connect to Trinket Pin 2 (these cross over so this goes to RX on Micro) (disconnect while uploading via USB as this is used for USB too) RX. Connect to Trinket Pin 1 (these cross over so this goes to TX on Micro) UG. Jumper to GND to enable UART mode. (this allows direct serial triggering using the Serial.print command set(less wires used)) These are the invokations for the sound effects: Please note that the files are named specifically on the FX Sound Board to play when these are called serially. 1. This invokes the bootup sound: Serial.print("#2\n"); 2. This invokes the click sound: Serial.print("#1\n"); 3. This invokes the firing sound: Serial.print("#3\n"); 4. This invokes the Grenade sound:Serial.print("#0\n"); The naming of the files has to be T00.wav, T01.wav, T02.wav, T03.wav. To call the files you have to call them minus the preceeding zero otherwise it will only play file 0. Also note that the files have to be 16-bit signed PCM at 22khz mono wav files. No other settings will work or play. Ogg files will not work as they cause a delay on looping sounds like the fire sfx. */ #include <Wire.h> #include <SoftwareSerial.h> #include "Adafruit_Soundboard.h" #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" // pins used for Serial communication with the audio board #define SFX_TX 1 #define SFX_RX 0 // This calls the LCD display for it to operate and it uses Digital Pins 2 and 3 for SCL/SDA on Micro, A4/A5 on Trinket Pro. SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX); Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, NULL); Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4(); //this is for the mg rounds Adafruit_AlphaNum4 alpha5 = Adafruit_AlphaNum4(); //this is for the grenade rounds // constants: const int triggerPin = 5; // the number of the firing trigger pin const int safetyPin = 4; // pin for the "safety" toggle const int fireSoundPin = 8; // pin for the firing sound const int muzzlePin = 9; // the number of the LED pin const int startSoundPin = 9; // pin for the "boot-up" sound const int clickSoundPin = 4; // pin for the bolt "click" sound const int grenadeSoundPin = 5; const int fireDelay = 50; // duration in milliseconds for each "shot" // these are the additional pins const int grenadePin = 8; // pin for the grenade sound const int fullPin = 7; // pin for fire selection mode select const int semiPin = 6; // other pin for fire selection mode select // variables: boolean safetyOn = false; int triggerState = 0; // variable for reading the trigger status int safetyState = 0; // variable for reading the safety switch status int lastTriggerState = 0; // previous state of the trigger int lastSafetyState = 0; // previous state of the safety switch int ammoCount = 299; String ammoDisp = String(ammoCount); // these are for the additional pins int grenadeCount = 200; //default grenade ammo count String grenadeDisp = String(grenadeCount); int fireSelect = 0; int lastgrenadetriggerState = 0; int grenadetriggerState = 0; int semiState = 0; int fullState = 0; boolean fullOn = false; boolean semiOn = false; int lastsemiState = 0; int lastfullState = 0; int lastburstState = 0 ; int burstState = 0; boolean burstOn = false; int fullbuttonCount = 0; int semibuttonCount = 0; void setup() { // initialize the LED pin as an output: pinMode(muzzlePin, OUTPUT); // initialize the trigger and safety pins as input: pinMode(triggerPin, INPUT); pinMode(safetyPin, INPUT); // initialize the audio pins pinMode(startSoundPin, INPUT); pinMode(clickSoundPin, INPUT); // pinMode(fireTailSoundPin, INPUT); pinMode(fireSoundPin, INPUT); pinMode(grenadeSoundPin, INPUT); // pinMode(triggerPin, INPUT); //duplicate // pinMode(safetyPin, INPUT); // duplicate // These are the additional pin declarations. pinMode(grenadePin, INPUT); pinMode(fullPin, INPUT); pinMode(semiPin, INPUT); // set up the audio trigger pins to give a path to GND when set to OUTPUT // this sets the initial led status to off on the muzzle strobe LEDs digitalWrite(muzzlePin, LOW); digitalWrite(triggerPin, HIGH); digitalWrite(safetyPin, HIGH); // These are the additional button pin declarations. digitalWrite(grenadePin, HIGH); digitalWrite(fullPin, HIGH); digitalWrite(semiPin, HIGH); Serial.begin(9600); Serial1.begin(9600); ss.begin(9600); alpha4.begin(0x70); // pass in the address alpha5.begin(0x71); delay(200); //give the audio board time to power up; otherwise bootup sound will be called before audio board is ready Serial1.print("#2\n"); //this plays the bootup sound // Change this number if you change the default ammo count above to match alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '2'); alpha4.writeDigitAscii(2, '9'); alpha4.writeDigitAscii(3, '9'); alpha4.writeDisplay(); alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '1'); alpha5.writeDigitAscii(2, '9'); alpha5.writeDigitAscii(3, '9'); alpha5.writeDisplay(); delay(100); // these are the round load effects for (int x = 4; x > 0; x--) { updateAmmoCounter(); ammoCount--; delay(50); } updateAmmoCounter(); for (int x = 1; x > 0; x--) { updateGrenadeCounter(); grenadeCount--; delay(50); } updateGrenadeCounter(); } // this function calls the current value of ammoCount and writes it to the LED display void updateAmmoCounter() { String ammoDisp = String(ammoCount); if (ammoCount < 10) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, '0'); alpha4.writeDigitAscii(3, ammoDisp[0]); } else if (ammoCount < 100) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, ammoDisp[0]); alpha4.writeDigitAscii(3, ammoDisp[1]); } else if (ammoCount < 1000) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, ammoDisp[0]); alpha4.writeDigitAscii(2, ammoDisp[1]); alpha4.writeDigitAscii(3, ammoDisp[2]); } else if (ammoCount < 10000) { alpha4.writeDigitAscii(0, ammoDisp[0]); alpha4.writeDigitAscii(1, ammoDisp[1]); alpha4.writeDigitAscii(2, ammoDisp[2]); alpha4.writeDigitAscii(3, ammoDisp[3]); } alpha4.writeDisplay(); } // this displays and writes the grenade ammo count void updateGrenadeCounter() { String grenadeDisp = String(grenadeCount); if (grenadeCount < 10) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, '0'); alpha5.writeDigitAscii(3, grenadeDisp[0]); } else if (grenadeCount < 100) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, grenadeDisp[0]); alpha5.writeDigitAscii(3, grenadeDisp[1]); } else if (grenadeCount < 1000) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, grenadeDisp[0]); alpha5.writeDigitAscii(2, grenadeDisp[1]); alpha5.writeDigitAscii(3, grenadeDisp[2]); } else if (grenadeCount < 10000) { alpha5.writeDigitAscii(0, grenadeDisp[0]); alpha5.writeDigitAscii(1, grenadeDisp[1]); alpha5.writeDigitAscii(2, grenadeDisp[2]); alpha5.writeDigitAscii(3, grenadeDisp[3]); } alpha5.writeDisplay(); } void setSafe() { safetyOn = true; alpha4.clear(); alpha4.writeDisplay(); delay(40); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); delay(40); alpha4.clear(); alpha4.writeDisplay(); delay(40); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); } void setArm() { safetyOn = false; alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setSemi() { semiOn = false; alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setFull() { semiOn = false; alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setBrst() { burstOn = true; alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } // --MAIN LOOP STARTS HERE-- void loop() { // begin safety pin and firemode selection section safetyState = digitalRead(safetyPin); if (safetyState != lastSafetyState) { if (safetyState == LOW) { if (safetyOn == false) { setSafe(); } else if (safetyOn == true) { setArm(); } } } semiState = digitalRead(semiPin); if (semiState != lastsemiState) { if (semiState == LOW) { if (semiOn == true) { setBrst(); } else if (semiOn == false) { fullbuttonCount++; } }} fullState = digitalRead(fullPin); if (fullState != lastfullState) { if (fullState == LOW) { if (fullOn == true) { setBrst(); } else if (fullOn == false) { semibuttonCount++; } } } if (semibuttonCount == 1){setBrst();semibuttonCount++;} if (semibuttonCount == 3){setSemi();semibuttonCount++;} if (semibuttonCount == 5){setFull();semibuttonCount++;} if (semibuttonCount == 6){semibuttonCount=0;} if (fullbuttonCount == 1){setBrst();fullbuttonCount++;} if (fullbuttonCount == 3){setSemi();fullbuttonCount++;} if (fullbuttonCount == 5){setFull();fullbuttonCount++;} if (fullbuttonCount == 6){fullbuttonCount=0;} lastSafetyState = safetyState; lastsemiState = semiState; lastfullState = fullState; // end safety pin and firemode selection section // grenade trigger section grenadetriggerState = digitalRead(grenadePin); if (grenadetriggerState != lastgrenadetriggerState){ if (grenadetriggerState == HIGH) { } // this can be used to add a grenade flash using a declared pin later. the ethernet cable has no spare pins currently. It would be something along these lines: digitalWrite(muzzlePin, LOW); if (grenadetriggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); grenadetriggerState = digitalRead(grenadePin); } if (grenadeCount <= 0) { grenadetriggerState = digitalRead(grenadePin); } if (safetyOn == false && grenadeCount > 0) { Serial1.print("#0\n"); grenadeCount--; updateGrenadeCounter(); delay(400); grenadetriggerState = digitalRead(grenadePin);} if (safetyOn == false && grenadeCount == 0) { Serial1.print("q\n"); Serial1.print("#1\n"); } if (safetyOn == false && grenadetriggerState == HIGH) { Serial1.print("q\n"); } lastgrenadetriggerState = grenadetriggerState; } // end grenade trigger section triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } while (triggerState == LOW) { if (safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); return; } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); return; } if (safetyOn == false) { if (ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(39); triggerState = digitalRead(triggerPin); if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } if (ammoCount == 0){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } } } else { return; } } lastTriggerState = triggerState; } } |
Author: | knoxvilles_joker [ Sun Mar 10, 2024 9:02 pm ] |
Post subject: | Re: my smartgun progress |
OK, I got the structure built for the state machine for the fire control states. Fortunately I stumbled upon the desired states as i was optomizing the code. Code: enum { full,
semi, burst, }; unsigned char autostate = full; if (semibuttonCount == 1){autostate = brst} if (semibuttonCount == 2){autostate = semi} if (semibuttonCount == 3){autostate = full} switch (autostate) { case full: triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } while (triggerState == LOW) { if (safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); return; } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); return; } if (safetyOn == false) { if (ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(39); triggerState = digitalRead(triggerPin); if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } if (ammoCount == 0){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } } } else { return; } } lastTriggerState = triggerState; } break; case semi: triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } if (triggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(509); triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount == 0 ){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } if (safetyOn == false && triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } } lastTriggerState = triggerState; } break; case burst: triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } if (triggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(39); triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount == 0 ){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } if (safetyOn == false && triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } } lastTriggerState = triggerState; } break; } |
Author: | knoxvilles_joker [ Sun Mar 10, 2024 9:31 pm ] |
Post subject: | Re: my smartgun progress |
OK, I just have to debug the state machine, so yay more fun Code: /*
CryBaby FX Kit v1.0, written by Sean Maio (outcry27@gmail.com) Designed for use with the Adafruit Pro Trinket and Adafruit audio FX board Credit and many thanks to the writers of the numerous tutorials available on both the Arduino and Adafruit websites, without which this project could never have been completed! Updated January 2024 Cobra_shipwreck adding grenade counter, second grenade display and counter, and full/semi/burst triggering Please be advised screw terminal or directly soldered wires are the best way to connect things. Jumper wires are problematic. And jumper wires are known to be problematic due to intermittant connection issues and strain issues worsen things. It is recommended that you have spare parts for things due to con wear and board altering shorts. If you are using an actual motorcycle light switch assembly ( you need one with buttons: Horn, Highbeam, light, hazard, left and right signal) 1. Horn is the Fire Switch 2. High beam is the Grenade Switch 3. Hazard is the safety Switch 4. Left is Semi Auto (default is burst fire) 5. Right is Full auto 6. Light Switch is used for the Mosfet for the airsoft portion and is a manual battery disconnect for the LIPO the airsoft gun uses -Pin Map- Pro Trinket: (Micro pin noted in parenthesis) 0. Serial RX, connect to Audio FX Serial TX (on Micro labeled D1/TX/PD3) 1. Serial TX, connect to Audio FX Serial RX (on Micro labeled D0/RX/PD2) 3. Fire Switch -> GND (on Micro D3 is SCL, so use D4/PD4) 4. Safety toggle switch -> GND (on Micro use D5/PC6) 9. Muzzle LED, connect this to the GATE pin on the muzzle strobe MOSFET (on Micro use D9/PB5) 8. Grenade -> GND (on Micro D8/PB4) 7. Semi -> GND (on Micro D7/PE6) 6. Full -> GND (on Micro D6/PD7) DigitalRead is used to detect momentary button presses a value of HIGH means pressed, a value of LOW means not pressed. Please note Please note on the arduino Micro the UART(serial) has to be called using Serial1.blah. Due to the design there is not an easy way to test things with the serial monitor. The Arduino Micro uses the same chip as the Leonardo so if you use that board it wll have the same issue as well. And UART on the micro can only be used on the tx/rx pins, it will not work on any other pins. Audio FX board: TX. Connect to Trinket Pin 2 (these cross over so this goes to RX on Micro) (disconnect while uploading via USB as this is used for USB too) RX. Connect to Trinket Pin 1 (these cross over so this goes to TX on Micro) UG. Jumper to GND to enable UART mode. (this allows direct serial triggering using the Serial.print command set(less wires used)) These are the invokations for the sound effects: Please note that the files are named specifically on the FX Sound Board to play when these are called serially. 1. This invokes the bootup sound: Serial.print("#2\n"); 2. This invokes the click sound: Serial.print("#1\n"); 3. This invokes the firing sound: Serial.print("#3\n"); 4. This invokes the Grenade sound:Serial.print("#0\n"); The naming of the files has to be T00.wav, T01.wav, T02.wav, T03.wav. To call the files you have to call them minus the preceeding zero otherwise it will only play file 0. Also note that the files have to be 16-bit signed PCM at 22khz mono wav files. No other settings will work or play. Ogg files will not work as they cause a delay on looping sounds like the fire sfx. */ #include <Wire.h> #include <SoftwareSerial.h> #include "Adafruit_Soundboard.h" #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" // pins used for Serial communication with the audio board #define SFX_TX 1 #define SFX_RX 0 // This calls the LCD display for it to operate and it uses Digital Pins 2 and 3 for SCL/SDA on Micro, A4/A5 on Trinket Pro. SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX); Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, NULL); Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4(); //this is for the mg rounds Adafruit_AlphaNum4 alpha5 = Adafruit_AlphaNum4(); //this is for the grenade rounds // constants: const int triggerPin = 5; // the number of the firing trigger pin const int safetyPin = 4; // pin for the "safety" toggle const int fireSoundPin = 8; // pin for the firing sound const int muzzlePin = 9; // the number of the LED pin const int startSoundPin = 9; // pin for the "boot-up" sound const int clickSoundPin = 4; // pin for the bolt "click" sound const int grenadeSoundPin = 5; const int fireDelay = 50; // duration in milliseconds for each "shot" // these are the additional pins const int grenadePin = 8; // pin for the grenade sound const int fullPin = 7; // pin for fire selection mode select const int semiPin = 6; // other pin for fire selection mode select // variables: boolean safetyOn = false; int triggerState = 0; // variable for reading the trigger status int safetyState = 0; // variable for reading the safety switch status int lastTriggerState = 0; // previous state of the trigger int lastSafetyState = 0; // previous state of the safety switch int ammoCount = 299; String ammoDisp = String(ammoCount); // these are for the additional pins int grenadeCount = 200; //default grenade ammo count String grenadeDisp = String(grenadeCount); int fireSelect = 0; int lastgrenadetriggerState = 0; int grenadetriggerState = 0; int semiState = 0; int fullState = 0; boolean fullOn = false; boolean semiOn = false; int lastsemiState = 0; int lastfullState = 0; int lastburstState = 0 ; int burstState = 0; boolean burstOn = false; int fullbuttonCount = 0; int semibuttonCount = 0; enum { full, semi, burst, }; unsigned char autostate = full; void setup() { // initialize the LED pin as an output: pinMode(muzzlePin, OUTPUT); // initialize the trigger and safety pins as input: pinMode(triggerPin, INPUT); pinMode(safetyPin, INPUT); // initialize the audio pins pinMode(startSoundPin, INPUT); pinMode(clickSoundPin, INPUT); // pinMode(fireTailSoundPin, INPUT); pinMode(fireSoundPin, INPUT); pinMode(grenadeSoundPin, INPUT); // pinMode(triggerPin, INPUT); //duplicate // pinMode(safetyPin, INPUT); // duplicate // These are the additional pin declarations. pinMode(grenadePin, INPUT); pinMode(fullPin, INPUT); pinMode(semiPin, INPUT); // set up the audio trigger pins to give a path to GND when set to OUTPUT // this sets the initial led status to off on the muzzle strobe LEDs digitalWrite(muzzlePin, LOW); digitalWrite(triggerPin, HIGH); digitalWrite(safetyPin, HIGH); // These are the additional button pin declarations. digitalWrite(grenadePin, HIGH); digitalWrite(fullPin, HIGH); digitalWrite(semiPin, HIGH); Serial.begin(9600); Serial1.begin(9600); ss.begin(9600); alpha4.begin(0x70); // pass in the address alpha5.begin(0x71); delay(200); //give the audio board time to power up; otherwise bootup sound will be called before audio board is ready Serial1.print("#2\n"); //this plays the bootup sound // Change this number if you change the default ammo count above to match alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '2'); alpha4.writeDigitAscii(2, '9'); alpha4.writeDigitAscii(3, '9'); alpha4.writeDisplay(); alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '1'); alpha5.writeDigitAscii(2, '9'); alpha5.writeDigitAscii(3, '9'); alpha5.writeDisplay(); delay(100); // these are the round load effects for (int x = 4; x > 0; x--) { updateAmmoCounter(); ammoCount--; delay(50); } updateAmmoCounter(); for (int x = 1; x > 0; x--) { updateGrenadeCounter(); grenadeCount--; delay(50); } updateGrenadeCounter(); } // this function calls the current value of ammoCount and writes it to the LED display void updateAmmoCounter() { String ammoDisp = String(ammoCount); if (ammoCount < 10) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, '0'); alpha4.writeDigitAscii(3, ammoDisp[0]); } else if (ammoCount < 100) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, ammoDisp[0]); alpha4.writeDigitAscii(3, ammoDisp[1]); } else if (ammoCount < 1000) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, ammoDisp[0]); alpha4.writeDigitAscii(2, ammoDisp[1]); alpha4.writeDigitAscii(3, ammoDisp[2]); } else if (ammoCount < 10000) { alpha4.writeDigitAscii(0, ammoDisp[0]); alpha4.writeDigitAscii(1, ammoDisp[1]); alpha4.writeDigitAscii(2, ammoDisp[2]); alpha4.writeDigitAscii(3, ammoDisp[3]); } alpha4.writeDisplay(); } // this displays and writes the grenade ammo count void updateGrenadeCounter() { String grenadeDisp = String(grenadeCount); if (grenadeCount < 10) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, '0'); alpha5.writeDigitAscii(3, grenadeDisp[0]); } else if (grenadeCount < 100) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, grenadeDisp[0]); alpha5.writeDigitAscii(3, grenadeDisp[1]); } else if (grenadeCount < 1000) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, grenadeDisp[0]); alpha5.writeDigitAscii(2, grenadeDisp[1]); alpha5.writeDigitAscii(3, grenadeDisp[2]); } else if (grenadeCount < 10000) { alpha5.writeDigitAscii(0, grenadeDisp[0]); alpha5.writeDigitAscii(1, grenadeDisp[1]); alpha5.writeDigitAscii(2, grenadeDisp[2]); alpha5.writeDigitAscii(3, grenadeDisp[3]); } alpha5.writeDisplay(); } void setSafe() { safetyOn = true; alpha4.clear(); alpha4.writeDisplay(); delay(40); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); delay(40); alpha4.clear(); alpha4.writeDisplay(); delay(40); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); } void setArm() { safetyOn = false; alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setSemi() { semiOn = false; alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setFull() { semiOn = false; alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setBrst() { burstOn = true; alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } // --MAIN LOOP STARTS HERE-- void loop() { // begin safety pin and firemode selection section safetyState = digitalRead(safetyPin); if (safetyState != lastSafetyState) { if (safetyState == LOW) { if (safetyOn == false) { setSafe(); } else if (safetyOn == true) { setArm(); } } } semiState = digitalRead(semiPin); if (semiState != lastsemiState) { if (semiState == LOW) { if (semiOn == true) { setBrst(); } else if (semiOn == false) { fullbuttonCount++; } }} fullState = digitalRead(fullPin); if (fullState != lastfullState) { if (fullState == LOW) { if (fullOn == true) { setBrst(); } else if (fullOn == false) { semibuttonCount++; } } } if (semibuttonCount == 1){setBrst();semibuttonCount++;} if (semibuttonCount == 3){setSemi();semibuttonCount++;} if (semibuttonCount == 5){setFull();semibuttonCount++;} if (semibuttonCount == 6){semibuttonCount=0;} if (fullbuttonCount == 1){setBrst();fullbuttonCount++;} if (fullbuttonCount == 3){setSemi();fullbuttonCount++;} if (fullbuttonCount == 5){setFull();fullbuttonCount++;} if (fullbuttonCount == 6){fullbuttonCount=0;} lastSafetyState = safetyState; lastsemiState = semiState; lastfullState = fullState; // end safety pin and firemode selection section // grenade trigger section grenadetriggerState = digitalRead(grenadePin); if (grenadetriggerState != lastgrenadetriggerState){ if (grenadetriggerState == HIGH) { } // this can be used to add a grenade flash using a declared pin later. the ethernet cable has no spare pins currently. It would be something along these lines: digitalWrite(muzzlePin, LOW); if (grenadetriggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); grenadetriggerState = digitalRead(grenadePin); } if (grenadeCount <= 0) { grenadetriggerState = digitalRead(grenadePin); } if (safetyOn == false && grenadeCount > 0) { Serial1.print("#0\n"); grenadeCount--; updateGrenadeCounter(); delay(400); grenadetriggerState = digitalRead(grenadePin);} if (safetyOn == false && grenadeCount == 0) { Serial1.print("q\n"); Serial1.print("#1\n"); } if (safetyOn == false && grenadetriggerState == HIGH) { Serial1.print("q\n"); } lastgrenadetriggerState = grenadetriggerState; } // end grenade trigger section switch (autostate) { case full: triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } while (triggerState == LOW) { if (safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); return; } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); return; } if (safetyOn == false) { if (ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(39); triggerState = digitalRead(triggerPin); if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } if (ammoCount == 0){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } } } else { return; } } lastTriggerState = triggerState;} if (semibuttonCount == 1){autostate = burst;} if (semibuttonCount == 3){autostate = semi;} if (semibuttonCount == 5){autostate = full;} break; case semi: triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } if (triggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(509); triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount == 0 ){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } if (safetyOn == false && triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } } lastTriggerState = triggerState; if (semibuttonCount == 1){autostate = burst;} if (semibuttonCount == 3){autostate = semi;} if (semibuttonCount == 5){autostate = full;} break; case burst: triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } if (triggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(390); triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount == 0 ){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } if (safetyOn == false && triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } } lastTriggerState = triggerState; if (semibuttonCount == 1){autostate = burst;} if (semibuttonCount == 3){autostate = semi;} if (semibuttonCount == 5){autostate = full;} break; } } |
Author: | knoxvilles_joker [ Sun Mar 10, 2024 11:34 pm ] |
Post subject: | Re: my smartgun progress |
ok button logic is sorted and it works in different fire select modes. I was thinking though, since I have two separate buttons for fire select why not make one for the mg and one for the grenade? Code: /*
CryBaby FX Kit v1.0, written by Sean Maio (outcry27@gmail.com) Designed for use with the Adafruit Pro Trinket and Adafruit audio FX board Credit and many thanks to the writers of the numerous tutorials available on both the Arduino and Adafruit websites, without which this project could never have been completed! Updated January 2024 Cobra_shipwreck adding grenade counter, second grenade display and counter, and full/semi/burst triggering Please be advised screw terminal or directly soldered wires are the best way to connect things. Jumper wires are problematic. And jumper wires are known to be problematic due to intermittant connection issues and strain issues worsen things. It is recommended that you have spare parts for things due to con wear and board altering shorts. If you are using an actual motorcycle light switch assembly ( you need one with buttons: Horn, Highbeam, light, hazard, left and right signal) 1. Horn is the Fire Switch 2. High beam is the Grenade Switch 3. Hazard is the safety Switch 4. Left is Semi Auto (default is burst fire) 5. Right is Full auto 6. Light Switch is used for the Mosfet for the airsoft portion and is a manual battery disconnect for the LIPO the airsoft gun uses -Pin Map- Pro Trinket: (Micro pin noted in parenthesis) 0. Serial RX, connect to Audio FX Serial TX (on Micro labeled D1/TX/PD3) 1. Serial TX, connect to Audio FX Serial RX (on Micro labeled D0/RX/PD2) 3. Fire Switch -> GND (on Micro D3 is SCL, so use D4/PD4) 4. Safety toggle switch -> GND (on Micro use D5/PC6) 9. Muzzle LED, connect this to the GATE pin on the muzzle strobe MOSFET (on Micro use D9/PB5) 8. Grenade -> GND (on Micro D8/PB4) 7. Semi -> GND (on Micro D7/PE6) 6. Full -> GND (on Micro D6/PD7) DigitalRead is used to detect momentary button presses a value of HIGH means pressed, a value of LOW means not pressed. Please note Please note on the arduino Micro the UART(serial) has to be called using Serial1.blah. Due to the design there is not an easy way to test things with the serial monitor. The Arduino Micro uses the same chip as the Leonardo so if you use that board it wll have the same issue as well. And UART on the micro can only be used on the tx/rx pins, it will not work on any other pins. Audio FX board: TX. Connect to Trinket Pin 2 (these cross over so this goes to RX on Micro) (disconnect while uploading via USB as this is used for USB too) RX. Connect to Trinket Pin 1 (these cross over so this goes to TX on Micro) UG. Jumper to GND to enable UART mode. (this allows direct serial triggering using the Serial.print command set(less wires used)) These are the invokations for the sound effects: Please note that the files are named specifically on the FX Sound Board to play when these are called serially. 1. This invokes the bootup sound: Serial.print("#2\n"); 2. This invokes the click sound: Serial.print("#1\n"); 3. This invokes the firing sound: Serial.print("#3\n"); 4. This invokes the Grenade sound:Serial.print("#0\n"); The naming of the files has to be T00.wav, T01.wav, T02.wav, T03.wav. To call the files you have to call them minus the preceeding zero otherwise it will only play file 0. Also note that the files have to be 16-bit signed PCM at 22khz mono wav files. No other settings will work or play. Ogg files will not work as they cause a delay on looping sounds like the fire sfx. */ #include <Wire.h> #include <SoftwareSerial.h> #include "Adafruit_Soundboard.h" #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" // pins used for Serial communication with the audio board #define SFX_TX 1 #define SFX_RX 0 // This calls the LCD display for it to operate and it uses Digital Pins 2 and 3 for SCL/SDA on Micro, A4/A5 on Trinket Pro. SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX); Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, NULL); Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4(); //this is for the mg rounds Adafruit_AlphaNum4 alpha5 = Adafruit_AlphaNum4(); //this is for the grenade rounds // constants: const int triggerPin = 5; // the number of the firing trigger pin const int safetyPin = 4; // pin for the "safety" toggle const int fireSoundPin = 8; // pin for the firing sound const int muzzlePin = 9; // the number of the LED pin const int startSoundPin = 9; // pin for the "boot-up" sound const int clickSoundPin = 4; // pin for the bolt "click" sound const int grenadeSoundPin = 5; const int fireDelay = 50; // duration in milliseconds for each "shot" // these are the additional pins const int grenadePin = 8; // pin for the grenade sound const int fullPin = 7; // pin for fire selection mode select const int semiPin = 6; // other pin for fire selection mode select // variables: boolean safetyOn = false; int triggerState = 0; // variable for reading the trigger status int safetyState = 0; // variable for reading the safety switch status int lastTriggerState = 0; // previous state of the trigger int lastSafetyState = 0; // previous state of the safety switch int ammoCount = 299; String ammoDisp = String(ammoCount); // these are for the additional pins int grenadeCount = 200; //default grenade ammo count String grenadeDisp = String(grenadeCount); int fireSelect = 0; int lastgrenadetriggerState = 0; int grenadetriggerState = 0; int semiState = 0; int fullState = 0; boolean fullOn = false; boolean semiOn = false; int lastsemiState = 0; int lastfullState = 0; int lastburstState = 0 ; int burstState = 0; boolean burstOn = false; int fullbuttonCount = 0; int semibuttonCount = 0; enum { full, semi, burst, }; unsigned char autostate = full; void setup() { // initialize the LED pin as an output: pinMode(muzzlePin, OUTPUT); // initialize the trigger and safety pins as input: pinMode(triggerPin, INPUT); pinMode(safetyPin, INPUT); // initialize the audio pins pinMode(startSoundPin, INPUT); pinMode(clickSoundPin, INPUT); // pinMode(fireTailSoundPin, INPUT); pinMode(fireSoundPin, INPUT); pinMode(grenadeSoundPin, INPUT); // pinMode(triggerPin, INPUT); //duplicate // pinMode(safetyPin, INPUT); // duplicate // These are the additional pin declarations. pinMode(grenadePin, INPUT); pinMode(fullPin, INPUT); pinMode(semiPin, INPUT); // set up the audio trigger pins to give a path to GND when set to OUTPUT // this sets the initial led status to off on the muzzle strobe LEDs digitalWrite(muzzlePin, LOW); digitalWrite(triggerPin, HIGH); digitalWrite(safetyPin, HIGH); // These are the additional button pin declarations. digitalWrite(grenadePin, HIGH); digitalWrite(fullPin, HIGH); digitalWrite(semiPin, HIGH); Serial.begin(9600); Serial1.begin(9600); ss.begin(9600); alpha4.begin(0x70); // pass in the address alpha5.begin(0x71); delay(200); //give the audio board time to power up; otherwise bootup sound will be called before audio board is ready Serial1.print("#2\n"); //this plays the bootup sound // Change this number if you change the default ammo count above to match alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '2'); alpha4.writeDigitAscii(2, '9'); alpha4.writeDigitAscii(3, '9'); alpha4.writeDisplay(); alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '1'); alpha5.writeDigitAscii(2, '9'); alpha5.writeDigitAscii(3, '9'); alpha5.writeDisplay(); delay(100); // these are the round load effects for (int x = 4; x > 0; x--) { updateAmmoCounter(); ammoCount--; delay(50); } updateAmmoCounter(); for (int x = 1; x > 0; x--) { updateGrenadeCounter(); grenadeCount--; delay(50); } updateGrenadeCounter(); } // this function calls the current value of ammoCount and writes it to the LED display void updateAmmoCounter() { String ammoDisp = String(ammoCount); if (ammoCount < 10) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, '0'); alpha4.writeDigitAscii(3, ammoDisp[0]); } else if (ammoCount < 100) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, ammoDisp[0]); alpha4.writeDigitAscii(3, ammoDisp[1]); } else if (ammoCount < 1000) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, ammoDisp[0]); alpha4.writeDigitAscii(2, ammoDisp[1]); alpha4.writeDigitAscii(3, ammoDisp[2]); } else if (ammoCount < 10000) { alpha4.writeDigitAscii(0, ammoDisp[0]); alpha4.writeDigitAscii(1, ammoDisp[1]); alpha4.writeDigitAscii(2, ammoDisp[2]); alpha4.writeDigitAscii(3, ammoDisp[3]); } alpha4.writeDisplay(); } // this displays and writes the grenade ammo count void updateGrenadeCounter() { String grenadeDisp = String(grenadeCount); if (grenadeCount < 10) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, '0'); alpha5.writeDigitAscii(3, grenadeDisp[0]); } else if (grenadeCount < 100) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, grenadeDisp[0]); alpha5.writeDigitAscii(3, grenadeDisp[1]); } else if (grenadeCount < 1000) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, grenadeDisp[0]); alpha5.writeDigitAscii(2, grenadeDisp[1]); alpha5.writeDigitAscii(3, grenadeDisp[2]); } else if (grenadeCount < 10000) { alpha5.writeDigitAscii(0, grenadeDisp[0]); alpha5.writeDigitAscii(1, grenadeDisp[1]); alpha5.writeDigitAscii(2, grenadeDisp[2]); alpha5.writeDigitAscii(3, grenadeDisp[3]); } alpha5.writeDisplay(); } void setSafe() { safetyOn = true; alpha4.clear(); alpha4.writeDisplay(); delay(40); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); delay(40); alpha4.clear(); alpha4.writeDisplay(); delay(40); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); } void setArm() { safetyOn = false; alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setSemi() { semiOn = false; alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setFull() { semiOn = false; alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setBrst() { burstOn = true; alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } // --MAIN LOOP STARTS HERE-- void loop() { // begin safety pin and firemode selection section safetyState = digitalRead(safetyPin); if (safetyState != lastSafetyState) { if (safetyState == LOW) { if (safetyOn == false) { setSafe(); } else if (safetyOn == true) { setArm(); } } } semiState = digitalRead(semiPin); if (semiState != lastsemiState) { if (semiState == LOW) { if (semiOn == true) { } else if (semiOn == false) { fullbuttonCount++; } }} fullState = digitalRead(fullPin); if (fullState != lastfullState) { if (fullState == LOW) { if (fullOn == true) { } else if (fullOn == false) { semibuttonCount++; } } } if (semibuttonCount == 1){setBrst();semibuttonCount++;} if (semibuttonCount == 3){setSemi();semibuttonCount++;} if (semibuttonCount == 5){setFull();semibuttonCount++;} if (semibuttonCount == 7){semibuttonCount=0;} if (fullbuttonCount == 1){setBrst();fullbuttonCount++;} if (fullbuttonCount == 3){setSemi();fullbuttonCount++;} if (fullbuttonCount == 5){setFull();fullbuttonCount++;} if (fullbuttonCount == 7){fullbuttonCount=0;} // end safety pin and firemode selection section // grenade trigger section grenadetriggerState = digitalRead(grenadePin); if (grenadetriggerState != lastgrenadetriggerState){ if (grenadetriggerState == HIGH) { } // this can be used to add a grenade flash using a declared pin later. the ethernet cable has no spare pins currently. It would be something along these lines: digitalWrite(muzzlePin, LOW); if (grenadetriggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); grenadetriggerState = digitalRead(grenadePin); } if (grenadeCount <= 0) { grenadetriggerState = digitalRead(grenadePin); } if (safetyOn == false && grenadeCount > 0) { Serial1.print("#0\n"); grenadeCount--; updateGrenadeCounter(); delay(400); grenadetriggerState = digitalRead(grenadePin);} if (safetyOn == false && grenadeCount == 0) { Serial1.print("q\n"); Serial1.print("#1\n"); } if (safetyOn == false && grenadetriggerState == HIGH) { Serial1.print("q\n"); } lastgrenadetriggerState = grenadetriggerState; } // end grenade trigger section //begin fireselect mode section if (semibuttonCount == 2 || fullbuttonCount == 2 ){ triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } if (triggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); ammoCount--; updateAmmoCounter(); delay(20); triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount == 0 ){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } if (safetyOn == false && triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } } lastTriggerState = triggerState; } if (semibuttonCount == 4 || fullbuttonCount == 4){ triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } if (triggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(509); triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount == 0 ){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } if (safetyOn == false && triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } } lastTriggerState = triggerState; } if (semibuttonCount == 6 || fullbuttonCount == 6|| fullbuttonCount == 0 || semibuttonCount == 0){ triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } while (triggerState == LOW) { if (safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); return; } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); return; } if (safetyOn == false) { if (ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(39); triggerState = digitalRead(triggerPin); if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } if (ammoCount == 0){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } } } else { return; } } lastTriggerState = triggerState;} } lastSafetyState = safetyState; lastsemiState = semiState; lastfullState = fullState; } |
Author: | knoxvilles_joker [ Mon Mar 11, 2024 12:23 am ] |
Post subject: | Re: my smartgun progress |
OK, I split out the fire select modes, one button controls grenade, other controls the mg portion. Rought draft anyways but it should work. Code: /*
CryBaby FX Kit v1.0, written by Sean Maio (outcry27@gmail.com) Designed for use with the Adafruit Pro Trinket and Adafruit audio FX board Credit and many thanks to the writers of the numerous tutorials available on both the Arduino and Adafruit websites, without which this project could never have been completed! Updated January 2024 Cobra_shipwreck adding grenade counter, second grenade display and counter, and full/semi/burst triggering Please be advised screw terminal or directly soldered wires are the best way to connect things. Jumper wires are problematic. And jumper wires are known to be problematic due to intermittant connection issues and strain issues worsen things. It is recommended that you have spare parts for things due to con wear and board altering shorts. If you are using an actual motorcycle light switch assembly ( you need one with buttons: Horn, Highbeam, light, hazard, left and right signal) 1. Horn is the Fire Switch 2. High beam is the Grenade Switch 3. Hazard is the safety Switch 4. Left is Semi Auto (default is burst fire) 5. Right is Full auto 6. Light Switch is used for the Mosfet for the airsoft portion and is a manual battery disconnect for the LIPO the airsoft gun uses -Pin Map- Pro Trinket: (Micro pin noted in parenthesis) 0. Serial RX, connect to Audio FX Serial TX (on Micro labeled D1/TX/PD3) 1. Serial TX, connect to Audio FX Serial RX (on Micro labeled D0/RX/PD2) 3. Fire Switch -> GND (on Micro D3 is SCL, so use D4/PD4) 4. Safety toggle switch -> GND (on Micro use D5/PC6) 9. Muzzle LED, connect this to the GATE pin on the muzzle strobe MOSFET (on Micro use D9/PB5) 8. Grenade -> GND (on Micro D8/PB4) 7. Semi -> GND (on Micro D7/PE6) 6. Full -> GND (on Micro D6/PD7) DigitalRead is used to detect momentary button presses a value of HIGH means pressed, a value of LOW means not pressed. Please note Please note on the arduino Micro the UART(serial) has to be called using Serial1.blah. Due to the design there is not an easy way to test things with the serial monitor. The Arduino Micro uses the same chip as the Leonardo so if you use that board it wll have the same issue as well. And UART on the micro can only be used on the tx/rx pins, it will not work on any other pins. Audio FX board: TX. Connect to Trinket Pin 2 (these cross over so this goes to RX on Micro) (disconnect while uploading via USB as this is used for USB too) RX. Connect to Trinket Pin 1 (these cross over so this goes to TX on Micro) UG. Jumper to GND to enable UART mode. (this allows direct serial triggering using the Serial.print command set(less wires used)) These are the invokations for the sound effects: Please note that the files are named specifically on the FX Sound Board to play when these are called serially. 1. This invokes the bootup sound: Serial.print("#2\n"); 2. This invokes the click sound: Serial.print("#1\n"); 3. This invokes the firing sound: Serial.print("#3\n"); 4. This invokes the Grenade sound:Serial.print("#0\n"); The naming of the files has to be T00.wav, T01.wav, T02.wav, T03.wav. To call the files you have to call them minus the preceeding zero otherwise it will only play file 0. Also note that the files have to be 16-bit signed PCM at 22khz mono wav files. No other settings will work or play. Ogg files will not work as they cause a delay on looping sounds like the fire sfx. */ #include <Wire.h> #include <SoftwareSerial.h> #include "Adafruit_Soundboard.h" #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" // pins used for Serial communication with the audio board #define SFX_TX 1 #define SFX_RX 0 // This calls the LCD display for it to operate and it uses Digital Pins 2 and 3 for SCL/SDA on Micro, A4/A5 on Trinket Pro. SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX); Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, NULL); Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4(); //this is for the mg rounds Adafruit_AlphaNum4 alpha5 = Adafruit_AlphaNum4(); //this is for the grenade rounds // constants: const int triggerPin = 5; // the number of the firing trigger pin const int safetyPin = 4; // pin for the "safety" toggle const int fireSoundPin = 8; // pin for the firing sound const int muzzlePin = 9; // the number of the LED pin const int startSoundPin = 9; // pin for the "boot-up" sound const int clickSoundPin = 4; // pin for the bolt "click" sound const int grenadeSoundPin = 5; const int fireDelay = 50; // duration in milliseconds for each "shot" // these are the additional pins const int grenadePin = 8; // pin for the grenade sound const int fullPin = 7; // pin for fire selection mode select const int semiPin = 6; // other pin for fire selection mode select // variables: boolean safetyOn = false; int triggerState = 0; // variable for reading the trigger status int safetyState = 0; // variable for reading the safety switch status int lastTriggerState = 0; // previous state of the trigger int lastSafetyState = 0; // previous state of the safety switch int ammoCount = 299; String ammoDisp = String(ammoCount); // these are for the additional pins int grenadeCount = 200; //default grenade ammo count String grenadeDisp = String(grenadeCount); int fireSelect = 0; int lastgrenadetriggerState = 0; int grenadetriggerState = 0; int semiState = 0; int fullState = 0; boolean fullOn = false; boolean semiOn = false; int lastsemiState = 0; int lastfullState = 0; int lastburstState = 0 ; int burstState = 0; boolean burstOn = false; int fullbuttonCount = 0; int semibuttonCount = 0; enum { full, semi, burst, }; unsigned char autostate = full; void setup() { // initialize the LED pin as an output: pinMode(muzzlePin, OUTPUT); // initialize the trigger and safety pins as input: pinMode(triggerPin, INPUT); pinMode(safetyPin, INPUT); // initialize the audio pins pinMode(startSoundPin, INPUT); pinMode(clickSoundPin, INPUT); // pinMode(fireTailSoundPin, INPUT); pinMode(fireSoundPin, INPUT); pinMode(grenadeSoundPin, INPUT); // pinMode(triggerPin, INPUT); //duplicate // pinMode(safetyPin, INPUT); // duplicate // These are the additional pin declarations. pinMode(grenadePin, INPUT); pinMode(fullPin, INPUT); pinMode(semiPin, INPUT); // set up the audio trigger pins to give a path to GND when set to OUTPUT // this sets the initial led status to off on the muzzle strobe LEDs digitalWrite(muzzlePin, LOW); digitalWrite(triggerPin, HIGH); digitalWrite(safetyPin, HIGH); // These are the additional button pin declarations. digitalWrite(grenadePin, HIGH); digitalWrite(fullPin, HIGH); digitalWrite(semiPin, HIGH); Serial.begin(9600); Serial1.begin(9600); ss.begin(9600); alpha4.begin(0x70); // pass in the address alpha5.begin(0x71); delay(200); //give the audio board time to power up; otherwise bootup sound will be called before audio board is ready Serial1.print("#2\n"); //this plays the bootup sound // Change this number if you change the default ammo count above to match alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '2'); alpha4.writeDigitAscii(2, '9'); alpha4.writeDigitAscii(3, '9'); alpha4.writeDisplay(); alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '1'); alpha5.writeDigitAscii(2, '9'); alpha5.writeDigitAscii(3, '9'); alpha5.writeDisplay(); delay(100); // these are the round load effects for (int x = 4; x > 0; x--) { updateAmmoCounter(); ammoCount--; delay(50); } updateAmmoCounter(); for (int x = 1; x > 0; x--) { updateGrenadeCounter(); grenadeCount--; delay(50); } updateGrenadeCounter(); } // this function calls the current value of ammoCount and writes it to the LED display void updateAmmoCounter() { String ammoDisp = String(ammoCount); if (ammoCount < 10) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, '0'); alpha4.writeDigitAscii(3, ammoDisp[0]); } else if (ammoCount < 100) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, ammoDisp[0]); alpha4.writeDigitAscii(3, ammoDisp[1]); } else if (ammoCount < 1000) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, ammoDisp[0]); alpha4.writeDigitAscii(2, ammoDisp[1]); alpha4.writeDigitAscii(3, ammoDisp[2]); } else if (ammoCount < 10000) { alpha4.writeDigitAscii(0, ammoDisp[0]); alpha4.writeDigitAscii(1, ammoDisp[1]); alpha4.writeDigitAscii(2, ammoDisp[2]); alpha4.writeDigitAscii(3, ammoDisp[3]); } alpha4.writeDisplay(); } // this displays and writes the grenade ammo count void updateGrenadeCounter() { String grenadeDisp = String(grenadeCount); if (grenadeCount < 10) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, '0'); alpha5.writeDigitAscii(3, grenadeDisp[0]); } else if (grenadeCount < 100) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, grenadeDisp[0]); alpha5.writeDigitAscii(3, grenadeDisp[1]); } else if (grenadeCount < 1000) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, grenadeDisp[0]); alpha5.writeDigitAscii(2, grenadeDisp[1]); alpha5.writeDigitAscii(3, grenadeDisp[2]); } else if (grenadeCount < 10000) { alpha5.writeDigitAscii(0, grenadeDisp[0]); alpha5.writeDigitAscii(1, grenadeDisp[1]); alpha5.writeDigitAscii(2, grenadeDisp[2]); alpha5.writeDigitAscii(3, grenadeDisp[3]); } alpha5.writeDisplay(); } void setSafe() { safetyOn = true; alpha4.clear(); alpha4.writeDisplay(); delay(40); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); delay(40); alpha4.clear(); alpha4.writeDisplay(); delay(40); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); alpha5.clear(); alpha5.writeDisplay(); delay(40); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'F'); alpha5.writeDigitAscii(3, 'E'); alpha5.writeDisplay(); delay(40); alpha5.clear(); alpha5.writeDisplay(); delay(40); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'F'); alpha5.writeDigitAscii(3, 'E'); alpha5.writeDisplay(); } void setArm() { safetyOn = false; alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, ' '); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'R'); alpha5.writeDigitAscii(3, 'M'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, ' '); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'R'); alpha5.writeDigitAscii(3, 'M'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, ' '); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'R'); alpha5.writeDigitAscii(3, 'M'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); delay(50); alpha5.writeDigitAscii(0, ' '); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'R'); alpha5.writeDigitAscii(3, 'M'); alpha5.writeDisplay(); delay(30); updateGrenadeCounter(); } void setSemi() { semiOn = false; alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setSemig() { semiOn = false; alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'E'); alpha5.writeDigitAscii(2, 'M'); alpha5.writeDigitAscii(3, 'I'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'E'); alpha5.writeDigitAscii(2, 'M'); alpha5.writeDigitAscii(3, 'I'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'E'); alpha5.writeDigitAscii(2, 'M'); alpha5.writeDigitAscii(3, 'I'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'E'); alpha5.writeDigitAscii(2, 'M'); alpha5.writeDigitAscii(3, 'I'); alpha5.writeDisplay(); delay(30); updateAmmoCounter(); } void setFull() { semiOn = false; alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setBrst() { burstOn = true; alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setBrstg() { burstOn = true; alpha5.writeDigitAscii(0, 'B'); alpha5.writeDigitAscii(1, 'R'); alpha5.writeDigitAscii(2, 'S'); alpha5.writeDigitAscii(3, 'T'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'B'); alpha5.writeDigitAscii(1, 'R'); alpha5.writeDigitAscii(2, 'S'); alpha5.writeDigitAscii(3, 'T'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'B'); alpha5.writeDigitAscii(1, 'R'); alpha5.writeDigitAscii(2, 'S'); alpha5.writeDigitAscii(3, 'T'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'B'); alpha5.writeDigitAscii(1, 'R'); alpha5.writeDigitAscii(2, 'S'); alpha5.writeDigitAscii(3, 'T'); alpha5.writeDisplay(); delay(30); updateAmmoCounter(); } // --MAIN LOOP STARTS HERE-- void loop() { // begin safety pin and firemode selection section safetyState = digitalRead(safetyPin); if (safetyState != lastSafetyState) { if (safetyState == LOW) { if (safetyOn == false) { setSafe(); } else if (safetyOn == true) { setArm(); } } } semiState = digitalRead(semiPin); if (semiState != lastsemiState) { if (semiState == LOW) { if (semiOn == true) { } else if (semiOn == false) { fullbuttonCount++; } }} fullState = digitalRead(fullPin); if (fullState != lastfullState) { if (fullState == LOW) { if (fullOn == true) { } else if (fullOn == false) { semibuttonCount++; } } } if (semibuttonCount == 1){setBrstg();semibuttonCount++;} if (semibuttonCount == 3){setSemig();semibuttonCount++;} // if (semibuttonCount == 5){setFull();semibuttonCount++;} if (semibuttonCount == 5){semibuttonCount=0;} if (fullbuttonCount == 1){setBrst();fullbuttonCount++;} if (fullbuttonCount == 3){setSemi();fullbuttonCount++;} if (fullbuttonCount == 5){setFull();fullbuttonCount++;} if (fullbuttonCount == 7){fullbuttonCount=0;} // end safety pin and firemode selection section // grenade trigger section if (semibuttonCount ==2 || semibuttonCount == 0) { //brst grenadetriggerState = digitalRead(grenadePin); if (grenadetriggerState != lastgrenadetriggerState){ if (grenadetriggerState == HIGH) { } // this can be used to add a grenade flash using a declared pin later. the ethernet cable has no spare pins currently. It would be something along these lines: digitalWrite(muzzlePin, LOW); if (grenadetriggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); grenadetriggerState = digitalRead(grenadePin); } if (grenadeCount <= 0) { grenadetriggerState = digitalRead(grenadePin); } if (safetyOn == false && grenadeCount > 0) { Serial1.print("#0\n"); grenadeCount--; updateGrenadeCounter(); delay(300); grenadetriggerState = digitalRead(grenadePin);} if (safetyOn == false && grenadeCount == 0) { Serial1.print("q\n"); Serial1.print("#1\n"); } if (safetyOn == false && grenadetriggerState == HIGH) { Serial1.print("q\n"); } lastgrenadetriggerState = grenadetriggerState; } } if (semibuttonCount ==4) { // semi if (grenadetriggerState != lastgrenadetriggerState){ if (grenadetriggerState == HIGH) { } // this can be used to add a grenade flash using a declared pin later. the ethernet cable has no spare pins currently. It would be something along these lines: digitalWrite(muzzlePin, LOW); if (grenadetriggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); grenadetriggerState = digitalRead(grenadePin); } if (grenadeCount <= 0) { grenadetriggerState = digitalRead(grenadePin); } if (safetyOn == false && grenadeCount > 0) { Serial1.print("#0\n"); grenadeCount--; updateGrenadeCounter(); delay(800); grenadetriggerState = digitalRead(grenadePin);} if (safetyOn == false && grenadeCount == 0) { Serial1.print("q\n"); Serial1.print("#1\n"); } if (safetyOn == false && grenadetriggerState == HIGH) { Serial1.print("q\n"); } lastgrenadetriggerState = grenadetriggerState; } } // end grenade trigger section //begin fireselect mode section if (fullbuttonCount == 2 ){ triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } if (triggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); ammoCount--; updateAmmoCounter(); delay(20); triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount == 0 ){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } if (safetyOn == false && triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } } lastTriggerState = triggerState; } if (fullbuttonCount == 4){ triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } if (triggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(509); triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount == 0 ){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } if (safetyOn == false && triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } } lastTriggerState = triggerState; } if (fullbuttonCount == 6|| fullbuttonCount == 0){ triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } while (triggerState == LOW) { if (safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); return; } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); return; } if (safetyOn == false) { if (ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(39); triggerState = digitalRead(triggerPin); if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } if (ammoCount == 0){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } } } else { return; } } lastTriggerState = triggerState;} } lastSafetyState = safetyState; lastsemiState = semiState; lastfullState = fullState; // end mg fire mode selection section } |
Author: | knoxvilles_joker [ Mon Mar 11, 2024 12:56 am ] |
Post subject: | Re: my smartgun progress |
OK all logic pieces sorted, I think this is done and working. Code: /*
CryBaby FX Kit v1.0, written by Sean Maio (outcry27@gmail.com) Originally Designed for use with the Adafruit Pro Trinket and Adafruit audio FX board This now uses an arduino Micro, 2x 14segment ht16k33 backpacks, fxsoundboard, motorcycle light handlebar assembly for switches Credit and many thanks to the writers of the numerous tutorials available on both the Arduino and Adafruit websites, without which this project could never have been completed! Updated January 2024 Cobra_shipwreck adding grenade counter, second grenade display and counter, and full/semi/burst triggering Please be advised screw terminal or directly soldered wires are the best way to connect things. Jumper wires are problematic. And jumper wires are known to be problematic due to intermittant connection issues and strain issues worsen things. It is recommended that you have spare parts for things due to con wear and board altering shorts. If you are using an actual motorcycle light switch assembly ( you need one with buttons: Horn, Highbeam, light, hazard, left and right signal) 1. Horn is the Fire Switch 2. High beam is the Grenade Switch 3. Hazard is the safety Switch 4. Left is Semi Auto (default is burst fire) 5. Right is Full auto 6. Light Switch is used for the Mosfet for the airsoft portion and is a manual battery disconnect for the LIPO the airsoft gun uses -Pin Map- Pro Trinket: (Micro pin noted in parenthesis) 0. Serial RX, connect to Audio FX Serial TX (on Micro labeled D1/TX/PD3) 1. Serial TX, connect to Audio FX Serial RX (on Micro labeled D0/RX/PD2) 3. Fire Switch -> GND (on Micro D3 is SCL, so use D4/PD4) 4. Safety toggle switch -> GND (on Micro use D5/PC6) 9. Muzzle LED, connect this to the GATE pin on the muzzle strobe MOSFET (on Micro use D9/PB5) 8. Grenade -> GND (on Micro D8/PB4) 7. Semi -> GND (on Micro D7/PE6) 6. Full -> GND (on Micro D6/PD7) DigitalRead is used to detect momentary button presses a value of HIGH means pressed, a value of LOW means not pressed. Please note Please note on the arduino Micro the UART(serial) has to be called using Serial1.blah. Due to the design there is not an easy way to test things with the serial monitor. The Arduino Micro uses the same chip as the Leonardo so if you use that board it wll have the same issue as well. And UART on the micro can only be used on the tx/rx pins, it will not work on any other pins. Audio FX board: TX. Connect to Trinket Pin 2 (these cross over so this goes to RX on Micro) (disconnect while uploading via USB as this is used for USB too) RX. Connect to Trinket Pin 1 (these cross over so this goes to TX on Micro) UG. Jumper to GND to enable UART mode. (this allows direct serial triggering using the Serial.print command set(less wires used)) These are the invokations for the sound effects: Please note that the files are named specifically on the FX Sound Board to play when these are called serially. 1. This invokes the bootup sound: Serial.print("#2\n"); 2. This invokes the click sound: Serial.print("#1\n"); 3. This invokes the firing sound: Serial.print("#3\n"); 4. This invokes the Grenade sound:Serial.print("#0\n"); The naming of the files has to be T00.wav, T01.wav, T02.wav, T03.wav. To call the files you have to call them minus the preceeding zero otherwise it will only play file 0. Also note that the files have to be 16-bit signed PCM at 22khz mono wav files. No other settings will work or play. Ogg files will not work as they cause a delay on looping sounds like the fire sfx. */ #include <Wire.h> #include <SoftwareSerial.h> #include "Adafruit_Soundboard.h" #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" // pins used for Serial communication with the audio board #define SFX_TX 1 #define SFX_RX 0 // This calls the LCD display for it to operate and it uses Digital Pins 2 and 3 for SCL/SDA on Micro, A4/A5 on Trinket Pro. SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX); Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, NULL); Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4(); //this is for the mg rounds Adafruit_AlphaNum4 alpha5 = Adafruit_AlphaNum4(); //this is for the grenade rounds // constants: const int triggerPin = 5; // the number of the firing trigger pin const int safetyPin = 4; // pin for the "safety" toggle const int fireSoundPin = 8; // pin for the firing sound const int muzzlePin = 9; // the number of the LED pin const int startSoundPin = 9; // pin for the "boot-up" sound const int clickSoundPin = 4; // pin for the bolt "click" sound const int grenadeSoundPin = 5; const int fireDelay = 50; // duration in milliseconds for each "shot" // these are the additional pins const int grenadePin = 8; // pin for the grenade sound const int fullPin = 7; // pin for fire selection mode select const int semiPin = 6; // other pin for fire selection mode select // variables: boolean safetyOn = false; int triggerState = 0; // variable for reading the trigger status int safetyState = 0; // variable for reading the safety switch status int lastTriggerState = 0; // previous state of the trigger int lastSafetyState = 0; // previous state of the safety switch int ammoCount = 299; String ammoDisp = String(ammoCount); // these are for the additional pins int grenadeCount = 200; //default grenade ammo count String grenadeDisp = String(grenadeCount); int fireSelect = 0; int lastgrenadetriggerState = 0; int grenadetriggerState = 0; int semiState = 0; int fullState = 0; boolean fullOn = false; boolean semiOn = false; int lastsemiState = 0; int lastfullState = 0; int lastburstState = 0 ; int burstState = 0; boolean burstOn = false; int fullbuttonCount = 0; int semibuttonCount = 0; enum { full, semi, burst, }; unsigned char autostate = full; void setup() { // initialize the LED pin as an output: pinMode(muzzlePin, OUTPUT); // initialize the trigger and safety pins as input: pinMode(triggerPin, INPUT); pinMode(safetyPin, INPUT); // initialize the audio pins pinMode(startSoundPin, INPUT); pinMode(clickSoundPin, INPUT); // pinMode(fireTailSoundPin, INPUT); pinMode(fireSoundPin, INPUT); pinMode(grenadeSoundPin, INPUT); // pinMode(triggerPin, INPUT); //duplicate // pinMode(safetyPin, INPUT); // duplicate // These are the additional pin declarations. pinMode(grenadePin, INPUT); pinMode(fullPin, INPUT); pinMode(semiPin, INPUT); // set up the audio trigger pins to give a path to GND when set to OUTPUT // this sets the initial led status to off on the muzzle strobe LEDs digitalWrite(muzzlePin, LOW); digitalWrite(triggerPin, HIGH); digitalWrite(safetyPin, HIGH); // These are the additional button pin declarations. digitalWrite(grenadePin, HIGH); digitalWrite(fullPin, HIGH); digitalWrite(semiPin, HIGH); Serial.begin(9600); Serial1.begin(9600); ss.begin(9600); alpha4.begin(0x70); // pass in the address alpha5.begin(0x71); delay(200); //give the audio board time to power up; otherwise bootup sound will be called before audio board is ready Serial1.print("#2\n"); //this plays the bootup sound // Change this number if you change the default ammo count above to match alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '2'); alpha4.writeDigitAscii(2, '9'); alpha4.writeDigitAscii(3, '9'); alpha4.writeDisplay(); alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '1'); alpha5.writeDigitAscii(2, '9'); alpha5.writeDigitAscii(3, '9'); alpha5.writeDisplay(); delay(100); // these are the round load effects for (int x = 4; x > 0; x--) { updateAmmoCounter(); ammoCount--; delay(50); } updateAmmoCounter(); for (int x = 1; x > 0; x--) { updateGrenadeCounter(); grenadeCount--; delay(50); } updateGrenadeCounter(); } // this function calls the current value of ammoCount and writes it to the LED display void updateAmmoCounter() { String ammoDisp = String(ammoCount); if (ammoCount < 10) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, '0'); alpha4.writeDigitAscii(3, ammoDisp[0]); } else if (ammoCount < 100) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, ammoDisp[0]); alpha4.writeDigitAscii(3, ammoDisp[1]); } else if (ammoCount < 1000) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, ammoDisp[0]); alpha4.writeDigitAscii(2, ammoDisp[1]); alpha4.writeDigitAscii(3, ammoDisp[2]); } else if (ammoCount < 10000) { alpha4.writeDigitAscii(0, ammoDisp[0]); alpha4.writeDigitAscii(1, ammoDisp[1]); alpha4.writeDigitAscii(2, ammoDisp[2]); alpha4.writeDigitAscii(3, ammoDisp[3]); } alpha4.writeDisplay(); } // this displays and writes the grenade ammo count void updateGrenadeCounter() { String grenadeDisp = String(grenadeCount); if (grenadeCount < 10) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, '0'); alpha5.writeDigitAscii(3, grenadeDisp[0]); } else if (grenadeCount < 100) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, grenadeDisp[0]); alpha5.writeDigitAscii(3, grenadeDisp[1]); } else if (grenadeCount < 1000) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, grenadeDisp[0]); alpha5.writeDigitAscii(2, grenadeDisp[1]); alpha5.writeDigitAscii(3, grenadeDisp[2]); } else if (grenadeCount < 10000) { alpha5.writeDigitAscii(0, grenadeDisp[0]); alpha5.writeDigitAscii(1, grenadeDisp[1]); alpha5.writeDigitAscii(2, grenadeDisp[2]); alpha5.writeDigitAscii(3, grenadeDisp[3]); } alpha5.writeDisplay(); } void setSafe() { safetyOn = true; alpha4.clear(); alpha4.writeDisplay(); delay(40); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); delay(40); alpha4.clear(); alpha4.writeDisplay(); delay(40); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); alpha5.clear(); alpha5.writeDisplay(); delay(40); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'F'); alpha5.writeDigitAscii(3, 'E'); alpha5.writeDisplay(); delay(40); alpha5.clear(); alpha5.writeDisplay(); delay(40); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'F'); alpha5.writeDigitAscii(3, 'E'); alpha5.writeDisplay(); } void setArm() { safetyOn = false; alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, ' '); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'R'); alpha5.writeDigitAscii(3, 'M'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, ' '); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'R'); alpha5.writeDigitAscii(3, 'M'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, ' '); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'R'); alpha5.writeDigitAscii(3, 'M'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); delay(50); alpha5.writeDigitAscii(0, ' '); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'R'); alpha5.writeDigitAscii(3, 'M'); alpha5.writeDisplay(); delay(30); updateGrenadeCounter(); } void setSemi() { semiOn = false; alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setSemig() { semiOn = false; alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'E'); alpha5.writeDigitAscii(2, 'M'); alpha5.writeDigitAscii(3, 'I'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'E'); alpha5.writeDigitAscii(2, 'M'); alpha5.writeDigitAscii(3, 'I'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'E'); alpha5.writeDigitAscii(2, 'M'); alpha5.writeDigitAscii(3, 'I'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'E'); alpha5.writeDigitAscii(2, 'M'); alpha5.writeDigitAscii(3, 'I'); alpha5.writeDisplay(); delay(30); updateGrenadeCounter(); } void setFull() { semiOn = false; alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setBrst() { burstOn = true; alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setBrstg() { burstOn = true; alpha5.writeDigitAscii(0, 'B'); alpha5.writeDigitAscii(1, 'R'); alpha5.writeDigitAscii(2, 'S'); alpha5.writeDigitAscii(3, 'T'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'B'); alpha5.writeDigitAscii(1, 'R'); alpha5.writeDigitAscii(2, 'S'); alpha5.writeDigitAscii(3, 'T'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'B'); alpha5.writeDigitAscii(1, 'R'); alpha5.writeDigitAscii(2, 'S'); alpha5.writeDigitAscii(3, 'T'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'B'); alpha5.writeDigitAscii(1, 'R'); alpha5.writeDigitAscii(2, 'S'); alpha5.writeDigitAscii(3, 'T'); alpha5.writeDisplay(); delay(30); updateGrenadeCounter(); } // --MAIN LOOP STARTS HERE-- void loop() { // begin safety pin and firemode selection section safetyState = digitalRead(safetyPin); if (safetyState != lastSafetyState) { if (safetyState == LOW) { if (safetyOn == false) { setSafe(); } else if (safetyOn == true) { setArm(); } } } semiState = digitalRead(semiPin); if (semiState != lastsemiState) { if (semiState == LOW) { if (semiOn == true) { } else if (semiOn == false) { fullbuttonCount++; } }} fullState = digitalRead(fullPin); if (fullState != lastfullState) { if (fullState == LOW) { if (fullOn == true) { } else if (fullOn == false) { semibuttonCount++; } } } if (semibuttonCount == 1){setBrstg();semibuttonCount++;} if (semibuttonCount == 3){setSemig();semibuttonCount++;} // if (semibuttonCount == 5){setFull();semibuttonCount++;} if (semibuttonCount == 5){semibuttonCount=0;} if (fullbuttonCount == 1){setBrst();fullbuttonCount++;} if (fullbuttonCount == 3){setSemi();fullbuttonCount++;} if (fullbuttonCount == 5){setFull();fullbuttonCount++;} if (fullbuttonCount == 7){fullbuttonCount=0;} // end safety pin and firemode selection section // grenade trigger section if (semibuttonCount ==2) { //brst grenadetriggerState = digitalRead(grenadePin); if (grenadetriggerState != lastgrenadetriggerState){ if (grenadetriggerState == HIGH) { } // this can be used to add a grenade flash using a declared pin later. the ethernet cable has no spare pins currently. It would be something along these lines: digitalWrite(muzzlePin, LOW); if (grenadetriggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); grenadetriggerState = digitalRead(grenadePin); } if (grenadeCount <= 0) { grenadetriggerState = digitalRead(grenadePin); } if (safetyOn == false && grenadeCount > 0) { Serial1.print("#0\n"); grenadeCount--; updateGrenadeCounter(); delay(300); grenadetriggerState = digitalRead(grenadePin);} if (safetyOn == false && grenadeCount == 0) { Serial1.print("q\n"); Serial1.print("#1\n"); } if (safetyOn == false && grenadetriggerState == HIGH) { Serial1.print("q\n"); } lastgrenadetriggerState = grenadetriggerState; } } if (semibuttonCount ==4 || semibuttonCount == 0) { // semi grenadetriggerState = digitalRead(grenadePin); if (grenadetriggerState != lastgrenadetriggerState){ if (grenadetriggerState == HIGH) { } // this can be used to add a grenade flash using a declared pin later. the ethernet cable has no spare pins currently. It would be something along these lines: digitalWrite(muzzlePin, LOW); if (grenadetriggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); grenadetriggerState = digitalRead(grenadePin); } if (grenadeCount <= 0) { grenadetriggerState = digitalRead(grenadePin); } if (safetyOn == false && grenadeCount > 0) { Serial1.print("#0\n"); grenadeCount--; updateGrenadeCounter(); delay(600); grenadetriggerState = digitalRead(grenadePin);} if (safetyOn == false && grenadeCount == 0) { Serial1.print("q\n"); Serial1.print("#1\n"); } if (safetyOn == false && grenadetriggerState == HIGH) { Serial1.print("q\n"); } lastgrenadetriggerState = grenadetriggerState; } } // end grenade trigger section //begin fireselect mode section if (fullbuttonCount == 2 ){ triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } if (triggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); ammoCount--; updateAmmoCounter(); delay(20); triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount == 0 ){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } if (safetyOn == false && triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } } lastTriggerState = triggerState; } if (fullbuttonCount == 4){ triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } if (triggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(509); triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount == 0 ){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } if (safetyOn == false && triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } } lastTriggerState = triggerState; } if (fullbuttonCount == 6|| fullbuttonCount == 0){ triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } while (triggerState == LOW) { if (safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); return; } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); return; } if (safetyOn == false) { if (ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(39); triggerState = digitalRead(triggerPin); if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } if (ammoCount == 0){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } } } else { return; } } lastTriggerState = triggerState;} } lastSafetyState = safetyState; lastsemiState = semiState; lastfullState = fullState; // end mg fire mode selection section } |
Author: | knoxvilles_joker [ Sun Mar 17, 2024 2:15 am ] |
Post subject: | Re: my smartgun progress |
OK, think I fixed an issue with the Safe/Arm display logic Code: /*
CryBaby FX Kit v1.0, written by Sean Maio (outcry27@gmail.com) Originally Designed for use with the Adafruit Pro Trinket and Adafruit audio FX board Updated January 2024 Cobra_shipwreck adding grenade counter, second grenade display and counter, and full/semi/burst triggering Credit and many thanks to the writers of the numerous tutorials available on both the Arduino and Adafruit websites, without which this project could never have been completed! This now uses an arduino Micro, 2x 14segment ht16k33 backpacks, fxsoundboard, motorcycle light handlebar assembly for switches https://www.adafruit.com/product/1911 (this is the display used) https://www.adafruit.com/product/2220 (this is the fx soundboard) https://store-usa.arduino.cc/products/arduino-micro (this is the arduino micro used) https://www.adafruit.com/product/4981 (this is the ethernet screw terminal adapter I use) Please be advised screw terminal or directly soldered wires are the best way to connect things. Jumper wires are problematic. And jumper wires are known to be problematic due to intermittant connection issues and strain issues worsen things. It is recommended that you have spare parts for things due to con wear and board altering shorts. If you are using an actual motorcycle light switch assembly ( you need one with buttons: Horn, Highbeam, light, hazard, left and right signal) 1. Horn is the Fire Switch 2. High beam is the Grenade Switch 3. Hazard is the safety Switch 4. Left is Semi Auto (default is burst fire) 5. Right is Full auto 6. Light Switch is used for the Mosfet for the airsoft portion and is a manual battery disconnect for the LIPO the airsoft gun uses -Pin Map- Pro Trinket: (Micro pin noted in parenthesis) 0. Serial RX, connect to Audio FX Serial TX (on Micro labeled D1/TX/PD3) 1. Serial TX, connect to Audio FX Serial RX (on Micro labeled D0/RX/PD2) 3. Fire Switch -> GND (on Micro D3 is SCL, so use D4/PD4) 4. Safety toggle switch -> GND (on Micro use D5/PC6) 9. Muzzle LED, connect this to the GATE pin on the muzzle strobe MOSFET (on Micro use D9/PB5) 8. Grenade -> GND (on Micro D8/PB4) 7. Semi -> GND (on Micro D7/PE6) 6. Full -> GND (on Micro D6/PD7) DigitalRead is used to detect momentary button presses a value of HIGH means pressed, a value of LOW means not pressed. Please note on the arduino Micro the UART(serial) has to be called using Serial1.blah. Due to the design there is not an easy way to test things with the serial monitor. The Arduino Micro uses the same chip as the Leonardo so if you use that board it wll have the same issue as well. And UART on the micro can only be used on the tx/rx pins, it will not work on any other pins. I have verified this bit, but you are welcome to prove me wrong if you so desire. Audio FX board: TX. Connect to Trinket Pin 2 (these cross over so this goes to RX on Micro) (disconnect while uploading via USB as this is used for USB too) RX. Connect to Trinket Pin 1 (these cross over so this goes to TX on Micro) UG. Jumper to GND to enable UART mode. (this allows direct serial triggering using the Serial.print command set(less wires used)) These are the invokations for the sound effects: Please note that the files are named specifically on the FX Sound Board to play when these are called serially in UART mode. 1. This invokes the bootup sound: Serial.print("#2\n"); 2. This invokes the click sound: Serial.print("#1\n"); 3. This invokes the firing sound: Serial.print("#3\n"); 4. This invokes the Grenade sound:Serial.print("#0\n"); The naming of the files has to be T00.wav, T01.wav, T02.wav, T03.wav. To call the files you have to call them minus the preceeding zero otherwise it will only play file 0. Also note that the files have to be 16-bit signed PCM at 22khz mono wav files. No other settings will work or play. Ogg files will not work as they cause a delay on looping sounds like the fire sfx. Please note that these adjustments can be done in Audacity, a free and open source sound editing program. There are youtube tutorials and writeups on how to edit sound files. Just bear in mind edit or convert the files as few times as possible as the more you convert the file the more fidelity(audio quality) you lose. */ #include <Wire.h> #include <SoftwareSerial.h> #include "Adafruit_Soundboard.h" #include "Adafruit_LEDBackpack.h" #include "Adafruit_GFX.h" // pins used for Serial communication with the audio board #define SFX_TX 1 #define SFX_RX 0 // This calls the LCD display for it to operate and it uses Digital Pins 2 and 3 for SCL/SDA on Micro, A4/A5 on Trinket Pro. SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX); Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, NULL); Adafruit_AlphaNum4 alpha4 = Adafruit_AlphaNum4(); //this is for the mg rounds Adafruit_AlphaNum4 alpha5 = Adafruit_AlphaNum4(); //this is for the grenade rounds // constants: const int triggerPin = 5; // the number of the firing trigger pin const int safetyPin = 4; // pin for the "safety" toggle const int fireSoundPin = 8; // pin for the firing sound const int muzzlePin = 9; // the number of the LED pin const int startSoundPin = 9; // pin for the "boot-up" sound const int clickSoundPin = 4; // pin for the bolt "click" sound const int grenadeSoundPin = 5; const int fireDelay = 50; // duration in milliseconds for each "shot" // these are the additional pins const int grenadePin = 8; // pin for the grenade sound const int fullPin = 7; // pin for fire selection mode select const int semiPin = 6; // other pin for fire selection mode select // variables: boolean safetyOn = false; int triggerState = 0; // variable for reading the trigger status int safetyState = 0; // variable for reading the safety switch status int lastTriggerState = 0; // previous state of the trigger int lastSafetyState = 0; // previous state of the safety switch int ammoCount = 299; String ammoDisp = String(ammoCount); // these are for the additional pins int grenadeCount = 200; //default grenade ammo count String grenadeDisp = String(grenadeCount); int fireSelect = 0; int lastgrenadetriggerState = 0; int grenadetriggerState = 0; int semiState = 0; int fullState = 0; boolean fullOn = false; boolean semiOn = false; int lastsemiState = 0; int lastfullState = 0; int lastburstState = 0 ; int burstState = 0; boolean burstOn = false; int fullbuttonCount = 0; int semibuttonCount = 0; enum { full, semi, burst, }; unsigned char autostate = full; void setup() { // initialize the LED pin as an output: pinMode(muzzlePin, OUTPUT); // initialize the trigger and safety pins as input: pinMode(triggerPin, INPUT); pinMode(safetyPin, INPUT); // initialize the audio pins pinMode(startSoundPin, INPUT); pinMode(clickSoundPin, INPUT); // pinMode(fireTailSoundPin, INPUT); pinMode(fireSoundPin, INPUT); pinMode(grenadeSoundPin, INPUT); // pinMode(triggerPin, INPUT); //duplicate // pinMode(safetyPin, INPUT); // duplicate // These are the additional pin declarations. pinMode(grenadePin, INPUT); pinMode(fullPin, INPUT); pinMode(semiPin, INPUT); // set up the audio trigger pins to give a path to GND when set to OUTPUT // this sets the initial led status to off on the muzzle strobe LEDs digitalWrite(muzzlePin, LOW); digitalWrite(triggerPin, HIGH); digitalWrite(safetyPin, HIGH); // These are the additional button pin declarations. digitalWrite(grenadePin, HIGH); digitalWrite(fullPin, HIGH); digitalWrite(semiPin, HIGH); Serial.begin(9600); Serial1.begin(9600); ss.begin(9600); alpha4.begin(0x70); // pass in the address alpha5.begin(0x71); delay(200); //give the audio board time to power up; otherwise bootup sound will be called before audio board is ready Serial1.print("#2\n"); //this plays the bootup sound // Change this number if you change the default ammo count above to match alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '2'); alpha4.writeDigitAscii(2, '9'); alpha4.writeDigitAscii(3, '9'); alpha4.writeDisplay(); alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '1'); alpha5.writeDigitAscii(2, '9'); alpha5.writeDigitAscii(3, '9'); alpha5.writeDisplay(); delay(100); // these are the round load effects for (int x = 4; x > 0; x--) { updateAmmoCounter(); ammoCount--; delay(50); } updateAmmoCounter(); for (int x = 1; x > 0; x--) { updateGrenadeCounter(); grenadeCount--; delay(50); } updateGrenadeCounter(); } // this function calls the current value of ammoCount and writes it to the LED display void updateAmmoCounter() { String ammoDisp = String(ammoCount); if (ammoCount < 10) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, '0'); alpha4.writeDigitAscii(3, ammoDisp[0]); } else if (ammoCount < 100) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, '0'); alpha4.writeDigitAscii(2, ammoDisp[0]); alpha4.writeDigitAscii(3, ammoDisp[1]); } else if (ammoCount < 1000) { alpha4.writeDigitAscii(0, '0'); alpha4.writeDigitAscii(1, ammoDisp[0]); alpha4.writeDigitAscii(2, ammoDisp[1]); alpha4.writeDigitAscii(3, ammoDisp[2]); } else if (ammoCount < 10000) { alpha4.writeDigitAscii(0, ammoDisp[0]); alpha4.writeDigitAscii(1, ammoDisp[1]); alpha4.writeDigitAscii(2, ammoDisp[2]); alpha4.writeDigitAscii(3, ammoDisp[3]); } alpha4.writeDisplay(); } // this displays and writes the grenade ammo count void updateGrenadeCounter() { String grenadeDisp = String(grenadeCount); if (grenadeCount < 10) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, '0'); alpha5.writeDigitAscii(3, grenadeDisp[0]); } else if (grenadeCount < 100) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, '0'); alpha5.writeDigitAscii(2, grenadeDisp[0]); alpha5.writeDigitAscii(3, grenadeDisp[1]); } else if (grenadeCount < 1000) { alpha5.writeDigitAscii(0, '0'); alpha5.writeDigitAscii(1, grenadeDisp[0]); alpha5.writeDigitAscii(2, grenadeDisp[1]); alpha5.writeDigitAscii(3, grenadeDisp[2]); } else if (grenadeCount < 10000) { alpha5.writeDigitAscii(0, grenadeDisp[0]); alpha5.writeDigitAscii(1, grenadeDisp[1]); alpha5.writeDigitAscii(2, grenadeDisp[2]); alpha5.writeDigitAscii(3, grenadeDisp[3]); } alpha5.writeDisplay(); } void setSafe() { safetyOn = true; alpha4.clear(); alpha4.writeDisplay(); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'F'); alpha5.writeDigitAscii(3, 'E'); alpha5.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'F'); alpha4.writeDigitAscii(3, 'E'); alpha4.writeDisplay(); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'F'); alpha5.writeDigitAscii(3, 'E'); alpha5.writeDisplay(); } void setArm() { safetyOn = false; alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); alpha5.writeDigitAscii(0, ' '); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'R'); alpha5.writeDigitAscii(3, 'M'); alpha5.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); alpha5.writeDigitAscii(0, ' '); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'R'); alpha5.writeDigitAscii(3, 'M'); alpha5.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); alpha5.writeDigitAscii(0, ' '); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'R'); alpha5.writeDigitAscii(3, 'M'); alpha5.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, ' '); alpha4.writeDigitAscii(1, 'A'); alpha4.writeDigitAscii(2, 'R'); alpha4.writeDigitAscii(3, 'M'); alpha4.writeDisplay(); alpha5.writeDigitAscii(0, ' '); alpha5.writeDigitAscii(1, 'A'); alpha5.writeDigitAscii(2, 'R'); alpha5.writeDigitAscii(3, 'M'); alpha5.writeDisplay(); delay(300); updateAmmoCounter(); updateGrenadeCounter(); } void setSemi() { semiOn = false; alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'S'); alpha4.writeDigitAscii(1, 'E'); alpha4.writeDigitAscii(2, 'M'); alpha4.writeDigitAscii(3, 'I'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setSemig() { semiOn = false; alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'E'); alpha5.writeDigitAscii(2, 'M'); alpha5.writeDigitAscii(3, 'I'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'E'); alpha5.writeDigitAscii(2, 'M'); alpha5.writeDigitAscii(3, 'I'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'E'); alpha5.writeDigitAscii(2, 'M'); alpha5.writeDigitAscii(3, 'I'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'S'); alpha5.writeDigitAscii(1, 'E'); alpha5.writeDigitAscii(2, 'M'); alpha5.writeDigitAscii(3, 'I'); alpha5.writeDisplay(); delay(30); updateGrenadeCounter(); } void setFull() { semiOn = false; alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'F'); alpha4.writeDigitAscii(1, 'U'); alpha4.writeDigitAscii(2, 'L'); alpha4.writeDigitAscii(3, 'L'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setBrst() { burstOn = true; alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(50); alpha4.clear(); alpha4.writeDisplay(); delay(50); alpha4.writeDigitAscii(0, 'B'); alpha4.writeDigitAscii(1, 'R'); alpha4.writeDigitAscii(2, 'S'); alpha4.writeDigitAscii(3, 'T'); alpha4.writeDisplay(); delay(30); updateAmmoCounter(); } void setBrstg() { burstOn = true; alpha5.writeDigitAscii(0, 'B'); alpha5.writeDigitAscii(1, 'R'); alpha5.writeDigitAscii(2, 'S'); alpha5.writeDigitAscii(3, 'T'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'B'); alpha5.writeDigitAscii(1, 'R'); alpha5.writeDigitAscii(2, 'S'); alpha5.writeDigitAscii(3, 'T'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'B'); alpha5.writeDigitAscii(1, 'R'); alpha5.writeDigitAscii(2, 'S'); alpha5.writeDigitAscii(3, 'T'); alpha5.writeDisplay(); delay(50); alpha5.clear(); alpha5.writeDisplay(); delay(50); alpha5.writeDigitAscii(0, 'B'); alpha5.writeDigitAscii(1, 'R'); alpha5.writeDigitAscii(2, 'S'); alpha5.writeDigitAscii(3, 'T'); alpha5.writeDisplay(); delay(30); updateGrenadeCounter(); } // --MAIN LOOP STARTS HERE-- void loop() { // begin safety pin and firemode selection section safetyState = digitalRead(safetyPin); if (safetyState != lastSafetyState) { if (safetyState == LOW) { if (safetyOn == false) { setSafe(); } else if (safetyOn == true) { setArm(); } } } semiState = digitalRead(semiPin); if (semiState != lastsemiState) { if (semiState == LOW) { if (semiOn == true) { } else if (semiOn == false) { fullbuttonCount++; } }} fullState = digitalRead(fullPin); if (fullState != lastfullState) { if (fullState == LOW) { if (fullOn == true) { } else if (fullOn == false) { semibuttonCount++; } } } if (semibuttonCount == 1){setBrstg();semibuttonCount++;} if (semibuttonCount == 3){setSemig();semibuttonCount++;} // if (semibuttonCount == 5){setFull();semibuttonCount++;} if (semibuttonCount == 5){semibuttonCount=0;} if (fullbuttonCount == 1){setBrst();fullbuttonCount++;} if (fullbuttonCount == 3){setSemi();fullbuttonCount++;} if (fullbuttonCount == 5){setFull();fullbuttonCount++;} if (fullbuttonCount == 7){fullbuttonCount=0;} // end safety pin and firemode selection section // grenade trigger section if (semibuttonCount ==2) { //brst grenadetriggerState = digitalRead(grenadePin); if (grenadetriggerState != lastgrenadetriggerState){ if (grenadetriggerState == HIGH) { } // this can be used to add a grenade flash using a declared pin later. the ethernet cable has no spare pins currently. It would be something along these lines: digitalWrite(muzzlePin, LOW); if (grenadetriggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); grenadetriggerState = digitalRead(grenadePin); } if (grenadeCount <= 0) { grenadetriggerState = digitalRead(grenadePin); } if (safetyOn == false && grenadeCount > 0) { Serial1.print("#0\n"); grenadeCount--; updateGrenadeCounter(); delay(300); grenadetriggerState = digitalRead(grenadePin);} if (safetyOn == false && grenadeCount == 0) { Serial1.print("q\n"); Serial1.print("#1\n"); } if (safetyOn == false && grenadetriggerState == HIGH) { Serial1.print("q\n"); } lastgrenadetriggerState = grenadetriggerState; } } if (semibuttonCount ==4 || semibuttonCount == 0) { // semi grenadetriggerState = digitalRead(grenadePin); if (grenadetriggerState != lastgrenadetriggerState){ if (grenadetriggerState == HIGH) { } // this can be used to add a grenade flash using a declared pin later. the ethernet cable has no spare pins currently. It would be something along these lines: digitalWrite(muzzlePin, LOW); if (grenadetriggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); grenadetriggerState = digitalRead(grenadePin); } if (grenadeCount <= 0) { grenadetriggerState = digitalRead(grenadePin); } if (safetyOn == false && grenadeCount > 0) { Serial1.print("#0\n"); grenadeCount--; updateGrenadeCounter(); delay(600); grenadetriggerState = digitalRead(grenadePin);} if (safetyOn == false && grenadeCount == 0) { Serial1.print("q\n"); Serial1.print("#1\n"); } if (safetyOn == false && grenadetriggerState == HIGH) { Serial1.print("q\n"); } lastgrenadetriggerState = grenadetriggerState; } } // end grenade trigger section //begin fireselect mode section if (fullbuttonCount == 2 ){ triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } if (triggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); ammoCount--; updateAmmoCounter(); delay(20); triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount == 0 ){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } if (safetyOn == false && triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } } lastTriggerState = triggerState; } if (fullbuttonCount == 4){ triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } if (triggerState == LOW && safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(509); triggerState = digitalRead(triggerPin); } if (safetyOn == false && ammoCount == 0 ){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } if (safetyOn == false && triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } } lastTriggerState = triggerState; } if (fullbuttonCount == 6|| fullbuttonCount == 0){ triggerState = digitalRead(triggerPin); if (triggerState != lastTriggerState) { if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); } while (triggerState == LOW) { if (safetyOn == true) { Serial1.print("#1\n"); triggerState = digitalRead(triggerPin); return; } if (ammoCount <= 0) { triggerState = digitalRead(triggerPin); return; } if (safetyOn == false) { if (ammoCount > 0) { Serial1.print("#3\n"); digitalWrite(muzzlePin, HIGH); ammoCount--; updateAmmoCounter(); delay(10); digitalWrite(muzzlePin, LOW); delay(39); triggerState = digitalRead(triggerPin); if (triggerState == HIGH) { digitalWrite(muzzlePin, LOW); Serial.print("q\n"); } if (ammoCount == 0){ digitalWrite(muzzlePin, LOW); Serial1.print("q\n"); delay(10); Serial1.print("#1\n"); } } } else { return; } } lastTriggerState = triggerState;} } lastSafetyState = safetyState; lastsemiState = semiState; lastfullState = fullState; // end mg fire mode selection section } |
Author: | knoxvilles_joker [ Sun Apr 21, 2024 6:44 am ] |
Post subject: | |
I have done a video compilation of progress pictures to my youtube: https://www.youtube.com/watch?v=j8vQfp32Fzw |
Page 1 of 1 | All times are UTC [ DST ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |