1
\$\begingroup\$

I'm trying to combine two working electronics projects into one. I have a standalone piezo sensor that I can read values from when it vibrates via an arduino, and I have a standalone audio board (no arduino needed) that will play a sound file when you connect one of its pins to ground (currently via a push button).

This is the basic setup for the audio board

and this is the basic setup for the piezo / button

What I want to do is remove the need for the button to trigger sound files, and instead use the vibration from the piezo to trigger a song to play.

The sound board is set up to play a track when you connect one of its pins to ground. It has a built in pullup resistor. With the piezo, I have code executing so that, if the vibration is over a certain value, it will trigger a function to play the sound:

if (piezoV > 0.1){ //play sound }

What do I need to from a wiring & code perspective to make the piezo play the sound? What I tried was setting up one of the arduino pins to do a digital write:

const int SOUND_PIN = 2; //Trigger Sound Board
void setup() {
  pinMode(LED_PIN, OUTPUT);
  pinMode(SOUND_PIN, OUTPUT);
}

void loop() {
  int piezoADC = analogRead(PIEZO_PIN);
  float piezoV = piezoADC / 1023.0;
  if (piezoV > 0.1){
    playSound();
    delay(5000);
    stopSound();
  } 
}

void playSound(){
  digitalWrite(SOUND_PIN, HIGH);
}

void stopSound(){
  digitalWrite(SOUND_PIN, LOW);
}

Then I figured I could connect a wire from the arduino's pin 2 to the sound board's ground, and a wire from the sound board's ground to its own pin 1 (to play track 1) - but it seems like, whether there's vibration or not, when I do that the sound plays unconditionally.

WIRING:

Piezo to A0, Arduino Pin 2 to Ground, Ground to Sound FX Board Pin 1

Wiring setup to play audio with a button:

enter image description here

If anyone can point me in the right direction I'd appreciate it!

\$\endgroup\$
  • \$\begingroup\$ Don't you have the polarity of the pin output reversed? Shouldn't you set it LOW to play the sound? \$\endgroup\$ – crj11 Jul 26 '18 at 3:50
  • \$\begingroup\$ Agreed with @crj11. digitalWrite(PIN, LOW) is the same as tieing something to ground (as it sets the microcontroller pin to 0V). While it shouldn't be used for high currents, I'm assuming that's fine here. As a result, the playSound() command should be setting the pin low, not high. \$\endgroup\$ – DSWG Jul 26 '18 at 4:08
  • \$\begingroup\$ Hmmm, must be something else I'm missing, perhaps with the wiring. I'll draw my current wiring. \$\endgroup\$ – mheavers Jul 26 '18 at 5:21
  • \$\begingroup\$ I don't see a connection between the Arduino Ground and the soundboard Ground. \$\endgroup\$ – Peter Bennett Jul 26 '18 at 15:58
1
\$\begingroup\$

Can you please connect the sound board in the usual way, Arduino ground to sound board ground , Arduino pin 2 to sound board play pin 1 and modify the output for inverted logic (LOW = play and HIGH = stop set as input = stop)?

Obviously it plays all the time because the soundboard play pin is always connected to soundboard ground pin.

This is your first setup:

schematic

simulate this circuit – Schematic created using CircuitLab

First option:

schematic

simulate this circuit

Arduino uses 0-5V I/O levels , the soundboard uses 0-3.3V that's why you should use only pinMode(SOUND_PIN, INPUT); disconnecting the sound play pin instead digitalWrite(SOUND_PIN, HIGH) that pulls the pin to 5V when you want to release the pin.

To pull the pin to GND use digitalWrite(SOUND_PIN, LOW);pinMode(SOUND_PIN, OUTPUT);

See the folowing example:

const int SOUND_PIN = 2; //Trigger Sound Board
void setup() {
  pinMode(LED_PIN, OUTPUT);
  pinMode(SOUND_PIN, INPUT);// high impedance, sound pin disconnected
  digitalWrite(SOUND_PIN, LOW);//make sure the pin will be low when using it
  //this last instruction has no effect yet as long as the pin is configured as input
}

void loop() {
  int piezoADC = analogRead(PIEZO_PIN);
  float piezoV = piezoADC / 1023.0;
  if (piezoV > 0.1){
    playSound();
    delay(5000);
    stopSound();
  } 
}

void playSound(){
  digitalWrite(SOUND_PIN, LOW);//make sure the pin will be low
  pinMode(SOUND_PIN, OUTPUT);// set as output to drive the sound pin to gnd
}

void stopSound(){
  pinMode(SOUND_PIN, INPUT);// high impedance, sound pin disconnected
}

You can use the resistor R1 for the development stage to protect the soundboard input from software errors.

Other options:

Using an optocoupler as you can see in this link that I found from this similar older question. The S2 must go to Soundboard ground ans S1 to PIN 1

Using a relay, here is an example but you can find plenty on the web

\$\endgroup\$
  • \$\begingroup\$ This doesn't work (still plays all the time). Maybe I need something that breaks the connection to ground? I'm posting a picture of how the soundboard works with a button. Is there something I can substitute for the button that has the same effect, only with current from the arduino instead of a physical press? \$\endgroup\$ – mheavers Jul 26 '18 at 13:08
  • \$\begingroup\$ A relay but I still think that you're doing something wrong. First disconnect pin 1 and see if still playing maybe you burned the input in the first attempt. Then try to use pinMode(SOUND_PIN, INPUT) instead digitalWrite(SOUND_PIN, HIGH); and digitalWrite(SOUND_PIN, LOW); pinMode(SOUND_PIN, OUTPUT); instead of digitalWrite(SOUND_PIN, LOW); to float the output when you want the pushbutton depressed. \$\endgroup\$ – Dorian Jul 26 '18 at 13:36
  • \$\begingroup\$ @mheavers Also try the code with only stop play code, it still playing? Please, do not revert to the first setup, it's plain wrong. \$\endgroup\$ – Dorian Jul 26 '18 at 13:47
  • \$\begingroup\$ @mheavers It seems that the soundcard inputs are using 3.3V. Arduino uses 5V outputs. It should be safe to use the code above but not digitalWrite(SOUND_PIN, HIGH); since it will output 5V. \$\endgroup\$ – Dorian Jul 26 '18 at 13:59
  • 1
    \$\begingroup\$ Great answer, thank you. There is only one detail that I missed for anyone working with this sound board, which is that if you want a sound to play only while ground is low, you need to name the sound file with the HOLD suffix. All the other naming conventions will continue to play. If you want the sound to loop until the pin is triggered low again, name it with the LATCH suffix. See learn.adafruit.com/adafruit-audio-fx-sound-board/… \$\endgroup\$ – mheavers Jul 28 '18 at 13:48
0
\$\begingroup\$

Thanks for the answer - was working on a separate project and had issues triggering the pins. There is a serial mode, but I have a lot of noise in the system, so DIO is preferred. Using INPUT to float the pins worked great. Here is my sample code. Note that you only need to hold the pin low for >120ms to trigger the audio.

#define PIN_RESET   2
#define PIN_SOUND0  3
#define PIN_SOUND1  4
#define PIN_SOUND2  5

#define AUDIO_TOUCH_DELAY 150

void setup() {
  pinMode(PIN_RESET, INPUT);     // high impedance, sound pin disconnected
  pinMode(PIN_SOUND0, INPUT);     // high impedance, sound pin disconnected
  pinMode(PIN_SOUND1, INPUT);     // high impedance, sound pin disconnected
  pinMode(PIN_SOUND2, INPUT);     // high impedance, sound pin disconnected
} // setup


void loop() {
  // don't need to reset to start
  //digitalWrite(PIN_RESET, LOW);  // make sure the pin will be low
  //pinMode(PIN_RESET, OUTPUT);    // set as output to drive the sound pin to gnd
  //delay(AUDIO_TOUCH_DELAY);
  //pinMode(PIN_RESET, INPUT);     // high impedance, sound pin disconnected
  //delay(500);

  // test interrupting a sound to play another - sound 0 is almost 2 seconds long
  digitalWrite(PIN_SOUND0, LOW);  // make sure the pin will be low
  pinMode(PIN_SOUND0, OUTPUT);    // set as output to drive the sound pin to gnd
  delay(AUDIO_TOUCH_DELAY);
  pinMode(PIN_SOUND0, INPUT);     // high impedance, sound pin disconnected
  delay(500);

  digitalWrite(PIN_RESET, LOW);  // make sure the pin will be low
  pinMode(PIN_RESET, OUTPUT);    // set as output to drive the sound pin to gnd
  delay(AUDIO_TOUCH_DELAY);
  pinMode(PIN_RESET, INPUT);     // high impedance, sound pin disconnected
  delay(500);

  // play the three sounds in order with delay time to play them
  digitalWrite(PIN_SOUND0, LOW);  // make sure the pin will be low
  pinMode(PIN_SOUND0, OUTPUT);    // set as output to drive the sound pin to gnd
  delay(AUDIO_TOUCH_DELAY);
  pinMode(PIN_SOUND0, INPUT);     // high impedance, sound pin disconnected
  delay(2000);

  digitalWrite(PIN_SOUND1, LOW);  // make sure the pin will be low
  pinMode(PIN_SOUND1, OUTPUT);    // set as output to drive the sound pin to gnd
  delay(AUDIO_TOUCH_DELAY);
  pinMode(PIN_SOUND1, INPUT);     // high impedance, sound pin disconnected
  delay(2000);

  digitalWrite(PIN_SOUND2, LOW);  // make sure the pin will be low
  pinMode(PIN_SOUND2, OUTPUT);    // set as output to drive the sound pin to gnd
  delay(AUDIO_TOUCH_DELAY);
  pinMode(PIN_SOUND2, INPUT);     // high impedance, sound pin disconnected
  delay(6000);

} // loop
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.