Skip to content

Instantly share code, notes, and snippets.

@stonehippo
Last active December 19, 2022 03:21
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save stonehippo/308a5f5c49d4981ac976 to your computer and use it in GitHub Desktop.
Save stonehippo/308a5f5c49d4981ac976 to your computer and use it in GitHub Desktop.
A simple Arduino trigger of the Adafruit Audio FX Sound Board
// A simple trigger for the Adafruit Audio FX Sound Board
// For complete info on the sound board, see https://learn.adafruit.com/adafruit-audio-fx-sound-board/overview
/*
This is a simple test of a direct trigger of the Audio FX Sounds Board from an Arduino.
For my test, I used an Arduino Pro Mini running at 3.3v & 8mHz. Digital pin #4 of the Arduino
was connected to trigger pin #0 of the Sound Board, and I tied them to a common ground. I powered
Sound Board via a USB external battery for the initial tests, and the Arduino via the FTDI cable.
For later tests, I powered the Sound Board via the Arduino's VCC (3v) pin directly.
*/
#define PIN 4
#define LED 13 // Most Arduinos have an LED on pin 13
#define BUTTON 2 // put a simple button on pin 2 to enable/disable sound playback
void setup() {
pinMode(LED, OUTPUT); // Make the LED pin active
pinMode(BUTTON, INPUT_PULLUP);
setupSound(PIN);
}
void loop() {
if (digitalRead(BUTTON) == HIGH) {
delay(500);
activateSound(PIN);
delay(500);
}
}
void setupSound(int pin) {
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH); // Set the pin high as the default state
}
void activateSound(int pin) {
digitalWrite(LED, HIGH);
digitalWrite(pin, LOW); // bring the pin low to begin the activation
/*
According to the documentation, the Audio FX board needs 50ms to trigger. However,
I've found that coming from my 3.3v Arduino Pro, it needs 100ms to get the trigger
the going
*/
delay(100); // hold the pin low long enough to trigger the board; may need to be longer for consistent triggering
digitalWrite(pin, HIGH); // bring the pin high again to end the activation
digitalWrite(LED, LOW);
}

A simple trigger for the Adafruit Audio FX Sound Board

For complete info on the sound board, see https://learn.adafruit.com/adafruit-audio-fx-sound-board/overview

What I'm Doing Here

This is a simple test of a direct trigger of the Audio FX Sounds Board from an Arduino.

For my test, I used an Arduino Pro Mini running at 3.3v & 8mHz. Digital pin #4 of the Arduino was connected to trigger pin #0 of the Sound Board, and I tied them to a common ground. I powered the Sound Board via a USB external battery for the initial tests, and the Arduino via the FTDI cable. For later tests, I powered the Sound Board via the Arduino's VCC (3v) pin directly.

Things to Note

The Audio FX board pins are triggered when connected to ground (they're set up this way so they'll work with simple normally open push buttons connected directly to the board's ground). This has a couple of implications:

  • To trigger a given pin on the Audio FX board, we need to bring the Arduino pin tied to it to LOW, then back to HIGH.
  • I've found that adding a delay of 100ms after setting to LOW is long enough for the Audio FX board to register the trigger event with my 3v3 Arduino. The documentation stats that the board should be able to detect the trigger in 50ms. Not sure if the discrepency is due to the slower clock speed (8mHz) on the Arduino. I'll try it with a 5v Arduino running at 16mHz to see if that has any effect.
    • It turns out even 100ms might not be enough. In another project that I've got going, I had to hold the pin LOW for 250ms to consistently get a trigger to fire.
  • When the board is first powered on, the Arduino pins get set to OUTPUT mode. When that happens, the pins are triggered, causing the sounds to play. I'm not sure of the best way to suppress this, but it bears investigating. UPDATE: I don't think this is actually the case. I added a button to trigger the beginning of the playback. There is no trigger until that button is pressed. Yay!
  • Don't forget to tie the sound board and Arduino's ground together! :)
@gerfderp
Copy link

Thank you for this. It saved me hours of trial and error.

@prichardson
Copy link

ty...

If using a mega try pin 52 instead.

@gizmoprops
Copy link

Thank you so much. The last bullet about the ground to the Arduino was the key for me.

@jnagy197163
Copy link

but , dont you need to include to adafruit library ??

@stonehippo
Copy link
Author

but , dont you need to include to adafruit library ??

@jnagy197163 I'm not sure why you'd need any libraries from Adafruit for this? This example is simply putting a pin on the Arduino is a state, and relying on the Sound Board's built-in trigger. It doesn't need any sort of I2C or SPI driver.

