Go Down

Topic: PIR->WaveShield->Speakers +total noob (Read 6019 times) previous topic - next topic

Steppenwolf

Hi there, I'm working on a project where when someone enters the bathroom, a music track randomly selected begins to play, and then shuts off when motion is no longer detected.  A test sketch that plays the track over and over, without the PIR, proves that the hardware is sound, and now I've attached the PIR to pin 0 and the 5v and ground, and added four more tracks to the SD card. 

Now I'm not really sure where to go.  I've done some searching around this forum and the adafruit forums and I cannot find a proper sketch for this, and the fact that I am new to all this means I don't really know how to go about modifying the one's I have seen to make them do what I want.

Can anyone help point me in the right direction?
Thanks in advance!

brucethehoon

Can you post the sketch you have? Be sure to click the # button so than it formats as code!

Big Oil

I did a similar project, every time someone walks in and triggers a distance sensor a song plays.  (it isn't randomized, it plays the next one down the line each time)
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1272995447/0#0

Steppenwolf

Hmm the serial monitor says:

WavWaveHC with 6 buttons
Free RAM: 608
Card init. failed!


SD I/O error: 6, 0


My code is:

Code: [Select]
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"


SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the filesystem on the card
FatReader f;      // This holds the information for the file we're play

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

#define DEBOUNCE 100  // button debouncer

// this handy function will return the number of bytes currently free in RAM, great for debugging!   
int freeRam(void)
{
  extern int  __bss_end;
  extern int  *__brkval;
  int free_memory;
  if((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__bss_end);
  }
  else {
    free_memory = ((int)&free_memory) - ((int)__brkval);
  }
  return free_memory;
}

void sdErrorCheck(void)
{
  if (!card.errorCode()) return;
  putstring("\n\rSD I/O error: ");
  Serial.print(card.errorCode(), HEX);
  putstring(", ");
  Serial.println(card.errorData(), HEX);
  while(1);
}

void setup() {
  // set up serial port
  Serial.begin(9600);
  putstring_nl("WaveHC with 6 buttons");
 
   putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
  Serial.println(freeRam());      // if this is under 150 bytes it may spell trouble!
 
  // Set the output pins for the DAC control. This pins are defined in the library
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);

  // pin13 LED
  pinMode(13, OUTPUT);

  //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
  if (!card.init()) {         //play with 8 MHz spi (default faster!) 
    putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
    sdErrorCheck();
    while(1);                            // then 'halt' - do nothing!
  }
 
  // enable optimize read - some cards may timeout. Disable if you're having problems
  card.partialBlockRead(true);

// Now we will look for a FAT partition!
  uint8_t part;
  for (part = 0; part < 5; part++) {     // we have up to 5 slots to look in
    if (vol.init(card, part))
      break;                             // we found one, lets bail
  }
  if (part == 5) {                       // if we ended up not finding one  :(
    putstring_nl("No valid FAT partition!");
    sdErrorCheck();      // Something went wrong, lets print out why
    while(1);                            // then 'halt' - do nothing!
  }
 
  // Lets tell the user about what we found
  putstring("Using partition ");
  Serial.print(part, DEC);
  putstring(", type is FAT");
  Serial.println(vol.fatType(),DEC);     // FAT16 or FAT32?
 
  // Try to open the root directory
  if (!root.openRoot(vol)) {
    putstring_nl("Can't open root dir!"); // Something went wrong,
    while(1);                             // then 'halt' - do nothing!
  }
 
  // Whew! We got past the tough parts.
  putstring_nl("Ready!");
}

void loop() {
  //putstring(".");            // uncomment this to see if the loop isnt running
  switch (check_switches()) {
    case 1:
      playcomplete("BanjoSong.wav");
      break;
    case 2:
      playcomplete("LittleMaggie.wav");
      break;
    case 3:
      playcomplete("OmieWise.wav");
      break;
    case 4:
      playcomplete("SameOldMan.wav");
      break;
    case 5:
      playcomplete("StrawFoot.wav");
      break;
    case 6:
      playcomplete("WayFaringStranger.wav");
  }
}

