Tuesday, May 19, 2020

Java Lighting Control Part 2 - Building a Simple Color and Brightness Controller

Monday, May 17th

In my previous post (available here), I explored integration of both of my Launchpads into Java. At the end, I teased a basic control project with both pads and explained I'd be posting about it. So here I am with the full project build process explained as best as I can.

The Goal

This is more of a first step in the ultimate goal of lighting control, rather than a functional project that I can actually use during gigs. My goal is to control up to 8 lights using both launchpads, one Launchpad to control the brightness and one to control the color.

Planning - Control Flow

The first thing I usually do when starting a Java project is draft the flow of data through the project so I can get an idea of what I'm trying to accomplish and what objects I will need to create. This usually takes the form of a whiteboard sketch.

From my initial brainstorming, I came up with the basics of what modules I need to build and how they communicate with each part of the program. I will need a way to create lighting fixture objects to store how many channels they have, what Art-Net universe they are on, and what their DMX address is. Then, I will need a fader class to act as a controller and middleman between the Launchpads and the lights. Finally, I will need to be able to store colors as both an RGB value for pushing to the lights and as a velocity value to push to the Launchpad.

As for the flow of data through the program, I ended up with two different control paths that I could use. The main difference between the two is how they handle pushing data to the lights.

First control flow idea
The first solution integrates everything I was talking about above, though the lines are a bit hard to follow. Let's start with the left of the program and work our way towards the right.

On the far left in pink are my two Launchpads, MIDI 1 being the MK2 and MIDI 2 being the S. Each push out data to one of two banks of faders, which are drawn in green. One bank of faders are single parameter control faders, which receive data from the Launchpad S and push back MIDI data to light up the Launchpad in a way that reflects the current state of the fader.

The second bank of faders, labeled '3fad', are responsible for holding the Red, Green, Blue, and White channels of the light they're assigned to. (To be fair, that's 4 parameters, it should be labeled '4fad'). This fader needs to be slightly more advanced so it can push RGBW commands to set the color of the light, as well as push color data back to the Launchpad MK2 display. The way it will do this is with the Color object I was talking about earlier that stores RGB(W) values alongside the velocity value for display on the launchpad.

In this solution, data from the faders is pushed to an array in each lighting object that stores the current value of each channel on that particular light. When it comes time to push that data over Art-Net, an object called a frame constructor puts together a list of commands for each channel on each light and pushes it to the Art-Net backbone of my program.

The Art-Net backbone is complex enough for it's own post (here when done), but for now it's important to explain the different types of data that it uses. The first is a DMXCommand, which is simply stores a channel, data value, and universe. The second is a DMXFrame, which is a collection of DMXCommands.

This was the first solution I came up with, but I realized that as more lights get added to the program it would start to take longer to update the universe since I would be generating new data based of the current state of the lights, even if nothing changed. This prompted me to generate a second solution that would be a bit more efficient at scale.

Second control flow idea
 Despite looking wildly different, there's actually a lot of similarities to the first solution here. MIDI input is handled exactly the same, and output to Art-Net is handled the same. The difference is that the faders send data both to the light objects and to the frame constructor, so that instead of rendering all channels all the time, the frame only contains changes that were made. The data is still stored to the lighting objects, however, just in case I need to get the current state of any given light in the future.

This should save vastly on processing time for larger projects, and even though the current project is a bit small, I feel it will be good to start building things efficiently the first time.

Coding Time

Fader Objects and MIDI Integration

I'll start by building the fader classes and setting up communication with MIDI devices. Upon starting this I realized I haven't implemented output for the Launchpad S or Launchpad MK2 classes, so I'll do a quick refresher of how I did that.

Turns out that translation from coordinates to values in the Launchpad S handler is actually super easy. I started by storing each row array into another array list. Now any time that I need to find a pitch value, I use the first value to find the row, and then the second value to find the number within that row.
I've also started commenting my code so it should be clearer
This is the whole code to go from a set of coordinates to a MIDI value with the Launchpad S. But it's clearly way more efficient than trying to go from a MIDI value to a set of coordinates.

