Cosplay blaster prop using Arduino Nano and Adafruit FX soundboard

Hello guys, I'm trying to build a prop gun that has a semi firing mode and a Stun firing mode. I'm using a Arduino Nano and a Adafruit FX soundboard for this build. I want to use UART mode to control the Adafruit FX board to play the wav file shot sounds. I want it have two buttons, one for the trigger and one button for the mode selection toggle switch to fire a lethal round or a stun round. I tried to combine different sketches which is not working out in my favor! If you guys can help me figure this out I would really appreciate it!

Post the sketches you are trying to combine.

Post your attempt to combine them.

Also, successfully combining sketches is a frequently sought result, google

Arduino combine two sketches

or similar, there are processes that can be followed to help you sort out why they mightn't get along.

a7

1 Like
Here's the sketch:  // switches to stun; In stun the stun sound plays and lights blue;
// Ammo count starts at 1000 and counts down with bars; At zero empty click plays until mode change button is pressed for reload
// Sounds are read from Adafruit_Soundboard sfx



#include <SoftwareSerial.h>
#include "Adafruit_Soundboard.h"




// Choose any two pins that can be used with SoftwareSerial to RX & TX
#define SFX_TX 5
#define SFX_RX 6

// Connect to the RST pin on the Sound Board
#define SFX_RST 4

// You can also monitor the ACT pin for when audio is playing!

// we'll be using software serial
SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX);

// pass the software serial to Adafruit_soundboard, the second
// argument is the debug port (not used really) and the third
// arg is the reset pin
Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, SFX_RST);
// can also try hardware serial with
// Adafruit_Soundboard sfx = Adafruit_Soundboard(&Serial1, NULL, SFX_RST);

type or paste code here


// pin definitions
//Fire button connects to pin D8
int fire = 8;
//Mode change button connects to pin D3
int modechange = 3;



// global variables
//These are the intial values that the script uses to setup counts for mode changes and fire button presses
int count1 = 1;
int count2 = 1;
int lastButtonState1 = 1;
int lastButtonState2 = 1;
long unsigned int lastPress1;
long unsigned int lastPress2;
volatile int buttonFlag1;
volatile int buttonFlag2;
int debounceTime = 20;
int ammo = 1000;


Adafruit_Soundboard ;



void setup() {
  // setup pin modes
  pinMode(modechange, INPUT_PULLUP);
  pinMode(fire, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(fire), _8, CHANGE);
  attachInterrupt(digitalPinToInterrupt(modechange), _3, CHANGE);
  Serial.begin(9600);  // dont forget to set your serial monitor speed to whatever is set here
  Serial.println("Running");



  //Adafruit_Soundboard sfx
  Serial.begin(9600);
  //Adafruit_Soundboard sfx.begin(Serial, true);
  Serial.println("Setting volume to max");
  //Adafruit_Soundboard sfx.volume(204);  // Set volume 0 to 204 (max is 204)




  //Play initial startup sound
  Serial.println("Play startup sound");
  //Triggers the startup sound to play
  //Format calls the directory on the Adafruit_Soundboard sfx )

}

