Monster House Project

Hello. I fairly new to arduino, and to programming in general, and am possibly in a bit over my head with a project I'm attempting to do with (for) my son. I've previously worked through the Arduino Projects Book, and I've made a little robot, but all I've really been doing is copying and pasting code, and then altering parameters.

So what we're trying to do is make a little model that replicates a scene from the animated movie Monster House. All that needs to happen is a door bell (momentary button) gets pressed and an audio clip of a door bell plays followed by the house lights (leds) going on.

Its at 1m25ish in this link: Monster House (2/10) Movie CLIP - Ding Dong Ditch Doom (2006) HD - YouTube

We have built a little cardboard model of the house, and successfully got the lights to go on with a delay using the Button code (https://www.arduino.cc/en/Tutorial/Button)

We have got the audio sample to play using the SimpleAudioPlayer (using a Due and a SD card shield) https://www.arduino.cc/en/Tutorial/SimpleAudioPlayer

So what I'd like to do is somehow combine them, but when i try I get all sort of exceptions as the form of the two codes is a bit different, and I don't really understand the nuances of the code that well.

Does anyone have any tips, suggestions for more applicable code?

Cheers

I would advise against copying code from others and trying to make it work without fully understanding it - this will only lead to frustration .
LeArn a bit of coding and do some simple tasks , then move on .

void setup() {
pinMode(buttonPin,INPUT_PULLUP); //buttonPin is the pin that the button is connected to, other site of button to ground. 
pinMode(lightPin,OUTPUT); //lightPin is the pin that lights are connected to, assuming active high. 
  // debug output at 9600 baud
  Serial.begin(9600);

  // setup SD-card
  Serial.print("Initializing SD card...");
  if (!SD.begin(4)) {
    Serial.println(" failed!");
    while(true);
  }
  Serial.println(" done.");
  // hi-speed SPI transfers

  // 44100kHz stereo => 88200 sample rate
  // 100 mSec of prebuffering.
  Audio.begin(88200, 100);
}

void loop() {
  int count = 0;
if (digitalRead(buttonPin==LOW) { //assuming your button is wired between buttonPin and ground
  // open wave file from sdcard
  File myFile = SD.open("test.wav");
  if (!myFile) {
    // if the file didn't open, print an error and stop
    Serial.println("error opening test.wav");
    while (true);
  }

  const int S = 1024; // Number of samples to read in block
  short buffer[S];

  Serial.print("Playing");
  // until the file is not finished
  while (myFile.available()) {
    // read from the file into buffer
    myFile.read(buffer, sizeof(buffer));

    // Prepare samples
    int volume = 1024;
    Audio.prepare(buffer, S, volume);
    // Feed samples to audio
    Audio.write(buffer, S);

    // Every 100 block print a '.'
    count++;
    if (count == 100) {
      Serial.print(".");
      count = 0;
    }
  }
  myFile.close();
  digitalWrite(lightPin,HIGH); // turn on the lights
  //what do you want to happen now? 
}
}

Quick spin at it, because it was so trivial that helping would take longer than just doing this - this is pretty basic stuff. You'll ofc need to replace lightPin and buttonPin with the pins you're using.

You should really consider trying to get at least a minimal understand the C programming language, at least the subset of it that we use in arduino - do some tutorials, read one of the hundreds of books or thousands of online tutorials, etc. This is probably the simplest sketch combining question I've seen here in ages.

All the 'learning code' suggestions are relevant...

I just wanted to point out that perhaps using a DFPlayer Mini for the Audio would only have cost roughly $3.00USD.. and are pretty easy to use!

Pro-Mini = $3.00USD
DFPlayer Mini = $3.00USD

easy and cheap project!

Thanks for all the input. Learning to write the code is definitely something I’m aiming to do, but I think I will have lost my sons interest by the time I’ve learnt to write it for this one. He’ll be crazy about some other animated movie or computer game within a month : )

So I copied and pasted Dr Azzy’s code and uploaded it (with the addition of one close bracket). It would appear that the SD card initialised but nothing happens on pressing the button. No lights, no sound.

From reading the code it would appear that the audio is meant to play with the buttonPin==LOW. If that is the case, that isn’t what i want. I need the audio to play then the lights to come on when buttonPin==HIGH (i.e press the button (door bell) and the sounds played then the lights come on).

I’ll include the code I’ve got for making the audio play and lights come on. They are on separate sketches which i’m struggling to combine.

Here is the code I’ve got to work for making the lights come on:

// constants won’t change. They’re used here to set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin

// variables will change:
int buttonState = 0; // variable for reading the pushbutton status

void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}

