Introduction: FamilyMart Doorbell

FamilyMart is one of the most largest convenience store chain in Asia. They use a characteristic door chime that is a Japanese melody called Melody Chime No.1 – Daiseikyou (メロディーチャイム第1番・大盛況; Daiseikyou translates to “great success/prosperity”), that is pretty iconic in Shanghai.

In IMA - NYU Shanghai we wanted to recreate this doorbell in the entrance of our Fab Lab, because we thought it would be a great opportunity to use some equipment available for the students, at the same time create some documentation that the students can use in future projects, and have some fun :)

For this project we are using a Grove - Serial MP3 Player, a Grove - PIR Motion Sensor, an Arduino UNO Genuino and a speaker. To have the arduino plugged we are using a 12V power source, and to arrange the electronics to the wall we are using some small pieces of velcro with adhesive tape.

Step 1: Programming and Connecting Each Sensor With Arduino

We are using the PIR Motion Sensor to detect any movement produced by someone who cross the door, according to a boolean function "isPeopleDetected()".



The sensor is connected to the Arduino according to this:

YELLOW wire connected to DIGITAL PIN 8 in Arduino
WHITE wire not connected
RED wire connected to 5V in Arduino
BLACK wire connected to GROUND in Arduino

the arduino code for detecting movement with the PIR Motion Sensor is:

/*macro definitions of PIR motion sensor pin and LED pin*/
#define PIR_MOTION_SENSOR 8 //Use pin 2 to receive the signal from the module 
#define LED 13 // you can see this LED in the Arduino board 
void setup() {
  pinsInit();
}


void loop() {
  if (isPeopleDetected()) //if it detects the moving people?
    turnOnLED();
  else
    turnOffLED();
}


void pinsInit() {
  pinMode(PIR_MOTION_SENSOR, INPUT);
  pinMode(LED, OUTPUT);
}


void turnOnLED() {
  digitalWrite(LED, HIGH);
}


void turnOffLED() {
  digitalWrite(LED, LOW);
}


/********/
/*Function: Detect whether anyone moves in it's detecting range*/
/*Return:-boolean, true is someone detected.*/


boolean isPeopleDetected() {
  int sensorValue = digitalRead(PIR_MOTION_SENSOR);
  if (sensorValue == HIGH) { //if the sensor value is HIGH?
    return true; //yes, return true
  } else {
    return false; //no, return false
  }
}





We wanted to play different versions of the FamilyMart song randomly, so we modified the basic code of the MP3 player, adding a random variable called "num", that is a random number according to the number or songs we storage in the micro SD card that the MP3 player has.

The MP3 Player is connected to the Arduino according to this:

YELLOW wire connected to DIGITAL PIN 2 in Arduino
WHITE wire connected to DIGITAL PIN 3 in Arduino
RED wire connected to 5V in Arduino
BLACK wire connected to GROUND in Arduino

The code for the MP3 Player is:

#include <SoftwareSerial.h>=
SoftwareSerial mp3(2, 3);//modify this with the connector you are using.
void setup() {
  mp3.begin(9600);
  Serial.begin(9600);
  delay(100);
  if (true == SetPlayMode(0x03))
    Serial.println("Set The Play Mode to 0x01, Single Loop Mode.");
  else
    Serial.println("Playmode Set Error");
  PauseOnOffCurrentMusic();
  randomSeed(analogRead(0));
}
void loop() {
  SetVolume(0x1F);
  SetPlayMode(0x01);
  delay(1000);
  int num = random(1, 4);
  Serial.print(num);
  SetMusicPlay(00, (uint8_t) num); // uint8_t will convert num into a hexadecimal value
  //PauseOnOffCurrentMusic();
  delay(1000);
  while (1);
}


//Set the music index to play, the index is decided by the input sequence
//of the music;
//hbyte: the high byte of the index
//lbyte: the low byte of the index;


boolean SetMusicPlay(uint8_t hbyte, uint8_t lbyte)
{
  mp3.write(0x7E);
  mp3.write(0x04);
  mp3.write(0xA0);
  mp3.write(hbyte);
  mp3.write(lbyte);
  mp3.write(0x7E);
  delay(10);
  while (mp3.available()) {
    if (0xA0 == mp3.read())
      return true;
    else
      return false;
  }
}


// Pause on/off the current music
boolean PauseOnOffCurrentMusic(void)
{
  mp3.write(0x7E);
  mp3.write(0x02);
  mp3.write(0xA3);
  mp3.write(0x7E);
  delay(10);
  while (mp3.available()) {
    if (0xA3 == mp3.read())
      return true;
    else
      return false;
  }
}


//Set the volume, the range is 0x00 to 0x1F
boolean SetVolume(uint8_t volume) {
  mp3.write(0x7E);
  mp3.write(0x03);
  mp3.write(0xA7);
  mp3.write(volume);
  mp3.write(0x7E);
  delay(10);
  while (mp3.available()) {
    if (0xA7 == mp3.read())
      return true;
    else
      return false;
  }
}


