Operating a relay with a PIR sensor

djsfantasi

Joined Apr 11, 2010
9,237
What difficulties are you having? The sketch that you attached won't run as is, so I am curious as to what specific problems you're encountering.

And what are you using to simulate the trigger? You need to define the pin and you can use a SPST switch connected to ground and the pin to simulate the sensor. And you need an mp3 file named "track001.mp3", on an SD card inserted in the shield.

Oh, and when posting code, use [ code] and [ /code] tags to surround it (without the space). It makes it much easier to read your post.
 

djsfantasi

Joined Apr 11, 2010
9,237
With one minor change (defining your trigger pin. I picked pin A0) and installing the Sparkfun MP3 libraries, your code compiles cleanly. Now as to what it does when it is executed, I cannot test (since I don't have a shield to test with).

So what ARE you having difficulty with?

I promised my code using the Adafruit, so here it is. However, be warned it may be confusing and may be ignored without hurting my feelings :)
Code:
/***************************************************
  This is an example for the Adafruit VS1053 Codec Breakout

  Designed specifically to work with the Adafruit VS1053 Codec Breakout
  ----> https://www.adafruit.com/products/1381

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries. 
  BSD license, all text above must be included in any redistribution
****************************************************/

// include SPI, MP3 and SD libraries
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// define the pins used
#define CLK 13       // SPI Clock, shared with SD card
#define MISO 12      // Input data, from VS1053/SD card
#define MOSI 11      // Output data, to VS1053/SD card
// Connect CLK, MISO and MOSI to hardware SPI pins.
// See http://arduino.cc/en/Reference/SPI "Connections"

// These are the pins used for the breakout example
//#define BREAKOUT_RESET  9      // VS1053 reset pin (output)
//#define BREAKOUT_CS     10     // VS1053 chip select pin (output)
//#define BREAKOUT_DCS    8      // VS1053 Data/command select pin (output)
// These are the pins used for the music maker shield
#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)

// These are common pins between breakout and shield
#define CARDCS 4     // Card chip select pin
// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

Adafruit_VS1053_FilePlayer audioplayer =
  // create breakout-example object!
  //Adafruit_VS1053_FilePlayer(BREAKOUT_RESET, BREAKOUT_CS, BREAKOUT_DCS, DREQ, CARDCS);
  // create shield-example object!
  Adafruit_VS1053_FilePlayer(SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
void setup() {
  int result;
  Serial.begin(9600);
  Serial.println("Adafruit VS1053 Simple Test");

  if (! audioplayer.begin()) { // initialise the music player
     Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
     while (1);
  }
  Serial.println(F("VS1053 found"));
if (!SD.begin(CARDCS)) {
    Serial.println(F("initialization failed!"));
    while(true){}}
  Serial.println(F("initialization done."));
  // Set volume for left, right channels. lower numbers == louder volume!
  audioplayer.setVolume(20,20);

  // Timer interrupts are not suggested, better to use DREQ interrupt!
  //audioplayer.useInterrupt(VS1053_FILEPLAYER_TIMER0_INT); // timer int

  // If DREQ is on an interrupt pin (on uno, #2 or #3) we can do background
  // audio playing
  audioplayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);  // DREQ int
  // Play one file, don't return until complete
  Serial.println(F("Playing track 5"));
  audioplayer.playFullFile("track5.mp3");
  // Play another file in the background, REQUIRES interrupts!
  Serial.println(F("Playing track 8"));
  audioplayer.startPlayingFile("track8.mp3");
}

void loop() {
  // File is playing in the background
  if (audioplayer.stopped()) {
    Serial.println(F("Done playing music"));
    while (1);
  }
  if (Serial.available()) {
    char c = Serial.read();
  
    // if we get an 's' on the serial console, stop!
    if (c == 's') {
      audioplayer.stopPlaying();
    }
  
    // if we get an 'p' on the serial console, pause/unpause!
    if (c == 'p') {
      if (! audioplayer.paused()) {
        Serial.println(F("Paused"));
        audioplayer.pausePlaying(true);
      } else {
        Serial.println(F("Resumed"));
        audioplayer.pausePlaying(false);
      }
    }
  }

  delay(100);
}
 
