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 } }