boolean SetPlayMode(uint8_t playmode) {
  if (((playmode == 0x00) | (playmode == 0x01) | (playmode == 0x02) | (playmode == 0x03)) == false) {
    Serial.println("PlayMode Parameter Error! ");
    return false;
  }
  mp3.write(0x7E);
  mp3.write(0x03);
  mp3.write(0xA9);
  mp3.write(playmode);
  mp3.write(0x7E);
  delay(10);


  while (mp3.available()) {
    if (0xA9 == mp3.read())
      return true;
    else
      return false;
  }
}


This MP3 Player uses Hexadecimal numbers, so you will need to use something like this web to convert integer values in order to control the board.

For example, the reference says:

There are 32 volume levels from 00 to 31. 00 is mute, and 31 for the maximum volume.

in order to set the volume to the maximum value: 31 we convert it to hexadecimal that is 1F

so in the code we write: SetVolume(0x1F);

Step 2: Final Arduino Code and Installing the Hardware

The final code combining both codes to trigger the sound every time the motion sensor detects movements is:


#include <SoftwareSerial.h>
#define PIR_MOTION_SENSOR 8 //Use pin 2 to receive the signal from the module
#define LED 13// this LED will light up when the sensor detects movement
SoftwareSerial mp3(2, 3); // modify this with the connector you are using.
boolean someoneThere = false;
boolean someoneWasThere = false;
void setup() {
  mp3.begin(9600);
  Serial.begin(9600);
  delay(100);
  if (true == SetPlayMode(0x00))
    Serial.println("Set The Play Mode to 0x00, Single Loop Mode.");
  else
    Serial.println("Playmode Set Error");
  PauseOnOffCurrentMusic();
  randomSeed(analogRead(0));
  pinMode(PIR_MOTION_SENSOR, INPUT);
  pinMode(LED, OUTPUT);
  SetVolume(0x1F);
}


void loop() {
  if (isPeopleDetected()) { //if it detects the moving people?
    digitalWrite(LED, HIGH);
    // someone there is now true
    someoneThere = true;
    int num = random(1, 12);
    Serial.println(num);
    SetMusicPlay(00, (uint8_t) num);
    delay(2500); // this delay is for the MP3 file
  } else {
    someoneThere = false;
    someoneWasThere = false;
    // Serial.println("no one");
    digitalWrite(LED, LOW);
    //PauseOnOffCurrentMusic();
  }


  if (someoneThere == true && someoneThere != someoneWasThere) {
    Serial.println("someone is there!");
    someoneWasThere = true;
  }
}


//Set the music index to play, the index is decided by the input sequence
//of the music;
//hbyte: the high byte of the index;
//lbyte: the low byte of the index;


boolean SetMusicPlay(uint8_t hbyte, uint8_t lbyte) {
  mp3.write(0x7E);
  mp3.write(0x04);
  mp3.write(0xA0);
  mp3.write(hbyte);
  mp3.write(lbyte);
  mp3.write(0x7E);
  delay(10);
  while (mp3.available()) {
    if (0xA0 == mp3.read())
      return true;
    else
      return false;
  }
}


// Pause on/off the current music
boolean PauseOnOffCurrentMusic(void) {
  mp3.write(0x7E);
  mp3.write(0x02);
  mp3.write(0xA3);
  mp3.write(0x7E);
  delay(10);
  while (mp3.available()) {
    if (0xA3 == mp3.read())
      return true;
    else
      return false;
  }
}


//Set the volume, the range is 0x00 to 0x1F
boolean SetVolume(uint8_t volume) {
  mp3.write(0x7E);
  mp3.write(0x03);
  mp3.write(0xA7);
  mp3.write(volume);
  mp3.write(0x7E);
  delay(10);
  while (mp3.available()) {
    if (0xA7 == mp3.read())
      return true;
    else
      return false;
  }
}


boolean SetPlayMode(uint8_t playmode) {
  if (((playmode == 0x00) | (playmode == 0x01) | (playmode == 0x02) | (playmode == 0x03)) == false) {
    Serial.println("PlayMode Parameter Error! ");
    return false;
  }
  mp3.write(0x7E);
  mp3.write(0x03);
  mp3.write(0xA9);
  mp3.write(playmode);
  mp3.write(0x7E);
  delay(10);
  while (mp3.available()) {
    if (0xA9 == mp3.read())
      return true;
    else
      return false;
  }
}


/***************************************************************


  Function: Detect whether anyone moves in it's detecting range
  Return:-boolean, true is someone detected.*/
boolean isPeopleDetected() {
  int sensorValue = digitalRead(PIR_MOTION_SENSOR);
  if (sensorValue == HIGH) { //if the sensor value is HIGH?
    return true;//yes,return true
  } else {
    return false;//no,return false
  }
}