void loop() {
  //Fire button check loop
  {
    int a = random(1, 12);
    int b = random(1, 12);
    int c = random(1, 12);
    int d = random(1, 12);
    int e = random(70, 90);


    //Debug statements commented out
    //Serial.print("LastButton:");
    //Serial.println(lastButtonState1);
    if ((millis() - lastPress1) > debounceTime && buttonFlag1) {
      lastPress1 = millis();                                //update lastPress
      if (digitalRead(fire) == 0 && lastButtonState1 == 1)  //if button is pressed and was released last change
      {
        Serial.println("Fire:");
        count1 = count1 + 1;
        //Serial.println(count1);
        //Blast - subroutine to play blast sound and light
        if (count2 == 1 && ammo != 0) {
          (0xff, 0x00, 0x00, 2);
          (0x00, 0x00, 0x00, 2);

        }
        //Stun - Subroutine if in stun mode
        if (count2 == 2 & ammo != 0) {
          (0x00, 0x00, 0xff, 2);
          (0x00, 0x00, 0x00, 2);


        }

        //lastButtonState1 = 0;    //record the lastButtonState
      }

      if (digitalRead(fire) == 1 && lastButtonState1 == 0)  //if button is not pressed, and was pressed last change
      {
        lastButtonState1 = 1;  //record the lastButtonState
      }
      buttonFlag1 = 0;
    }
    //Modechange check loop - checks if mode change button has been pressed
    if ((millis() - lastPress2) > debounceTime && buttonFlag2) {
      lastPress2 = millis();                                      //update lastPress
      if (digitalRead(modechange) == 0 && lastButtonState2 == 1)  //if button is pressed and was released last change
      {
        Serial.println("Mode:");
        //Count2 is used to determin mode 1=kill, 2=stun
        count2 = count2 + 1;
        Serial.println("Count Increase");
        if (count2 == 3) {
          count2 = 1;
        }
        //Play sound for mode change
        if (ammo != 0) {

        }


        //Decreases count2 by 1 to prevent mode change on reload
        count2 = count2 - 1;
        delay(1000);
      }
      //Serial.println(count2);


      //lastButtonState2 = 0;    //record the lastButtonState
    }

    else if (digitalRead(modechange) == 1 && lastButtonState2 == 0)  //if button is not pressed, and was pressed last change
    {
      lastButtonState2 = 1;  //record the lastButtonState
    }
    buttonFlag2 = 0;
  }
}

void _8() {
  buttonFlag1 = 1;
}

void _3() {
  buttonFlag2 = 1;

}

I would first try changing that pin 8 interrupt to pin 2.
In the future, I recommend the Nano Every over the Nano. I just find it far easier to work with.
Good luck

1 Like
                                                                                                                                                                                                                                                                                                                                   // This script is a simple Blaster OS; By default is plays a blast sound and lights red; Pressing the mode change button
// switches to stun; In stun the stun sound plays and lights blue;  
// Ammo count starts at 50 and counts down with bars; At zero empty click plays until mode change button is pressed for reload
// Sounds are read from SD card loaded in DFPLayer mini



#include <Adafruit_NeoPixel.h>
// DFPlayer Mini library that seems to work with all of the DFPlayer Minis
#include <DFPlayerMini_Fast.h>
#include <Arduino.h>
#include <U8g2lib.h>
#if !defined(UBRR1H)
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 1); // RX, TX
#endif

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif


//128x32 Ammo display on pins D9 & D10
U8G2_SSD1306_128X32_UNIVISION_F_SW_I2C u8g2(U8G2_R3, /* clock=*/ 9, /* data=*/ 10, /* reset=*/ U8X8_PIN_NONE);   // Adafruit Feather ESP8266/32u4 Boards + FeatherWing OLED
//64x32 Scop display on pins A4 & A5 (native Arduino Every SDA SCL pins)
U8G2_SSD1306_64X32_1F_1_HW_I2C u8g3(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
// End of constructor list

// pin definitions
//Fire button connects to pin D8
int fire = 8;
//Mode change button connects to pin D3
int modechange = 3;

//Addressable LED data pin D11
#define PIN 11  //LED Data Pin
#define NUM_LEDS 9  //Number of LEDs that will be lit


// global variables
//These are the intial values that the script uses to setup counts for mode changes and fire button presses
int count1 = 1;
int count2 = 1;
int lastButtonState1 = 1;
int lastButtonState2 = 1;
long unsigned int lastPress1;
long unsigned int lastPress2;
volatile int buttonFlag1;
volatile int buttonFlag2;
int debounceTime = 20;
int ammo = 50;

DFPlayerMini_Fast myMP3;


//Define addresable LED variables
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  // setup pin modes
  pinMode(modechange, INPUT_PULLUP);
  pinMode(fire, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(fire), ISR_button1, CHANGE);
  attachInterrupt(digitalPinToInterrupt(modechange), ISR_button2, CHANGE);
  Serial.begin(9600); // dont forget to set your serial monitor speed to whatever is set here
  Serial.println("Running");
  strip.begin();
  strip.show();
  u8g2.begin();
  u8g3.begin();

  //DFPlayer Setup
  mySerial.begin(9600);
  myMP3.begin(mySerial, true);
  Serial.println("Setting volume to max");
  myMP3.volume(30); // Set volume 0 to 30 (max is 30)

  
  // Ammo Count Boxes
  u8g2.setDrawColor(1);
  u8g2.setFontPosTop();
  u8g2.setFontDirection(0);
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_inb19_mn);
  u8g2.setCursor (2, 2);
  u8g2.print(ammo);
  
  //Draw Five Ammo Count Boxes
  u8g2.drawBox(2,110,30,17);
  u8g2.drawBox(2,91,30,17);
  u8g2.drawBox(2,72,30,17);
  u8g2.drawBox(2,53,30,17);
  u8g2.drawBox(2,34,30,17);
  u8g2.sendBuffer();

  //Play initial startup sound
  Serial.println("Play startup sound");
  //Triggers the startup sound to play
  //Format calls the directory on the SD card 01 and the third track; make sure files are named with 001, 002, 003, etc)
  myMP3.playFolder(01, 3);
}

