Introduction: DIY USB DJ Controller
Many people are getting into DJing these days, whether as a means of self-expression or a way to make extra money. I enjoy DJing because it provides a more interesting, involved, and interactive music-listening experience, whether in company of friends or while in private.
Hardware DJ Controllers are traditionally the next step after getting one’s feet wet using a software-based DJ Controller. And they are also traditionally expensive. I’m only a hobbyist DJ and didn’t really want to spend a lot of money on my first DJ Controller. They are out there for around $100 USD, but I am also into DIY! I have a passion for both music and electronics and wanted a way to combine the two, so I decided to build a custom DJ controller with low-cost and rapid construction in mind.
The DJ Controller I will construct in this Instructable will provide you with just one example of what you could build using the code, structure, and process that I show here. If you were to take this idea and expand it and polish it, you could end up with a really nice and/or totally different MIDI device. My favorite aspect of this project is how open it is to modification. The final product is simply something that takes analog and digital inputs and provides a unique and easy method to turn them into MIDI outputs. See the section on what I like to call “quasi-MIDI” later in this introduction. I modeled my controller after the Numark Mixtrack II.
My specific DJ Controller uses an early revision of the TI MSP430 Launchpad, a microcontroller development platform known for its low price ($10) and hobbyist following. The microcontroller code I provide is written using Energia and may transfer to Arduino with little effort, other microcontrollers may need to have the code ported to them specifically, which wouldn’t be too hard. A better microcontroller with more pins would be able to support more inputs, something to keep in mind if you are going to build this project differently. I will include a more extensive list of required materials, skills, and software later on in the Instructable.
What is a DJ Controller?
Funny you should ask. A DJ Controller is a physical device that you can connect to a computer that is equipped with a software based music-mixing program. A music-mixing program allows a DJ to play songs and add effects, “scratch” the track, control audio equalizers, volume, play loops and samples, and most importantly, mix multiple songs together to seamlessly switch from one song to another. This all happens live and is pretty impressive if the DJ is good (See this video, WARNING: Contains explicit language. She is using multiple DJ Controllers in this video to mix four tracks at once), sometimes akin to playing an instrument! The DJ Controller gives the DJ a physical interface to quickly perform all these actions. Using a mouse and keyboard to DJ quickly becomes limiting after some time, if you have used a software-based DJ Controller for some time, you know what I mean.
At the hardware level, entry-level DJ Controllers are very simple devices. They read input from a bunch of sensors (buttons, sliders, knobs, etc) and convert the input into control messages for the DJ software. A popular format for these messages is MIDI, which is pretty much what we will use here.
However, this project is not comparable with high-end professional level DJ Controllers which are a lot more complex and perform other functions (pre-cueing, integrated sound cards, etc). This project also doesn't have jogwheels (I don't know where to get the parts, I don't personally use them, and they would make this project cost a lot more).
Enter this project
This project provides a relatively simple and inexpensive custom interface to accomplish the basic tasks of DJing. It’s fun to build, customizable, extensible, and an entry level DJ controller for hobbyist DJs! Think of how cool it would be to have your own, hand-made DJ controller up on the table at parties, and know that it actually works!
- Low-cost (around $75 total)
- Customizable (especially with a 3D Printer! ;) )
- Extensible and Reconfigurable
- USB Connected (requires no external MIDI cables/converter)
- Cool Laser cut Case!
- Relatively simple and easy to make
- Cross platform on Windows, Mac, and Linux (untested, but more on this later)
- Can be used with many of the most popular professional DJing software programs (more on this later)
- The way I build it, there are more than 80 possible inputs!
How many and what controls does this DJ Controller have?
This controller has quite a few controls on it. Since I'm only using a 20-pin microcontroller, I decided to use two of the same microcontroller and also an additional 8-channel Analog-to-Digital Converter to get the most out of my little MSP430G2553s. My permutation of this controller has:
- 11 Knobs
- 3 Sliders
- 5 Buttons
- A Rotary Encoder w/ integrated button
- A 12-digit keypad that has 3 different modes and can affect either deck (12 X 3 X 2 = 72 different functions!)
- The deck switch also sends commands so that it can select the active deck/PFL
These controls can be programmed to do whatever you want! My configuration is shown later but it's basically:
Knobs - Bass/Mid/Treble/FX 1/FX 2 for each deck, and then a "master something"
Sliders - Crossfader, Deck 1 Volume, and Deck 2 Volume
Buttons - Play/Pause and Sync for each deck, and then a "!" button (whatever you want)
Rotary Encoder/Button - Used to browse music collection and select songs
Keypad - Mode 1 is for loops, Mode 2 is for effects, Mode 3 is for samples
What this Instructable will cover
In this Instructable, I will introduce you to quite a few electronics lessons that will combine to create the end product! A rough list of some things you can learn/practice by building this:
- Methods for rapidly prototyping a project involving a microcontroller and serial communication
- Using Energia, an Integrated Development Environment (IDE) for the TI Launchpad, and uploading code to a microcontroller
- Using Processing, a programming language and IDE that is perfect for quickly setting up serial communications with a project like this
- Connecting and interpreting digital (buttons) and analog (knobs and sliders called potentiometers) input
- Reading a 12-digit Keypad (useful in other projects too!)
- Reading input from a Rotary Encoder
- Raw binary serial communication between a computer and a microcontroller and between two microcontrollers
- Creating a custom low-data communication protocol (heavy use of bitwise math, good practice for digital logic studies!)
- SPI communication between two ICs (namely, a MSP430G2553 and the MCP3008 Analog-to-digital converter)
- Construction of circuits on perfboard
And possibly more!
Please note this project was very difficult to assemble so only attempt it if you are good with a soldering iron or can afford to make a few mistakes!
Overview of Materials Needed
This list will change depending on how you specifically build this project, but it provides a general overview of what you should expect to need. Specific lists of parts for each step will be included with the following steps. Links are provided for reference.
For the electronics:
- Rotary Potentiometers (x11, 10kOhm, linear taper, variable-resistors)
- Knobs for Potentiometers (x11, I got 7 red, 2 blue, and 2 white)
- Slide Potentiometers (I got one x-large and two medium)
- Tops for Slide Potentiometers (x3)
- Push-button switches (x5)
- Switches (1x Two-way, 1x Three-way [sourced from old alarm clock])
- A 12-digit keypad (x1)
- Rotary Encoder (x1)
- TI Launchpad or comparable microcontroller development platform
- MSP430G2553 or comparable microcontroller (two of them, you can get them from TI as free samples! Make sure to order the package type called “PDIP” or else it won’t fit in your Launchpad!)
- MCP3008 (x1), a 10-bit, 8-channel Analog to Digital Converter
- Lots of 22ga Hookup wire (solid core, do not get stranded!)
- A couple protoboards to cut up and use
- Some female/male headers (the duct tape of electronics, pick up a lot on ebay!)
- A few resistors (you won't need 500)
- You may want to put LEDs in the finished project to make it look super cool, try these (video)
For the case:
You will need access to a laser cutter to use my design. For the top and bottom panels we used 1/8" plywood, and for the side panels and inlays we used 1/8" plexiglass. This should be able to be sourced at the laser cut shop. You will also need superglue (I recommend both gel control and liquid Loctite). You may want to try plexiglass glue so it comes out clear, but I found it wasn't strong enough.
And that’s it!
Overview of Tools/Equipment Needed:
A few tools aren't completely necessary, but they make the construction go a lot faster. I used:
- Access to laser cutter
- Various hand tools (needle nose pliers, flush wire-cutters, razor-blades, screwdrivers, etc)
- Wire Strippers
- Rotary Tool (IE: Dremel, a suitable one can be had for $20 or less. My favorite tool!)
- Soldering Iron (suitable one for $20)
- Rosin Core Electronics Solder
- Various soldering supplies (desoldering braid, flux, etc)
- Helping Hands (I just used my housemate)
- Sandpaper (600/fine grit, 100/coarse grit)
- Safety Glasses :)
Overview of Skills Needed
I’ll try to make this project as easy to follow as possible, but some things you should have a basic understanding of include:
- Soldering skills (tutorial here)
- Compiling and uploading software to your specific microcontroller platform (tutorials for Energia can be found here, consider doing a few easier projects first if you are unfamiliar)
- Using a software DJ program, like what I will be using: Virtual DJ
- Programming experience is a plus, as my code may not directly work with your configuration
- An understanding of bitwise math
What is “Quasi-MIDI”?
Quasi-MIDI, as I like to call it, is something I made up for this project. When I was first coming up with how to link the hardware to the DJing software in the quickest and simplest way, I thought of MIDI immediately. Almost every major DJing program supports it, it can be used for other projects, and it’s a pretty simple protocol in its own right. However, the archaic connector that it uses is no longer found on modern computers, and you often need a MIDI to USB converter, which adds additional cost and possible incompatibility to the project. MIDI devices that actually conform to the industry standard also require additional circuitry (optoisolators, etc, more complicated!) and are just in general harder to rapidly prototype with. Thus I came up with the idea of using a couple intermediary programs. An overview of how it works is this:
1. Main Microcontroller receives hardware input
2. Main Microcontroller sends a specialized message to the computer over a USB serial connection
3. Host program on computer written using Processing listens on that port and receives the message
4. The Processing program converts this message into a MIDI message and sends this message over a virtual MIDI connection (more about this later). The virtual MIDI connection varies by platform, but on Windows I used loopMIDI by Tobias Erichsen. On Mac and Linux this feature is built-in…
5. The DJing program receives the MIDI message over the virtual MIDI connection and a specific function is mapped to that MIDI message.
I will do my best to elaborate on the specific steps involved in this process later on in the Instructable. This is far from robust but it works without the need for any additional hardware, a definite plus considering the original goals of my project. You can take this dataflow and modify it to fit any MIDI-based project you can come up with! Want to make your own custom digital MIDI drumset? Or something even weirder like what Purity Ring uses? You can easily do that using this method!
- Electronics and Code - Me!
- Case Design, most of the construction, and holding everything while I soldered it - My housemate Eric
- Rocket Ship Logo - My friend Philip
- DJ Demo - My friend Kyle
Music in the video:
Merce ft. Farisha - Rain City
- Attak (Feat. Danny Brown) - Rustie
- Roller - Mr Carmack
- Make it Bun Dem - Skrillex
- Tell Me (Feat. What So Not) - RL Grime
- Last Year - Borgore
- Sleepless - Flume
Shoutouts and stuff
I’d like to include a couple shoutouts to any judges that are evaluating this Instructable for several contests I want to enter :) .
Make the case for an electronics project has always been the hardest part for me. How will everything fit together? How will I route cables? How will the interface look and fit with the electronics? The final project was only going to be a breadboarded circuit on a piece of cardboard, but my housemate told me he could design a laser cut case so I went all out. The hardest part was still putting it in the case while making it look good. A laser cutter can only get you so far... 2 Dimensions. A 3D printer opens up a whole new level of customization. I like making electronics related to music and they should look as good as they sound.
My partner on this project is also an architect and could benefit greatly from a 3D printer. His models would be brought to life by high-quality 3D prints obtained from a resin 3D printer.
I'm also into restoring cars (specifically a 1980 MGB at the moment) and I think that your 3D printer would allow me to make high quality reproduction plastic parts for classic cars that are otherwise really expensive or unavailable new. The online MGB community I am apart of would definitely benefit from the reproduction parts that I could produce. I could also make a lot of cool upgrades/brackets and stuff for cars.
Plus, I've always wanted to learn CAD, and a 3D printer would give me some motivation :)
Microcontroller Contest Sponsored by Radioshack:
This project doesn’t just include one microcontroller, but it has two! That’s twice the required number of microcontrollers! I would also like to note that I used a more underrepresented microcontroller platform (TI MSP430), mainly because of its low initial cost and versatility. This project really shows how you can stretch the limited pins of this platform to do quite a lot.
Also, it is worth noting that the dataflow used in this project allows any serial-enabled microcontroller to become the brains of a MIDI instrument, not just MCU's with built in HID/USB hardware.
Tech Contest Sponsored by Littlebits:
This project and littlebits share a common goal: rapid prototyping. Ingenuity and the right tools go a long way when working towards a functional prototype, thus the “quasi-MIDI” method that I came up with. I also tried to introduce readers to rapid prototyping with one of my favorite programming tools, Processing.
Again, it is worth noting that the dataflow used in this project allows any serial-enabled microcontroller to become the brains of a MIDI instrument, not just MCU's with built in HID/USB hardware.
Thank you for your considerations!
Step 1: Case Construction - Front Panel/Cutting the Case
We'll start out by cutting all the case parts so we know what we're working with. I was originally just going to mount this stuff on a cardboard box, but my housemates are all architect majors at my university so they have access to a wide variety of fabrication tools. One offered to design and laser-cut a case for it, I will offer those designs so you can use them. This part assumes you have access to some sort of laser cutter (who doesn't?) but if you don't you can try to fabricate a similar front panel/case.
I will not go over the steps for laser cutting because it's pretty subjective depending on how you actually get it cut (I also do not know the sorcery of CAD programs). The files are there for download and you should be able to open them in most CAD programs.
We used two different materials for the case, plexiglass and plywood. Our materials were bought at the university's shop, I'd imagine that it'd be a similar setup for most people who do not personally own their laser cutters.
- Sheet of 1/8" Thick Plywood
- Sheet of 1/8" Thick Plexiglass
- Super glue (Loctite Gel Control/Liquid recommended)
- Sandpaper (fine grit, 600 I believe)
- The controls you will be using to check the fit
Cut the Case
We used the plywood for the base and the front panel of the case. We used the plexi for the sides (so everyone can see the cool electronics inside!), for filling the negative space of the rocketship logo on the front, and also to fill the deck selector LEDs.
Important Note: Some of my parts are probably different (keypad, switches) so you should double check and edit the laser cut files to fit your specific parts. Carefully measure their dimensions or find them in the part's datasheet and modify what you need to. You also need to check the sides and make sure that all your parts will fit inside. I tried to make the case as thin as possible. This is out of the scope of this Instructable (don't you hate it when textbooks do this?), but find a suitable program to edit the files and make the necessary changes. It shouldn't be too hard, they're just rectangles. Students can get Autodesk's AutoCAD for free here. You may also be able to use the free version of Google Sketchup. The original files were made with AutoCAD and Rhino3D.
Get both the plywood and the plexi files cut. Keep all the pieces! Some of the stuff may look like junk but it may be used later on so just keep the pieces together.
Glue the Plexiglass Inlays
So now you should have the front panel and the plexi bits, let's start putting it together! Take the loose plexi pieces of the rocket ship logo and set them aside. Then, take the front panel and lay it front side down. This will make the plexi parts flush with the front when we are done. Carefully superglue the plexi logo parts into the negative spaces of the wooden rocket ship logo and allow it to dry for a while. I suggest using gel control Loctite so that it can fill any small gaps. You can also try using plexiglass glue so that it comes out clear, but I found that it wasn't strong enough.
While the glue is drying, take the little plexi circles (I hope you kept them!) and glue them in the holes next to the deck selector switch, it's underneath the large rectangular gap for the keypad.
Once the glue is dry and it feels sturdy, you should be left with some pretty unattractive glue residue. To get rid of this, I decided to just frost the plexi inlays with sandpaper. This also helps to diffuse the LED lights so it's not so direct and retina-burning. Take some fine grit sandpaper (I believe we used 600) and sand down both sides of the plexi inlays until you are satisfied with the look. Protip: You can get rid of the burn marks on the wood by lightly sanding with the same fine grit sandpaper.
Prepare the Panel for the Controls
This step varies with your parts and configuration, but I had to make some modifications to my case to make the parts fit correctly.
First off, if you're using the potentiometers from adafruit that I linked to, you will notice there's a little locating nub on the top of it. This was a pleasant little surprise... not! It helps with stability but we have to modify the back of the front panel as a result. You can either: A.) Grind/Cut the nub off, or B.) Grind/Cut little holes in the back of the front panel to accommodate the nubs. I went with option B because I'd rather not modify the parts. To do this, I used a rotary tool with a grinding bit on it. It doesn't matter where the hole is as long as it's the proper distance from the center hole. Measure this distance twice, mark it, and then grind a hole. Do this for all 11 potentiometers. Be careful not to go all the way through.
Second, the switches didn't fit through their holes so we had to grind them a bit bigger. Make sure you check the fit every so often, you want it to be snug.
Third, the keypad I used had a mounting bracket that we didn't account for. We had to cut wings on the side of the keypad hole so it would fit. This will be different for you unless you have a keypad from a payphone!
That should be it! When you are satisfied with the fit and finish of the parts and panel, continue on to build the hardware for this project.
Step 2: Hardware
Note: The schematic for this project is provided in this step. I used a program called DipTrace to make it. It's not the best schematic but it gives you a general overview of how to connect things.
Overview of Hardware
The hardware of this project consists of a few different boards interconnected to pull together all the controls. The Launchpad itself acts as the USB host for serial communication. To make it as modular as possible, we use a few different boards and headers to connect each board. This is so that you can take parts out (without desoldering) if you ever want to use them again in a different project. It also makes the project easier to disassemble so that you can repair/modify it in the future. We construct a “shield” type connector for the Launchpad that plugs into the pins of the Launchpad and connects them to the main board. The main board hosts most of the potentiometers and centrally located controls as well as the secondary microcontroller and the MCP3008 A/D Converter. Any controls not directly connected to the main board may have their own small circuit boards that are then wired to the main board. The last auxiliary circuit board is the one that hosts the keypad and related components. This is then connected to the main board by another connector we will construct with headers.
Each step concerning hardware will show how to build each board involved in this project. Each step will also include the required parts for that board. Make sure you have all the parts on hand before you start building! It would be best to prototype the circuit on a breadboard. That way you know it will work before you make it permanent! Also, please read the datasheets for all the components (especially the ICs) so that you don't hook anything up wrong and let the magic smoke out/cause fires. This circuit connects directly to your computers USB port and could possibly damage your computer/the components if there's a short or something misconncected. I am not liable for any damages!
Remember, this project is totally customizable. You can choose what controls you want and use my dataflow and come out with a totally different but equally versatile MIDI-based instrument! Be creative! However, I will only cover how to build my specific configuration. I will try to include information on how to customize it at certain points.
Step 3: Hardware - Launchpad Configuration
This project requires a certain configuration of your Launchpad.
Make sure you do not solder on the optional crystal oscillator! We need to use those pins as inputs!
Remove the jumpers that connect the LEDs to pins P1.0 and P1.6.
For Launchpad Rev 1.4 and older:
You may notice on older revisions of the TI Launchpad like I am using, Pin 3 is labeled TXD (transmitting data) and Pin 4 is labeled RXD (receiving data). The problem with this is that on the MSP430G2553, these pins are switched! Pin 3 actually functions as the RXD and Pin 4 functions as the TXD. That means in order for our circuit to function properly, we need to cross-wire the jumpers located in the upper right corner of the board so that the pin labeled TXD on the board is connected to the RXD and the RXD on the board is connected to the TXD. In this step I also detail how to build a crossover board. This only affects Launchpads Revision 1.4 and older.
For Launchpad Rev 1.5 and newer:
Starting with Rev 1.5, they made it so that you can use the included jumpers to enable the UART on the MSP430G2553. This blog post has a section that details how to do this. You need to turn the jumpers sideways.
How to Build the crossover board:
- Female Headers (2 pieces, 1X2)
- Small piece of protoboard
- Hookup wire
Get a small piece of protoboard, some female headers, and some hookup wire. Use your rotary tool to cut off two 1X2 sections of female header. Solder the female headers onto the board so that they fit on the pins of the TXD/RXD header. Solder wires so that the connections are crossed and you're done! For more instruction, look at the pictures I included. You can now reliably use the hardware UART on the main microcontroller to communicate with the computer!
Step 4: Hardware - Build the Shield Connector
The shield connector allows us to easily attach the Launchpad board to the circuit without it being permanent. It attaches the pins of the Main Microcontroller to the Main board that hosts all of the controls and auxiliary integrated circuits.
Build the Board:
To build the board, break off two sets of 10 male headers (my two/three-year old Launchpad came with female and male, so I just used those). Then take the protoboard, cut it to size using the rotary tool, and solder 10 male headers on each side that are spaced to fit in the Launchpad's female headers.
I opted to solder wires to bring the 17 pins we will be connecting to the main board out to the edge of the shield in a horizontal fashion. This was very tedious and may not be necessary, be very careful if you do this! We need to connect every pin to the main board except for Pins 4 (TXD), 16 (RST), and 17 (TEST).
You may want to wait until you have your case design all set to solder the shield directly to the main board so you know it will reach. I will cover this part in the main board section.
Please note that I decided not to directly mount the launchpad board on the main board for a few reasons. For one, it saves board space. Two, since we will be plugging cables into the launchpad quite frequently throughout the life of this controller, mounting the launchpad using other means keeps us from stressing the solder connections of the male headers directly.
Step 5: Hardware - Build the Keypad Board and Connector
The keypad board will host - not surprisingly - the keypad itself as well as the mode switch, the deck switch, and the deck LEDs. I decided to solder each of these components to a separate mini board and the solder them all to the keypad board so that I could custom fit them to their holes. The keypad board provides a central location to bring the circuit together and provide a connector to hook it to the main board.
You will need a few things to build this board.
- Blue LED (x1, for Deck 1 indicator)
- Red LED (x1, for Deck 2 indicator)
- Slow-changing RGB LED (x1, for Logo Backlight)
- 2-way switch (x1, Deck change switch)
- 3-way switch (x1, Mode switch, got mine from an old alarm clock)
- 12-Key matrix keypad (x1, got mine from broken payphone)
- 330-Ohm Resistors (x2, for LEDs)
- Male headers (7X1 Row)
- Female headers (12X1 Row)
- Hookup wire
- Small pieces of plywood (spacers for mounting, use leftover plywood from case)
- Super glue
Build the Board
Start off by cutting a small piece of protoboard that can hold the 2-way switch and a few wires, make sure to leave enough room for the connections we have to make! Take the 2-way switch and solder it on as pictured. Then solder wires on so that it can reach the keypad board (check your layout frequently) and so that it can reach the LED boards. Solder a wire for power (+) on a corner of the board, solder a wire for ground (-) to the middle pin of the switch, and then solder a wire for the switch signal to one of the other pins of the switch. Since we use pullup-resistors to read the switch input, we only need to know when the pin is pulled low to detect that deck. The other switch pin is simply for switching the LEDs. Solder a wire from the left and right pins of the switch and put them off to either side of the board. Then solder two wires to the power (+) wire to provide power to the LEDs when the switch pulls their wire to ground. Make sure to make these wires long enough so that you are sure they will reach when we put the project in the case! It's better to have them be too long and cut them than to have them be too short!
Set that aside and cut another three pieces of protoboard (about 3X8) for the LED boards. Layout the LEDs and resistors as pictured, noting that the anode of the LED (+, longer lead) is soldered to the resistor. Solder the LEDs and their resistors on separate boards as shown. You should have three LED boards: red, blue, and RGB. The RGB LED is not associated with the keypad but it's easier to just construct them all at once.
Set the LED boards aside and cut another small piece of protoboard to mount the mode switch on. I salvaged my 3-way switch from an alarm clock so it's most likely different from yours. Because of this, you should figure out how your specific 3-way switch works. You should be able to read it with only two pins. Anyway, solder it to the small board and set it aside.
The way my switch works is: there is 1 input pin and then the rest of the pins are connected to the input pin when the switch is in a certain position. Since we have our inputs configured using internal pull-up resistors, the default input value is a digital high (1). The way I read the position of the switch is: When pin 1 is low and pin 2 is high, that means the switch is in the first position. When pin 2 is low and pin 1 is high, the switch is in the second position. When both pin 1 and pin 2 are high, the switch is in the third position (the output pin, pin 3, of the switch is left disconnected in this case). My configuration is pictured.
Cut another, medium sized piece of protoboard and solder a 7-pin male header on the board so that the keypad connector fits. If your keypad doesn't have a connector like mine does, devise another way to connect your keypad. I like to have it modular so that you can take parts out easily if you ever want to use them in another project. The keypad board will have a 12-pin connector (7 for keypad, 2 for power/ground, and 3 for the switches), so solder on a 12-pin row of female headers in a location that would be closest to your main board in the final project. The header layout is shown in the picture. The first pin is the positive voltage (Vcc), the second and third pins are the mode switch, the fourth pin is the deck switch, the next seven are the keypad (I soldered them directly across to make it simple), and the last pin is the ground.
The keypad connector is what plugs the keypad board into the main board. At this point, it's just a 12X2 board that has a row of 12 male headers on it. We will solder wires to the main board later. So simply cut a 12X2 section of protoboard and then solder 12 male headers onto it in a row. See the picture for more details.
Bring it Together
We now have all the parts that make up the keypad part of this project. I suggest waiting until you have your enclosure design all set to solder the pieces together so that you can get the best spacing possible. The 12 pin connector needs to have these connections:
- 7 pins for the keypad
- 1 pin for power
- 1 pin for ground
- 1 pin for the deck switch
- 2 pins for the mode switch
Solder wires to the main keypad board so that all these connections are made, look at the pictures to see how I did this.
You want to connect the LEDs so that the two-way switch connects one of them to ground in either position. I suggest breadboarding this with your specific part to be certain before you solder the permanent connections. My switch had 3 pins, the center one was the input and the left and right pins would be connected to the center pin depending on the switch's position. I simply had to connect the cathode (-) of the LED board to the left or right pin and the anode (+) to the supply voltage.
You should be all set! Glue the keypad boards in place on the panel, except for the LED boards. These will be mounted on the bottom panel later.
Step 6: Hardware - Build the Button/Slider/Knob Boards
This section is pretty much a catch-all for various boards that host controls and shows you how to solder leads onto a potentiometer. The buttons are soldered onto their own little boards mounted on wooden spacers and have the external buttons glued to them. See the pictures for a better explanation. The rotary encoder is also mounted on its own little board and then glued to the front panel. The sliders and potentiometers simply have leads soldered onto their pins and then shrinkwrap over them to prevent shorts.
- Tactile Push-button Switches (x5)
- 10 kOhm, Linear Potentiometers (x11)
- 10 kOhm, Linear Slide Potentiometers (x2 Medium, x1 X-Large)
- Rotary Encoder w/ Pushbutton (x1)
- Hookup Wire
- 1/4" Heat shrinkwrap tubing (optional)
Build the Button Boards
To build the button boards, you need to cut three pieces of protoboard. Measure before you cut and see how much you're going to need to accommodate the buttons and wires, as well as the standoffs we are going to use to attach them to the front panel. Also take into account the spacing of your buttons and try to get them centered as much as possible under the panel button. There should be two boards that have two buttons and one board that has one button (or one long board that has all buttons on it, but I didn't have a big enough piece of protoboard).
My pieces came out to measure 2 1/4" by 11/16" (for 2-button boards) and 1 1/4" by 5/8" (for single-button board).
Solder the buttons on, make sure you know which pins are connected when pressed and when not pressed! Then, solder three wires to the two-button boards and two wires to the one-button board. Make sure these will be long enough for the final installation! The two-button boards' wires are ground, button 1, and button 2. Solder ground connections to one side of each button and then solder the other two wires, one to each buttons' side opposite the ground connection. See the pictures for more details. Make sure to leave space on either side and in the center for standoffs that will we use to attach the boards to the front panel.
Build the Rotary Encoder Board
To build the rotary encoder board, you need to cut a piece of protoboard that will accommodate the encoder itself (I just cut out sections where the mounting pins are located), the five wires we need to solder on, as well as the two standoffs on either side that we will use to mount the encoder to the front panel.
Solder the encoder on and simply attach wires to each of the pins. Make sure they are long enough so that they will reach the main board during final assembly!
Solder Wires to the Potentiometers
In this step we will solder wires to the potentiometers since they will be panel mounted. This can get pretty tedious so be prepared! My preferred method of doing this is to twist the wire and then fit it over the pin of the potentiometer for physical support, then solder it on, and finally slide some shrinkwrap tubing over the connection to make it look neat and to prevent possible short circuits. This process is detailed in the pictures. Simply heat the shrinkwrap tubing to make it shrink. I used a super-high-tech space heater, just find something that works! Note that I used the front panel to hold all the potentiometers in place while I soldered wires onto them. Repeat this process for the slide potentiometers. Make sure the wires are long enough to reach during final assembly!
Now we will mount everything to the front panel.
For the button boards, cut a couple small pieces of plywood to act as spacers and glue them to the button boards on either side of the buttons, and one in the center. Then, glue these boards under the cutout holes for the buttons, making sure to center the buttons as much as possible. Look at the pictures to see how I positioned everything. When you are satisfied with their positioning, you can glue the wooden button tops directly to the push buttons. Use a very small amount of glue so that you don't affect the operation of the push button!
The rotary encoder can simply be glued directly to the front panel without any spacers. Be certain the knob will have enough clearance to be pushed down for the button functionality!
Mount the rotary potentiometers using the provided nut and washer, tighten them down so that they don't rotate while you turn them.
The slide potentiometers have screw mounting holes but I opted to just simply glue them into place. Line them up carefully so that the slider can go through its full range of motion. Make sure to strip the felt guard off the edges of the x-large slide pot where you will be gluing it or else it won't glue effectively (believe me). Use a couple wooden spacers so the slider doesn't stick out as much from the front panel. See the pictures for more details.
You should have most if not all of the controls mounted on the front panel now! It's finally starting to look like a DJ Controller!
In the next step, we transition to the firmware side of this project before we finish building the hardware. This so we don't have to be a contortionist later on to insert the ICs in the main board. So put the soldering iron down for a bit, breathe some fresh air, and get to coding!
Step 7: Firmware
Note: On this step I attached standalone demo code for the rotary encoder and MCP3008 SPI communication as a reference. This is the barebones code for each type of input. It's amazing how there are no tutorials for using the MCP3008 with Arduino or Launchpad! I may make an Instructable just to explain this...
As stated previously, this project has two different microcontrollers that manage different controls in the circuit. The primary microcontroller is responsible for reading input from 6 of the analog controls, reading the 5 buttons, interpreting the rotary encoder and its integrated push button, and passing serial data from the secondary microcontroller to the computer. The secondary microcontroller is responsible for SPI communication with the MCP3008 Analog-to-Digital Converter and interpreting input from the keypad circuit (which consists of the keypad, the deck switch, and the mode switch). These ICs work hand in hand to give us a diverse array of controls!
You're going to need a few things to program the microcontrollers.
Getting Set Up
If you have not used/installed the default IDE (TI’s Code Composer Studio) to program your Launchpad before, you need to get the drivers for the Launchpad before your computer will 'see' it. To get set up initially using Energia, follow this guide. If it's your first time using Energia, I recommend uploading a couple of their super simple demo programs first and trying it all out. It's very easy and doesn't take much time, I'll wait!
When you get back from that, we need to install the Keypad library. It's written for Arduino but it works with Energia too. To install the library, find your Energia folder (usually in Documents), and extract the keypad library zip into the folder Energia\libraries.
Make sure you have Energia set up to program an MSP430G2553 on a Launchpad, and that you have the correct COM port select. Follow the guide above to set this up and upload a demo program so you know it works!
Energia should be all set to program now!
Understanding the Protocol
The microcontrollers communicate with the computer using a custom protocol that I made. It uses only two-byte (16-bit) messages to tell the computer information about all the controls. This was in an attempt to cut down on any possible latency and just to practice my bitwise math skills. Note that the raw serial data is not human readable in the slightest! An explanation of the protocol is included in this section so you can understand how all the code works better. You don't have to read this section but it may help you if you want to modify this project.
The general format for all messages is as follows:
 |  | 