void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);

// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == HIGH) {
delay(2000);
// turn LED on:
digitalWrite(ledPin, HIGH);
delay(20000);
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
}
}

And this is what I’ve got making the audio play:

#include <SD.h>
#include <SPI.h>
#include <Audio.h>

void setup() {
// debug output at 9600 baud
Serial.begin(9600);

// setup SD-card
Serial.print(“Initializing SD card…”);
if (!SD.begin(4)) {
Serial.println(" failed!");
while(true);
}
Serial.println(" done.");
// hi-speed SPI transfers

// 44100kHz stereo => 88200 sample rate
// 100 mSec of prebuffering.
Audio.begin(88200, 100);
}

void loop() {
int count = 0;

// open wave file from sdcard
File myFile = SD.open(“test.wav”);
if (!myFile) {
// if the file didn’t open, print an error and stop
Serial.println(“error opening test.wav”);
while (true);
}

const int S = 1024; // Number of samples to read in block
short buffer~~;~~
~~ Serial.print(“Playing”);~~
~~ // until the file is not finished~~
~~ while (myFile.available()) {~~
~~ // read from the file into buffer~~
~~ myFile.read(buffer, sizeof(buffer));~~
~~ // Prepare samples~~
~~ int volume = 1024;~~
~~ Audio.prepare(buffer, S, volume);~~
~~ // Feed samples to audio~~
~~ Audio.write(buffer, S);~~
~~ // Every 100 block print a ‘.’~~
~~ count++;~~
~~ if (count == 100) {~~
~~ Serial.print(".");~~
~~ count = 0;~~
~~ }~~
~~ }~~
~~ myFile.close();~~
~~ Serial.println(“End of file. Thank you for listening!”);~~
~~ while (true) ;~~
}

please use code tags...

and remove anything that doesnt belong.. (also double check that any comments..... 'make sense')..

Sorry. It all seems to make sense to me, but i’ll try and simplify the comment, and repost the code with tags:

I copied and pasted Dr Azzy’s code and uploaded it. It would appear that the SD card initialised but nothing happens on pressing the button. There were no lights and no sound.

From reading the code it would appear that the audio is meant to play with the buttonPin==LOW. I think this means when the button isn’t pressed. If that is the case, that isn’t what i want. I need the audio to play then the lights to come on when the button is pressed.

I’ll include the code I’ve got for making the audio play and lights come on. They are on separate sketches which i’m struggling to combine.

Here is the code I’ve got that makes the lights come on:

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    delay(2000);
    // turn LED on:
    digitalWrite(ledPin, HIGH);
    delay(20000);
  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

And here is the code that makes the audio play:

#include <SD.h>
#include <SPI.h>
#include <Audio.h>

void setup() {
  // debug output at 9600 baud
  Serial.begin(9600);

  // setup SD-card
  Serial.print("Initializing SD card...");
  if (!SD.begin(4)) {
    Serial.println(" failed!");
    while(true);
  }
  Serial.println(" done.");
  // hi-speed SPI transfers

  // 44100kHz stereo => 88200 sample rate
  // 100 mSec of prebuffering.
  Audio.begin(88200, 100);
}

void loop() {
  int count = 0;

  // open wave file from sdcard
  File myFile = SD.open("test.wav");
  if (!myFile) {
    // if the file didn't open, print an error and stop
    Serial.println("error opening test.wav");
    while (true);
  }

  const int S = 1024; // Number of samples to read in block
  short buffer[S];

  Serial.print("Playing");
  // until the file is not finished
  while (myFile.available()) {
    // read from the file into buffer
    myFile.read(buffer, sizeof(buffer));

    // Prepare samples
    int volume = 1024;
    Audio.prepare(buffer, S, volume);
    // Feed samples to audio
    Audio.write(buffer, S);

    // Every 100 block print a '.'
    count++;
    if (count == 100) {
      Serial.print(".");
      count = 0;
    }
  }
  myFile.close();

  Serial.println("End of file. Thank you for listening!");
  while (true) ;
}

