Multiple level sound trigger

Hi all,

Hopefully you can help, I haven’t used Arduino before, I want to know if the following is possible using Arduino;

I need a system that has a proximity switch which detects once a user is close enough, this will trigger the Arduino to start listening through a microphone to the user.

The user is encouraged to talk to the system from a separate video playing next to the system.
It needs to detect the volume level that the user is talking at, let’s say there is three different levels.

  1. Talking
  2. Raised voice
  3. Shouting

At level 1 I want the system to trigger switch 1, if at level 2 it will trigger switch 2 and if at level 3 then switch 3 will be triggered.

Any help would be greatly appreciated

Yes, it should be possible. What, specifically, do you need help with?

If you can detect sound, you can detect loudness. :wink:

Then it's just a matter of using [u]if-statments[/u] to take different actions depending on loudness.

For example (this is the basic logic, not actual C code) -

If ADC reading is < 100, it's quiet so do nothing.
If ADC reading is > 99 and < 200 do something.
If ADC reading is > 199 and < 300 do something else.
...etc.

  1. Talking
  2. Raised voice
  3. Shouting

However, that is probably trickier than you think... People speak at different volume levels and it depends on how close they are to the microphone.

If you already have an Arduino and micrphone/preamp you can experiment by [u]reading the analog-to-digital converter[/u] and sending the readings to your computer via the [u]Serial Monitor[/u]. That should give you some quick results to find out if your project is feasible.

If you don't yet have the hardware, I'd suggest you make some recordings and "analyze" the sound with an audio editor. If you don't already have an audio editor, [u]Audacity[/u] is free, it can record, and it will display waveforms. And, there is an easy trick for finding the (relative) peak loudness if you're not getting enough information from looking at the waveforms.