ID Num | Type | Value
The ID number tells us what control sent the message. The type tells us if it's a digital (0) or analog (1) control. And the value is just a space for the control to put whatever message it needs to send.
Analog messages are super simple. They are formatted as follows:
 |  | 
ID Num | Type | 10-bit ADC Value
Look familiar? That's because it's exactly the same as a general message, only the type bit will always be a 1 for analog controls. The ADCs we happen to be using output 10-bit values, how convenient!
Digital controls are formatted exactly like analog controls, except the type bit will always be a 0 for digital controls. The value is just a boolean value, the last bit will either be a 1 (for digital high) or a 0 (for digital low).
This is where it starts getting a little more complicated. The keypad needs to communicate several different values in order to function properly. Because of this, its messages are formatted as follows:
 |  |  |  |  | 
ID Number | Type | Key ID | On/Off | Mode | Deck | Don't Care
The keypad will always be a digital control (type = 0). The ID number of 0 is reserved for keypad input so the first 6 bits will always be  for keypad messages. The next four bits are the Key ID number. Since we have a 12-button keypad, we use ID numbers 0 through 11. However, the remaining numbers can be used for other things since the hardware will never receive them as inputs. I decided to use the Key ID number 15 to indicate deck change commands (sent when the deck switch is flipped). This allows us to set the active deck and PFL with the deck selector switch. The next bit just tells us if the button was pressed (on) or released (off). The next two bits represent the mode that was selected. It ranges from 0 to 2 (thus we need two bits to represent the mode). The next bit represents the selected deck, either Deck 0 or Deck 1. The last two bits we don't care about and they won't be interpreted.
The Rotary Encoder is not as complicated, but note that it also has a reserved ID number of 1 for digital controls. The rotary encoder messages are formatted as follows:
 |  |  |  | 