bill_face:
From reading the code it would appear that the audio is meant to play with the buttonPin==LOW. I think this means when the button isn’t pressed.

No, look closely at this line of code that DrAzzy gave you, including the comment:

pinMode(buttonPin,INPUT_PULLUP); //buttonPin is the pin that the button is connected to, other site of button to ground.

The pin will read LOW when the button is pressed, because then the button connects the pin to ground. The pin will read HIGH when the button is not pressed, because “INPUT_PULLUP” enables the internal pull-up resistor inside the Arduino.

xl97:
I just wanted to point out that perhaps using a DFPlayer Mini for the Audio would only have cost roughly $3.00USD.. and are pretty easy to use!

Pro-Mini = $3.00USD
DFPlayer Mini = $3.00USD

I would second that suggestion but go further. With the DFPlayer mini, you would not need an Arduino at all!

You can simply connect your button from ground to the ADKEY1 pin on the DFPlayer and it will play track 1 from the sd card.

If you want to add more sounds with more buttons, you can connect 3 more buttons from ground to ADKEY1 with resistor values 3K, 6K2 and 9K1 to play tracks 2, 3 & 4. Tracks 5 to 15 can be played by connecting buttons & resistors to ADKEY2. See this link.
The player has a built-in amplifier that can directly drive small speakers up to 3W.

PaulRB:
No, look closely at this line of code that DrAzzy gave you, including the comment:

pinMode(buttonPin,INPUT_PULLUP); //buttonPin is the pin that the button is connected to, other site of button to ground.

The pin will read LOW when the button is pressed, because then the button connects the pin to ground. The pin will read HIGH when the button is not pressed, because "INPUT_PULLUP" enables the internal pull-up resistor inside the Arduino.

OK. That is somewhat opposite to how the code works in the Button code I have been using to get the lights to come on, which may explain why it doesn't work. More research needed...

I'll also try that DP Player mini, because then i think i may be able to wire that in with the Button LED code i already have working.

I was forgetting about your lights. The DFPlayer can't do that for you, so you will need an Arduino.

But with the DFPlayer, you would only need the most basic of Arduino. You could even use an ATtiny!

Here’s a non-improved version of your code spliced together.

#include <SD.h>
#include <SPI.h>
#include <Audio.h>

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup()
{
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);

  // debug output at 9600 baud
  Serial.begin(9600);

  // setup SD-card
  Serial.print("Initializing SD card...");
  if (!SD.begin(4)) 
  {
    Serial.println(" failed!");
    while (true);
  }
  Serial.println(" done.");
  // hi-speed SPI transfers

  // 44100kHz stereo => 88200 sample rate
  // 100 mSec of prebuffering.
  Audio.begin(88200, 100);
}

void loop()
{
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) 
  {
    delay(2000);
    PlayAudio();
    // turn LED on:
    digitalWrite(ledPin, HIGH);
    delay(20000);
  } else 
  {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}


void PlayAudio()
{
  int count = 0;

  // open wave file from sdcard
  File myFile = SD.open("test.wav");
  if (!myFile) {
    // if the file didn't open, print an error and stop
    Serial.println("error opening test.wav");
    while (true);
  }

  const int S = 1024; // Number of samples to read in block
  short buffer[S];

  Serial.print("Playing");
  // until the file is not finished
  while (myFile.available()) {
    // read from the file into buffer
    myFile.read(buffer, sizeof(buffer));

    // Prepare samples
    int volume = 1024;
    Audio.prepare(buffer, S, volume);
    // Feed samples to audio
    Audio.write(buffer, S);

    // Every 100 block print a '.'
    count++;
    if (count == 100) {
      Serial.print(".");
      count = 0;
    }
  }
  myFile.close();

  Serial.println("End of file. Thank you for listening!");
}

Not tested, not even compiled as I don’t have audio.h.

BOOM!!!

Wildbill you are like a coding Superman to the rescue.

The only problem I have no is on repeated presses of the button (when the cycle has completed) the audio goes glitchy...So to hear the sample properly the code needs to be re-uploaded for each button press. I think that is hardware related though...

I rather suspect that it will work again after you reset it by yanking the power - no need to reload the sketch every time.

The audio library you’re using is old and yet still marked experimental. It also throws a bunch of warnings if I turn warnings up to the max. Finally, I wonder why the example itself only plays the wav file once.