Last edited:

Thread Starter

allenpitts

Joined Feb 26, 2011
182
Hello DJ,

Have tried four sketches
1. https://github.com/madsci1016/Spark...EMP3Shield/Examples/FilePlayer/FilePlayer.ino
This one relies on input thru the serial port. Not suitable for PIR sensor. Couldn't get it to work anyway
Hundreds of lines long. Could not boil down to simplicity.
2. https://learn.sparkfun.com/tutorials/mp3-player-shield-hookup
On this page at "Step 3 Load up the code"
Got this code to work by shorting pin 0 to ground. But when I short it a second time nothing happens.
Can short to 0 then pin 1 and then back to 0 and so on back and forth . That works but cannot play the same track repeatedly
which is the function I want.
3. The Code posted yesterday, march 3 3:47 . Doesn't do anything
4. The sketch copied below. Plays track 1 in an infinite loop.

Trying to get a sketch that will
1. Play track 1 when it receives a signal from PIR Sensor
(The PIR from Sparkfun sends a LOW signal but I prefer
the sensor from AdaFruit which sends a HIGH signal as do the other PIR sensors used from Parallax and Radio Shack)
2. Play the same track when it receives the next signal

Thanks

Allen in Dallas

Code:
 #include <SPI.h>
  #include <SdFat.h>
  #include <SdFatUtil.h>
  #include <SFEMP3Shield.h>

  SdFat sd;
  SFEMP3Shield MP3player;
  int triggerPin = 0;
  void setup() {

  //start the shield
  sd.begin(SD_SEL, SPI_HALF_SPEED);
  MP3player.begin();
  }

  //do something else now
  void loop() {
  // main code here, to run repeatedly:
  // det trigger pin high
  triggerPin == LOW;
  // trigger pin shorted to ground plays track
  if (triggerPin == HIGH)
  {
  MP3player.playTrack(1);  //start playing track 1
  }
  if (MP3player.isPlaying())
  {delay (6000);
  MP3player.stopTrack();
  //set the trigger pin back to low so the high signal will trigger
  //the MP3player
  triggerPin == LOW;
  }
  }
 
Last edited:

djsfantasi

Joined Apr 11, 2010
9,237
I can help, to a certain extent (can't do any real testing as I don't have your hardware). But will have to work on it at home tonight.
 

djsfantasi

Joined Apr 11, 2010
9,237
So let's try to get a couple of SIMPLE programs to work first. I like to break a problem down in little pieces and test them one at a time. The use those 'pieces' as building blocks for the final result. My last skecth was about 800 lines, and its how that was developed.

For example, here is a simple program that does something when the PIR detects movement, waits and does nothing else until the sensor is cleared.

Code:
#define triggerpin 5

void setup() {
  // put your setup code here, to run once:
  pinMode(triggerpin,INPUT_PULLUP); // since sensor is active LOW
                                    // the default state s.b. HIGH
  Serial.begin(9600); // for debug output

}

void loop() {
  // put your main code here, to run repeatedly:
  int trigger=HIGH;
  int prevstate=HIGH;
  while (true) {
    trigger=digitalRead(triggerpin);
    if (trigger==LOW) {
      // sensor detects something
      //do whatever here, like play a track
      Serial.println("Sensor Activated");
      while (digitalRead(triggerpin)==LOW); // loop here until sensor clears
    }
    if (trigger!=prevstate) {
      Serial.println("Cleared");
      prevstate=trigger;
    }
  }
}
Then, try a program that simply plays one track over and over. I've added some error checking during the initialization, which may be instructive.

Code:
#include <SPI.h>
#include "SdFat.h"
#include <SdFatUtil.h>
#include <SFEMP3Shield.h>

SdFat sd; //create an instance of SdFat named sd
SFEMP3Shield MP3player; //create an instance of SFEMP3Shield named MP3player