Once you have the MIDI note value, all that's left is to output it to the Launchpad. This is handled super easily by one line, which takes a channel (always 0 in this case), pitch, and velocity and pushes it as a MIDI message to the desired bus.
Command to output a MIDI message to the desired bus
As you can imagine, the code for the Launchpad MK2 is a lot better since the MIDI notes are already a concatenation of the row and column.

The next step is to start writing the fader base class, which will be inherited by every different type of fader we will be creating. The base class stores the reference to the particular MIDI Handler we're using, the resolution of the fader, and the column of the launchpad which will serve as the control interface and display for the fader.

Once the base class was finished, I moved onto writing a single-parameter fader class. In addition to inheriting all the base functionality of the base class, this integrates functions for displaying the current state of the fader to the Launchpad in a pre-set velocity color, and updating the display and fader according to input from the MIDI bus.

The way I handle display is by creating an array called display which stores the state of each pixel in the form of a 1 for on, or 0 for off, with the index position representing the Y value of the pixel. The class also includes methods for displaying the data in that array, clearing that array, and updating it according to MIDI input.

In any given frame (representing one cycle of the program), the fader reaches to the MIDI bus it was assigned to when it was created to get the coordinates of the latest note pressed. If the column of the fader aligns with the X value of the data, then it clears the display and turns on any pixels at or beneath the Y value from the data. Finally, it checks through the display array and sends appropriate data to the Launchpad.

The best part is I wrote it in such a way where you can create as many faders as you want by specifying different column IDs. To demonstrate this, I created 8 faders and assigned each to a different column on the launchpad. The result looked something like this:

Faders in operation on the Launchpad S
 As you can see, you can control each fader by tapping on the corresponding button in any given column, and the display reacts accordingly. On the lighting control side, the higher a bar is, the brighter the light is going to be. Even though I haven't implemented Art-Net control to each fader quite yet, this is still a major milestone in actually using MIDI to control the program.

The next step is to write a 4-channel fader for controlling the color of each light. Thankfully, I have some experience now with writing the single-channel fader, however there's still work that needs to go into making this one. Instead of being one color, each pixel on the display has to be a different color, and rather than updating and changing the height of a bar, it simply needs to turn the pixel green when it is pressed to show that it's the current active color on that fader.

The way I plan to implement this is by creating a type of object called a LaunchColor. This stores a velocity value for use with a Launchpad, as well as Red, Green, Blue, and White values for use with Art-Net. I'll then create eight different displayable colors that I can reference and use with this particular fader.

The fader has two arrays, one is for the MIDI display and is purely for showing which color is in each slot. This array needs to be able to change to update the state of the display, which includes which color is active. However, because we also need an array to fall back on when we change the active color, and to continue sending up-to-date Art-Net data. For this reason, I will also be creating a default display array which is just to store what each slot is assigned to functionally.

There is also a method to set a pad color, which simply puts a color in the desired slot. This is so we can set what color is assigned to what pad, and change it if needed. Additionally, the updateDisplay and showDisplay methods are almost identical to the single fader, but output the display color and update the active display color instead of changing the pixels that are lit up.

Once I finished, I realized that running a test with 8 faders would require almost 20 lines of setup per fader. I decided to write a FaderBank class for each type of fader to store references to all my faders. This allows me to create all 8 4-channel faders at the same time, and also allows me to update and show each fader by calling the bank instead of calling each separately. I don't know what the impact on efficiency is, but it at least allows me to save time by not having to write as much code.

After that was done, I finally had my faders built, and it was time to build the actual lighting control side of things.
Finished Color and Brightness Faders
Lighting Fixture Objects and a Primer on DMX

The first thing to do is to create a lighting fixture class to hold data like the number of channels, current channel states, default channel states, and DMX starting address. Therefore, I can create a lighting fixture object for each light in my setup.

I'm sure you're wondering what all this actually is, so allow me to give you a quick primer in the ways of DMX.

DMX (Digital MultipleXing) is a common protocol used for controlling stage lights. It's capable of controlling 512 channels with values between 0 and 255 on a single line. This means that you can daisy-chain lights together with DMX, and as long as the total number of channels is less than or equal to 512, you can control each channel individually.