void loop() {
  //Fire button check loop
  u8g3.firstPage(); 
  do {
    int a = random(1, 12);
    int b = random(1, 12);
    int c = random(1, 12);
    int d = random(1, 12);
    int e = random(70, 90);
   
    //Draw Scope
    u8g3.drawCircle(32, 15, 15);//Outer Ring
    u8g3.drawCircle(32, 15, 2);//Inner ring
    u8g3.drawLine(20, 15, 15, 15);//left hash
    u8g3.drawLine(44, 15, 49, 15);//right hash
    u8g3.drawLine(32, 30, 32, 25);//bottom hash
    u8g3.drawLine(32, 1, 32, 5);//top hash
    
    u8g3.setFont(u8g2_font_tom_thumb_4x6_tf);
    u8g3.setCursor (46, 6);
    u8g3.print("TI-23");
    u8g3.setCursor(52, 26);
    u8g3.print("RNG");
    u8g3.setCursor(52, 32);
    u8g3.print(e);
    u8g3.print("m");
    //Top Left Bars
    u8g3.drawLine(1, 1, a, 1);//bar 1
    u8g3.drawLine(1, 3, b, 3);//bar 2
    u8g3.drawLine(1, 5, c, 5);//bar 3
    u8g3.drawLine(1, 7, d, 7);//bar 4
    delay(50);
  } while ( u8g3.nextPage() );
  //Debug statements commented out
  //Serial.print("LastButton:");
  //Serial.println(lastButtonState1);
  if((millis() - lastPress1) > debounceTime && buttonFlag1)
  {
    lastPress1 = millis();   //update lastPress                                                     
    if(digitalRead(fire) == 0 && lastButtonState1 == 1)    //if button is pressed and was released last change
    {
      Serial.println("Fire:");
      count1 = count1 + 1;
      //Serial.println(count1);
      //Blast - subroutine to play blast sound and light
      if (count2 == 1 && ammo != 0){
       colorWipe(0xff,0x00,0x00, 2);
       colorWipe(0x00,0x00,0x00, 2); 
       myMP3.playFolder(01, 1);
      }
      //Stun - Subroutine if in stun mode
      if (count2 == 2 & ammo != 0){
       colorWipe(0x00,0x00,0xff, 2);
       colorWipe(0x00,0x00,0x00, 2); 
       myMP3.playFolder(01, 2);
      }
      //Empty - Subroutine if empty; Plays empty sound until mode button is pressed for reload
      if (ammo == 0){
       Serial.println("Empty");
       myMP3.playFolder(01, 5);
      }


      
      
      
      //Ammo Bar
      //Five bars - Displays five bars on ammo display based on ammo count above 40
      if ((ammo <=50) && (ammo >= 40))
      {
        ammo = ammo - 1;
        //Five ammo count boxes already drawn
        Serial.println("50-40");
        u8g2.setCursor (2, 2);
        u8g2.print(ammo);
        u8g2.sendBuffer();
      }

      //four bars -Displays four bars on ammo display based on ammo count above 30
      if ((ammo <= 39) && (ammo >= 30))
      {
        ammo = ammo - 1;
        //Draw Four Ammo Count Boxes
        Serial.println("39-30");
        u8g2.clearBuffer();
        u8g2.drawBox(2,110,30,17);
        u8g2.drawBox(2,91,30,17);
        u8g2.drawBox(2,72,30,17);
        u8g2.drawBox(2,53,30,17);
        Serial.println(ammo);
        u8g2.setCursor (2, 2);
        u8g2.print(ammo);
        u8g2.sendBuffer();
      }

      //Three bars Displays three bars on ammo display based on ammo count above 20
      if ((ammo <= 29) && (ammo >= 20)) {
        ammo = ammo - 1;
        //Draw Four Ammo Count Boxes
        Serial.println("29-20");
        u8g2.clearBuffer();
        u8g2.drawBox(2,110,30,17);
        u8g2.drawBox(2,91,30,17);
        u8g2.drawBox(2,72,30,17);
        Serial.println(ammo);
        u8g2.setCursor (2, 2);
        u8g2.print(ammo);
        u8g2.sendBuffer();
      }

      //Two bars Displays on bar on ammo display based on ammo count above 10
      if ((ammo <= 19) && (ammo >= 10)) {
        ammo = ammo - 1;
        //Draw Four Ammo Count Boxes
        Serial.println("19-10");
        u8g2.clearBuffer();
        u8g2.drawBox(2,110,30,17);
        u8g2.drawBox(2,91,30,17);
        Serial.println(ammo);
        u8g2.setCursor (2, 2);
        u8g2.print(ammo);
        u8g2.sendBuffer();
      }

      //One bars
      if ((ammo <= 9) && (ammo >= 1)) {
        ammo = ammo - 1;
        //Draw Four Ammo Count Boxes
        u8g2.clearBuffer();
        u8g2.drawBox(2,110,30,17);
        Serial.println(ammo);
        u8g2.setCursor (2, 2);
        u8g2.print(ammo);
        u8g2.sendBuffer();
      }

      //Zero bars
      if ((ammo == 0)) {
        //Draw Four Ammo Count Boxes
        u8g2.clearBuffer();
        Serial.println(ammo);
        u8g2.setCursor (2, 2);
        u8g2.print(ammo);
        u8g2.sendBuffer();
      }
  
      //lastButtonState1 = 0;    //record the lastButtonState
    }
    
    else if(digitalRead(fire) == 1 && lastButtonState1 == 0)    //if button is not pressed, and was pressed last change
    {
      lastButtonState1 = 1;    //record the lastButtonState
    }
    buttonFlag1 = 0;
  }
  //Modechange check loop - checks if mode change button has been pressed
  if((millis() - lastPress2) > debounceTime && buttonFlag2)
  {
    lastPress2 = millis();   //update lastPress                                                     
    if(digitalRead(modechange) == 0 && lastButtonState2 == 1)    //if button is pressed and was released last change
    {
      Serial.println("Mode:");
      //Count2 is used to determin mode 1=kill, 2=stun
      count2 = count2 + 1;
      Serial.println("Count Increase");
      if (count2 == 3) {
        count2 = 1;
      }
      //Play sound for mode change
      if (ammo != 0) {
        myMP3.playFolder(01, 4);
      }
      //Reload Sequence
      if (ammo == 0) {
        Serial.println("Reload");
        myMP3.playFolder(01, 3);
        ammo = 50;
        //Re-Draw Five Ammo Count Boxes for reload
        u8g2.drawBox(2,110,30,17);
        u8g2.drawBox(2,91,30,17);
        u8g2.drawBox(2,72,30,17);
        u8g2.drawBox(2,53,30,17);
        u8g2.drawBox(2,34,30,17);
        u8g2.setCursor (2, 2);
        u8g2.print(ammo);
        u8g2.sendBuffer();
        //Decreases count2 by 1 to prevent mode change on reload
        count2= count2 - 1;
        delay(1000);
      }
      //Serial.println(count2);
      
    
      //lastButtonState2 = 0;    //record the lastButtonState
    }
    
    else if(digitalRead(modechange) == 1 && lastButtonState2 == 0)    //if button is not pressed, and was pressed last change
    {
      lastButtonState2 = 1;    //record the lastButtonState
    }
    buttonFlag2 = 0;
  }
  
}