byte check_switches()
{
  if (digitalRead(14) == HIGH)  // check for high signal on pin 14 (analog 0)
    {
       return 1;
    }
  return 0;
}

// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
  // call our helper to find and play this name
  playfile(name);
  while (wave.isplaying) {
  // do nothing while its playing
  }
  // now its done playing
}

void playfile(char *name) {
  // see if the wave object is currently doing something
  if (wave.isplaying) {// already playing something, so stop it!
    wave.stop(); // stop it
  }
  // look in the root directory and open the file
  if (!f.open(root, name)) {
    putstring("Couldn't open file "); Serial.print(name); return;
  }
  // OK read the file and turn it into a wave object
  if (!wave.create(f)) {
    putstring_nl("Not a valid WAV"); return;
  }
 
  // ok time to play! start playback
  wave.play();
}


CrossRoads

How do you have the PIR wired? I was just setting one of those up.
This one in fact
http://www.sparkfun.com/products/8630
and I found I had use an external pullup to +5V to get it to work well.
It has an open collector output, the output stays high unil it senses motion, then it pulls low. I used the low to create an interrupt on pin2 to wake up from sleep mode and do an action, then go back into sleep mode to save battery life (3 AAs).

You could poll the PIR output line every 1000mS or something, when you see it go low then play your song.
At top of void loop()
while (digitalRead(PIR_output) ==1){
delay (1000)
// at some point it will = 0 and then continue to the rest of the your code
}
If running on batteries, have it go to sleep and then wake up on interrupt into pin 2 or 3 (external interrupt lines:

at top of sketch:
#include <avr/sleep.h>      // powerdown library
#include <avr/interrupt.h>  // interrupts library
int interrupt = 2; // hardware interrupt, Motion Detector Open Collector pulls low

Interrupt Service Routine function:
//***************************************************
// *  Name:        pin2Interrupt, "ISR" to run when interrupted in Sleep Mode
void pin2Interrupt()
{
  /* This brings us back from sleep. */
}

Sleep function:
//***************************************************
// *  Name:        enterSleep
void enterSleep()
{
  /* Setup pin2 as an interrupt and attach handler. */
  attachInterrupt(0, pin2Interrupt, LOW);
  delay(50); // need this?
  /* the sleep modes
   SLEEP_MODE_IDLE - the least power savings
   SLEEP_MODE_ADC
   SLEEP_MODE_PWR_SAVE
   SLEEP_MODE_STANDBY
   SLEEP_MODE_PWR_DOWN - the most power savings
   */
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // setting up for sleep ...
  sleep_enable();                       // setting up for sleep ...
  sleep_mode();                         // now goes to Sleep and waits for the interrupt

  /* The program will continue from here after the interrupt. */
  // detachInterrupt(0);                 //disable interrupts while we wake up   COMMENTED OUT, didn't work otherwise

  /* First thing to do is disable sleep. */
  sleep_disable();

  // then go to the void Loop()
}


in setup:
  pinMode (interrupt, INPUT);  // hardware interrupt for waking up
  digitalWrite (interrupt, HIGH);  // internal pullup enabled

in loop:
// call this when song is done and you want to power down
  enterSleep();               // call Sleep function to put us out
                              //  THE PROGRAM CONTINUES FROM HERE after waking up in enterSleep()


Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Steppenwolf


brucethehoon


I have it connected to the 5v pin

I always vowed never to be this guy, but that has to be one of the least helpful responses possible.    No... "why?" would have beat it.

If possible, it's always helpful to post code and complete wiring information.  Want to really impress? Go to http://www.fritzing.org and build a graphic showing how you've got it connected.


Steppenwolf

The PIR is connected to the 5v pin, the GND, and analog 0.


Serial Monitor returns:

Cardiled!


SD I/O error: 6, 0
WaveHC with 6 buttons
Free RAM: 608
Card init. failed!


SD I/O error: 6, 0


My code is:

Code: [Select]

#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"


SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the filesystem on the card
FatReader f;      // This holds the information for the file we're play

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

#define DEBOUNCE 100  // button debouncer

// this handy function will return the number of bytes currently free in RAM, great for debugging!   
int freeRam(void)
{
  extern int  __bss_end;
  extern int  *__brkval;
  int free_memory;
  if((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__bss_end);
  }
  else {
    free_memory = ((int)&free_memory) - ((int)__brkval);
  }
  return free_memory;
}

void sdErrorCheck(void)
{
  if (!card.errorCode()) return;
  putstring("\n\rSD I/O error: ");
  Serial.print(card.errorCode(), HEX);
  putstring(", ");
  Serial.println(card.errorData(), HEX);
  while(1);
}

void setup() {
  // set up serial port
  Serial.begin(9600);
  putstring_nl("WaveHC with 6 buttons");
 
   putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
  Serial.println(freeRam());      // if this is under 150 bytes it may spell trouble!
 
  // Set the output pins for the DAC control. This pins are defined in the library
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);

  // pin13 LED
  pinMode(13, OUTPUT);

  //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
  if (!card.init()) {         //play with 8 MHz spi (default faster!) 
    putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
    sdErrorCheck();
    while(1);                            // then 'halt' - do nothing!
  }
 
  // enable optimize read - some cards may timeout. Disable if you're having problems
  card.partialBlockRead(true);

// Now we will look for a FAT partition!
  uint8_t part;
  for (part = 0; part < 5; part++) {     // we have up to 5 slots to look in
    if (vol.init(card, part))
      break;                             // we found one, lets bail
  }
  if (part == 5) {                       // if we ended up not finding one  :(
    putstring_nl("No valid FAT partition!");
    sdErrorCheck();      // Something went wrong, lets print out why
    while(1);                            // then 'halt' - do nothing!
  }
 
  // Lets tell the user about what we found
  putstring("Using partition ");
  Serial.print(part, DEC);
  putstring(", type is FAT");
  Serial.println(vol.fatType(),DEC);     // FAT16 or FAT32?
 
  // Try to open the root directory
  if (!root.openRoot(vol)) {
    putstring_nl("Can't open root dir!"); // Something went wrong,
    while(1);                             // then 'halt' - do nothing!
  }
 
  // Whew! We got past the tough parts.
  putstring_nl("Ready!");
}