@jnagy197163
Copy link

I'm trying to program a button to execute a soundbit while lighting up a programmable led . that is . say I have a monolog saved on the adafruit fx soundboard . I press the button that is connected to say PIN 2 . I have WS2812 led on PIN 13 . I want to program LED #1 to flicker with the monolog , dont have to be perfect . I am no arduino programmer , I am a noob ,
Thank You

@stonehippo
Copy link
Author

@jnagy197163 ah I think I see. The Sound FX Board may not be exactly what you want, though I think you could get what you’re looking for (sort of). You don’t have any way to sync the components of the sound to this board directly, but you could feed it’s line level output on the R/L pins to an ADC or two (one per channel if it’s stereo, or either channel into a single ADC if it’s mono). You can then use that to read the gain on the output sound. Depending on the audio track you’re workin with, this might produce an interesting effect if you take the read values and use them to drive the LED pin’s PWM output.

If you were going to use my code above to try this, you’d have to make some changes. This code makes liberal use of delay(), which basically suspends the execution of the microcontroller for a period of time (in other words, delay() blocks the CPU). You’d what to use a non-blocking method, such as a millis() based counter (see https://github.com/stonehippo/sploder/blob/master/include/TimingHelpers.h for an example of code that implements such a timer, and https://github.com/stonehippo/sploder/blob/master/src/sploder.cpp for some code that uses it). This is because you’ll probably want to read the ADC on each pass through the Arduino loop(). You need a very simple version of “multi-tasking” to do this, trigger the sound, and animate the CPU.

You have other options that could give you the effect you want. For example, you could create an animation for the LED that’s independent of the sounds level, but is triggered at the same time. It you look in the Sploder code I linked to above, there’s a “breathing” animation for the LED when it’s in one state, which is implemented in a non-blocking fashion.

I hope this helps. Let me know if you need some help with the code or circuits. I’m betting that you’re doing something for Halloween, and probably want to get it done soon. ;-)

@stonehippo
Copy link
Author

stonehippo commented Oct 18, 2020

