Introduction: Child Piano Toy
Hello.
Ones my daughter come to me and say: "daddy my piano not working"
It was cheep "china piano". The problem was really simple - just replace battery and clue Brocken casing.
But daddy want not repair but upgrade this "ugly" device
What Wrong was with old toy?
1. Cheap plastic that can hart child’s hand
2. Awful sound
3. Buttons was not equal as note
4. Etc, etc, etc
I disassembled this "toy" and what I saw
1. Keys
1.1 Keys was grouped by 10
1.2 keys was randomly connected between. In group of 10 key 4 keys was connected? This means that 1 key was connected to 2 key, 3 key to 4 key..... In real it was 6 keys in group when you press DO_key1 RE_key2 MI-key3 FA_key4 FA_key5 SOL_key6 SOL_key7 LA_key8 SI_key9 SI_key10. When I looked on PCB - I can’t understand any logic of this wired method. It was really randomly generated by MAD-brain
1.3 Advanced buttons was really interesting
1.3.1 SOUND UP
1.3.2 SOUND DOWN
1.3.3 UNCNOWN_melody /Next melody
1.3.4 RHYTHM (piano play drum rhythm, but when you press any button on piano rhythm stopped)
1.3.5 CHANGE instrument
1.3.6 =1.3.3
1.3.7 =1.3.4
1.3.8 = brainstorm of unknown melody
After experiments I decide to build for my daughter sounds-like real piano. It was weekend project.
In beginning I decide use maximum parts from "china" piano + add arduino (3$) and DFPLAYER (which was ordered and delivered in an hour). In next steps you'll se full life of project
Totally all parts for project costs me 45$ at the end. All parts I bought in local store. If you'll use eBay it will be really cheaper
What we need:
38+8 pushbuttons
1 arduino uno/nano/mega/etc
DFPLAYER mini mp3 module http://www.picaxe.com/docs/spe033.pdf
In next steps i'll show how i decode "china toy keyboard" and how price grow from 10$ to 45 $
Step 1: Datasheet of Project and Explanation How Keyboard Work
On this step I’ll try to explain how this keyboard works.
When I bought arduino – I was surprised that inside toy there were no any resistors on pushbutton lines. As it was weekend project I have no resistors at home…
After 2 hours of experiments I discovered next algorithm:
10 lines from any group of buttons are connected to MCU input (Check datasheet below. In that datasheet I use same connection like in chine keyboard) 1 line connected to from MCU output to button-group this mean that 4 groups of button connected to the same input pins on MCU and has different PWM MCU output lines From MCU to each group connected 1 line
How it work (check arduino datasheet below)
I using PWM send sequence to group in loop. It works like https://www.arduino.cc/en/Tutorial/Button but without using resistors
Arduino CODE
This is curently worked datasheet
Description
1. Top left: Connection from arduino to DFPLAYER using Hardware Serial. As DFPLAYER Serial work on 3.3 v logic is needed to add 1KOhm resistors on line. I have 500ohm resistors, and it work fine.
I discovered that DF player can be connected directly to PC USB like a flash drive. In that mode player will ignore any commands from Arduino
2. Top center buttons group: it used as advanced func buttons
3. Right group of buttons - keys
Upd 29.06.2016 Thanks for RaedT
Buttons from old PC keyboard and conductive inc
https://www.youtube.com/watch?v=W_ouYLeIkoo
Turn fire into conductive ink and paint, then build electronic circuits, paper musical instruments and inputs for your Arduino boards!
Step 2: First Keyboard. Fails and Solutions
On the beginning I try to use all parts from “china” piano. What wrong was you can check on photos?
Problem: In 10-button group in fact was 6 buttons. Else 4 buttons was spited
Solution: cut spited road and connect directly to right wire
Problem: in some place you couldn’t connect in any reason
No solution.
When I spend all night with experiments I decide exchange buttons.
I cut all roads on PCB Drill holes using solder iron and nail….
Installed new buttons
Solder new wires
Algorithm that was used in “china” keyboard I use for new keyboard
1. Using PWM generate ~5V on PWM_1.
2. Read state of pin_1 to pin_10. If button will be pressed you’ll get pin change event
3. Using PWM generate ~5V on PWM_2.
4. …
Step 3: Second Keyboard. Recycling Junk to the Toy
I use 2 plastic plates as PCB.
Missed buttons unsolder from JUNK
Step 4: Casing Assembly
Laser cutted and glued
Step 5: Electronics Installing
In Keyboard rev_1 i make mistake in buttons position. Check photos number 4 and 5
Step 6: DFPLAYER
DFPLayer
Mini
DFPLayer Mini module is a serial MP3 module provides the perfect integrated MP3, WMV, WAV hardware decoding. While the software supports TF card driver, supports FAT16, FAT32 file system. Through simple serial commands to specify music playing, as well as how to play music and other functions, without the cumbersome underlying operating, easy to use, stable and reliable are the most important features of this module
http://www.dfrobot.com/wiki/index.php/DFPlayer_Min...
I added PDF with bigger DATASHEET than on original page.
What problem with this module I’ve got:
1. On datasheet logic described only for standard function like play file from root folder.
2. When you’ll want to play file from folder – this is real problem.
This simple code will play file from folder. Note that I changed original library, and check for included sketch
3. If you’ll need to start playback of another file – just send MP3_PLAY command. Stop command not needed
4. Loop command/loop folder command/random command work only for root directory
5. Commands for working with folders are not listed in datasheet. You’ll need test this commands by hands….
Thanks Ype Brada for useful command decoding http://forum.banggood.com/forum-topic-59997.html
/*
DF Player mini command discovery
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Program is mend to discover all the possibilities of the command
structure of the DFPlayer mini. No special libraries are needed.
Program is very easy to understand and can be the basis for your own mp3 player sketch.
Note: Commands are not always correct described in the manual. I tried to fix it, but
there is still a something to do. The commands recoverd so far are listed below.
Use of sketch: Enter three (separated) decimal numbers in the Serial Monitor with no end of line character.
First number : Command
Second number: First (High Byte) parameter
Third number : Second (Low Byte) parameter
E.g.: 3,0,1 will play the first track on the TF card
Very important: Use serial 1K resistors or a level shifter between module RX and TX
and Arduino to suppress noise
Connect Sound module board RX to Arduino pin 11 (via 1K resistor)
Connect Sound module board TX to Arduino pin 10 (via 1K resistor)
Connect Sound module board Vcc to Arduino Vin when powered via USB (preferably 3.0)
else use seperate 5V power supply
Connect Sound module board GND to Arduino GND
General DF Player mini command structure (only byte 3, 5 and 6 to be entered in the serial monitor):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Byte Function Value
==== ================ ====
(0) Start Byte 0x7E
(1) Version Info 0xFF (don't know why it's called Version Info)
(2) Number of bytes 0x06 (Always 6 bytes)
(3) Command 0x__
(4) Command feedback 0x__ If enabled returns info with command 0x41 [0x01: info, 0x00: no info]
(5) Parameter 1 [DH] 0x__
(6) Parameter 2 [DL] 0x__
(7) Checksum high 0x__ See explanation below. Is calculated in function: execute_CMD
(8) Checksum low 0x__ See explanation below. Is calculated in function: execute_CMD
(9) End command 0xEF
Checksum calculation.
~~~~~~~~~~~~~~~~~~~~
Checksum = -Sum(byte(1..6)) (2 bytes, notice minus sign!)
Commands without returned parameters (*=Confirmed command ?=Unknown, not clear or not validated)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CMD CMD
HEX Dec Function Description Parameters(2 x 8 bit)
==== === =================================== ========================================================================
0x01 1 Next * [DH]=X, [DL]=X Next file in current folder.Loops when last file played
0x02 2 Previous * [DH]=X, [DL]=X Previous file in current folder.Loops when last file played
0x03 3 Specify track(NUM) * [DH]=highByte(NUM), [DL]=lowByte(NUM)
1~2999 Playing order is order in which the numbers are stored.
Filename and foldername are arbitrary, but when named starting with
an increasing number and in one folder, files are played in
that order and with correct track number.
e.g. 0001-Joe Jackson.mp3...0348-Lets dance.mp3)
0x04 4 Increase volume * [DH]=X, [DL]=X Increase volume by 1
0x05 5 Decrease volume * [DH]=X, [DL]=X Decrease volume by 1
0x06 6 Specify volume * [DH]=X, [DL]= Volume (0-0x30) Default=0x30
0x07 7 Specify Equalizer * [DH]=X, [DL]= EQ(0/1/2/3/4/5) [Normal/Pop/Rock/Jazz/Classic/Base]
0x08 8 Specify repeat(NUM) * [DH]=highByte(NUM), [DL]=lowByte(NUM).Repeat the specified track number
0x09 9 Specify playback source (Datasheet) ? [DH]=X, [DL]= (0/1/2/3/4)Unknown. Seems to be overrided by automatic detection
(Datasheet: U/TF/AUX/SLEEP/FLASH)
0x0A 10 Enter into standby – low power loss * [DH]=X, [DL]=X Works, but no command found yet to end standby
(insert TF-card again will end standby mode)
0x0B 11 Normal working (Datasheet) ? Unknown. No error code, but no function found
0x0C 12 Reset module * [DH]=X, [DL]=X Resets all (Track = 0x01, Volume = 0x30)
Will return 0x3F initialization parameter (0x02 for TF-card)
"Clap" sound after excecuting command (no solution found)
0x0D 13 Play * [DH]=X, [DL]=X Play current selected track
0x0E 14 Pause * [DH]=X, [DL]=X Pause track
0x0F 15 Specify folder and file to playback * [DH]=Folder, [DL]=File
Important: Folders must be named 01~99, files must be named 001~255
0x10 16 Volume adjust set (Datasheet) ? Unknown. No error code. Does not change the volume gain.
0x11 17 Loop play * [DH]=X, [DL]=(0x01:play, 0x00:stop play)
Loop play all the tracks. Start at track 1.
0x12 18 Play mp3 file [NUM] in mp3 folder * [DH]=highByte(NUM), [DL]=lowByte(NUM)
Play mp3 file in folder named mp3 in your TF-card. File format exact
4-digit number (0001~2999) e.g. 0235.mp3
0x13 19 Unknown ? Unknown: Returns error code 0x07
0x14 20 Unknown ? Unknown: Returns error code 0x06
0x15 21 Unknown ? Unknown: Returns no error code, but no function found
0x16 22 Stop * [DH]=X, [DL]=X, Stop playing current track
0x17 23 Loop Folder 01 * [DH]=x, [DL]=1~255, Loops all tracks in folder named "01"
0x18 24 Random play * [DH]=X, [DL]=X Random all tracks, always starts at track 1
0x19 25 Single loop * [DH]=0, [DL]=0 Loops the track that is playing
0x1A 26 Pause * [DH]=X, [DL]=(0x01:pause, 0x00:stop pause)
Commands with returned parameters (*=Confirmed command ?=Unknown, not clear or not validated)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CMD CMD
HEX Dec Function Description Parameters(2 x 8 bit)
==== === =================================== ===========================================================================
0x3A 58 Medium inserted * [DH]=0, [DL]=(1:U-disk, 2:TF-card)
0x3B 59 Medium ejected * [DH]=0, [DL]=(1:U-disk, 2:TF-card)
0x3C 60 Finished track on U-disk * [DH]=highByte(NUM), [DL]=lowByte(NUM)
Not validated. Returns track number when song is finished on U-Disk
0x3D 61 Finished track on TF-card * [DH]=highByte(NUM), [DL]=lowByte(NUM)
Returns track number when song is finished on TF
0x3E 62 Finished track on Flash * [DH]=highByte(NUM), [DL]=lowByte(NUM)
Not validated. Returns track number when song is finished on Flash
0x3F 63 Initialization parameters * [DH]=0, [DL]= 0 ~ 0x0F. Returned code when Reset (0x12) is used.
(each bit represent one device of the low-four bits)
See Datasheet. 0x02 is TF-card. Error 0x01 when no medium is inserted.
0x40 64 Error ? [DH]=0, [DL]= 0~7 Error code(Returned codes not yet analyzed)
0x41 65 Reply ? [DH]=0, [DL]= 0~? Return code when command feedback is high
0x00 no Error (Other returned code not known)
0x42 66 The current status * [DH] = Device number [DL] = 0 no play, 1 play
0x43 67 The current volume * [DH]=0, [DL]= Volume (0-30)
0x44 68 The current EQ * [DH]=0, [DL]= EQ(0/1/2/3/4/5) [Normal/Pop/Rock/Jazz/Classic/Base]
0x45 69 The current playback mode * [DH]=0, [DL]= (0x00: no CMD 0x08 used, 0x02: CMD 0x08 used, not usefull)
0x46 70 The current software version * [DH]=0, [DL]= Software version. (My version is 5)
0x47 71 The total number of U-disk files * [DH]=highByte(NUM), [DL]=lowByte(NUM). Not validated
0x48 72 The total number of TF-card files * [DH]=highByte(NUM), [DL]=lowByte(NUM)
0x49 73 The total number of flash files * [DH]=highByte(NUM), [DL]=lowByte(NUM). Not validated
0x4A 74 Keep on (Datasheet) ? Unknown. No returned parameter
0x4B 75 The current track of U-Disk * [DH]=highByte(NUM), [DL]=lowByte(NUM), Current track on all media
0x4C 76 The current track of TF card * [DH]=highByte(NUM), [DL]=lowByte(NUM), Current track on all media
0x4D 77 The current track of Flash * [DH]=highByte(NUM), [DL]=lowByte(NUM), Current track on all media
0x4E 78 Folder "01" [DH]=x, [DL]=1 * [DH]=0, [DL]=(NUM) Change to first track in folder "01"
Returns number of files in folder "01"
0x4F 79 The total number of folders * [DH]=0, [DL]=(NUM), Total number of folders, including root directory
Additional info can be found on DFRobot site, but is not very reliable
Additional info:http://www.dfrobot.com/index.php?route=product/product&product_id=1121
Ype Brada 2015-04-06
*/
Check photo for file-tree
In standart library i add 2 new functions
void mp3_send_cmd (uint8_t cmd, uint16_t arg);
void mp3_send_cmd (uint8_t cmd, uint16_t arg, uint16_t arg2);
void mp3_send_cmd (uint8_t cmd, uint16_t arg) {
send_buf[3] = cmd;
fill_uint16_bigend ((send_buf+5), arg);
mp3_fill_checksum ();
send_func (); }
void mp3_send_cmd (uint8_t cmd, uint16_t arg,uint16_t arg2) {
send_buf[3] = cmd;
send_buf[5]=arg;
send_buf[6]=arg2;
mp3_fill_checksum (); send_func ();
}
Check next step for arduino project
Attachments
Step 7: Drawings for Casing Cutting
Drawings for CorelDraw
Drawings for Autocad Inventor 2015
Attachments
Step 8: Arduino Scetch, Library, and Files
Attached
1. Dfplayer upgraded library
2. Arduino sketch
3. Sdcard file tree sample
Step 9: What Else Can Be Improved
What you can improve in this project
1. All buttons can be connected to one analog pin. In this case you’ll get A1-A5 and D2-D13 pins free
2. If you want create Polysound piano with real sound combination you’ll need 2+ dfplayer modules
2.1 if button_1 pressed than dfplayer_1 play sound
2.2 if button_2 pressed and dfplayer_1 busy than dfplayer_2 play sound 2
2.3 if button_3 pressed and dfplayer_1 busy than if dfplayer_2 busy than dfplayer_3 play sound3
2.4 …..
2.5 Play sound of free dfplayer
2.6 All mp3 modules can be connected to shift register…. In this case only 3 pin will be used for 2+ mp3 modules. Control shift register via spi, Emulate software serial to work with spi
3. I have an idea that arduino +SD module can do the same as arduino + dfplayer.
4. It can be added sound amplifier….