I have several different kinds of lights, though for this project I'll be using a couple of XPC Pars, which are cheap lights I bought in a bundle on Amazon (link here. They're good lights for what they are but bear in mind, you get what you pay for). Each light has 8 channels (dimmer, strobe, macro 1, macro 2, red, green, blue, and white) which means the total number of lights I can put up to 64 of these on a single DMX chain and still be able to control all 8 channels individually for each light. Light 1 would be address 1 on a chain, light 2 is address 9, light 3 is address 17, etc because each light covers it's starting address and as many channel addresses as it has channels.

The way I control my DMX lights using Java is with a protocol called Art-Net, which I've mentioned previously. Art-Net is a protocol that allows for lighting control using IP networking, which allows for more than 30,000 universes (sets of 512 channels) can be controlled individually. I'll go into more detail about how I implement this into my programs when I cover the Art-Net backbone, but for now just know that I control lights by pushing data to a DMX chain using Art-Net.

DMXCommands from Faders

Referring back to the control flow at the beginning of the project, each fader has to store the channel that it's going to be controlling, and output a value associated with that channel to Art-Net. In the case of the quad-channel fader, it has to be able to output data to 4 different channels at once. These come in the form of DMXCommands, a simple message that basically says "Set this channel to this value on this universe".

On the single-channel fader side of things, all I have to do is assign a light, channel, and universe to each fader so it knows what to control. Then I have to program a way for the MIDI commands to generate data to push to that channel and universe. In this case, the brightness should slowly increase as the Y value of the fader increases.

The good news is that I have a way to get the total Y value of the fader, and that's by adding up the value of all the integers in the display array. Being the math nerd that I am, I decided to hop on over to desmos.com/calculator, one of the greatest free resources on the whole of the internet to see if I could figure out what that equation is.

Graph depicting relationship of brightness to button pressed
I started by graphing 2 points to represent button 1 being 0 brightness and button 8 being full brightness (255). The equation for this line is y = 36x - 36. This means that the value output needs to be 36 less than 36 times the number of the button pressed. However, since Art-Net and DMX really don't like decimal numbers, we have to make sure we cast the result as a whole integer.

From there all we have to do is calculate what channel on the universe this data will be going to since we assign the channel to the fader using the channel per fixture, rather than per universe. This is mainly to keep my head straight, and it's a simple calculation to figure out which channel on the universe we are trying to control.

Calculation of channel in universe relative to channel in fixture.
And there you go, that's how you use math to control lights. After we have that information we just write a method to output the result of our above equation to the channel we get in the lower equation in the universe we get from the fixture that was defined on that fader.

Code for sending DMX data based on the Y value of the single fader
That's all for the single fader, and the quad fader doesn't have to do nearly as much math. However, it does have to output a series of commands for the Red, Green, Blue, and White channels of the fixture it's controlling. This is going to be much easier since we have an array full of colors already that we can pull the RGBW values from.

Code for sending DMX data based on active color of the 4-channel fader
All that's left is to find somewhere to push this data to, and that's where the Frame Constructor comes into play.

DMXFrame Constructor

The frame constructor is the final link between the faders and the Art-Net output. The first step of making this work is creating references to an active frame in both types of faders. Then we create an empty DMXFrame object and add it to all of the faders in our banks so that when the faders output data, it goes to that frame.

Finally, the frame is pushed to a newly created ArtnetRouter, an object that is part of the Art-Net backbone for this program and I will discuss in detail in my post about it. From there it's pushed to my Art-Net node and then out to my lights on the DMX chains!

The Finished Project

After adding all of the object creation to the main function of the program, the program should be fully operational! And there you have it! A simple color and brightness controller for up to 8 different lights written entirely in Java utilizing both Launchpads! This project took me two days to get working, but I think it's an excellent first step in my journey to create my own lighting control application.
Final project demonstration - brightness inconsistency due to phone camera being bad
Thanks for reading this far! I hope you enjoyed! Keep on making things!
-Will