Here’s a tweaked version - it calls arduino.begin and end every time you play a file in the vain hope that it will reset everything without resorting to cycling the power.

#include <SD.h>
#include <SPI.h>
#include <Audio.h>

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup()
{
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);

  // debug output at 9600 baud
  Serial.begin(9600);

  // setup SD-card
  Serial.print("Initializing SD card...");
  if (!SD.begin(4)) 
  {
    Serial.println(" failed!");
    while (true);
  }
  Serial.println(" done.");
  // hi-speed SPI transfers

}

void loop()
{
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) 
  {
    delay(2000);
    PlayAudio();
    // turn LED on:
    digitalWrite(ledPin, HIGH);
    delay(20000);
  } else 
  {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}


void PlayAudio()
{
  int count = 0;

  // 44100kHz stereo => 88200 sample rate
  // 100 mSec of prebuffering.
  Audio.begin(88200, 100);
  // open wave file from sdcard
  File myFile = SD.open("test.wav");
  if (!myFile) 
  {
    // if the file didn't open, print an error and stop
    Serial.println("error opening test.wav");
    while (true);
  }

  const int S = 1024; // Number of samples to read in block
  short buffer[S];

  Serial.print("Playing");
  // until the file is not finished
  while (myFile.available()) 
  {
    // read from the file into buffer
    myFile.read(buffer, sizeof(buffer));

    // Prepare samples
    int volume = 1024;
    Audio.prepare(buffer, S, volume);
    // Feed samples to audio
    Audio.write(buffer, S);

    // Every 100 block print a '.'
    count++;
    if (count == 100) 
    {
      Serial.print(".");
      count = 0;
    }
  }
  myFile.close();

  Serial.println("End of file. Thank you for listening!");
  Audio.end();
}

Compiled, this time; still no testing though.

Hello again.

After a long convalescence, I'm having another crack at this project. The last code from Wild Bill didn't work (can't remember why), so I sort of gave up for a bit, but then decided I'd have another go and got a DF Player Mini.

I have got the DF Player to work, you connect one of its legs to ground and it plays the sample, which I have successfully wired up with a button. However I'm trying to get it to work with some LEDs lighting simultaneously with the sample when the button is pressed, and I can't figure it out.

The button circuit I have seems to work by connecting 5V into the the arduino which it reads as HIGH, which is the opposite to the DF Player.

I gather from one of the early code suggestions above that this could be done instead with a PIN PULLUP, which may work in the same way as the DF Player.

If anyone could help me out I'd be most appreciative.

Cheers

Arduino can trigger the DFplayer in the way I think you are suggesting, by using an output pin to simulate a button connected directly to the player. This works and is simple, but it does require an Arduino pin for each sound to be played.

The more usual way to connect the Arduino to the DFplayer is with a serial line. This way, only one Arduino pin is needed and can be used to send a code/command to play any one of 100 sounds, maybe more.

As the only hardware serial pin is used for program upload and serial monitor on many Arduino, a software serial library is needed to allow another pin to send serial data.

I hope this helps, because it was not completely clear from your last post what you need help with.

This is exactly the way the DFPlayer (mini's) work.

Also.. be careful about 'clones' using fake YX5200 chips..

they do not support all the functions in the stock/default DFRobot library.

I -do- suggest using a library.. unless you want to handle straight serial/hex communication with checksums..etc..

Finally cracked it!

Using this code

void setup() {
  //start serial connection
  Serial.begin(9600);
  //configure pin 2 as an input and enable the internal pull-up resistor
  pinMode(2, INPUT_PULLUP);
  pinMode(13, OUTPUT);

}

void loop() {
  //read the pushbutton value into a variable
  int sensorVal = digitalRead(2);
  //print out the value of the pushbutton
  Serial.println(sensorVal);

  // Keep in mind the pull-up means the pushbutton's logic is inverted. It goes
  // HIGH when it's open, and LOW when it's pressed. Turn on pin 13 when the
  // button's pressed, and off when it's not:
  if (sensorVal == HIGH) {
    digitalWrite(13, LOW);
  } else {
    delay(5 000);
    digitalWrite(13, HIGH);
    delay(10000);
  }
}

and just a simple switch connecting pin2 on the arduino and the ADKEY_1 on the DF MINI PLAYER to ground. Just like here:https://www.arduino.cc/en/Tutorial/InputPullupSerial

Here is a video : )