void loop() {
  //putstring(".");            // uncomment this to see if the loop isnt running
  switch (check_switches()) {
    case 1:
      playcomplete("BANJOSONG.WAV");
      break;
    case 2:
      playcomplete("LITTLEMAGGIE.WAV");
      break;
    case 3:
      playcomplete("STRAWFOOT.WAV");
      break;
    case 4:
      playcomplete("SAMEOLDMAN.WAV");
      break;
    case 5:
      playcomplete("WAYFARINGSTRANGER.WAV");
      break;
    case 6:
      playcomplete("OMIEWISE.WAV");
  }
}

byte check_switches()
{
  if (digitalRead(14) == HIGH)  // check for high signal on pin 14 (analog 0)
    {
       return 1;
    }
  return 0;
}


// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
  // call our helper to find and play this name
  playfile(name);
  while (wave.isplaying) {
  // do nothing while its playing
  }
  // now its done playing
}

void playfile(char *name) {
  // see if the wave object is currently doing something
  if (wave.isplaying) {// already playing something, so stop it!
    wave.stop(); // stop it
  }
  // look in the root directory and open the file
  if (!f.open(root, name)) {
    putstring("Couldn't open file "); Serial.print(name); return;
  }
  // OK read the file and turn it into a wave object
  if (!wave.create(f)) {
    putstring_nl("Not a valid WAV"); return;
  }
 
  // ok time to play! start playback
  wave.play();
}

CrossRoads

Not fritzing. Might as well take a blurry picture and post that.
Get a real schematic editor, so much more useful as tool.

So, your program stops right here:

  //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
  if (!card.init()) {         //play with 8 MHz spi (default faster!) 
    putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
    sdErrorCheck();
    while(1);                            // then 'halt' - do nothing!   <<<<<<<<<<<<<<<<<<<<< 
  }