@jnagy197163 I should also note that my example was for direct triggering. The Sound Boards can also be triggered via their UART (serial) interfaces, which does use the Soundboard library (as documented at https://learn.adafruit.com/adafruit-audio-fx-sound-board/serial-audio-control). I was looking for something different when I wrote this code (it’s been a while, so I don’t recall why), but that may be a simpler way to do the UART triggering if you’re firing off multiple sounds (since you don’t have to wire to multiple trigger pins).

@Fredteam
Copy link

Fredteam commented Oct 4, 2021

Please excuse my bad English, I am French...
Nobody is perfect...
Could you post a sketch, I don’t understand how pin #4 of the Arduino and pin #0 of the Audio Fx board can connect to the same ground?..
Sorry, in addition to my bad English, I’m just getting started in computer science...
Thank you.

@stonehippo
Copy link
Author

@Freadteam

Sorry if this was unclear. You need to connect pin #4 (or GPIO another pin of your choice) on the Arduino to pin #0 on the Audio FX board. You also need to connect the ground on the Arduino to the ground on the Audio FX board. So there are two wires, from pin 4 to pin 0 and from ground to ground.

I hope this helps.

@Fredteam
Copy link

Fredteam commented Oct 4, 2021 via email

@Fredteam
Copy link

Fredteam commented Oct 5, 2021

Sorry, I’m back...
I can’t make the sketch work properly:
The sound of the wired Fx audio on pin #4 runs in loop...
How is the push button connected?..
On one side, on pin #2 of the Arduino but on the other side?…
Thanks…

@jnagy197163
Copy link

jnagy197163 commented Oct 5, 2021 via email

@Fredteam
Copy link

Fredteam commented Oct 5, 2021 via email

@jnagy197163
Copy link

jnagy197163 commented Oct 5, 2021 via email

@Fredteam
Copy link

Fredteam commented Oct 5, 2021 via email

@tinker424
Copy link

Hi, and thank you for a very nice script. It sorted out a lot for me.

Is it possible to trigger it randomly, and trigger two pins with a fixed interval between them? I wouldnt know where to start to change the code to make this happen, so I would be very happy for any help/pointers I can get.

Let me try to illustrate;
[random time interval] -> Trigger PIN4 [1500msec delay] then trigger PIN3 -> [random time interval] rinse and repeat.

@stonehippo
Copy link
Author

stonehippo commented Nov 22, 2021

@tinker424 sure, there's a few things you'd want to change to do that. If you're using this example (which probably could use a re-write).

First, you would need to define all the pins you want to trigger. Might as well define the fixed interval, too. Based on your scenario:

...
#define PIN3 3
#define PIN4 4

#define FIXED_INTERVAL 1500 // time between triggers in msec
...

Second, in setup(), you want to make sure all the pins are configured, and set up a randomSeed() so that your sequence is not the same every time (note: I've removed the button setup code, since you want to trigger on random intervals).

void setup() {
  setupSound(PIN4);
  setupSound(PIN3);
  randomSeed(analogRead(0));
}

Let's add a little function to give us random intervals:

void randomInterval(long min, long max) {
    long wait = random(min, max);
    delay(wait);
}

Lastly, you need to setup the triggers in loop():

void loop() {
    randomInterval(MIN_RAND_INTVL, MAX_RAND_INTVL); // between MIN and MAX (say 1 to 5 seconds)
    activateSound(PIN4); // trigger first sound
    delay(FIXED_INTERVAL); // wait for a fixed amount of time
    activeSound(PIN3); // trigger second sound
}

This example will wait between 1 and 5 seconds, trigger the first sound, wait another 1.5 seconds, then trigger the second sound. Then the main loop will come back around again. You might need to tweak the fixed interval, to give the sound board enough time to reset. If you wanted to tweak the first delay at startup, add a call to randomInterval() to the end of setup() and move the call to randomInterval() in loop() to the end of that function (it can go at the top or bottom of the function, since it's just defining a gap between the activations).

This code could be better, including dropping delay() and using a non-blocking timing mechanism.

I hope this helps.

@tinker424
Copy link

@stonehippo ;

Thank you so much for your help, patience and sharing of knowledge! I will play around with it after work today, last night was all chores and no play....

@tinker424
Copy link

tinker424 commented Nov 23, 2021

A rare, quiet day at work allowed me to play with it now, and I got it working thanks to you! I removed the activation of the second PIN from this code, to check that it worked. The following is part your original, part the new code you posted. And it compiles and runs perfect.

`#define PIN4 4

void setup() {
setupSound(PIN4);
randomSeed(analogRead(0));
}

void randomInterval(long min, long max) {
long wait = random(min, max);
delay(wait);
}

void loop() {
randomInterval(1000, 5000); // between MIN and MAX (say 1 to 5 seconds)
activateSound(PIN4); // trigger first sound
}

void setupSound(int pin) {
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH); // Set the pin high as the default state
}

void activateSound(int pin) {
digitalWrite(pin, LOW); // bring the pin low to begin the activation
delay(100); // hold the pin low long enough to trigger the board; may need to be longer for consistent triggering
digitalWrite(pin, HIGH); // bring the pin high again to end the activation
}

I see now that my post from yesterday was unclear; I do not wish to play sound 1 then sound 2. I need to close a secondary circuit, then wait a fixed time, then trigger a pin to play the sound. PIN0 closes a circuit which releases a magnetic door. After 1.5 seconds I need the sound to play using PIN4 to trigger the soundboard.

Is it possible use minutes instead of milliseconds for "randomInterval"?

Now that this works, I will set up PIN0 on the Trinket m0 to handle the magnet. Thank you again for your help so far!

@stonehippo
Copy link
Author

stonehippo commented Nov 23, 2021

@tinker424 Here’s a trivial little application that shows one way to wait for minutes instead of milliseconds (I mean, you’re still waiting for milliseconds, but doing it in whole minutes).

There are a lot of design choices you could make, but for this example, I decided to limit the wait time between 1 and 60 minutes so that you’re always waiting for at least 1 minute. I think you get the idea, and can probably adapt this to whatever you need. As always, there are other ways to do this, but I tried for a simple, readable design.

@Darrell1972
Copy link

Darrell1972 commented Jul 18, 2022

@stonehippo, I'm trying to put together a Halloween scare house project for my kids using two Arduino Nano boards paired via Bluetooth using two Paired HC-05 Bluetooth Modules, also a Adafruit FX sound board and I want to trigger the sound with a break Beam sensor by Adafruit. I want to have the break beam sensor connected to the slave Bluetooth connected Nano board so when the beam is broken it activates and trigger the sound on the FX sound board that's connected to the master Nano board. I could really use your help to make this work if possible.

@MwaniN
Copy link

MwaniN commented Dec 19, 2022

Thank you so much for this! I wasn't sure how to trigger the pins to fire on the sound board, this helped a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment