basic questions on use of a shield and a sensor

Hello,

I am new to Arduino and coding.

I have recently completed my first project (with the kind help of the Arduino forum members). I successfully used an SRF05 sonic range finder sensor to control the amplitude of an audio oscillator running in Processing.

For my current project I want to trigger MP3 files when someone comes within 2 meters of sensor. I have ordered the Rmp3 shield and downloaded the relevant libraries.

I have 2 basic questions :

  1. Once I have connected the shield to the top of my Arduino Uno, do I then hook up my sensors (Ground, 5v, and receive/transmit) directly to the shield, or will the relevant pins still be exposed on my Arduino ?

  2. How do I convert the data coming from the sensor in to reasonable play/stop/skip comands to be sent to the Rmp3 shield for triggering Mp3's ?

Many thanks
Twogan

Many thanks for that reply - very positive.

OK, last time I used this code to get the sensor running :

int duration;                          // Stores duratiuon of pulse in
int distance;                          // Stores distance
int srfPin = 2;                        // Pin for SRF05

void setup(){
Serial.begin(9600);
}

void loop(){
  pinMode(srfPin, OUTPUT);
  digitalWrite(srfPin, LOW);           // Make sure pin is low before sending a short high to trigger ranging
  delayMicroseconds(2);
  digitalWrite(srfPin, HIGH);          // Send a short 10 microsecond high burst on pin to start ranging
  delayMicroseconds(10);
  digitalWrite(srfPin, LOW);           // Send pin low again before waiting for pulse back in
  pinMode(srfPin, INPUT);
  duration = pulseIn(srfPin, HIGH);    // Reads echo pulse in from SRF05 in micro seconds
  distance = duration/58;              // Dividing this by 58 gives us a distance in cm
  Serial.println(distance);
  delay(50);                           // Wait before looping to do it again
}

And I want to use this rmp3 code:

/******************************************
rMP3 Trigger with Time-Out Example
 
rMP3 Control Requirements
* Play songs in order when trigger is set.
* If trigger clears, start timer and stop
  playback if timer runs out.
 
Assumptions
* When timer runs out, playback starts
  at the beginning.
* Playback will continue if trigger re-sets
  before timer runs out.
 
******************************************/
 
#include <RogueSD.h>
#include <RogueMP3.h>
#include <NewSoftSerial.h>
 
// 30 second timeout
#define TIMER_MAX 30000
#define INPUT_PIN 8
 
// Objects
NewSoftSerial rmp3_serial(6, 7);
 
RogueMP3 rmp3(rmp3_serial);
RogueSD filecommands(rmp3_serial);
 
// global variables
int numberOfSongs;
int currentSong = 0;
boolean triggered = false;
boolean playing = false;
uint32_t triggerTimer = 0xffffffff - TIMER_MAX;
char filePath[96];
 
// consts
const char *directory = "/rMP3";
 
void setup()
{
  pinMode(INPUT_PIN, INPUT);
  digitalWrite(INPUT_PIN, HIGH);
 
  Serial.begin(9600);
 
  rmp3_serial.begin(9600);
 
  // synchronize audio player
  rmp3.sync();
  rmp3.stop();
 
  // synchronize file system controller
  filecommands.sync();
 
  Serial.println("rMP3 Synchronized.");
 
  // get the number of songs available
  strcpy(filePath, directory);
  strcat(filePath, "/");
  strcat(filePath, "*.mp3");
 
  numberOfSongs = filecommands.filecount(filePath);
 
  if (numberOfSongs < 0)
  {
    // rMP3 error
    if (filecommands.LastErrorCode == 8)
      Serial.println("No card inserted.");
    else
    {
      Serial.print("rMP3 Error Code: ");
      Serial.println(filecommands.LastErrorCode, HEX);
    }
 
    Serial.println("Reset required to continue.");
    for (;;);
  }
 
  Serial.print(numberOfSongs, DEC);
  Serial.println(" files available.");
 
  // rewind directory
  filecommands.opendir(directory);
 
  Serial.println("Awaiting trigger.");
}
 
 
// Play next song, if we can
void playNextSong()
{
  char filename[80];
 
  if (playing == true)
  {
    if (filecommands.status() == 0)
    {
      // card is inserted and good to go
      if (currentSong == 0)
      {
        // rewind directory
        filecommands.opendir(directory);
      }
 
      if (currentSong < numberOfSongs)
      {
        // get the next song
        filecommands.readdir(filename, "*.mp3");
 
        rmp3.playfile(directory, filename);
 
        Serial.print("Playing: ");
        Serial.print(directory);
        Serial.print('/');
        Serial.println(filename);
 
        currentSong++;
      }
      else
      {
        playing = false;
        currentSong = 0;
      }
    }
    else
    {
      if (filecommands.LastErrorCode == 8)
      {
        Serial.println("No card inserted.");
      }
      else
      {
        Serial.print("rMP3 Error Code: ");
        Serial.println(filecommands.LastErrorCode, HEX);
      }
 
      Serial.println("Reset required to continue.");
      for (;;);
    }
  }
}
 
 
// This is the function to check the input
boolean checkTrigger(void)
{
  if (digitalRead(INPUT_PIN) == HIGH)
    return true;
  else
    return false;
}
 
 
/******************************************
Main loop
******************************************/
 
void loop()
{
  char rMP3Status = rmp3.getplaybackstatus();
 
  // First, check the trigger
  if (checkTrigger())
  {
    if (triggered == false)
    {
      Serial.println("Trigger set.");
      if (playing == false)
      {
        // Start from the top
        playing = true;
        currentSong = 0;
      }
    }
    triggered = true;
  }
  else
  {
    if (triggered == true)
    {
      Serial.println("Trigger cleared.");
 
      triggered = false;
      triggerTimer = millis();
    }
    else
    {
      if ((millis() - triggerTimer) > TIMER_MAX)
      {
        if (playing == true)
        {
          playing = false;
          Serial.println("Playback stopped.");
        }
 
        if (rMP3Status == 'P')
        {
          // stop playback
          rmp3.stop();
        }
      }
    }
  }
 
  if (triggered == true || ((millis() - triggerTimer) < TIMER_MAX))
  {
    if (rMP3Status != 'P')
      playNextSong();
  }
 
  // Arbitrary delay
  delay(250);
}

So in the first code above, instead of
Serial.println(distance);
, can I combine the code and say something like:

If distance is less than 200 then make pin 8 go high ( thus trigering the playback on the rmp3)

As you can tell I am way out of my depth.

Can anyone give me some clues/tips/code to make this a reality...

Sorry for my ignorance.
Twogan

can I combine the code and say something like:

If distance is less than 200 then make pin 8 go high

Of course you can.

if(distance < 200)
   digitalWrite(8, HIGH);

However, 200 is a very large value for distance, and is likely beyond the range of valid distances that the sensor can measure. Perhaps, distance is not the value you want to trigger on.

Also, how will you prevent restarting the track on every pass through loop? Should the track stop if the distance goes above the threshold?

The better job you do of defining your requirements, the easier it is to convert them to code, and the more likely that the end program will do exactly what you want.

Many Thanks indeed for the reply and code PaulS.

The 200 figure is the measurement in centimetres that I should get from the SRF05. Hence if someone comes closer than 2 meters the mp3 is triggered. I did get large numbers like this last time I used the SRF05 to control the oscillator in processing, but please do explain if I am wrong on this.

To answer your (good) question about the behaviour - I don't know how I will prevent restarting on each pass through loop. I was hoping the 'trigger with time out example' would do that... any help on that appreciated !!

To be clear, here is what I want to achieve:-

There will be 5 mp3s on my SD card on the RMP3 playback module

  1. If someone comes within 200cm of the sensor then start playback of track 1. Whilst someone stays within range it continues playback sequentially through the tracks and repeats continuously

  2. When they leave the area, playback continues for say, 1 minute

  3. If someone comes back into the 200cm area during that 1 minute then playback continues

  4. If no-one comes back to within 200cm of sensor during that 1 minute then playback stops

  5. OPTIONAL - the next time someone comes into range playback starts with track 2, rather than always starting at track 1. And the next time it starts with track 3 etc... This is optional to be honest, This stuff is already a stretch so I need to make things as simple as possible!

Many Thanks
Twogan

The rmp3 shield allows you to know whether a song is playing. If one is playing, you can simply not call the play() function again.

You can note when the sensor reports "victim in range" and "victim out of range". If the now minus victim out of range time exceeds some value, stop the playback.

Keeping track of which track was played last, and playing a different track should be pretty easy. At least, the keeping track of a counter and wishing to play a different track is. I have no experience with that particular shield (and library), but I'd be surprised if the necessary capabilities do not exist.