ID Number | Type | Value | Super Speed | Don't Care
The ID Number of the Rotary Encoder will always be 1 and the type will always be 0. The value has three different meanings, 0 means clockwise rotation, 1 means counterclockwise rotation, and 2 means a double click, 3 is not used. The last 7 bits we don't care about and they won't be interpreted.
That's all there is to it! The protocol really isn't that hard to understand. And it's a good way to practice bitwise math skills and stretch the limits on how small you can get data packets. I decided to use 5 bits for the ID number so that the protocol can support up to 32 digital inputs and 32 analog inputs (5^2 = 32).
Step 8: Firmware - Secondary Microcontroller
Place one of the MSP430G2553's in the Launchpad and plug it into your computer. Download the provided code and open it in Energia. Below I provide a general outline of how the code functions. I will not cover the operation of the keypad library because it is fairly well documented here
The Secondary Microcontroller is responsible for communicating with the MCP3008 over SPI and interpreting keypad input. I have included both the Secondary Microcontroller code for this project and a demo I made for communicating with the MCP3008 in general (only tutorial I found was for Raspberry Pi). This should work on Launchpad and Arduino I think.
Understanding the Code
Whenever a key is pressed, released, or held, the function called keypadEvent is called. This function is responsible for sending messages to the main microcontroller when the state of the keypad changes.
Anyway, when a key is pressed for example, SendKeypadEvent is called with the arguments of key (the key that was pressed), a true (1, meaning the key was pressed), a digitalRead of P1.7 (which is the 2-way switch that identifies the deck that is affected by the key press), and the current Mode (which is determined in the main loop of the program).
SendKeypadEvent formats the message so that it can be understood later down the line. See the previous step for more information about how the protocol is formatted for each control. It sends two bytes that tells the program what key was pressed (or if it was released), the current deck, and the current mode.
Now if we look at the main program loop we see a few chunks of code. The first bit of code reads the keypad and any new keypresses are sent from there.The second section reads all the analog controls. The third section sends out a deck change message. This is done in the main loop using a flag set by the interrupt service routine because sending serial data in ISR's is inefficient.
The knobs are all SPI_Control classes. This localizes all the variables and methods and allows you to register any number of knobs you need. The main loop just checks if the class has determined there is a new (enough) value, and if there is, it sends out a message detailing what knob and what the new value is. My in-code comment summarizes communication with the MCP3008 over SPI fairly well:
On reading data from the MCP3008 ADC IC:
Please note, the SPI is in mode 0,0, which means SCLK idles in a 'low' state
- Pull CS/SS (Chip select/Slave select) pin LOW (0)
- Send start bit data, which is 00000001 or 0x01 (Read the datasheet)
- Send the input configuration/channel selection data
- Note: Input config data format: SGL/DIFF, D2, D1, D0, X, X, X, X. SGL/DIFF selects what mode, D2, D1, and D0 (3 bits) select channel to read (0-7) and XXXX do not matter. 1 = single-ended, 0 = differential
- The first byte received will be as follows: ?/?/?/?/?/0/B9/B8, where ? is unknown, 0 is a null bit, and B9 and B8 are the first bits of the 10-bit sample. The next byte received will be the rest of the 10-bit sample
- To get a meaningful reading, we have to combine the 2 bits from the first message with the second message. We can acomplish this by trimming the first 6 bits of the first byte (using bitwise & with the mask 0b00000011) shifting the bits 8 to the left, and the bitwise OR-ing the first byte with the second byte
- End communication by setting CS/SS back high
That's a little confusing, but all you need to know is that the function readADC just gets a 10-bit value from the MCP3008 for any channel.
If we look at the function SendDeckChange, you will notice that it is sent as a keypad press. Since we only have 12 keys, but we represent the key that was pressed with 4 bits, we can use 12-15 for whatever because they will never be received as input from the hardware. So we use the key ID 15 to represent deck changes.
That's pretty much it. Every clock cycle the microcontroller scans to see if a keypad button has been pressed, queries the MCP3008 for all the knob values and checks if they have changed within a certain sensitivity, and also checks to see if the deck switch has been flipped. See the code for more explanation, it's fairly well commented.
Uploading the Code
Now you should have an understanding of how the Secondary Microcontroller firmware works, so let’s go ahead and upload it! Get the code I posted into your Energia code window and click the checkmark in the corner to verify/compile it. It should all check out. When that is done, upload the code to the microcontroller by clicking on the arrow next to the checkmark. When that is complete, unplug the Launchpad, remove the microcontroller, and set it aside for now.
Step 9: Firmware - Primary Microcontroller
Now we can program the primary microcontroller. Place the other MSP430G2553 in the Launchpad and connect it to your computer. Energia should be all set up already.
The Main microcontroller is responsible for reading various buttons, the rest of the analog controls (6 in total), interpreting input from the rotary encoder, and passing serial data from the secondary microcontroller through to the connected computer.
Understanding the Code
I will first discuss what the main microcontroller does with the Secondary Microcontroller's messages because it is the simplest. The Secondary Microcontroller's messages already come in on the RXD pin preformatted, so the main microcontroller simply resends the received message on its own TXD pin to the computer. The code for this is found in the main loop at the bottom. That is all there is to the keypad messages for now.
Now if we look to the top of the program, you will notice that I define a class called AnalogControl. This class is almost identical to the SPI_Control in the secondary microcontroller firmware, but it reads the on-board ADC instead of asking the MCP3008 for a value. It has built-in averaging and smoothing code. Making this a class allows you to easily configure any number of analog controls. You can set what the control ID is, the pin that the ADC value is sampled from, and the sensitivity of the control.
Next is the Rotary Encoder class. This allows you to easily configure any number of rotary encoders as well, but for me one is enough in this project. The Rotary Encoder class simply needs to know what pins to use. The first two are the actual rotary encoder and the third is the integrated button input.
In the loop, we call isNew for each control and use its return value to determine if we should send a control change or not. The isNew function contains built-in smoothing for analog controls so that a new value isn’t sent every loop (measured resistances can be slightly unstable for various reasons like temperature and vibrations), this prevents control jitter.
We also check an array of boolean values that indicate whether a digital control has changed state. This flag is set in the interrupt service routines for a certain button. Again, this is done because sending serial data in an ISR is inefficient.
For an explanation of how the rotary encoder code works, check out this tutorial.
Thank you to the bildr tutorial above, that's what I based my rotary encoder code off of!
Uploading the Code
Now that you understand the main microcontroller code, we can upload it to the microcontroller! Copy my code into your Energia window and click the verify button. When the build process is complete and without errors, you can upload the code to the microcontroller.
This microcontroller stays in the Launchpad in the completed project so you can just leave it where it is once you are done programming it.
Step 10: Hardware - Build the Main Board
Now we will finally build the main board! This is where most of the hardware magic happens. The main board hosts the secondary microcontroller (hereafter referred to as 'SMCU') and the MCP3008 ADC chip, as well as all the controls. It has connectors soldered on for the keypad board and the launchpad as well.
- 20-pin IC Socket (x1)
- 16-pin IC Socket (x1)
- MSP430G2553 (x1)
- MCP3008 (x1)
- 10 kOhm Resistor (x1, pull-up for the reset pin on the G2553)
- Lots of hookup wire
- Suitably sized protoboard
Build the Board
Before We Begin: For detailed information on how to make all the necessary connections, see the attached circuit schematic! For help reading this schematic, see this tutorial by Sparkfun. Try to follow it as we go along. Also, remember to keep the datasheets for the MSP430G2553 and the MCP3008 open while soldering to make sure the proper connections are made! For an explanation of how the SPI (Serial Peripheral Interface) protocol works, see this tutorial by Sparkfun.
IC Sockets& Launchpad Connector
The bulk of the board is wired connections to all other controls of the DJ controller, but the few components that actually populate the board are the ICs/sockets and a single resistor. The rest is all wire! I soldered the 20-pin IC socket in the center top of the board and then soldered the 16-pin IC socket below it, leaving a gap in the center for the rotary encoder board to clear. Don't insert the actual IC's just yet, soldering heat can damage them! I then soldered on 17 wires for the Launchpad shield and began to solder some connections off of that. Make sure you write down what wires will be what when attached to the Launchpad! Solder the other end of these wires to the Launchpad shield we made earlier. Make sure they will reach!
From those pins, we need to solder both power and ground to the SMCU and the MCP3008. To do this, choose what wires will be power and ground from the Launchpad and solder a wire from power to pin 1 of the SMCU and pin 16 of the MCP3008. Since the reference voltage (Vref) will be the same as our supply voltage, bridge pins 16 and 15 of the MCP3008. To wire up ground to both chips, solder a ground connection to pin 20 of the SMCU and another to pin 14 (AGND) of the MCP3008. Since our AGND and DGND are the same, solder a connection from pin 14 to pin 9 of the MCP3008. That's it! Both chips should receive power now.
At this point, we are also going to solder on the pull-up resistor to the reset pin of the SMCU. This is necessary for the microcontroller to function independently. To do this, take the 10kOhm Resistor and solder it between pin 1 (supply voltage) and pin 16 (RST) of the SMCU. I used a bit of extra shrinkwrap tubing to help prevent short circuits. See the pictures for help.
Next, solder connections for the SPI interface from the MCP3008 to the secondary microcontroller. Pins 7, 8, 14, and 15 on the secondary microcontroller go to pins 13, 10, 12, and 11 on the MCP3008, respectively.
Here's where the rest of the fun happens: soldering all the controls onto the main board. To start, cut all the wires for the controls down so they reach without a lot of extra wire (leave a little slack), especially the potentiometers near the mounting position of the main board. Strip them appropriately and start positioning their wires in the board so they don't conflict. You can try to directly wire the controls where they need to be, but you can also use a bit of jumper wire.
Note: I found that mounting the main board later on was super difficult because of the wire placement of the controls. Consider leaving the wires long and wiring them to the edges of the board instead of directly in line.
The potentiometers need a ground connection on the uppermost pin and a power connection on the bottommost pin. The middle pin is the potentiometer's output. I wired the trebel, mid, and bass potentiometers to the main microcontroller. Solder the output of these six to pins 2, 5, 6, 7, 14, and 15. The other 5 potentiometers need to be wired to the MCP3008. The pins on the left side are all channel inputs so any 5 of those will do. On the slide potentiometers the pins are a bit different. On the extra-large slide pot, the pins are labeled 1, 2, and 3. Pin 1 should be connected to ground, pin 3 should be connected to positive voltage, and pin 2 is the output and should be wired to the MCP3008's left side. On the medium slide pot, the two pins on top are ground and the output from left to right, and the single pin on the bottom is positive power.
The rotary encoder has 5 wires coming off of it. These are: 2 ground connections, 1 button connection, and 2 connections for the rotary encoder output. On the three-pin side, the middle pin needs to be connected to ground. The left pin goes to pin 8 of the main microcontroller and the right pin goes to pin 9. On the two-pin side, one pin goes to ground and the other pin goes to pin 10. It doesn't matter which pin is which. For more help on hooking this up, see the pictures or check out this page.
Recall what connection you decided to be ground on the button boards. This needs to be soldered to ground, and then have their outputs soldered to the appropriate pins of the Launchpad wires that lead to the main microcontroller. The button inputs on the main microcontroller are pins 11, 12, 13, 18, and 19.
Find the little 12X2 header you made for the keypad connector a while ago and solder wires to it so that they reach the main board. Remember which wires are which! Then make the appropriate connections. The power and ground pins need to be connected accordingly. The deck switch pin goes to pin 5 on the secondary microntroller. The two mode pins go to pins 18 and 19. The keypad pins 1-7 go to pins 12, 2, 11, 10, 13, 9, and 6, respectively. See the schematic for a better idea.
Solder the shield connector to the mainboard using the layout you determined earlier. I wrote mine on the side of the board. Triple check the connections before you make them permanent! You could really mess up everything if a wire is routed wrong here!
Now we should have all the hardware hooked up where it needs to go electrically. The only thing left to do is position the LEDs and connect them where they need to go. We will do this in the next step where we finish building the case.
Insert the MSP430G2553 that is programmed with the secondary microcontroller's code into the 20-pin IC socket, and then insert the MCP3008 into the 16-pin IC socket. Make sure you insert the correct microcontroller, the primary microcontroller wouldn't be too happy in this circuit.
Now, glue the main board on the center of the front panel. Use some more wooden spacers to make it fit properly. Make sure that there are no clearance issues or possible short circuits. Remember that wires may shift around inside a bit throughout the lifetime of this controller so you may want to secure the wires with electrical tape or wire ties.
Plug the Launchpad into the shield and let it dangle for now.
Look at the clearance you would have to work with in order to insert the ICs now. Aren't you glad we waited a bit?
Step 11: Case Construction
Now we will finish putting the case together. You will need a few materials to do this:
- The pieces of plexiglass you cut earlier for the sides
- The wooden base you cut earlier
- The small rectangular pieces of wood that seemed pointless
- The front panel with all the hardware on it
- Super glue
Mount the Sides
To mount the sides, I just used super glue on the bottom panel. Note which side panel has a hole cut out for the USB connector. This will be the front side panel. Glue the pieces into position right on the edge of the base.
Now, you see those small wooden pieces? Those are meant to hold the Launchpad in place so you can remove it and use it in other projects if you need to! Glue those in the top-left of the base so they line up with the plexiglass sides. Make sure you use the Launchpad board as a guide while doing this so you know it fits properly! The USB connector of the Launchpad should line up with the laser cut hole in the plexiglass.
Next, we will install the LEDs. The blue LED goes under the left deck indicator, and the red LED goes under the right deck indicator, you may want to try making tubes so the light doesn't diffuse throughout the case. I would suggest plastic straws with some shrinkwrap over them. The RGB LED goes under the rocketship logo. You may want to sand the exterior of the LEDs to help diffuse the light even more. Try to position the RGB LED so that the center of it hits a wooden part of the logo, the illumination will look much more even if you do this. Glue them in place when you are satisfied with the positioning.
Get out the soldering iron one last time and solder the deck LEDs to the deck switch (you should have wires hanging off for this already). The RGB LED is always on when the controller is plugged in so just solder that to power and ground. Make sure you get the polarity correct, LEDs do not work backwards (that's the point of a diode).
Mount the Front Panel
To mount the front panel, you can either use super glue (permanently seal everything inside...), tack it on with some plexiglass glue, or find some suitable brackets. Drilling/screwing into plexiglass is not really a good idea as it will just crack. Be careful not to damage the plexiglass sides or the front panel while doing this!
Note: The finished product in these pictures is just the rough prototype. The laser cutter wasn't available to cut the sides so we just roughly made them by scoring them with a razor and breaking them over some drumsticks. The hardware had some bugs so I didn't want to completely seal the parts in. It still looks cool but it's not as polished as I would like it to be. Also, I didn't solder the launchpad shield on just yet, I plugged the wires in. Experiment with different ways to mount the Launchpad!
Put the Launchpad in the little nook we made for it earlier in this step. The USB hole should line up and the wooden panels should hold the Launchpad in place effectively.
That's it! You should be all done with the hardware/physical construction side of this project.
Step 12: Software
Phew, we're finally done with the hardware. Pour yourself a hot/cold beverage (coffee or refreshing imbibery) and sit down at your desk. Now we start the software side of this project.
The Software side of this project consists of a custom program written using Processing, an IDE/Language very similar to Arduino/Java, some sort of virtual MIDI driver, and your personal favorite DJing Software. We will cover the configuration of each of these programs in the next few steps, but for now you're going to need a couple things!
- Download and extract Processing (make sure it's the 32-bit version, I suggest downloading both)
- proMIDI 1.0 (library for Processing, make sure to get the older 1.0 version)
- controlP5 (GUI library for Processing)
- A virtual MIDI driver
We will be using a couple libraries with Processing. proMIDI 1.0 allows us to send/receive MIDI commands in our program, very useful! controlP5 is a great Processing library. It allows us to rapidly create a nice looking and functional user interface for our program. A virtual MIDI driver carries the MIDI messages we create in our program directly over to the DJing program without the need of a physical cable/real MIDI connection. For Windows, we have to use loopMIDI. Mac and Linux have a native solution. I will cover setting this virtual connection up in the next steps.
For the DJing Software, I have only tested this with Virtual DJ Pro because that’s my software of choice. However, the method we use (custom MIDI command mapping) is supported by quite a few of the top DJing programs, such as: Traktor Pro, Ableton Live, Serato DJ, Image-Line Deckadance, and maybe even Algoriddim’s DJay for Mac (not sure about this one, but try it). Those links are MIDI controller mapping tutorials for the respective programs. Any DJ Software that you can map custom MIDI commands for should work. I will only cover setting up this controller for use with Virtual DJ Pro in this Instructable.
Note: I don't know about other DJing programs, but Virtual DJ allows you to export and import custom mappings. If the Instructables community actually builds this it would be possible to swap mappings for other programs in the comments. I didn't map everything on my controller yet, but I will upload what I have done.
Since Processing is cross platform, you should theoretically be able to use this project with most operating systems. However, I have only tested it on Windows.
Step 13: Software - Virtual MIDI Driver
Before we get started with anything else, we're going to need a way to virtually connect our interpreting program and the DJing software. To do this, we need a virtual MIDI driver. On Windows, you can download and install loopMIDI, on Mac or Linux, this feature is built in. Follow the directions here for Mac, and here for Linux. Note that I haven't tested this setup on Mac or Linux, but it should be possible. You might have to play around. This should be all set up, and we can see whether or not it worked in the next step!
To set up loopMIDI, simply open the program, type a name in the "New Port Name" box, and then click the "+" button. You should then be able to find a MIDI port named whatever you put into the box!
EDIT: So after wrestling with LoopBe1's "convenient" feedback prevention feature, I have decided to switch to a different virtual MIDI driver for Windows. The feedback prevention pretty much just monitored if a lot of messages were being sent in a short period of time. Seeing as we're modifying multiple sliders at the same time on a DJ Controller fairly often, this resulted in LoopBe1 muting the MIDI channel and cutting off control. Very inconvenient if you ask me. It should at least be configurable. Anyway, the new software that I began using is called loopMIDI by Tobias Erichsen. Good software, simple, no frills software MIDI passthrough. Thank you Tobias!
Step 14: Software - Processing Program
This program connects to the serial port of the Launchpad so we can receive input. It gets the messages, decodes them, and formats a MIDI message and sends it out. It also includes a user interface that allows you to select the proper serial port and MIDI connection. You can play some pretty spooky piano with the keypad if you connect to the Microsoft MIDI Synth! Anyway, I'll give an overview of how the software works and then tell you how to configure it. We need a few things first.
- Processing IDE
- proMIDI 1.0 library
- controlP5 library
See the previous step for links
Start by installing the libraries. Find your Processing folder (usually in Documents) and the go to Processing\libraries. Extract the libraries to this folder and you should be all set (it's the same as installing libraries for Energia or Arduino).
Understanding the Code
There are some parts of the code unrelated to processing the input from the DJ Controller. These include managing the serial port and MIDI connections as well as creating the user interface. I will not cover these parts of the code. See the page for the certain library in question if you want an explanation of how everything works.
The data from the controller enters our program in the function called 'serialEvent.' In this function, the two separate bytes of the message are combined into one 16-bit char (not integer... because Processing doesn't have unsigned data types, see the code comments for more information and ranting). It then calls the function 'ParseMessage'...
ParseMessage is the starting point for processing the bits we receive from the controller. It uses bitwise math to decode the ID number and type of the control that sent the message. Based on these properties, it can then send the message to the proper function to be processed.
If the control is an analog control, it calls 'ProcessAnalog'. This function decodes the 10-bit value of the control and turns it into a MIDI value between 0 and 127. It then sends a control change MIDI message by calling 'SendControlChange'. A control change is a type of MIDI control that has a variable input instead of a note, which has an on-off state.
If the control is a digital control, it has 3 choices in how to process it: If the ID number is 0, that number is reserved for the keypad so it sends it to 'ProcessKeypad'. If the ID number is 1, that number is reserved for the rotary encoder so it sends it to 'ProcessRotary'. If the ID number is neither of these reserved values, it processes it as a general digital input (aka button) by sending the message to 'ProcessDigital'.
ProcessKeypad decodes what key was pressed, its on/off state, the mode that was selected at the time, and the deck that was selected at the time. It then sends a MIDI note based on this information. The MIDI note number is calculated using a special algorithm that gives each combination a unique note value.
ProcessRotary decodes what the value of the message is and whether the integrated button was pushed while the rotary encoder was turned. The values range from 0 to 2, with 0 meaning clockwise rotation, 1 meaning counterclockwise rotation, and 2 meaning a double click (used for loading tracks to selected deck). The superspeed bit is set to 1 if the integrated button was pushed down while rotating, and if it was pressed down, the program sends 10 MIDI messages. Since the rotary encoder is intended to be used for browsing a library, this allows you to scroll more quickly through songs.
ProcessDigital simply decodes the last bit in the message and that tells whether to send an on or an off MIDI message for the specific note associated with that control.
For more information concerning the protocol used in this project, see the first step in the Firmware section.
Running the Code and Configuring the Software
Now that you understand the code, lets get to running it!
You will notice when you first open Processing it is almost identical to Energia. They are based off the same thing kind of (Wiring, I believe). This makes it super intuitive to get started! Copy and paste my code into the editor window and click the Play button in the top left-hand corner ("Run").
A little window should pop up that has two drop-down menus and three buttons. These controls allow you to select what MIDI output to connect to and what Serial port input to listen on. The refresh button allows you to refresh the lists if you unplug/plug in your launchpad or a MIDI connection. For our purposes, connect the MIDI Out line to loopMIDI (Windows) or the virtual MIDI port you created earlier (Mac/Linux). Plug in the controller and connect the Serial port to the serial port that the controller is on. It should be the one you used with Energia. MIDI input from your controller should now reach whatever is connected to the other end of your virtual MIDI port.
Step 15: Software - DJing Program
Note: The file attached to this step is my (incomplete) mapping for the DJ Controller I built. It will work with Virtual DJ Pro 8. Simply find your VirtualDJ folder (usually in Documents), and then paste this file into the VirtualDJ\Mappers folder. That should do the trick!
This is the final step in getting set up! It varies by what software you use to DJ but I used Virtual DJ Pro 8. It has a handy scripting system called VDJScript that allows you map complex commands to MIDI messages and made this controller super powerful. Other DJing software might have a similar system, check with your user manual or the software company's website.
I will not cover how to map commands in great detail because it can become very complicated, but I will include my (incomplete) mapping for Virtual DJ. Note that depending on how you hooked up controls the ID numbers may be different so the controls might change a bit. Therefore, it is best if you just learn how to map commands for your specific DJing software. That way you can customize the operation of this controller even more! Here is a good tutorial for Virtual DJ Pro. I linked to some more tutorials for other software in the intro step. Again, check the company's website!
The general way you map controls in Virtual DJ Pro is:
Click on the settings button and go to the Controllers tab. Find the virtual midi driver input and click on it (for mine it said "loopMIDI (custom mapping)"). Then, use a control on the controller and it should appear in the key learn box below. You can then select that key and map it to some action. For example, mapping 0-SLIDER70 to the action 'crossfader' would map a knob/slider to the crossfader. Be creative and use the action learn button (screen with a magnifying glass icon). That allows you to use your mouse to select actions from the interface. Read up and come up with shortcuts that work with your DJing style!
Step 16: Finishing Up - Notes for the Future
You should be all set up with your very own DIY DJ Controller now! Go out there and start DJing!
Some notes about this project for people who construct it in the future:
I noticed that sometimes the analog MIDI controls can be very unstable. This can be fixed either through hardware or software. There is a sensitivity parameter for analog controls, and you could perhaps use a higher resistance potentiometer for a higher impedance circuit (uses less power and probably more stable).
If I were to redo this project, I would definitely plan out the cable routing better. Getting the main board soldered to all the controls was really a pain. I actually broke the rotary encoder while I was fixing something else because it was already glued down. In the future, I would ideally not glue anything down. I wanted to get this Instructable in on time for a couple contests so I had to make due with the quickest methods.
I plan to fix a few more things with the hardware and update the software so it's more stable in the future, but the project works pretty well as it is. Also, LoopBe1 has a very annoying auto-mute function that mutes the MIDI channel when too many messages are sent in a short period of time. This can cause some cut-outs when operating several analog controls at once. A software update to the Processing program could probably remedy this. EDIT: Changed the suggested virtual MIDI driver. See the software step pertaining to setting up the Virtual MIDI driver for more information. Cutouts are finally gone :) !
Remember this project is totally reconfigurable. Most of the inputs are classes so you can configure different numbers of them. The ability to easily change the inputs in code and how they affect the DJ program through VDJScript (or equivalent) really makes this project/dataflow powerful and simple. Though I'll admit that a bitwise protocol was almost masochistic ;)
I hope that you enjoyed following me along with this Instructable! Thank you for reading! Check out the video in the intro!