Sunday, May 17, 2020

Java Lighting Control Part 1 - Dual Launchpad Integration

Sunday, May 16th

I told you I'd have a post soon on my Java Lighting Control project so here I am. So far I've built the Art-Net backbone of the program, and so I decided that today's project was to implement MIDI support for both of my launchpads.

Quick primer - what is MIDI and why do I need it?

MIDI stands for Musical Instrument Digital Interface, and it's a technology that's been around for quite a while and something I am all to familiar with. It's basically a communication protocol that allows for MIDI devices to send channel, velocity, and pitch data from something like a MIDI keyboard to a computer based synthesizer without the keyboard itself doing the sound synthesis.

The reason I'm using MIDI as my control interface is because it will allow me to control the application with a pair of Launchpads. If you've spent any amount of time looking at electronic music covers on YouTube I can almost guarantee you've seen one of these before.

A launchpad outputs MIDI messages which I can read using a handy library I found for Java called TheMidiBus (available here for those who are curious). I settled on this Java library because it's nice and lightweight, and I couldn't get the default Java library working after three days of struggle. It doesn't offer nearly as many features as the default Java library, but in all honesty the added complexity of channels, tracks, and sequencers made the signal flow of the project a nightmare. This was the perfect solution.

There are two components of a MIDI message that I'm focused on in this project, which are the pitch and the velocity. On the input side, I'm only focused on the pitch since it tells me which button on the launchpad was pressed. However, in order to make the launchpad light up you have to send MIDI data back. The pitch tells the launchpad which button to light up, and the velocity tells it what color to light up.

It's a bit annoying not being able to use standard LED coloring with RGB values, but the easy solution to this problem is to write an object in Java that stores an RGB value for on-screen display alongside a velocity value to send to the Launchpad. That way I can read a color value to both the application and the launchpad, and both will have data to tell it what color it needs to use.

I've worked with MIDI before in various projects so this isn't my first time working with it. For example, I used Python to write a version of Pong that was controlled and outputted to my Launchpad MK2 (the code is available here for those who want to try it out for themselves. Though it only works for Launchpad MK2). Together with my friend Caden (who is a vastly better Java developer than I am), we wrote a version of this in Java to get the basics of MIDI input and output down. That code isn't publicly available yet but I imagine it will be at some point.

LaunchPong in Python
So I have figured out MIDI input with one device, however, with the way I'm building this control software I want to be able to run two Launchpads side by side to control various aspects of the lighting rig. So that was today's project.

My two Launchpads
On the left is my Launchpad MK2, the new guy on the block and the one featured in the above gif. I purchased it for reasons I will explain later, but it's gotten to see two gigs of lighting control before I ran out of gigs to DJ at. On the right is my Launchpad S, which I bought from a friend when I was first getting into music production. It's been running lights for almost the entire time I've had lights, and has been quite faithful, although it did have a problem.

The problem with the Launchpad S

The main problem I faced with the Launchpad S was due to the way that MIDI channels work. MIDI supports up to 16 different channels of data, which is important when you have, for example, several devices controlling different things. Whenever I would do DJ gigs, I would have two MIDI devices plugged into my laptop at any given time. The first was the Launchpad, which controlled lights via MIDI commands in a program called QLab (full post on this someday). The other was my DDJ-400, a DJ controller that ran Rekordbox, my DJing program of choice.

Both these devices work on the same MIDI channel (which defaults to channel 1 I believe). And while Rekordbox was good at making sure that the incoming data from the Launchpad didn't accidentally pause the music during a gig, QLab just took any MIDI commands that came in on the specified channel and controlled the lights regardless of what device the command had come from. I found myself accidentally turning all the lights green when I pushed play, or turning on strobe whenever I touched my EQ, which was not great. The worst part is, I was completely oblivious to this until I was DJing my Senior prom, and I was fortunate to have Caden as my lighting engineer for the night to correct my mistakes when I was DJing.

