├── drumkit.zip ├── .gitattributes ├── .gitignore ├── README.md └── AirDrum.py /drumkit.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davejavu1969/RPiAirDrum/HEAD/drumkit.zip -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RPiAirDrum 2 | Raspberry Pi Air Drum Kit 3 | 4 | Nice easy project that's a lot of fun too. 5 | 6 | You'll need to install the following if these libraries are not already installed on your Pi... 7 | 8 | Bluetooth... 9 | 10 | sudo apt-get install --no-install-recommends bluetooth 11 | 12 | Cwiid... With thanks to Donnie Smith for the original and very awesome library! 13 | 14 | sudo apt-get install python-cwiid 15 | 16 | You'll need to know the MAC addresses of both controllers. 17 | 18 | Enter the following at the command prompt... 19 | 20 | hcitool scan 21 | 22 | Then press buttons 1 + 2 on both controllers, their MAC addresses will then be displayed. 23 | You need to enter these into the AirDrum.py script where it says to do so. 24 | 25 | You'll need to unzip the 'drumkit' folder to the same location as the .py file. The code currently has these both just on the pi user Desktop. 26 | 27 | I've kept the code very simple so you can play around with it. You can also get literally thousands of drum samples online 28 | 29 | Try getting some different ones and see what you can make it sound like! 30 | 31 | Enjoy :-) 32 | -------------------------------------------------------------------------------- /AirDrum.py: -------------------------------------------------------------------------------- 1 | import cwiid 2 | import time 3 | import os 4 | 5 | 6 | wm = None 7 | wm2 = None 8 | 9 | i=1 10 | 11 | while not wm: 12 | for x in range(0,6): 13 | try: 14 | time.sleep(0.5) 15 | print "Bluetooth pairing attempt " + str(i) 16 | wm = cwiid.Wiimote("Insert WiiMote MAC address here") 17 | wm.led = 1 18 | if wm: 19 | break 20 | 21 | 22 | except RuntimeError: 23 | if (i>=5): 24 | print("cannot create connection") 25 | quit() 26 | print "Error opening wiimote connection" 27 | i +=1 28 | 29 | print "Remote #1 Connected" 30 | 31 | time.sleep(1) 32 | 33 | i=1 34 | 35 | while not wm2: 36 | for x in range(0,5): 37 | try: 38 | time.sleep(0.5) 39 | print "Bluetooth pairing attempt " + str(i) 40 | wm2 = cwiid.Wiimote("Insert WiiMote MAC address here") 41 | wm2.led = 2 42 | if wm2: 43 | break 44 | 45 | except RuntimeError: 46 | if (i>=5): 47 | print("cannot create connection") 48 | quit() 49 | print "Error opening wiimote connection" 50 | i +=1 51 | 52 | print "Remote #2 Connected" 53 | 54 | time.sleep(1) 55 | 56 | 57 | #set wiimote to report button presses and accelerometer state 58 | wm.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC 59 | 60 | wm2.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC 61 | 62 | 63 | buttons = wm.state['buttons'] 64 | buttons2 = wm2.state['buttons'] 65 | acc = wm.state 66 | acc2 = wm2.state 67 | 68 | tom_hit = False 69 | tom_hit2 = False 70 | 71 | snare_hit = False 72 | bongo_hit = False 73 | 74 | cym1_hit = False 75 | cym1_hit2 = False 76 | 77 | while not(buttons == 140 or buttons2 == 140): 78 | buttons = wm.state['buttons'] 79 | buttons2 = wm2.state['buttons'] 80 | acc = wm.state 81 | acc2 = wm2.state 82 | pos1 = acc['acc'] 83 | pos2 = acc2['acc'] 84 | but1 = acc['buttons'] 85 | but2 = acc2['buttons'] 86 | 87 | if (buttons == 13): # Halt 88 | wm.led = 2 89 | print ("Halting Raspberry Pi...") 90 | bashCommand = ("sudo halt") 91 | 92 | ## Controller #1 ## 93 | if but1 == 0 and pos1[0] >= 120 and pos1[2] <= 105 and not tom_hit: 94 | print "Tom1" 95 | print pos1 96 | os.system('aplay /home/pi/Desktop/drumkit/Tom01.wav &' ) 97 | tom_hit = True 98 | 99 | if but1 == 4 and pos1[0] >= 120 and pos1[2] <= 105 and not bongo_hit: 100 | print "Bongo" 101 | print pos1 102 | os.system('aplay /home/pi/Desktop/drumkit/kit1103.wav &' ) 103 | bongo_hit = True 104 | 105 | if pos1[0] <= 30 and pos1[1] >= 141 and not cym1_hit: 106 | print "Cymbal" 107 | print pos1 108 | os.system('aplay /home/pi/Desktop/drumkit/CYMBL1.wav &' ) 109 | cyml_hit = True 110 | 111 | if pos1[2] >= 110 and tom_hit: 112 | tom_hit = False 113 | if pos1[2] >= 110 and bongo_hit: 114 | bongo_hit = False 115 | if pos1[0] > 50 and cym1_hit: 116 | cym1_hit = False 117 | 118 | 119 | 120 | ## Controller #2 ## 121 | 122 | if but2 == 4 and pos2[0] >= 120 and pos2[2] <= 105 and not tom_hit2: 123 | print "Tom2" 124 | print pos2 125 | os.system('aplay /home/pi/Desktop/drumkit/kit252.wav &' ) 126 | tom_hit2 = True 127 | 128 | if but2 == 0 and pos2[0] >= 120 and pos2[2] <= 105 and not snare_hit: 129 | print "Snare1" 130 | print pos2 131 | os.system('aplay /home/pi/Desktop/drumkit/Snare09.wav &' ) 132 | snare_hit = True 133 | 134 | 135 | if pos2[0] >= 190 and not cym1_hit2: 136 | print "Cymbal2" 137 | print pos2 138 | os.system('aplay /home/pi/Desktop/drumkit/Ride2.wav &' ) 139 | cyml_hit2 = True 140 | 141 | if pos2[2] >= 110 and tom_hit2: 142 | tom_hit2 = False 143 | if pos2[2] >= 110 and snare_hit: 144 | snare_hit = False 145 | if pos2[0] > 50 and cym1_hit2: 146 | cym1_hit2 = False 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | --------------------------------------------------------------------------------