void ISR_button1()
{
  buttonFlag1 = 1;
}

void ISR_button2()
{
  buttonFlag2 = 1;
}


int SpeedDelay = .1;
void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {
  for(uint16_t i=0; i<NUM_LEDS; i++) {
      setPixel(i, red, green, blue);
      showStrip();
      delay(SpeedDelay);
  }
}
void showStrip() {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.show();
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   FastLED.show();
 #endif
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip.setPixelColor(Pixel, strip.Color(red, green, blue));
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;

 #endif
}
 

This is Blaster sketch I wanted to use because it had only three modes, Fire, reload, and mode change for firing lethal or stun. I want to eliminate the reload and the ammo counter so it would just fire forever in lethal mode or stun mode. I want to eliminate all the LEDS, Neopixels and the ammo display screen and the scope display screen. I wanted a simple two button sketch with a firing button and a change mode button that makes a sound when it changes the firing sound from lethal to stun, I don't want all the other functions in this Blaster sketch. I want to use the Adafruit FX soundboard for the sounds instead of a MP3 play that was used.

Given how different your requirements are from the what the original sketch does, you're probably better off just writing your own code from scratch to do exactly what you want.

I wish I could, I have brain damage that have taken away my short term memory and screwed up my ability to learn, so I have to see a sketch and copy it, I tried to use different sketches to create one sketch that would do what I need but it didn't work out for me. I'm trying to do this for my son for his cosplay for Halloween, I'm doing my best to do this for him but I'm having a hard time because of my disability! I got the Arduino Nano and the Adafruit FX soundboard but the sketch is my biggest challenge!