Try changing the 2 lines around, maybe slower will work for you.

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Steppenwolf


Steppenwolf

It might be my sd card.  It's being totally inconsistent.  Sometimes I get the card.init failure, sometimes it says ready, but then when I wave in front of the PIR, it says can't open BanjoSong.wav endlessly (which is at least encouraging, because it means the PIR is working).

CrossRoads

How was the card loaded with songs? I imagine via PC or something? Is the card still readable there?
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Steppenwolf

It was loaded on my mac, and it perfectly readable there.  I used a program called Blue Harvest to erase the "dust" (the invisible files that macs put on things like usb drives and sd cards), because they were giving the wave shield a hard time.  But it is fat16 formatted and what not.

CrossRoads

Ok, then I guess the next step is looking at your code compared to this working come from this thread and see whats different that this works and yours doesn't
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1272995447/0#0

I don't  have time right now, maybe later tonight, after 8pm east coast time.

Code: [Select]

#include <AF_Wave.h> //You will need the AF Wave library
#include <avr/pgmspace.h>
#include "util.h"
#include "wave.h"

AF_Wave card;
File f;
Wavefile wave;     

#define redled 9

uint16_t samplerate;

int Power = 19;

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Wave test!");



  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(redled, OUTPUT);
  pinMode(Power, OUTPUT);
 
  if (!card.init_card()) {
    putstring_nl("Card init. failed!"); return;
  }
  if (!card.open_partition()) {
    putstring_nl("No partition!"); return;
  }
  if (!card.open_filesys()) {
    putstring_nl("Couldn't open filesys"); return;
  }

if (!card.open_rootdir()) {
    putstring_nl("Couldn't open dir"); return;
  }

  putstring_nl("Files found:");
  ls();
}

void ls() {
  char name[13];
  int ret;
 
  card.reset_dir();
  putstring_nl("Files found:");
  while (1) {
    ret = card.get_next_name_in_dir(name);
    if (!ret) {
       card.reset_dir();
       return;
    }
    Serial.println(name);
  }
}

uint8_t tracknum = 0;

void loop() {
int sensor = 0;
int sensorPin = 0;
  sensor = analogRead(sensorPin);
  uint8_t i, r;
   char c, name[15];


   card.reset_dir();
   // scroll through the files in the directory
 
//------------------------------------------------ 
   // THIS IS THE BUTTON IF STATEMENT!!!!
  //
 
    digitalWrite(Power, LOW);  //This turns the Speaker system
                              //Off using a powerSwitchTail relay
                             // when no music is playing.
                             // You don't need this if you
                             // want to leave your speakers on
 
   if (sensor > 300){    // 300 is for the IR distance sensor,
                         // you can change that number depending
                         // on the type of sensor you use.
                         // This sensor is on pin Analog 0.
 
  digitalWrite(Power, HIGH);  //This turns the speakers ON using
                                //the powerswitchtail Relay
   for (i=0; i<tracknum+1; i++) {
     r = card.get_next_name_in_dir(name);
     if (!r) {
       // ran out of tracks! start over
       tracknum = 0;
       return;
     }
   }
   putstring("\n\rPlaying "); Serial.print(name);
   // reset the directory so we can find the file
   card.reset_dir();
   playcomplete(name);
   tracknum++;
}
  }
void playcomplete(char *name) {
  uint16_t potval;
  uint32_t newsamplerate;
 
  playfile(name);
  samplerate = wave.dwSamplesPerSec;
  while (wave.isplaying) {   
// you can do stuff here!
delay(500);
   }
  card.close_file(f);
}

void playfile(char *name) {
   f = card.open_file(name);
   if (!f) {
      putstring_nl(" Couldn't open file"); return;
   }
   if (!wave.create(f)) {
     putstring_nl(" Not a valid WAV"); return;
   }
   // ok time to play!
   wave.play();
}
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

CrossRoads

You don't have this in yours:

playfile(name);
samplerate = wave.dwSamplesPerSec;   <<<  maybe this line has something to do with playback not working ??
while (wave.isplaying) {
// you can do stuff here!
delay(500);
}
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Go Up