The solution was quite simple, all I had to do was change the MIDI channel that QLab was reading and the channel that the Launchpad was outputting. The problem was that Launchpad S is basically diet Launchpad, and while it allows you to change which device ID the Launchpad is (something that Ableton uses for distinguishing which device is which), it does not allow you to configure the MIDI channel. This is when I decided to purchase the Launchpad MK2 as my primary lighting controller since it allows the configuration of which MIDI channel it's outputting on.

This is actually one issue that I actually don't have to worry about in Java. When creating MIDI Bus objects using TheMidiBus library, you actually have to specify sending and receiving devices for that particular bus. Therefore I don't have to muck about with channels, I just have to make sure the correct devices are selected when setting them up.

The other problem with the Launchpad S

Most of my code for this test project was copied and pasted over from the LaunchPong Java project, which was written for the Launchpad MK2. I figured that the control mapping was the exact same on both devices, but I was dead wrong.


Control Mappings for Launchpad MK2
Above is a labeled diagram showing the pitch for each button. Starting in the bottom left with 11 and working up to 88 in the top right. This is really easy on me as far as control schemes go, because to get the X and Y coordinates of the button that was pressed, I just have to split the incoming pitch apart into row and column values. For example, a value of 36 would be row 3, column 6, or (6,3) in traditional Cartesian coordinates.


So I wrote a quick test project to implement both Launchpads controlling at once, and I discovered that I had a huge problem.

Control Mappings for Launchpad S
As you can see, the top left note is 0, and then they increment up by 1 until they reach note 8 at the end of the row. However, instead of continuing to increment up by 1 starting on the second row, it starts over at 16 and continues to do so. The next row starts at 32, and so on. In no way shape or form does it emulate the wonderful note mapping that is present on the MK2.

This is a slightly trickier problem to solve, since my code is written to process things in terms of X and Y values. This doesn't play nicely with the fact that the MK2 and the S have completely different numbering schemes.