write your own in that case. You want a state machine, using switch case statements as a driver.
Here's mine, for a large robot. It has two "arms" which are over volted Nerf Prometheus. It gets its cues (the chars) from a companion Processing sketch that uses a Kinect camera. In your case, you'd replace the Serial input chars for button states in the switch/case arrangement. Good luck and hopefully you find my sketch useful.


/*

  Processing companion sketch sentryBotMarkX2
  Relay triggers for sentry bot blasters. Reworked from MarkI Arduino,
  took out testing servo triggers and replacing with 4 channel relay module

  Relay module will control:
  relay 1 - left feeder motor (red and black wires) arduino white wire
  relay 2 - left dual firing motors (2x in parallel) arduino orange
  relay 3 - right feeder motor (red and black motors) arduino yellow
  relay 4 - right dual firing motors (2x in parallel) arduino purple

  Arduino Nano Every 5V pin to VCC on relay board
  Arduino ground not connected (since using JD-VCC option header removed on relay board which isolates
           completely the Arduino from the 12V switching side)
  +12V to buck converter to +5V and ground (the one along the Arduino pins next to "IN1"
          to power relay coils via JD-VCC (header removed)
  +12V power rail to each relay N/O
  Each relay COM connects to positive on respective motors/blaster wires

  whole circuit relies on 12V switched power so one switch kills whole blaster capability
  (rocker switch on right side)


  NOTE:
  The input pins are active low, which means that a logic LOW activates
  the relay and a logic HIGH deactivates it.

  The relay module has two LED_BUILTINs that indicate
  the status of the relay. When a relay is activated,
  the corresponding LED_BUILTIN lights up.


  October 23-26, 2022

*/
#include <elapsedMillis.h>

elapsedMillis timeElapsed;
char command;
int idleCounter = 0;
unsigned int interval = 20000;

const int leftFeederRelay1 = 2; //white
const int leftFiringMotorsRelay2 = 3; // orange
const int rightFeederRelay3 = 4; // yellow
const int rightFiringMotorsRelay4 = 5; // purple