void setup() {
//start the shield
int result=0;

if(!sd.begin(SD_SEL, SPI_HALF_SPEED)) sd.initErrorHalt(); // init SD card
result = MP3player.begin();  // init MP3 player
//check result, see readme for error codes.
if(result != 0) {
    Serial.println(F("Error code: "));
    Serial.print(result);
    Serial.println(F(" when trying to start MP3 player"));
    }

}

void loop() {

  MP3player.playTrack(1); //play track 1
  while(MP3player.isPlaying()); //loop until track is finished

}
If you have any questions on why I did what I did, let me know.

For example, when defining the pin, I used INPUT_PULLUP because that mode ensures that HIGH is the default state. Your PIR sensor then changes it to LOW when it detects something.

I defined "triggerpin" to be 5, because while you got it to work with pin 2, the shield uses pin 2, so we can't use it for something else (see the "hookup" page for the shields pin usage)

I put a while loop after the track starts playing, which waits for it to finish before doing anything else. From your requirements, there is no reason not to wait.

I did something similar with detecting motion Once it has been detected and you do what you want (play a track), there is no reason not to wait until it clears.

These are some things I thought of off the top of my head. Like I said, ask any questions that you may have.

If you can get these examples to work (no guarantees on their correctness from me, unfortunately), you can likely figure how to merge them.
.
 
Last edited:

Thread Starter

allenpitts

Joined Feb 26, 2011
182
Hello djsfantisi and any one else working a SparkFun MP3 w a PIR sensor,

Finally got it to work.
There was no problem with the hardware the info at
https://learn.sparkfun.com/tutorials/mp3-player-shield-hookup
and
https://www.sparkfun.com/tutorials/392
was enough to get everything hooked up.
The problem was the code.
There were several examples but they all wanted
one to trigger using buttons or input at the serial monitor.
Mote importantly they were hundreds of lines
long and I always got some kind of
compile error when I tries to dumb them down.

I just wanted the MP3 player to trigger one track
from a PIR sensor signal.

Then I got an idea: use the PIR sensor sketch to receive the
sensor signal and a simple if statement to trigger the MP3.
Bingo! It worked!
The sketch used as a basis is actually on the AdaFruit site at
https://learn.adafruit.com/pir-passive-infrared-proximity-motion-sensor/using-a-pir

Sketch morphed to use the SparkFun MP3 player copied below.

Thanks to djsfantis for his generous help.

Allen in Dallas

Code:
+++++++++++++++++begin sketch++++++++++++++++

/*
2. * PIR sensor tester
3. */
#include <SPI.h>
#include <SdFat.h>
#include <SdFatUtil.h>
#include <SFEMP3Shield.h>
SdFat sd;
SFEMP3Shield MP3player;

int ledPin1 = 10;  // choose the pin for the LED
int inputPin = 5;  // choose the input pin (for PIR sensor)
int pirState = LOW;  // we start, assuming no motion detected
int val = 0;  // variable for reading the pin status

void setup() {

  //start the shield
  sd.begin(SD_SEL, SPI_HALF_SPEED);
  MP3player.begin();

  pinMode(ledPin1, OUTPUT);  // declare LED as output
  pinMode(inputPin, INPUT);  // declare sensor as input

  Serial.begin(9600);
}

void loop(){
  val = digitalRead(inputPin);  // read input value
  if (val == HIGH) {  // check if the input is HIGH
  digitalWrite(ledPin1, HIGH);  // turn LED ON

  MP3player.playTrack(1);

  if (pirState == LOW) {
  // we have just turned on
  Serial.println("Motion detected!");
  // We only want to print on the output change, not state
  pirState = HIGH;
  }
  } else {
  digitalWrite(ledPin1, LOW); // turn LED OFF
//  digitalWrite(ledPin2, LOW); // turn LED OFF
  if (pirState == HIGH){
  // we have just turned of
  Serial.println("Motion ended!");
  // We only want to print on the output change, not state
  pirState = LOW;
  }
  }
}

+++++++++++++end sketch++++++++++++
Moderators note: Please use code tags for pieces of code
 
Last edited by a moderator:
Top