The best way to explain this is to go over how my code works. If you're familiar with Java you're welcome to criticize me (please go easy I'm still learning). If you don't know how programming works, Don't be alarmed! I'll do my best to explain so it makes sense.

My first idea was to write a MIDIHandler class for the Launchpad, which would hold functions such as doing something when it received MIDI input, and translating the note that came in to X and Y coordinates for use in the program later. This was a complex beast of code, and since I'm not sure how to paste code into Blogger's editor I'm just going to share screenshots.

The class constructor and MIDI Listener
Methods for translating from data to coordinates and vice versa
The first screenshot shows the class constructor and the MIDI Listener. The first line creates a new MidiBus with the input and output devices that I specify (in our case the Launchpad MK2). The note pressed simply stores the pitch of the last note pressed. The listener is exactly what it sounds like, it simply listens for any input data and when it receives some, it executes the code in the brackets which is to record the pitch of the message that just came in.

The lowest code block on the top screenshot is the constructor, a set of code that's always executed when a new object is created of this particular type. In this case, it just assigns the created listener to the bus specified in the class so the listener knows to listen on that bus.

The lower screenshot uses Java magic to convert a single MIDI pitch into two separate numbers, and the other combines two numbers into one. I'll be honest, Caden wrote these so I'm not fully sure how they work. I just know that they do work and that's all that matters.

So it was here I discovered that copying my previous class from my last project wasn't going to be a good solution. It was here that I decided I needed to add a generous amount of Object Oriented Programming magic.

My idea was to take most of the functionality from this class and make a base class out of it that I can extend to the different types of Launchpad. If you aren't sure what I'm talking about, imagine that the Launchpad MK2 is an eagle and the Launchpad S is a hummingbird. Both are birds and perform bird-like actions such as eating and flying, however the Eagle lets out a majestic screech while a hummingbird hums? (I'll be honest I don't know what sound a hummingbird makes). The idea is to make an object that handles all the things a bird might need to do, and then to create objects that inherit those things from the bird, but also modify or introduce their own functionality depending on what type of bird they are.

Translating this into programming, I have to create a base object for actions that all MIDI devices will need like using a listener, outputting MIDI messages, and things like that. Then, I need to create separate objects for the Launchpad MK2 and Launchpad S since they handle MIDI data differently. I know for sure that more work is going to go into the Launchpad S class since it has to handle translating seemingly arbitrary numbers into X and Y coordinates.

There are several ways I could've done this, but I ended up using an array approach and a whole bunch of if statements (If statements are simple code logic blocks, which see if something is true and if it is, does a thing), along with pre-defined arrays for each row on the Launchpad S.

Forgive my horrible use of white space, it's mainly for making the explanation clearer
The easiest explanation for these is that each array represents a row on the Launchpad (indexed with bottom being 1 so it's like the Launchpad MK2) and each spot in that array represents what column it is. For example, note 17 is row 7, column 2, or (2,7). I know computers start counting at 0 but because Launchpads start at 1, I will be 1-indexing in the MIDIHandler class (I will be 0-indexing everywhere else though).

Prepare for Spaghetti, and make it double
Calling this method will return an array containing the row in the 1st position and the column in the 2nd position. The way it accomplishes this is by checking if the note is within a specific range, and if it is, it runs through the row to see if the note is inside and if it is, it returns what slot it's in +1, since I'm starting my Cartesian coordinates at (1,1).

Is this the best solution? Absolutely not. Is it the solution I know how to program? Yes, it is. I'm sorry for subjecting your eyes to such madness, but I promise it works.

Thankfully, the method inside Launchpad MK2's handler is much more graceful.

This is the whole thing

Basically, when you ask for an array of coordinates from the Launchpad MK2, it simply converts the note into a string, grabs the first and second characters of the string and turns them back into notes, and then returns an array with those numbers as row and column coordinates. Super easy, not painful at all. This version of note to coordinate translation is my own method, because I wanted to prove I am capable of writing one.

After some testing, I've proven this successful, and I'll call it good for my MIDIHandlers for the Launchpad MK2 and the Launchpad S as far as note to coordinate translation is concerned!

The final problem with the Launchpad S

This one is more of a complaint about the design choice and how it is going to be limiting in terms of functionality. Remember when I called my Launchpad S the diet Launchpad? Well for whatever reason Novation decided not to include a blue LED in the Launchpad S's pads, so they're limited on the color range they can show to shades of green, orange, red, and yellow. This is way more limited than the Launchpad S's full RGB pads, which can show 127 different colors depending on what velocity value is passed.

This isn't a deal breaker for an initial test prototype, but it is annoying since I will absolutely be utilizing the full RGB capabilities of the Launchpad when it comes time to start putting together a more refined version of the software.

Final test project

So with all of this knowledge and work that I've done, I wanted to build a basic color and dimmer control for Art-Net output using both launchpads. The Launchpad MK2 will be taking on the job of setting the color for one of four lights, and the Launchpad S will take on the job of being the brightness control. It's not a super fancy application but it's simple enough to demonstrate proof-of-concept for MIDI to Art-Net out. Because the whole program is complex enough to be it's own post, I will be writing one on just that project alone and that will be here when it releases!

For now, thanks for reading! Keep on making things!
-Will

Welcome to my Blog!

Saturday, May 16th,

Welcome to my blog!

My name is Will, and I have too many hobbies. These range from music production to 3D modeling, Java programming to sewing,  and writing to stage tech. Almost all of my hobbies include making in some way, because I find that my worries fade away as I create, and working with my hands is what makes my life enjoyable.

I'm currently studying Electrical Engineering at the University of Utah (though thanks to the COVID-19 pandemic those plans are a bit wobbly at the moment). I'm also studying for a CCNA (Cisco Certified Networking Associate), and I'm Dante level 1 certified with plans to pursue levels 2 and 3. I currently work on a Networking Operations helpdesk, a job I really do enjoy. I'm also a tool mentor for a makerspace on the bottom floor of my dorm building, Lassonde Studios.

Needless to say, almost every aspect of my life is encompassed by STEAM (Science, Technology, Engineering, Art, and Math). If you enjoy that sort of thing, hopefully you'll find this blog is for you. Even if you're just a bit curious about learning more about technology I hope you'll enjoy the posts here. I hope to create a documentation of my various technological ventures so that readers are able to see what I'm creating, and maybe even learn a thing or two for themselves!

It's a pleasure to meet you! I hope you enjoy reading this chronicle of crazy adventures in making things!

How did we get here?

It's the summer of 2020. I originally planned to take eight credit hours at the University of Utah but due to COVID-19 those plans kind of fell through.

I was one of the fortunate ones to maintain employment, so at least I've got that. But all of the events I had planned out for the summer got cancelled. One of these activities was the Above & Beyond Acoustic III concert, which I was going to go to in June. Additionally, I hear I won't be doing stage tech for Snowbasin's Blues Brews and Barbecue like I did last summer, which really sucks. But maybe this time is a blessing in disguise, but only if I put it to good use.

I now face a summer off, but it wouldn't be any fun if I didn't plan out a whole bunch of projects to try and complete before the school year starts up again.

Summer goals.

I was challenged by my dad to draft up a checklist of things I want to do before the summer ends. I did so on the whiteboard in my room at home, however to save on time and clarity I'll give you the abridged version.


1. Cisco CCNA Class

For those of you who don't know, the CCNA is an associate's level networking certification offered by Cisco, the largest networking company in the world (last I checked, correct me if I'm wrong). I'm currently enrolled in an online class to teach everything that would be on the certification exam, which is mostly networking fundamentals. Even if I don't get certified this summer, I'd like to make my way through the class.


2. Save up for a Portable Rack Case

I should clarify that I'm saving up for the materials to build one, not to buy one. I recently came into possession of a Cisco 2951 router and Catalyst 3650 network switch, and while these look okay being stacked onto my desk, I'd like to build a rack to mount them in. My first thought was to buy a standard stage rack box on wheels, but I ran into two problems with this. First, they were way too tall and expensive, and second, they wouldn't fit the router.

Standard mounting depth for stage racks is 19". This works great because stage equipment isn't longer than 19".  The switch would fit in a pre-built rack just fine, but the router is exactly 19" and if I bought a rack with that depth, there wouldn't be room for optimal air-flow to cool the equipment.

My solution is to build a custom rolling case with a 22" rack depth. I've already started design for this project in Autodesk Fusion 360, my CAD (Computer Aided Design/Drafting) software of choice.

3D render of my rack case, not including hardware, mounting rails, or clasps.
There will be more info on this project when I get to it, but I'm not starting it until I have access to the makerspace in Lassonde when I move out again in the fall. However my goal is to save enough money for the hardware and materials required to build this thing so I'm able to do so when the semester starts up again. My goal is in the ballpark of $600 for supplies and parts.

3. Build Lab Configuration

This one kind of goes hand in hand with 1 and 2, which involves building the configuration for all the devices in my network lab. The explanation for how I plan to do this is a bit complicated so the details will come in the post about that project.

4. Java Lighting Control

This is a project I've been ruminating about quite a bit, but I want to build my own custom lighting control software in Java. There are many motivations for doing this and I've planned quite a bit out so far, but I've still got a long way to go. This is the project that I feel closest to completing right now, and I'll cover as much as I can on this project in the next blog post!

5. Custom Lighting Fixture with Arduino

In addition to building my own custom lighting control software, I also want to build some custom lights to go along with it. I'm going to base the project off an Arduino Uno but make the whole circuit as small and inexpensive as possible. 
 

6. Produce 3 songs by the time I move out

Whether or not I actually finish this one is to be seen, but I want to write and produce 3 songs by the time I move out. Lately I've been in a rut with music production so this one might be a challenge.


7. Turn 19

This one is more of an inevitable milestone but I put it on here anyways.

Closing

So there you have it, my abridged goals for the summer of 2020. I'll hopefully keep to this blog thing going and document the process of building all of these things, and maybe even surprise myself and finish them all.

I will try to post on a regular schedule rather than when I write articles, so I'll leave the original date of the articles on when I wrote them but post them every Tuesday and Friday so keep posted for those! For now I think I'm going to wrap this up. Thanks for taking the time to read through it! Keep an eye out for a post about the Java Lighting soon, I'm sure all of the other projects will follow!

Keep Making Things,
Will