void setup() {
  pinMode(leftFeederRelay1, OUTPUT);
  pinMode(leftFiringMotorsRelay2, OUTPUT);
  pinMode(rightFeederRelay3, OUTPUT);
  pinMode(rightFiringMotorsRelay4, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  // digitalWrite(leftFeederRelay1, HIGH);
  // digitalWrite(leftFiringMotorsRelay2, HIGH);
  // digitalWrite(rightFeederRelay3, HIGH);
  // digitalWrite(rightFiringMotorsRelay4, HIGH);
  digitalWrite(LED_BUILTIN, LOW);

  delay(3000); // give it a sec on first power
  Serial.begin(57600); // sentryBotMarkX2_rev1 baud rate
  // Serial.println(F("sentryBotMarkXRelayTriggers"));
  restState();
}

void loop() {
  if (Serial.available()) {
    command = Serial.read();
    switch (command) {

      // noted are the companion Processing functions driving these chars
      // giveInfo();
      case 'i':
        informMode();
        break;

      //addingTarget(); alrtNonComNoSafe(); alrtNoWarning(); hostTarLockGrn();
      case 'j':
        threatFound();
        break;

      //no Processing function uses char t yet
      case 't':
        targeting();
        break;

      //giveTheMini();
      case 'w':
        weaponsHot();
        break;

      // givetheGat();
      case 'x':
        bulletRain();
        break;

      default:
        restState();
    }
  }

  else if (Serial.available() == 0) {
    restState();
    if (timeElapsed > interval) {
      if (idleCounter == 1) {
        Serial.println('1');
        timeElapsed = 0;
      }
      else if (idleCounter == 2) {
        Serial.println('2');
        timeElapsed = 0;
      }
      else if (idleCounter == 3) {
        Serial.println('3');
        timeElapsed = 0;
      }
      else if (idleCounter == 4) {
        Serial.println('4');
        timeElapsed = 0;
      }
      else if (idleCounter == 5) {
        Serial.println('5');
        timeElapsed = 0;
      }
      else if (idleCounter == 6) {
        Serial.println('6');
        timeElapsed = 0;
      }
      else if (idleCounter == 7) {
        Serial.println('7');
        timeElapsed = 0;
      }
      idleCounter++;
      if (idleCounter > 6) {
        idleCounter = 0;
      }
    }
  }
}

// weapons cold

void restState() { // off
  digitalWrite(leftFeederRelay1, HIGH); // recall these relays are active LOW
  digitalWrite(leftFiringMotorsRelay2, HIGH); // so HIGH is off or not activated
  digitalWrite(rightFeederRelay3, HIGH);
  digitalWrite(rightFiringMotorsRelay4, HIGH);
  digitalWrite(LED_BUILTIN, LOW);
}

// go time
void bulletRain() { // on
  digitalWrite(leftFeederRelay1, LOW); // recall these relays are active LOW
  digitalWrite(leftFiringMotorsRelay2, LOW); // so HIGH is off or not activated
  digitalWrite(rightFeederRelay3, LOW);
  digitalWrite(rightFiringMotorsRelay4, LOW);
  digitalWrite(LED_BUILTIN, HIGH);
 // Serial.println("light 'em up!");
  delay(5000);
}

void weaponsHot() { // on, quick blast audio clip is a second long
  digitalWrite(leftFeederRelay1, LOW);
  digitalWrite(leftFiringMotorsRelay2, LOW);
  digitalWrite(rightFeederRelay3, LOW);
  digitalWrite(rightFiringMotorsRelay4, LOW);
  digitalWrite(LED_BUILTIN, HIGH);
 // Serial.println("quick shot");
  delay(1000);
}

// the following three modes are relics of original design
// that I'm leaving in because I don't want to mess with
// the Processing sketch that sends chars to activate these modes.
// I may be able to add on in the future using these modes
// which originally set servo positions
// commented out in each function
// who knows? maybe laser targeting in the future or something?
// or using 1/5 scale servos to tilt the arms up and down
void informMode() { // off
  digitalWrite(leftFeederRelay1, HIGH);
  digitalWrite(leftFiringMotorsRelay2, HIGH);
  digitalWrite(rightFeederRelay3, HIGH);
  digitalWrite(rightFiringMotorsRelay4, HIGH);
  digitalWrite(LED_BUILTIN, LOW);
 // Serial.println("interrogative");
}

void threatFound() { // off
  digitalWrite(leftFeederRelay1, HIGH);
  digitalWrite(leftFiringMotorsRelay2, HIGH);
  digitalWrite(rightFeederRelay3, HIGH);
  digitalWrite(rightFiringMotorsRelay4, HIGH);
  digitalWrite(LED_BUILTIN, LOW);
 // Serial.println("threat found");
}

void targeting() { // off
  digitalWrite(leftFeederRelay1, HIGH);
  digitalWrite(leftFiringMotorsRelay2, HIGH);
  digitalWrite(rightFeederRelay3, HIGH);
  digitalWrite(rightFiringMotorsRelay4, HIGH);
  digitalWrite(LED_BUILTIN, LOW);
}
1 Like

Oh, also, I'm not sure you need interrupts in your sketch at all. It's likely snappier but I wonder if using them will mess with the Adafruit audio stuff. I'm not sure, legit. I've personally used plenty of Wave shields from Adafruit (who give excellent walkthroughs for their products btw) and I seem to remember something about interrupts messing with reading SD cards, .wav files, something. I could be wrong but I can say getting the audio to work in my projects was finicky. Hopefully you have better luck.

1 Like

This is a special branch of hacking, and can be quite fun and easy.

It can also require, however, at least the same skill level it would take to just write the code in the first place as @gfvalvo suggests.

The sketch below is where I ended up with the code you presented. It bears little resemblence to the original. There is no reason for the interrupt-based button handling, and the handling was flawed in other ways besides.

It watches a Mode button and cycles through three modes. It watches a Fire! button and fires (prints) a single shot of the current mode.

You'll have to add the actual calls to the Adafruit FX soundboard in UART mode. You may want to use a simpler mode, but you do you.

Play with it here:


Wokwi_badge Mode/Fire Control


// https://forum.arduino.cc/t/cosplay-blaster-prop-using-arduino-nano-and-adafruit-fx-soundboard/1182601
// https://wokwi.com/projects/379751701654688769

# include <SoftwareSerial.h>
# include "Adafruit_Soundboard.h"

# define SFX_TX 5
# define SFX_RX 6

# define SFX_RST 4

SoftwareSerial ss = SoftwareSerial(SFX_TX, SFX_RX);

Adafruit_Soundboard sfx = Adafruit_Soundboard(&ss, NULL, SFX_RST);

//Fire button connects to pin D2
const int fire = 2;
//Mode change button connects to pin D3
const int modechange = 3;

int count1 = 0;
int mode = 0;
int lastButtonState1;
int lastButtonState2 = 1;
long unsigned int lastPress1;
long unsigned int lastPress2;

int debounceTime = 20;

Adafruit_Soundboard ;

void setup() {
  pinMode(modechange, INPUT_PULLUP);
  pinMode(fire, INPUT_PULLUP);

  Serial.begin(9600);  // dont forget to set your serial monitor speed to whatever is set here
  Serial.println("Running");

  //Adafruit_Soundboard sfx
  Serial.begin(9600);
  //Adafruit_Soundboard sfx.begin(Serial, true);
  Serial.println("Setting volume to max");
  //Adafruit_Soundboard sfx.volume(204);  // Set volume 0 to 204 (max is 204)

  Serial.println("Play startup sound");
  //Adafruit_Soundboard sfx. ????

  lastButtonState1 = !digitalRead(fire);
}

void loop() {
//Serial.println(" loop "); delay(100);

  unsigned long now = millis();

  if (now - lastPress2 > debounceTime)
    if (!digitalRead(modechange) != lastButtonState2) {

      lastPress2 = now;

      if (!lastButtonState2) {
        Serial.print("Mode: ");
        mode++; if (mode == 3) mode = 0;
        Serial.println(mode);
      }
      lastButtonState2 = !lastButtonState2;
    }

  if (now - lastPress1 > debounceTime) 
    if (!digitalRead(fire) != lastButtonState1) {

      lastPress1 = now;

      if (!lastButtonState1) {
        Serial.print("Fire: f/x ");
        Serial.print(mode); Serial.print("    ");
        count1++;
        Serial.println(count1);
      }
      lastButtonState1 = !lastButtonState1;
    }
}

HTH. If you learn by reading example sketches, take a close look at the button handling. There are two code sections that are nearly identival, one for each of the two buttons. Any more buttons and I'd be advising you to use a button library or create your iwnn function out of the pattern twice repeated here laxily, by @alto777.

a7

1 Like

Thanks Buddy I'll do my best to make it work!!:+1:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.