[u]This microphone board[/u] has a microphone, the electronics for powering an electret mic, a preamp, and a bias circuit so you can read the negative-half of the audio signal. (You don't need the negative side for "loudness" but the Arduino can be damaged for actual negative voltages. The bias can be subtracted-out in software.) The one thing that board is lacking is a gain/sensitivity control.

Hi,

I'm looking for an example code to trigger specific tracks from the the Sparkfun / Robertsonics MP3 Tirgger using the RX / TX pins rather than the trigger pins.

I want to read the volume of a person shouting at a microphone and play audio clips back at them telling them they need to be louder / they are loud enough

I have it set up already to read three levels
1.quiet
2.moderate
3.loud

its just how i would then trigger the right tracks i'm stuck with.

many thanks, James

Simply connect three trigger pin inputs to three arduino outputs. Set these outputs high and when you want to trigger a sound just put the appropriate pin low delay about 10mS and then put it high again.

Don't forget to connect the ground of your arduino to the ground of your trigger board.

Hi,

Thanks for your responses.
I've since learned a little more about Arduino and have a basic system working.
I have a microphone reading the noise level and gives me a reading of quiet / moderate / loud and once it reads loud it triggers a relay which is the "reward"
I just need to sort out some audio now;

I need to cycle through four different introduction tracks (different characters) with a pause between them
if the user pushes the start button (to start the microphone listening) then the rest of the sequence needs to continue in that characters voice, so the response for the moderate and loud readings will match the voice played before the users pushes start.

Is this possible?

Many thanks. James

Can the tracks be triggered just using the RX / TX pins and not the trigger pins as i don't have eough outputs left on my Arduino for the number of different audio tracks that I want to trigger.

@James_sfx ,
Please don't cross post (same question in multiple threads).
Topics merged.

James_sfx:
Can the tracks be triggered just using the RX / TX pins and not the trigger pins as i don't have eough outputs left on my Arduino for the number of different audio tracks that I want to trigger.

No you can't. But did you know you can use the analogue input pins as digital outputs. Call them pins 14 to 19 for analogue 0 to 5.

It is simple to add extra outputs using a shift register or a port expander.

Hi,

sorry for 'cross posting' i'm new to all this.

i can run the example code that comes with the mp3 trigger:

#include <SoftwareSerial.h>
#include <MP3Trigger.h>

SoftwareSerial trigSerial = SoftwareSerial(1, 0);
MP3Trigger trigger;

void setup() {
// Start serial communication with the trigger (over SoftwareSerial)
trigger.setup(&trigSerial);
trigSerial.begin( MP3Trigger::serialRate() );
trigger.update();
trigger.play(1);
Serial.println("play track 1");
delay(7000);
trigger.play(2);
Serial.println("play track 2");
delay(4000);
trigger.play(3);
Serial.println("play track 3");
delay(10000);
}

void loop() {

}

and this will play tracks 1 - 3 just using the serial pins on the trigger, not the 1-18 trigger pins, how can i modify this code to trigger specific tracks when certain if conditions are met from readings gathered from a sensor?

sorry for 'cross posting' i'm new to all this.

Now go and read the "how to use this forum" sticky post to find out how to post code correctly.

sorry again, the code i was using is as follows:

#include <SoftwareSerial.h>
#include <MP3Trigger.h>

SoftwareSerial trigSerial = SoftwareSerial(1, 0);
MP3Trigger trigger;

void setup() {
 // Start serial communication with the trigger (over SoftwareSerial)
 trigger.setup(&trigSerial);
 trigSerial.begin( MP3Trigger::serialRate() );
trigger.update();
 trigger.play(1);
 Serial.println("play track 1");
 delay(7000);
 trigger.play(2);
 Serial.println("play track 2");
 delay(4000);
 trigger.play(3);
 Serial.println("play track 3");
 delay(10000);
}

void loop() {
 
}

Thanks.

Now where did you get that code from? You see it uses software serial but it uses the hardware serial pins. That is just a silly thing to do.

the code did use pins 2 and 3 i changed it to pins 0 and 1 as i wanted to use it alongside other code i had already which had pin 2 already being used.

is that what you meant by software serial using hardware serial pins?

I'm not familiar with what this means.

is that what you meant by software serial using hardware serial pins?

Yes you should never use software serial on the hardware pins. It will interfere with uploading code. You have to change it to other pins.

That code, does it play the first three samples?
If so the piece of code that does the actual playing is for example:-

trigger.play(2);

So if you want to make some code that plays the sample if say an analogue input is over a certain threshold then you have to use an if statement to compare the reading with some threshold and if it is then play that sample.

int threshold = 1000;
void loop(){
int reading = analogRead(0);
if (reading > 1000) {
  trigger.play(2);  // play the sound
// now wait until the input drops below the trigger point
   while( analogRead(0) > 1000) { // do nothing
   }
 }
}

Thanks for your quick responses,

this is how I have tried to impliment the example code into my own, and its not working;

#include <SoftwareSerial.h>
#include <MP3Trigger.h>

SoftwareSerial trigSerial = SoftwareSerial(3, 4);
MP3Trigger trigger;

#define PIN_GATE_IN 2
#define IRQ_GATE_IN  0
#define PIN_LED_OUT 13
#define PIN_ANALOG_IN A0
#define PIN_RELAY_OUT 10

void soundISR()
{
  int pin_val;

  pin_val = digitalRead(PIN_GATE_IN);
  digitalWrite(PIN_LED_OUT, pin_val);   
}
int Relay = 10;
int stateRelay = LOW;

void setup()
{
 
  pinMode(Relay, OUTPUT);
  Serial.begin(38400);

  //  Configure LED pin as output
  pinMode(PIN_LED_OUT, OUTPUT);

  // configure input to interrupt
  pinMode(PIN_GATE_IN, INPUT);
  attachInterrupt(IRQ_GATE_IN, soundISR, CHANGE);


  // Display status
  Serial.println("Initialized");
}

void loop()
{
  int value;

  // Check the envelope input
  value = analogRead(PIN_ANALOG_IN);

  // Convert envelope value into a message
  Serial.print("Status: ");
  if(value <= 60)
  {
    Serial.println("Quiet.");
  }
  else if( (value > 60) && ( value <= 200) )
  {
    Serial.println("Moderate.");
 trigger.setup(&trigSerial);
  trigSerial.begin( MP3Trigger::serialRate() );
trigger.update();
  trigger.play(2);
   delay(2500);
  }
  else if(value > 200)
  {
    Serial.println("Loud.");
     
 digitalWrite(Relay,HIGH);
 delay(17000);
 digitalWrite(Relay,LOW);
}

  // pause for 1 second
  delay(500);
}

The serial monitor lets me know the readings, quiet, moderate or loud, my relay triggers at loud, but no audio at moderate

I move this section of the code;

trigger.setup(&trigSerial);
  trigSerial.begin( MP3Trigger::serialRate() );
trigger.update();

to just beneath the void loop() line and its working!

next thing to get my head around is the different charcaters

Good morning,

What would be the best way to structure my code for the following to happen?

• An audio introduction is played - four different ones with say a 30second pause between them

• a user pushes a 'start' button, the next audio clip played needs to match the voice of the last introduction played as with all subsequent audio clips until that users go is finished where it will go back to cycling through the different character’s until another users pushes start.

I imagine it is possible to do this in code, although one idea I had was to have four separate Arduino’s with the same sequence of events on them but with the different voices triggered from each and they would be called upon depending on when the ‘start’ button was pushed

Advice is greatly appreciated, I’m learning very fast here on a real life job – I’ve defiantly jumped in at the deep end!

the next audio clip played needs to match the voice of the last introduction played as with all subsequent audio clips until that users go is finished where it will go back to cycling through the different character's until another users pushes start.

Silly to have four Arduinos for this. The name of the file you want should be in a two dimensional array. The first array index is the phrase and the second array index is the character. The contents of the array is the file name.

So you will have to learn about using arrays. First start with one dimensional ones before progressing to two dimensions.

Some links that might help:-
http://www.arduino.cc/en/Tutorial/Array

http://www.thebox.myzen.co.uk/Tutorial/Arrays.html

How would I break out of one loop at the push of a momentary button, and go into another loop?
but I want the second loop that you get taken into to be determined by at which point in the first loop the button is pushed?