IntroductionWe've all experienced the frustration when a movie or show has a very quiet scene that you can barely hear, forcing you to crank up the volume, only for the next scene to blow your ears out without any warning. Well, maybe you like that style of audio mixing because you've got a slick home theater setup without any neighbors to submit noise complaints. But for the rest of us who would prefer to keep our eardrums and not annoy our neighbors, it's quite frustrating at times, always having to be on top of the volume control. If only there were a solution! Good news, there is! It's called an audio compressor, and a quick Google search shows they only cost... hundreds or thousands of dollars!? And they require a rack mount?? That's not what I'm looking for! From my own research, there really aren't any consumer level compressors for sale, at least not that I can find! Everything seems to be either for recording studios or audiophiles, who are already spending loads on high quality audio equipment. But most of us aren't audiophiles, and don't really care to get the flattest response with minimal distortion. Heck, most of us can't tell the difference between a $30 and $3k set of speakers without them being side-by-side. There are other solutions, of course. The best would be for movies to have a mix for home theater use, but I doubt that will happen any time soon. There's also software solutions, some TVs support features like Roku's "Volume Leveler" on their newer models. However my Roku TV is old enough that it doesn't support that feature. Some AV receivers support that too, but I'm using a cheap soundbar that only has basic volume control. I was feeling a bit hopeless about it, until I remembered that I'm a hobbyist who likes building circuits! So I'll just build one, how hard can it be? Circuit DesignI had a basic understanding of how audio compressors work. The audio signal goes through a cable between my TV and soundbar, represented as some changing voltage. All I had to do was splice into that audio cable, add a circuit to measure the voltage amplitude, and use that to control some attenuator for the output. I've built amplitude detector circuits before, but I was less familiar with how to dynamically control the attenuation. My first instinct was to use some kind of op amp, and somehow change its gain with the amplitude signal. But if you've ever worked with op amps before, you know the gain is set by resistors. Take the classic inverting op amp circuit: The gain is given by (V_OUT / V_IN) = (R_F / R_IN). For an audio compressor, we'd need to adjust either R_F or R_IN, but it's not exactly easy to change a resistor's value. I did consider a potentiometer driven by a servo, but that's more work than I thought was reasonable for this project. Some analog circuit should be sufficient, no need to add microcontrollers. I discovered you can actually buy Voltage Controlled Amplifiers (VCA), which appear to act similarly to op amps, but they've got an additional input for the gain voltage. Sounds like exactly what I was looking for! I even found this great compressor design by Matt Rottinghaus that makes use of a THAT 2181, a type of VCA. However I found his circuit fairly complicated and a little hard to follow. I also didn't have that VCA on hand (or any VCA, for that matter), and I wanted to make something with components I had on hand. So I eventually decided again using a VCA, and kept researching alternatives. I came across this relatively simple circuit from w2aew on YouTube. His circuit uses diodes as attenuators, since their impedance effectively decreases as more current passes through them. After acquiring the signal amplitude, that controls a BJT to drive current through a couple diodes. More volume means more current through the diodes, which means less impedance, resulting in the output level being reduced. His demonstration of the circuit had some excellent results, so I built it on a breadboard. Unfortunately I wasn't able to get nearly as good results. His video shows the input signal amplitude range from 200mVpp to 3Vpp, and the output amplitude was almost constantly at 40mVpp. When I built the circuit, the output amplitude closely followed the input amplitude until around 1Vpp. Above 1Vpp, I started getting pretty severe distortion of the output. The top of the output waveform started clipping around 0.2V, which is the forward voltage of these diodes. I'm not certain why my circuit resulted in wildly different behavior. The fact that the video shows great results indicates I must have built my circuit wrong, or something like that. I've never seen diodes used as attenuators like this before, so I wasn't really sure how to debug it. I decided to keep researching other options. I came across a page from Elliott Sound Productions describing various VCA circuit designs. I found most of their circuits to be fairly complicated, and I didn't really understand how a lot of them worked. Then I came across their circuit using an LED pointing at a photoresistor. It's fairly straightforward, and I fully understood how each component was used, so I felt confident in trying to build it. My initial tests with this VCA circuit had some great results, so I added some components to measure the audio voltage. This is the circuit I ended up with: Components D1, C2, and R5 measure the audio amplitude, and store that as a voltage. That then drives the base of Q1, which turns on the LED. The higher the audio voltage, the more the LED turns on. That LED is pointing directly at a photoresistor, whose resistance decreases with more light. It's part of a voltage divider with R2, resulting in the output amplitude being reduced as the input amplitude increases. This resulted in significantly better results than before! At low amplitude (up to 1Vpp), the output matched the input as desired. As the input voltage increased beyond 1Vpp, the output amplitude remained roughly constant just like I wanted it to! The only problem was a phase shift in the output, but this was caused by C1. I initially added it to AC couple the output, but later realized it was not needed. Above about 4Vpp, the LED was fully turned on, so the output amplitude started increasing again. But I was content with that, it's still a fairly substantial reduction in amplitude. Time to hook it up to my TV, right? Well, no so fast. I'd assumed the audio signal between my TV and soundbar would be in the range of 100mV to a few V in amplitude, and I'd be able to tweak some component values to make this circuit compatible. However the signal level was actually on the order of 1mV to 100mV. The BJT driving the LED doesn't even turn on until 0.4V or so. So I figured the simplest solution was to amplify the input signal with an op amp before measuring its amplitude, then the rest of the circuit remains the same. And this actually resulted in very good performance! I spent a while tweaking component values until I got something that worked well for my setup. Here's the final circuit, along with a description of what each section does. The input is first AC filtered with C2 and R8, which is then passed to the op amp. D2 ensures this voltage is always positive (or at least above -0.2V) to protect the input of the op amp. Since I'm only using a single supply, this also ensures the input voltage is (mostly) positive so it can actually be amplified correctly. The op amp is configured as non-inverting, again because I'm using a single supply. The gain is set by 1+(R6 / R7), or about 50x in this case. The amplitude of this amplified signal is then captured by D1, C1, and R1. That then drives a small current through the base of Q1, which turns on the LED, causing the resistance of R4 to decrease. R4 and R5 form a voltage divider, resulting in the output being attenuated. I was initially using VCC=5V, but discovered the op amp was maxing its output with large signals, and the circuit wasn't able to keep attenuating. I happened to have a 9V supply lying around, so I used that instead and that fixed the problems. After some thorough testing with my TV, I was very happy with the results! Loud parts of shows are significantly reduced in volume to a much more comfortable level, no need to adjust the volume at all! Final ImplementationUntil this point, I'd been prototyping on a breadboard. But I wanted something more permanent, so I pulled out my box of protoboards. I spent a while playing with different arrangements until I found something suitable. Here's what the layout looks like: Note that I had to build the circuit twice, since there are left and right audio channels. The LM358 is a dual channel op amp, so I only needed one chip. I also wanted to ensure the photoresistors wouldn't be affected by the LED of the other channel, so I 3D printed some little shrouds to go around each. I spent the next few hours soldering, and gave it a test on my TV. But there was no attenuation at all! Dang! Well as it turns out, there's apparently no standard for which side op amp inputs are meant to be placed. I've always been used to the inverting input (-) on bottom, and non-inverting (+) on top, But the circuit design software I'd been using had those flipped, so the inputs were backwards on my protoboard! That wasn't actually a huge problem, I was able to swap those fairly easily. I gave it another test, and... Success!!! Loud parts are dramatically reduced in amplitude to a comfortable volume, and quiet parts are unaffected, so everything is easy to hear. My main qualitative test was to watch the very first scene of Lost In Space, it starts very quiet, but quickly gets very loud as they crash (oh, uh, spoilers!). Normally I have my TV volume set to around 20% for this show, which is fine for the quiet sections, but sounds like someone's yelling during loud parts. Normally I'd have to reduce the TV volume to below 15% or so to make it tolerable. But now with the audio compressor, I don't have to touch the volume at all! This thing is fantastic! I have noticed there's a very slight 60Hz buzz coming out of the sound bar. You can't hear it at all when there's sound, but it's faintly there when nothing is playing. I assumed it was an issue with the power supply, so I added some capacitors to VCC, however that didn't really change anything. Interestingly, I discovered that placing the compressor closer to to the TV results in more buzzing than when it's next to the sound bar. I'm not certain what the problem is, it could be a number of things, but it's a small enough problem that I'm just going to leave it. If I get annoyed with it, then I'll look into fixing it. I wanted to do some quantitative tests too. I hooked it up to a function generator producing a sine wave with variable amplitude and frequency, and measured both the input and output with my oscilloscope. I began with a frequency of 1kHz, and swept the amplitude from 0V to 5Vpp while recording input and output amplitudes. This gave the following response curve: Up until about 30mVpp, the output matches the input. Between 30mVpp and 300mVpp, the slope of the line is decreased, which is where the attenuation occurs. At 300mVpp, the op amp maxes its output. This prevents the LED from getting any brighter, resulting in maximum attenuation.
The attenuation slope may look subtle on this plot, but keep in mind it's a logarithmic scale. At 300mVpp on the input, the output is reduced to around 70mVpp. That's 4x lower in amplitude, meaning 4x lower volume! And as my qualitative testing showed, it's absolutely sufficient for watching movies and shows. I also swept through a range of input frequencies to see whether it caused any kind of frequency dependent distortions. Human hearing is typically in the range of 20Hz to 20kHz, so my goal is for that range to have a flat response. And oh boy, is it a flat response! It can go all the way up to 1MHz before seeing any reduction in amplitude. On the low end, it gets to around 5Hz before the output amplitude reduces. I think this is mostly a result of the C2/R8 and C1/R1 pairs acting like high-pass filters, they have a cutoff frequency of just a couple Hz. And there's no audible distortion when watching movies and shows, it sounds just as clear as without the compressor! I'm planning on creating a box for this to protect it, and to prevent my cat from getting at it. It may also benefit from some metal shielding, that might help with the 60Hz buzzing. If I were to do it again, I would also consider swapping some resistors for potentiometers to dynamically change its behavior. Overall, I'm very happy with this! I managed to save a heck of a lot of money over buying one of those expensive audiophile compressors. At scale, these could probably be produced for a few dollars each. It did occur to me that I could make these and sell them, but everyone has a different audio setup that I can't control for. So instead, I'm publishing this for anyone to use and modify as you like! If you decide to make one for yourself, let me know how it goes! IntroductionI'm a PC gaming enthusiast, and I follow a handful of related YouTube channels, one of which is Linus Tech Tips (LTT). A few years ago, they built a computer into a desk that looked really cool! I had recently gotten into woodworking with a small collection of tools, so I decided to build a desk PC of my own! DesignThere's a lot that I liked about the LTT design. It's a fairly simply construction without any weird contours, there's a lot of space to put components, and the glass top makes everything easily visible. So I ended up following their general design, but changed some of the things I didn't like (I'll get to those later). The first step was actually figuring out the glass top. It's possible to order custom sized glass panes, but they get expensive quickly. Another option is to buy a used glass-top table that's close to the right size. This saves a lot of money, but means the desk size is constrained to whatever you can find. For me, the ideal size was roughly 3x5ft. I did consider 2x4ft, but it really wasn't enough space for components to fit like I wanted, and I also just appreciate having more desk space. I kept searching Craigslist for a couple weeks until I found this Ikea GRANAS dining table pop up. It's a little smaller than the 3x5ft I was looking for, but it was definitely big enough. And I was tired of waiting, and they were selling it for cheap, so I bought it! Up until this point, I had tinkered with a few different layouts in CAD with various glass dimensions. But now that I had finalized the glass, I could finalize the layout. This is what I had come up with in my CAD software: This is where my design starts to differ from LTT's. I wasn't a fan of how they placed their motherboard (MOBO), graphics card (GPU), and power supply (PSU) off to the right. Those are the core parts of a computer, so I feel they should be centered. In addition, I made space for some extra storage drives on the left, and an uninterruptible power supply (UPS, basically a battery for your computer during blackouts) on the right. The whole desk is supported by a couple of IKEA drawers, because I can never have enough storage space. I was planning to build the whole thing from a sheet of MDF, so I extended the back of the bottom piece a few inches to create a shelf for some cable "management" (just throw cables back there and don't look at it!). LTT cut out the front rectangle, but I decided to keep it. I initially used it as a shelf for storing things I use frequently, with my keyboard and mouse (KB/M) sitting on the glass above it. But I found this to be a little uncomfortable, and I was frequently moving my KB/M around as I worked on stuff, so I eventually put my KB/M on the shelf instead. The CAD model was a useful tool for playing with layouts, but it's sometimes difficult to get a sense of scale. So I made some cardboard cutouts of the components and moved them around on the glass table. This was a great way to get a sense for the spacing between components, and to verify the dimensions in my model were actually correct. Computers have components that get hot, so cooling is pretty important. In my initial design, I made space for several intake fans at the front. My original plan was to have 10 intake fans and exhaust all the air out the back, but I eventually changed this. Given all the components on the back wall, adding vent holes would have been tricky. 10 intake fans also would have been excessive, so I moved the 4 side intakes to the front faces above the drawers and made them exhaust fans. Air comes in from the middle, flows outwards, then back out the front sides. In winter, this makes for good hand warmers! LTT created a custom water cooling loop for their system, which I was interested in doing, but really didn't want to pay for. It's hundreds of dollars worth of stuff for really marginal benefits. Sure, it could cool down some components by a few degrees, but that wouldn't translate into any performance benefits for me. Plus water cooling is just a pain to deal with from a maintenance perspective, and it would have at least doubled the cost of the desk for just a little more cool factor. But that's not to say I'll never do it. It's conceivable that I'll want to add water cooling at some point, so I took care to make it possible. Specifically, the exhaust holes are designed to accommodate a pair of 240mm radiators, and the sides are have space for water cooling hardware like reservoirs and pumps. Whether I end up adding water cooling is up in the air, but it's possible! I later updated my CAD model to include my KB/M and monitors (more on those later), which ended up very similar to the real thing! ConstructionWith the design and layout finalized, it was time to start building! Like I said, I wanted to construct the whole thing from a sheet of MDF. I did consider plywood, but the good stuff is fairly expensive, and it has a tendency to chip and splinter in my experience. Plus I hadn't really used MDF before, so it was a good excuse to get some experience with it! I bought a 4x8ft sheet of 3/4" MDF from Home Depot, which had enough area to make all the parts I needed. And I quickly learned that MDF is quite heavy. I don't know exactly what the weight was, but I think it was around 100 pounds! That was quite the struggle to move by myself, I would definitely recommend having a friend help! I eventually got it home and started cutting out pieces with a circular saw. Once I had all the side pieces cut to length, I did a quick test layout to verify my dimensions. All was looking good! I also wanted to verify that the air would flow how I expected. It was important that there was sufficient airflow everywhere inside, so I set up this test with all the intake fans in position. I dropped in little pieces of paper, which got blown around by the fans. I also did a smoke test by lighting a piece of scrap wood on fire, and placing the end of it at various location to see the airflow. This worked pretty well, and I could see decent airflow everywhere! My next step was adding fan holes. In hindsight, the best way to do this is with a hole saw. However I rarely make big holes, so that idea didn't occur to me. Instead, I used a handheld router. I wasn't very experienced with routers, so I made a fan cutout on a test piece first. After drawing a circle of the right size, I cut out a slightly smaller circle with the router, then slowly approached the line until I was happy with it. I then wont over the edge with a roundover bit, which made a nice smooth transition. Turned out pretty well! Now that I was feeling more comfortable, I just had to repeat it 10 more times on the real parts! Fortunately I didn't make any major mistakes, they all turned out fine. I also learned how much dust routers can create, this shirt I was wearing is normally dark blue! Definitely glad I had a good dust mask for this one! As I was cutting these parts out, I did come close to ruining a part and injuring myself with the router. In order to get the router bit deeper into the wood, some handheld routers have a mechanism to plunge the bit into the material. But mine did not, so I was making helical plunges like you'd see a milling machine do. I was taking it really slow, so I didn't have any issues there. But at one point, I had the idea to drill a hole first so I didn't have to plunge. The largest drill bit I had was 1/4", and my router bit was also 1/4". I did my best to hold the router steady in the middle of the hole, but I don't have the strength and precision of a milling machine. When I turned on the router, the bit was not perfectly centered (obviously!), so the bit caught on one side of the hole. Because it wasn't up to speed, rather than cutting that material, it shoved the router to the side. The router bit then caught on that edge, shoving the router again, repeat. And because the router was speeding up very quickly, this became very violent before I could react. In a fraction of a second, the router jumped out of the hole, and its momentum caused it to twist towards my arm. Fortunately it didn't touch me, but that was pretty scary! It also ended up creating a large gouge in the piece, but it was all contained in the area I was cutting out anyways. So that was pretty stupid of me. Lesson learned, don't start up the router while the bit is touching stuff! Once I finished, I did a test fit with the fans, and it turned out great! I needed 4 more holes in the bottom of the desk to add some wiring grommets. This would allow me to connect stuff from the front shelf to the motherboard by routing underneath the desk. And I finally remembered that hole saws exist, so I used that instead of the router. My cheap hand drill struggled with this, but it eventually succeeded, and was a lot safer than the router. I also bought some of these cable management tracks that I was planning on sticking under the desk to prevent cables from dropping. They came with some double sided tape for mounting, which is actually really strong, it's basically permanent! However, I didn't want these to be permanently attached in case I needed to put the desk on the ground (such as during transit). So I've omitted them for now, I don't mind a bit of caple droop where I can't see it. One option is to attach them with screws, but I didn't get around to that. I was getting to the point where I needed to make cutouts for all the components, so I took apart my computer and did a test fit. Everything looked good! There was a few more things to do before I could start gluing all the pieces together: add cutouts for components with external connections. This included the motherboard, GPU, PSU, UPS, and front IO. For the front IO, I bought a panel that's designed to go into a 5 1/4" bay of a normal case. It has multiple USB ports, a couple SD card slots, plus a couple other connectors I've not heard of before. As you can see in the photo above, this went on the left side of the front shelf. I like symmetry, so I wanted something else on the right to match it. My old computer case had a CD drive in it, so I figured I could use that. Yeah, I know, CDs are outdated, no one uses them any more. But I already had it, and figured I could prevent more E-waste by reusing it. Plus I have actually found a use for it like every other year, so it's been useful! I made these cutouts with the router as well. Rather than doing it by hand, I clamped a makeshift fence to the part to guide the router along the top line. This worked really well, there was minimal cleanup to do along that edge afterwards. However it did make the corners rounded, whereas I needed them to be sharp. I just trimmed these down with a file, and eventually got a nice fit with both parts. I also added the power button on the left side. For the components along the back wall, I did pretty much the same thing by making cutouts with the router. The PSU is secured in place with screws on the rear, so I was careful to create these tabs for those screws. The UPS I bought is intended to sit on a desk, so it doesn't really have a way to mount it. But I wanted it in the desk. It has a taper to it, so it couldn't come out of the cutout. But you could push it further into the desk while plugging stuff into it, so I 3D printed these little brackets that screw into the bottom. These do a good job of preventing the UPS from going anywhere. The GPU was a little more complicated than the other parts. It's normally secured by the PCIE slot on the motherboard, and the side bracket. However I wanted it to be mounted separate from the motherboard, and instead connect with a PCIE riser cable. This required me to elevate the GPU to make space for the cable, so I put a couple wood blocks under it. This also meant the only way of securing the GPU was with the PCIE bracket. With the router, I carved out a thin cavity in the rear side panel in the same shape as the bracket. I then added a couple screws on either end of the bracket, which does a decent job of holding the GPU in place. It probably won't work well if the desk gets inverted, but I don't intend on doing that any time soon! And with that, I could finally start gluing everything together! Those holes for the wiring grommets actually proved to be quite useful, I could put my clamps through them to hold the inner pieces. Here's how it looked after all the glue dried: If you recall from before, I also wanted to include a handful of extra hard drives for storage. I ended up buying 4x2TB drives that I later configured as a RAID 0 array for 8TB of storage! In order to mount these securely, I constructed this bay that just screws into the bottom of the desk. Before I could begin painting, there was one more thing I needed to add. You see, I really like putting LEDs on stuff. It's not an addiction, I swear! I can stop anytime I want, I just don't want to stop! LTT put LEDs on their desk too, and I ended up copying how they did it. There's an extra strip of wood glued onto the top edge of the side pieces, and the LEDs are mounted on the bottom of these strips pointing downwards. This creates an even illumination along the inside surfaces, which looks awesome! This is the last strip being glued into place: That was the last piece to be glued, so it was now ready for painting! As any good painter will tell you, good paint jobs are all about the preparation. And my preparation actually began with a couple tests. If you research properties of MDF, you'll hear a lot of people saying that it soaks up water like a sponge and inflates when exposed to water. A lot of sources I saw recommended using sanding sealer to help with water protection, so I bought some. I was curious to test this out and see how significant the effect is, so I applied it to a test piece and compared it to paint versus nothing. I learned that it's really important to sand between the layers of sealer, otherwise it creates a very rough surface. I poured some water over the piece, and was happy to see no inflation. But I also so no inflation of the bare MDF. I grabbed a scrap piece and dunked it into a glass of water for a few minutes, and almost nothing happened. The thickness only increased by a few thousandths of an inch, I wouldn't exactly call that "inflating". Maybe it's a slow effect, or maybe I just have water resistant MDF, I don't know. Sounds to me like the sanding sealer is not really necessary, especially if the MDF is painted. But I had a whole container of it, so I decided to use it anyways, couldn't hurt. I first sanded down all the surfaces of the desk until they were nice and smooth. I then added a few layers of sanding sealer, being sure to sand between coats to prevent any rough texture. Once that dried, it was time to actually start putting paint on it! Using a roller, I added a couple coats until it was all even. This is another spot where I differed from the LTT desk. They painted theirs black in order to not make the LEDs overwhelmingly bright. I, on the other hand, don't believe LEDs can be too bright, so I made my desk white for maximum brightness! I was also planning on controlling the LEDs with a microcontroller, so I could program it to have reduced brightness if it was really needed. Once the paint was dry, I excitedly assembled everything and added the LEDs. It looked fantastic! However assembly wasn't as smooth as I'd hoped it would be. For the front IO and storage drives, I manufactured the parts with a slight friction fit. However I didn't account for the fact that paint has some thickness to it, which completely ruined the nice fit I had created. Rather than slight friction fits, they had turned into interference fits (the hole is smaller than the object going into it). For the front IO, this meant I had to hammer them into place, which unfortunately chipped off some paint on the left side. I couldn't hammer the hard drives into their bay, because that would most likely damage them. So I instead used a clamp to slowly push them into place. This wasn't exactly comfortable to do, but it was fine in the end. For some reason I decided to add the screws, even though they were absolutely not necessary! MonitorsIf you've been paying close attention, you'll notice that I had 2 monitors in the picture above, but my design actually included third monitor. That was intended to be the Odyssey G9, which Samsung had recently released. I really wanted to buy one, but I couldn't find them in stock anywhere. Supposedly there was a manufacturing defect in the early batches, and I suspect Samsung was working to fix that for while. But I eventually found it restocked with a big discount, and I instantly bought one. It was delivered a few days later, and holy moly is this monitor huge! This one monitor is bigger than both of my old monitors combined! I got it set up on my desk, it takes up quite a lot of space! Importantly, this monitor is not to replace my old monitors. Oh no, I can never have enough monitors! I bought a tall dual-arm monitor stand to hold my old monitors above the new one, here's the final setup with an example of how I utilize all the monitors while doing homework: Another feature I added was a script on my computer that updates the desktop wallpaper to a live satellite view of Earth. This runs every 10 minutes, and grabs the latest image from the GOES-East satellite. I made the code available on this GitHub page if you're interested in trying it out for yourself. Note that it's designed for my specific monitors, so it will require tweaking for a different arrangement. Component ListFor anyone curious what components I have in my system, here's the list of parts:
FansWhen I first started looking to buy fans, I hadn't realized just how expensive they can be! Some of the nicer quality ones, such as those from Corsair, can go up to $40 per fan! For my desk, that would have been at least a couple hundred dollars just to blow some hot air! I kept researching, and eventually found this 6-pack from a company called upHere for just $45! And they're not even bad, they actually push air pretty well with no annoying whining, and the LEDs are diffused nicely. They don't light up the fan blades like their product images show, it's mostly just the hub, but I still think it looks cool. And they come with a connector hub so it's easy to connect to the motherboard. All the fans are at the front, meaning they're prone to people sticking their fingers into them. So I wanted to add some mesh over the front of them for finger safety, as well as dust filtering. I ordered a pack of 120mm dust filters, but I wasn't really happy with them. They blocked a lot of airflow, and made the lights on the fans appear very dim. So I started looking into alternatives. My next idea was to use screen door mesh. I ordered some material and cut it out to size. This was much better for airflow and light, but the mesh was very flimsy because I couldn't tension it properly. So I kept trying alternatives. The next idea that came to mind was to 3D print a mesh! Then I could customize the spacing and thickness to get something I was happy with. After a couple tests, I got something that worked well for all my requirements. It's modelled as a solid rectangle with holes in the corners, then I changed my slicer settings to create the mesh pattern. I reduced the number of top and bottom layers to 0, set the number of perimeters to 1, and used a rectilinear infill with 30% density. The total thickness is 0.8mm, printed at 0.2mm layer height in PLA. It's really important to have minimal squish on the first layer, otherwise it blocks light and airflow. So I raised my nozzle a bit, which unfortunately resulted in a few strands of the first layer not sticking well, causing them to get pulled sideways by the second layer. Though this is only a visual flaw, they still work just as well! And here's my comparison between each of the different meshes I tested out, along with their results for my requirement categories. I was happy with the 3D printed one, so I stuck with that. These have also proved to be fairly effective as dust filters. Over a few months, the front shelf accumulates an obvious layer of dust and hair, but there's almost none inside the desk. The meshes end up with a layer of dust that can be cleaned off, but not super easily. Removing them requires unscrewing the fans, which is more of a pain than it's worth. So I just scrape what I can off the front, which does leave some dust trapped in the mesh, but it gets most of it. Here's a comparison between a dusty mesh (right) and clean mesh (left): As I said, the fans came with a hub to easily connect them to the motherboard, but I wasn't really happy with it. It took up a lot of space, and the pre-programmed animations weren't what I wanted. And my motherboard doesn't have an ARGB header, so I couldn't customize it easily. So instead, I used a microcontroller! These fans are actually really easy to control. There are 2 connectors, one for controlling the fan, the other for the LEDs. Let's start with the fan connectors, since that's a bit simpler. This is what the connector looks like, and the function of each pin (source): The ground and 12V pins just provide power to the fans. The pulse width modulation (PWM) pin is used to control the speed of the fan. If you're not familiar with PWM, the basic idea is to create a voltage that rapidly jumps between 0V and 5V, usually at least 20 thousand times per second. The more time spent at 5V than 0V, the faster the fan spins. If it's constantly at 5V, the fan spins at max speed (around 1700RPM). If it's constantly at 0V, the fan stops. The tachometer pin indicates the current speed of the fan, which is the result of a hall effect sensor on the fan hub. The rotating part of the fan has a couple magnets that pass over the hall sensor, which measures the magnetic field created by them. When the magnet polarity changes, the hall sensor changes its output voltage. This is a digital sensor, so the signal jumps between 0V and 5V as well. The faster these pulses occur, the faster the fan is spinning. The LEDs are a little more interesting in my opinion. Something important to note is the difference between normal RGB and ARGB (addressable RGB) LEDs. Normal RGB devices use a 4-wire connector, and all the LEDs are the same color. ARGB devices use a 3-wire connector that looks almost identical to the 4-wire connector, and allows each LED to be different colors. These are what the LED connectors looks like, and the function of each pin (source): The fact that these 2 different types of LEDs use the same connector boggles my mind, these should absolutely be different from each other. Connecting an ARGB device into a normal RGB header can kill the LEDs. And this connector is also really easy to plug in backwards, which may not cause damage, but can waste your time as you figure out what the problem is. Ok, let's put my gripes about this connector aside and talk about the LEDs! It appears to me that most ARGB devices use the WS2812B for the actual LEDs. I'm not certain about they, but they use the same communication protocol, so I can only assume they are. These LEDs are very popular among maker communities, so they're very well documented and easy to use. The 5V and ground pins provide power to all the LEDs, then the data pin goes just to the first LED. The data signal looks a lot like a PWM signal, where a short duration pulse indicates a binary 0, and a long duration pulse indicates a binary 1. If we take a look at the WS2812B datasheet, this is what those pulses look like: Each LED uses 8 bits for each color (red, green, and blue), or a total of 24 bits of color data. Once the first LED receives its 24 color bits, it passes the rest of the data onto the second LED. Once that gets its 24 bits, it passes the rest of the data to the next LED, and so on. This data is sent very quickly, 800 thousand bits per second! Each fan has 8 LEDs, so all the data can be sent in just 240 microseconds! After sending no data for the reset period of another 50 microseconds, the LEDs are ready to be updated again. My first implementation used an Arduino to control the fans, making use of the FastLED library (it's very popular for these kinds of projects). My code just set the LEDs to a rainbow pattern, which worked perfectly. As I was playing with it, I set the brightness really low on the LEDs. They change their brightness by just flashing really quickly, which normally isn't visible. However because the fan was spinning, this meant the blades were illuminated very briefly at some point in their rotation. The fan speed happened to be close to a multiple of of the LED flashing rate, so this caused a strobing effect on the fan blades. This gave me an idea! What if I were to intentionally turn the LEDs on and off at just the right time so the fan blades were always illuminated at the same location? After a couple hours of writing and debugging my code, I got it to work! In this photo, the fan on the right is stationary, and the fan on the left is actually spinning! The brief pulses of light just make it appear to be stationary, but it's actively pushing air through it! Here's a brief explanation of how the code works: The tachometer is used to measure the fan speed. The sensor pulse durations have to be averaged, because they tended to fluctuate a bit, but the true fan speed was very steady. Once the fan speed was measured, the LEDs get turned on very briefly, then off again. It then waits for the fan to rotate 1/9th of a revolution, because there are 9 fan blades, then briefly turns the LEDs on again. The fan speed is measured constantly, so even if the fan speed changes, the blades appear to remain in the same location. Because I'm averaging the tachometer pulse durations, this causes a fun effect when the fan speed changes. If the fan speeds up, the blades appear to slowly catch up due to the strobing rate being too slow. If the fan slows down, the opposite effect happens. I was mesmerized by this effect, it worked so well! The only downside is that it's fairly dim, because the LEDs are only turned on very briefly. For this reason, I've not implemented it into the final code since it's too dark to see, but it's still super cool anyways! ResultsThe final implementation looks very similar to my initial designs, so I'm very happy with that! And my love for LEDs is very well satisfied, I could stare at my desk all day long. On top of that, the amount of monitor real estate I have is fantastic for the stuff I do, it's hard for me to use any computer with fewer monitors. I'm super happy with how this all turned out! Another benefit of the glass top with white paint is that I can use my desk as a whiteboard! I really like having whiteboards for making quick sketches or writing equations, it's great for doing homework! One other feature I considered adding is "smart glass" to the glass top. If you've ever seen one of those fancy conference rooms with windows that turn opaque for privacy, that's what it is. I thought this would be fantastic as a whiteboard surface that can be toggle on/off!
More accurately, it's called PDLC glass, or polymer dispersed liquid crystals. The idea is exactly the same as any other liquid crystal display, except it's one big cell rather than many small pixels, and there's no backlight other than whatever is behind the glass. Under normal conditions, the liquid crystals are randomly ordered, causing light to be reflected in all directions. But when a voltage is applied across it, all the crystals align with each other, allowing light to pass through. There are other ways of creating smart glass, but this seems to be the most common. You can order these as films that are applied to a glass surface, there's a number of companies that sell it. However that's when I learned just how expensive this stuff is. If I wanted to cover my whole top surface, it probably would have cost around $1k. On top of that, they require high voltage to operate, which I didn't really want to deal with. So I've not included it, but if I ever build a second version of this desk, I'll certainly consider it again! And that's all I have on my desk! I've been using it for over a year, and I'm very happy with it! It's always been a joy to use, especially with all the unicorn vomit, that makes me way happier than it should! I've not had any major issues with it, except for a few small gripes here and there. I've considered building another one in the future to address those issues, but that won't be for a while longer. I'll keep using this one for the foreseeable future! IntroductionThe Fall semester of 2019 had just started, and I was sitting in class when I got a call from my mom. My brother had a brain tumor. Long story short, everything turned out well! But it was a pretty stressful period, with him needing to have brain surgery to remove it, followed by a few months of chemo and proton therapy to destroy the remaining parts of the tumor. Of course, he had MRI scans performed so they knew where the tumor was located and how big it was. Here's one of the scans: It was in the front-left of his brain, and had grown to roughly 7cm in diameter, about the same size as a baseball. That's pretty huge! In terms of volume, that's roughly 1/8th of his total brain, so he's decided to adopted the nickname 7/8. Yeah, he's still the same person :D As we were looking at the scans, I was thinking it would be cool to have a physical model of his brain with the tumor in it. I was working on my new 3D printer at the time, so I figured I could 3D print it if I could create a 3D model! I asked the staff at the hospital, and they were happy to give us a copy of the MRI scans. I got to work! Warning I've included some images in this post that you may disturbing. There's no pictures of the surgery or anything like that, it's mostly just images and renders from MRI scans. However some of these images and renders can be a bit creepy, I even made myself uncomfortable at times. If you're not comfortable viewing medical images, I'd recommend skipping this post. The content above is enough to get the idea of this project, the rest of this post is just about how I created the 3D model. Brain ModelCreating the model was the most difficult part of this project. They gave us a CD with the MRI files on it, so I loaded it up. The CD also contained software to view the MRI scans, which gave me images like the one above. But I needed a 3D model, not pictures. The MRI viewer allows you to scroll through layers of the scan, in this case from the bottom to the top of the head. My first thought was to grab many of these image layers, then import them into my CAD software (SolidWorks). I could then trace the perimeter of each image, and create a loft feature between each of the layers (a loft just connects 2 different cross sections together). I gave this a test with 2 adjacent layers. Importing and positioning the images in SolidWorks was easy enough, the hard part was tracing the outside of each image. One option is to manually trace the perimeters, but that would take forever. Fortunately SolidWorks has an autotrace feature, where it evaluates the image to find the edges, and automatically creates lines along those edges. I tried it out, but I wasn't exactly pleased with the results: This was about the best I could get. The main problem is that there's no hard boundaries in the image, it's smooth transitions everywhere. Autotracing features like this really don't work well with soft boundaries, so the computed contour is questionable at best. Regardless, I did the same autotracing with the adjacent layer, and removed all the extra holes inside the main contour. I tried running the loft tool between these 2 sketches, but it refused to create a loft due to the result creating self-intersecting geometry. That's mostly caused by each contour having concave regions in different places due to the autotrace being imperfect: I did consider just getting the overall shape without any of the spaghetti texture, but I wasn't content with that. It would have just looked like a ball with a cavity like the Death Star, I wanted the final object to obviously be a brain. I convinced myself that traditional CAD software like SolidWorks wasn't the right solution, so I did some research. I eventually came across some software called 3D Slicer (not to be confused with Slic3r, the slicing program used in 3D printing) It's a free and open source program used for medical research, and it has the ability to read MRI files and convert them into 3D models! Perfect! I downloaded it and started playing around. It took me a while to figure out what the heck I was doing (actually a couple months of periodically working on it), so here's the outline of the process. The MRI scans are stored in DICOM files (Digital Imaging and Communications in Medicine). Slicer can load this DICOM data, which first needs to be imported from wherever it's saved on your computer. In my case, the MRI files I had contained multiple scans, so I just select and load them all (again, I didn't really know what I was doing, just found a method that worked for me). Slicer gave me a few warnings and errors about some of the scans, but I just ignored them and had it load what it could. After loading the DICOM data, Slicer didn't do anything. I expected it to automatically display something, but it turns out you have to manually specify what to view. The top left has a drop down menu for selecting various tools, and I needed to select the View Controllers. Then under each of the slice controllers, I had to specify which scan to view (again, because there were multiple scans), then enable each slice to get the 3D view. Then I could finally see the MRI scans! The sliders on the slice controllers allowed me to sweep through the entire head along each axis, which helped me to visualize it, but that's still not any better than what I had before. That's where I needed a different tool, called Volume Rendering. All I had to do was select on the the MRI scans an enable it, which resulted in a 3D render of my brother's head! Cool! As you can see, it was pretty fuzzy all around his head. I discovered the Volume Rendering tool has presets available for different types of DICOM data. One of which was for brain MRI scans, so I selected it, and... AH! CREEPY! Where'd his mouth go!? There's a huge cavity there! Looks like something out of a zombie movie! I'm not sure why the MRI didn't capture that area, perhaps because your mouth is a big cavity? Fortunately the Volume Rendering had a crop feature so I could stop looking at his mouth, it was really creeping me out. That also meant I could look more closely at the brain portion of the scan, and actually see what it looked like in 3D. I set the crop region to remove some portions of the skull so I could actually see the brain. And it looked like a brain! Viewing the scans in 3D is great and all, but I needed a 3D model that I could actually print. As I said before, Slicer has a tool for that, but I first needed to remove everything that wasn't the brain, otherwise it would include other parts of the head. After some more research, I learned that Slicer supports extensions, and there are actually a few specifically for extracting just the brain from the head. The one I ended up using is called Swiss Skull Stripper, which did a good job of removing everything except for the brain. Once I had it installed, I could select it from the tool drop down in Slicer (under the Segmentation category). I then just had to select a few settings, including the input volume (the same one used for Volume Rendering), and the output volume and mask (I created a new one for each). I'm not sure what the Atlas settings are for, but I just ignored them. Once set up, I clicked Apply, and it ran for a minute. Once it finished, I was expecting it to show the brain, but nothing happened. Instead, it creates a new volume (you know, like I told it to!) that I had to manually enable. And it did a fantastic job! As I understand it, the extension generates a 3D mask from the input volume, which it then uses to exclude any parts of the volume that are not contained within the mask. I took a look at the mask out of curiosity, which looks like a piece of voxel art. And this is exactly why I didn't want to do this by hand, there's no way I could get that level of detail without losing my mind. (Heh, get it? I'd lose my mind while creating this model of a brain? Get it? Get it? Eh, never mind...) With that, I could finally start creating a 3D model from this! Slicer calls this Segmentation, which is basically where it finds the boundaries of the Volume and creates a solid object from it. This process is actually very similar in principle to the autotracing I used in Solidworks, except it works in 3D and is actually quite decent for this type of object. It's actually relevant to talk about what exactly MRI scans measure. Without going into the physics, they basically just measure the density of hydrogen atoms. The more hydrogen there is in a certain location, the greater the returned signal value. In the Volume Rendering, this density is represented by the color, where blue is more dense and yellow is less dense. Importantly, different parts of the brain have different densities of hydrogen; the surface noodles have relatively high density, and the tumor has relatively low density. So when Slicer tries to find the boundaries of the brain, it's really looking at the density of hydrogen at every location and determining whether it's above or below some threshold that I manually specify. If that particular location is more dense than the threshold, it's included in the solid model, and vice versa. Once every location in the Volume has been checked, it creates a solid object that ideally looks like a brain! To actually do this in Slicer, the Segmentation Editor has to be selected from the tool drop down, then a new Segment is created using the Volume created by the Swiss Skull Stripper. There are several Effects to choose to create and modify Segments, but the first one I used was Threshold. This creates a 3D object using the process I just described, and created this: And that's a 3D model of the brain! I could export this now and send it to my printer, but there are some improvements to be made first. If we take a closer look at the model it created, there are some flaws, especially near the tumor itself. Although the tumor has a lower density of hydrogen, some parts of it have higher density so they were still included. There's also lots of jagged surfaces all around, so these need to be smoothed out. Fortunately there's a smoothing tool for this exact reason. There are different smoothing methods, each of which can be tweaked to adjust how much smoothing is applied. And these smoothing operations can be applied multiple times, which can further affect the results. The first operation I used was the joint smoothing, which got rid of most of the mess without filling gaps between the noodles. I then used the opening and closing methods to get rid of any extra floating pieces and cavities in the model. These didn't get everything, but I was planning on cleaning it up manually later anyways. After these operations, the model was looking really good! It had the right shape, and all the surface linguini you'd expect a brain to have. Except for the back, that was completely smooth. I think this is caused by the fact that he was lying down during the MRI scan, causing fluids to pool up near the back of the head. I spent a long time playing with all the Segment tools, and I could never get exactly what I wanted. A threshold that's good for the front makes the back smooth. A threshold that's good for the back makes the front very sparse. I eventually decided the best solution was to keep it with the smooth back, since that made the majority of the model look good. I was also planning on cleaning up the model later anyways, so I could also manually carve in the grooves if I really wanted to (spoiler, I did want to!). Now that I had finally created the model, I needed to export it into a useable format. For objects like this, STL is one of the most common formats (you're probably familiar with it if you've 3D printed stuff). With the Sementations selected from the drop down in Slicer, expand the "Export to files" section. The destination directory and file format can be selected (STL is default), then just click Export. And with that, I had a 3D model of my brother's brain! Refining the ModelThere's a handful of things I wanted to do to the model before printing it, one of which was some cleanup like I'd talked about before. What I mean by that is just doing things to make it easier to print. Although I used the "closing" tool in Slicer to remove holes, it only removes holes smaller than a certain size. This model still has some relatively large holes inside it, which can't be filled with the closing tool without messing up other parts of the model. So I had to fill these in manually with another program. I chose Blender for this task, because it's a popular modelling software that has the tools I need for this project. For example, I needed to remove these floating pieces from the tumor: My solution was to perform a difference operation with another object. This is one of 3 boolean modifications that Blender supports, with the others being intersection and union. This page on the Blender website has a good illustration of these operations between a cube and a sphere: Union (left) basically adds the 2 objects together, intersection (center) keeps only the parts where the objects overlap, and difference (right) subtracts one object from the other). In this case, I used a sphere that I scaled and translated to overlap with the one of the floating pieces. After applying the difference operation, the floating piece is removed! Similarly, we can use the union operation to fill any holes. I positioned the camera inside the model to view the holes, which you can see in this image. Note that you're seeing the inside faces of the surfaces, so those big blob in the middle are actually big holes in the model. Again, I just moved and scaled the sphere so it overlaps with the holes in the model. After performing the union, the holes covered up by the sphere were removed! This is where things got tedious. There's a lot of these little cavities everywhere that needed to be filled for 3D printing. I spent many hours moving the sphere around and performing these union operations to fill everything in. These holes wouldn't have necessarily been a problem for 3D printing, but I wanted the final object to not have any weird defects, so it was worth it for me. And I'm sure there's some other tool I could have used that would have been faster, but this is what I managed to come up with. However that's not the only tool I used for cleaning up the mode. I also used the sculpting tools to deform and smooth various areas. For example, there were a few areas that had little bits sticking out like this: Are just more artifacts that the Slicer smoothing tools didn't get rid of, but Blender's sculpting tools made it easy to get rid of them: Speaking of which, the sculpting tools were exactly what I needed to fix the back of the model! It felt very wrong for the back to not have any fettuccini, so I spent a long time manually carving in grooves while referencing the the Volume Rendering in Slicer to make it accurate. I eventually got something I was happy with: And with that, the brain was done! However I wasn't ready to print yet, I wanted to do one more thing. Tumor ModelI really wanted to print the tumor as well, and have it slot into the cavity of the brain. So I went back to Slicer and created a new Segmentation. For the brain, I grabbed every part of the MRI scan above some threshold, and this got rid of the tumor. So logically, I could grab every part of the MRI scan below that threshold to get the tumor. This does work, but it also grabs a lot of extra stuff around the edges of the brain. That's where another one of Slicer's tools comes in handy, the scissors. The idea here is to trace out the tumor on each of the perpendicular layer views to remove anything outside of the tumor This does a good job of removing everything that isn't the tumor, though there are still a few weird bits here and there. Fortunately the scissors tool also works on the 3D view, so you can just rotate the camera to any angle and cut from there. After cutting out its shape, the tumor has a pretty jagged surface on the back. After some more smoothing operations, it cleaned up pretty well. Once I finished with that, I exported it as another STL and brought it into Blender for more cleanup. And to my surprise, the tumor actually fit into the cavity of the brain really well! It shouldn't really be that surprising, but after all the smoothing operations, I expected the dimensions of the objects would have changed significantly. Now in reality, I don't think the tumor should actually be as smooth as my model is. However it was really difficult to get anything that wasn't smooth from the MRI scans. Plus I think it helps illustrate that it's not part of the brain, it's something else that doesn't belong. So I actually ended up preferring it having a smooth surface. I could have finished the models there and printed, but I wanted to do just one more thing. If I printed them as is, the tumor would easily fall out of the brain, which could be annoying. I could have fused the brain and tumor together to prints as one solid object, but I wanted the tumor to be removable. So I decided to create an attachment mechanism so they could be snapped apart and back together again. Specifically, I thought of making a buckle. I had recently seen this video from Maker's Muse, where he stepped through the process of designing a buckle, and it sounded like the perfect mechanism for my project! I designed this prototype: The basic idea is that the long arms ar flexible, so they bend inwards as it slides in and out of the receptacle. The nubs at the end hold the buckle in place, but they're relatively shallow so it can be pulled out with just a bit of force. I printed out a test buckle and it performed really well. So I imported both the buckle and receptacle into Blender, and with some more boolean operations, I embedded the buckle onto the tumor, and the receptacle into the cavity in the brain: Although I later decided it would be better if both the brain and tumor had receptacles, and to print a separate double-sided buckle. That made printing the tumor easier, and it would be really easy to replace the buckle if it broke. And with that, I was finally ready to start printing! PrintingThis was more difficult than it should have been. If you've read my post on my 3D printer, I said it's almost always been dependable. However this was the exception. I had a number of problems during the print that took quite some effort to fix. I'll got to those later, the first step was slicing the model for the printer (again, not to be confused with 3D Slicer, the program I used to create the model). I loaded the model, enabled support material, and hit the slice button. It took a couple minutes, but it eventually created the G-code. It just barely fit on my print bed at 100% scale too, so I was happy with that! I took a careful look at the preview to make sure everything looked good. Once I was happy, I looked at the estimated print time: Oh. That's 38 hours. The longest print I've ever done before is 12 hours, so this would be a new personal record! I exporte the G-code and got my printer set up. And that's when the issues started. I went to load the filament, when I discovered there was something clogging the extruder. I couldn't easily fix it, so I had to disassemble the entire extruder just to clear it. Ugh... It looked like a piece of filament had just fallen into the extruder and got stuck inside the heat sink. As I started putting the extruder back together, I managed to drop the heat sink onto my power supply, which caused its fan to stop spinning. Ugh... I took it apart and got to the circuit board of the fan. It's pretty simple, just the coil windings, a resistor, and a black chip. And somehow when the heat sink hit the power supply, it caused the resistor to come loose! It's a surface mount resistor, there should be no way for mechanical shock to cause that to come loose! How do you make such a bad solder connection? Anyways, I resoldered the resistor, and the fan worked fine afterwards. With those issues fixed, I could finally start printing! And I immediately ran into another issue: the MINTEMP error. Anyone who owns a 3D printer can tell you that's a dangerous error to see. That error occurs when the measured nozzle temperature doesn't match the target temperature, and is usually a sign that the heating element or temperature sensor has come loose. Without an accurate temperature measurement, this can lead to a fire. Fortunately this safety feature is built into the firmware to prevent that from happening. I fiddled with the temperature sensor for a while, but that didn't seem to be the problem. It appeared to be an issue with the heater, because it was actually getting cold when MINTEMP triggered. I made sure it was securely clamped in the heater block, but it was still having issues. I suspected one of the wire must have been loose, so I just replaced the heater. That seemed to fix it! And with that, it was finally printing! It was about 2am by this point, so I went to bed. I woke up about 5 hours later to discover that it had stopped printing. Ugh... Interestingly, it was not a MINTEMP error that caused it to stop. The communication between the printer and OctoPrint failed. I figured the printer was working on a very detailed part of the perimeter, and the serial communication wasn't fast enough to keep up due to how many G-code commands had to be processed. This is easily fixed by the Resolution setting in PrusaSlicer. It's found under the Advanced->Slicing settings, and requires Expert mode to view and change. The Resolution setting is used to simplify the geometry of the model. The main purpose of this feature is to speed up slicing time, however I could also use it to reduce the G-code density. I set it to 0.1mm, which caused no visible difference, but the G-code file reduced from 70MB to 43MB. Now, I could have restarted the print, but I realized I could actually resume printing from where it was. The bed was still hot, so it the part was still stuck to it. And because the printer was still powered, it still knew where the extruder was located. This would save both time and filament, both of which I didn't have much to spare. All I had to do was find where it left off in the G-code file, delete everything before that point, then just resume sending G-code from there. I did all that, and surprisingly, it actually worked! And then it promptly stopped printing again. Ugh... Ok, changing the resolution may not have actually fixed the problem. But this time I was watching while it occured, and I figured out what the actual problem was. Every time the printer receives a G-code command, the printer sends back an acknowledgment to OctoPrint. If an acknowledgement isn't received, OctoPrint tries to send the command again. If an acknowledgement isn't returned for several commands in a row, OctoPrint assumes communication with the printer is lost and gives up. And that's exactly what happened. I suspected the communication was just intermittent, and that it was actually working fine most of the time. OctoPrint has a "Fake Acknowledgement" feature that makes it keep sending G-code anyways. When I tried that, the printer kept on printing without problems, so I figured this would only be an occasional problem. However it kept occuring, and I was getting quite annoyed with constantly clicking the Fake Acknowledgement button. So I set up a macro on my mouse to periodically click the button while I hung out nearby. Everything went fine for a few hours, but then the printer stopped again. Ugh... I looked at the log file from OctoPrint, and saw this: To summarize, it was around line 38530 of the G-code. The printer hadn't received line 38530 correctly, so it requested OctoPrint to send it again. So OctoPrint resent that line, followed by the next couple lines. The then printer complained that the G-code lines were sent out of order, so it requested line 38530 again. OctoPrint sent it again, followed by the next couple lines. The printer then complained about a checksum being incorrect, so it requested line 38530 again. This actually occurred a total of 17 times (I cut off the log above) before OctoPrint gave up and assumed the communication was stuck. I tried resuming the print a few more times, but kept running into the same error (at different lines). So there was definitely a problem with the serial communication between the printer and OctoPrint. My printer has an SD card slot, so I decided to try that out. But there was one small problem, the LCD was showing random characters, meaning I couldn't even tell it to start printing. Ugh... The only way I could fix this was by rebooting the printer. I was really hesitant to do so, because the stepper motors would lose their position, and the part could come off the bed if it cooled down too much. I realized I could write down the location that was reported by OctoPrint, and just tell the printer of its location once it rebooted. As for the bed cooling down, I just had to be fast about telling it to maintain temperature. Somehow I managed to do all that and resume the print. Of course, I still had to delete the first part of the G-code so it would resume in the right place, which was always tricky to figure out. But it worked fine for a few more hours! Until it failed again. Ugh... Somehow when the printer was grabbing the G-code off the SD card, it failed to grab the G from the start of the line, resulting in this error message: Unknown command: "1 X77.089 Y141.751 E0.00168". I looked at that line of the G-code, and it definitely had a G at the start, so I could only assume there was a persistent communication issue of some kind. That was supported by the fact that the LCD was going crazy. The SD card and LCD are both connected to the main board by the same cable, so it's reasonable to assume they were related problems. I tried resuming the print a few times, but kept having the same problem. On top of that, somehow all my settings on the printer got deleted! One of which was the Z probe offset, so the printer was printing about 1mm too high during one of these resume attempts. Ugh... I realized I had one other way of printing: a USB connection to my computer. I previously disregarded it because I couldn't get it to connect at all, but I realized that was actually caused by disabling USB on the printer for OctoPrint. So I resumed the print again with Pronterface. And it worked fine for a few hours, at which point I had to go to bed. I'd been working on the printer all day, diagnosing and fixing problems, trying different solutions, all while constantly having to resume the print by editing the G-code file. The printer hadn't even gotten much further than when I found it in the morning, so I was really happy to find it still printing when I woke up the next morning! Somehow it managed to keep printing all day without any problems. By the time I went to bed again, it had just a few hours left, so it would finish in the middle of the night. I woke up to find it had successfully finished! Finally! Not only was that the longest print I've ever done, it was also the most stressful by far! On top of that, it was my brother's birthday! I wasn't able to gift it to him that day, but I at least wanted to reveal it to him, so I needed to finish the rest of it quickly. That began with printing out the tumor, which was fortunately only a 3 hour print. And USB was being very reliable, there were no problems during printing! While that was printing, I removed all the supports from the brain and made quite a mess on my desk! The big chunk on the bottom came off in one piece, which was super satisfying. The rest of it was a lot more tedious, as there was a lot of support material between all the macaroni. Took me a few hours, but I managed to remove it all. I discovered there were some visible artifacts near the bottom when I resumed the print each time. I had to home the XY axes multiple times, which doesn't always get the exact same position each time. Plus there were some layers that got printed multiple times, which resulted in those layers being thicker and leaving a band around the perimeter. But these were all at the bottom of the print, so they're not super visible. On top of that, I was basically out of filament and time, no way I could print another one! The last step was to print out the buckle, and then it was finally done! And these parts snapped together really well, I couldn't have asked for a better fit! I gave it to my brother the next time I saw him, he was certainly happy with it! He showed it to his doctors, who thought it was really cool. They also commented that something like it would be incredibly useful for the planning stages of surgery, and I can see why! Makes me wonder why they don't create 3D models like this for surgeons.
IntroductionBack in 2015, when 3D printing started becoming very popular, I got my first 3D printer. I absolutely loved it and made all sorts of things, from decorative things, to presents for family, to functional parts for my robotics club. There's so many unique things you can make with 3D printers! Take this triple gear for example, designed by Henry Segerman and Saul Schleimer from 2012. There's basically no way to make this with traditional manufacturing techniques, but 3D printers can do it! As I learned more about 3D printing over the years, I started to realize my 3D printer wasn't actually all that great. Sure, it could make parts, but they weren't very high quality. If you look closely at the triple gear, you can see a bunch of lines on the gears. Those are not the layer lines, those are bulges every mm or so. In fact, take a look at this test print next to the z-axis lead screw: That lines up perfectly! So clearly the rotation of that lead screw was somehow causing these bulges. I tried chasing it down for a while, but never managed to fix it. And there were other problems too. It was really loud, parts didn't stick to the bed very well, the bed wasn't flat, dimensional accuracy was low, etc. It was time for a new printer. Rather than buying a new one, I decided to build one from scratch! Then I could fully customize it how I like, it would be cheaper than buying one (I was wrong about that!), and it would be a fun experience. And I had enough experience from other projects that I felt comfortable taking on this challenge, so I got to work designing! Motion SystemThere were 2 printer companies that inspired my printer design: Prusa, and Ultimaker. Both make good quality printers, but there's some pretty big differences in their designs. The most prominent is the motion system: Ultimaker's extruder moves in the X and Y axes, whereas Prusa's extruder moves in the X and Z axes. The bed moves in the third axis. With 3D printers, it's typical for the X axis to be left/right, the Y axis to be forward/backward, and the Z axis to be up/down. So with Prusa's design, the bed moves a lot. I'm not really a fan of this arrangement, because it has a much bigger footprint. Suppose the bed is 1ft long; this means you need at least 2ft of space for the printer. Another problem is that the bed is relatively heavy, so moving it around causes vibrations that appears as artifacts on the printed object. In contrast, Ultimaker's printers only move the bed up/down. This means the overall footprint is about the same size as the bed, and there's fewer artifacts on the print due to vibrations. There can still be vibrations caused by the extruder moving around, but it has a much lower mass than the bed, and therefore smaller vibrations. So I decided that my printer should have the extruder move in the XY axes, and the bed in the Z axis. The smaller footprint also means that it's easier to enclose the build chamber, which is useful for materials that require higher temperatures. Now came the question of how to move each axis. There's really 2 main ways of moving axes in machines like these: lead screws, and belts. Lead screws are just threaded rods; there's a nut attached to the moving assembly, and as the screw turns, it pushes/pulls the assembly. With belts, there's something on the moving assembly that grabs the teeth of the belt, which is run in either direction by a motor with a pulley. Belts tend to be faster, and can be moved by hand while the motors are unpowered. Anything moving up/down has to fight gravity, so it's pretty typical to use lead screws for the Z axis. If belts were used, there would be nothing to stop it from falling when the motors are turned off. Lead screws also allow for finer resolution, which is especially important when setting the nozzle height for the first layer. So the bed would definitely use a lead screw, but where would it go? Ultimaker uses a cantilevered design, where the lead screw and guide rods are on the back side of the bed, and there's no other supports. This means the bed actually droops a small amount on the front side, and it's prone to flexing during fast movements. In reality it's not much, but it does need to be accounted for. One solution is actually to use 4 lead screws, one in each corner of the bed. However this adds complexity, requiring either 4 independent motors, or some mechanical connection to a single motor. I knew that I was going to use a Z probe (more on that later) to compensate for any variations in the bed, so I decided to go with the cantilevered design. It's the simplest design I can think of, and I like simple solutions. And because the Z axis hardly moves, I wasn't concerned about it flexing. This is the final design I created for the Z axis: Now for the XY axes. The challenge here is allowing the extruder to move in both X and Y simultaneously. One solution is to isolate each axis from each other, where the extruder moves along a carriage in the X axis driven by a motor. Then the whole carriage moves along the Y axis with another motor, meaning the extruder can go anywhere in the XY plane. One downside is that the carriage is relatively heavy, meaning the Y axis motor has to work harder, and vibrations are more likely due to more mass. There's a cool version of this implementation, which is called CoreXY. Both the motors are stationary, which significantly reduces the mass of the carriage. The motors move the axes with belts and a number of pulleys to route the belts. In this implementation, both belts actually connect to the extruder. As one belt moves, the carriage moves in the Y axis while the extruder moves along the X axis at the same rate. This causes the total extruder motion to be diagonal. The other belt causes the extruder to move along the other diagonal direction. To move in an orthogonal direction, both motors spin at the same speed. I think this is a really clever and simple solution, but it's not what I ended up using. There's another solution that Ultimaker uses on their printers called a crossed gantry (you can see it in the image above). The extruder hangs on 2 perpendicular rails in the middle, then ends of which are attached to blocks. These blocks slide along some rods, and are pulled by belts in the X and Y axes. Moving the blocks moves the extruder in the same direction. One challenge with this configuration is that blocks on opposite sides need to move in the same way. This is the really clever part: the belts are connected to pulleys on the rods, which mechanically connect the opposing belts and make them move in the same way! I just think this is super clever, because the rods serve 2 functions: connecting the belts, and providing something for the blocks to slide along. The novelty of this design really won me over, which is why I ended up building it. This is the final design I created: So my motion system ended up being basically the same as the Ultimaker design. After evaluating different options myself, I can see why Ultimaker has gone with this arrangement. I'm not sure why Prusa uses a moving bed design, it could just be that it's easier to build or something. Regardless, they're still fantastic printers. For anyone looking to buy one, I always recommend Prusa printers, you get such great value for a very reasonable price in my opinion. I should also mention that cartesian motion systems are not the only solutions. Another somewhat popular alternative is the delta configuration, where the extruder is moved by 3 separate arms that slide up and down. One that's even less common is the SCARA design, which is basically an extruder on the end of a robot arm. Both of these require some complicated inverse kinematics, which I wasn't prepared to figure out! FrameNow that I'd decided on a motion system, I needed some way to support all the parts. This was fairly straightforward, it's just a handful of aluminum extrusions connected together in a box shape. This seems to be fairly common with custom 3D printer designs, because it provides a very rigid structure with lots of mounting points along the edges. Here's what it looks like in the final design: The extrusion I chose was the 2020 profile from 80/20, a company that manufactures aluminum extrusion and related hardware. Their extrusion is pretty reasonably priced, only 22 cents per inch, or 42 cents if you go with black anodization, which I did! And you can get your pieces cut to length for $2 per cut. In total, the frame was 217 inches with 13 cuts, which ended up costing around $100 before shipping and tax. However pretty much everything else that 80/20 sells is expensive, so I got a lot of mounting hardware from AliExpress for much cheaper. For the mounting brackets in the corners, 80/20 charges like $8 each; I have 18 of them, which would have been around $150! They're just aluminum plates with holes in them! Even worse, they charge like 30 cents per screw and nut! There's a couple hundred fasteners in this whole assembly, that's way too expensive! I definitely save a lot of money by getting those parts from AliExpress, but I ended up paying for it in an unexpected way. The screws I purchased still had lots of machine oil on them from manufacturing, which I had to clean off before I could use them. Some were really rusty, and I even came across a couple that still had a plug in the socket for the allen wrench, making them unusable. But that's pretty minor, most were still usable. The real problem came with the T-slot nuts I bought. The idea with these is that they slide along the T-shaped cutout in the extrusion profile. Here's the 2020 profile dimensions: Note that the dimension of the opening on each side is 5.26mm. The nuts I bought were actually 6mm at that point, so they didn't fit. Yay. I could have ordered some other nuts, but shipping with AliExpress takes a long time. So I instead decided to make the openings of my extrusions bigger. My university had a machine shop with milling machines available for use, which made this pretty easy to do. I just clamped the extrusion in a vice, and ran an end mill down the length of it. Then repeat on all 4 sides of all 13 pieces, and that's it! And because I'd ordered the black anodizing, this resulted in shiny stripes along all the extrusions, which I think actually looks pretty cool! Also from AliExpress, I ordered a handful of these KP08 bearings to support the rods of the XY axes. These nicely mount straight onto the frame near the top, and are offset in height so the rods don't interfere with each other. Some of them were a little crunchy, but they seemed to get better over time. The XY motors mounted just below with a bracket, and are connected to the rods with a belt. As for the Z axis, the support rods are supported by some SK12 clamps at the top and bottom. I later 3D printed a piece to attach the Z motor to the frame. I made it a requirement that nothing stick out beyond the faces of the frame, because this allowed me to add plastic side panels later to enclose it. I bought some polycarbonate sheets for this from TAP Plastics, a company that sells all sorts of plastic-based materials. I ordered all the sheets I needed cut to size for about $60. I also had to cut out the corners to make space for the frame brackets and drill mounting holes, but that was easy enough. Also, quick tangent on plastic sheets - acrylic and polycarbonate are very popular, but I really don't recommend acrylic. It will shatter like glass if you stress it, whereas polycarbonate just deforms. I've also had acrylic crack when drilling holes near the edge, which is really annoying. Both materials cost about the same, so I usually avoid acrylic when I can. If my printer was accidentally kicked or something, I definitely didn't want to break a side panel! ExtruderThis was probably the most complicated assembly of the entire printer. There's a lot of parts in a very small space, so it was a bit of a head scratcher to make everything fit. Let's go over everything needed on the extruder:
That's a lot! Fortunately I was able to knock several things off this list by buying a pre-manufactured extruder. E3D is a company well known in the 3D printing community, largely due to their work on extruders. At the time I was working on this project, their most popular nozzle was the Titan, which includes the motor, feeder, heat sink, heater, and nozzle. Right after I finished the printer, E3D announced their Hemera extruder. It has a number of improvements over the Titan, and I did consider upgrading to it. But with how much work I'd already put into the extruder assembly, I didn't want to start over! And it works great anyways, so I stuck with it. Buying this knocked half the items off the list, but I still had to figure out the other half. The first thing I tackled was the heat sink fan. The idea was for a fan to be mounted right in front of the heat sink (the circular fins on the bottom half) with a 3D printed shroud to guide the air past the fins. It connects to the Titan's mounting bracket with a few screws. This shroud also served as a place to connect other parts of the extruder assembly. Sandwiched between those, I designed this 3D printed part to hold the linear bearings. I intentionally positioned the bearings up high so the extruder would hang down, ensuring it didn't go up beyond the top face of the frame. I also made sure these were close to the mounting bracket to minimize flexing. On the right side is where I added the part fan, a 3D printed duct to guide the air to the nozzle, and the Z probe. This is easily one of the most complicated assemblies I've ever created. Once I had all the parts delivered and printed, I worked on assembling it. This turned out to be pretty tricky. I had designed it in a way where some screws were really awkward to reach, some nuts were difficult to grab, and some parts were annoying to get into place. In hindsight, there's a lot of ways I could improve this design, but I eventually finished the assembly. And it looks exactly like the CAD model, so I'm happy with that! Print BedThis was one of the biggest problems with my old printer, it was a bare aluminum bed with a heater on the bottom. Aluminum is really not a good bed material for 3D printers, plastic doesn't really stick to it. Back in the day, there were 3 fairly popular solutions:
Nowadays there are much better solutions, and I think Prusa has the best one: a sheet of spring steel, coated in PEI, held down by magnets. The coating is the primary solution. PEI, or polyetherimide, is a magical material when it comes to 3D printing. When it's hot, plastic sticks to it really well. You could hit your part with a hammer and it wouldn't budge! When it cools down, it completely lets go of the plastic. You could blow on a small part, and it would slide away! Whoever invented this stuff must have sold their soul. If for some reason the PEI doesn't release your part, that's where the second solution comes in. Like I said, it's a sheet of spring steel, meaning it's flexible! It's held down by magnets, so you can pull it off the printer, flex it downward, and the part peels off the bed! Incredible! Because Prusa's beds were so fantastic, I used one on my printer. Well, not quite. At the time, Prusa was only selling spare parts to people who actually bought Prusa printers, so I had to get a knock-off version. But it turned out to be pretty good quality, so I've been happy with it. At this point, I needed some way to attach the bed to the Z axis. On normal Prusa printers, there's a carriage plate that couples the bed to the Y axis. I took inspiration from that, and just bought a large aluminum plate. It's intentionally longer than the bed so I could couple it to the Z axis. There's 2 linear bearings that ensure the bed assembly can only move up and down. The lead screw from the Z motor runs through a nut to control its position. The lead screw is only attached to the motor at the bottom, there's nothing to secure the top of it. The nut does a good job of constraining its position, so nothing else is needed. Once I had assembled this and started testing, I discovered the weight of the bed assembly was a bit problematic. The Z motor would sometimes skip steps when pushing the bed upwards. I did have the option to increase the current to that motor, but I didn't like that idea. I instead decided to add a spring to offset the gravitational force. Now I know what you're thinking: the spring force changes as it stretches, so it would be too much force at one end, and not enough at the other! For a normal coil spring, you're absolutely right, and that would be a bad idea. However there's another type of spring: constant force springs! These are simply strips of spring steel that have been rolled up. As you unroll it, the spring steel tries to roll itself up again, which exerts a force in opposition to the direction it's being unrolled. And importantly, this force is independent of how far it's been unrolled! This is actually exactly the same way that tape measures automatically roll themselves back in, they're pretty neat! I ordered a couple from McMaster Carr. I needed some way to mount these on the bed, so I made a 3D printed part for it. A common solution for constant force springs is to just have them rolled up on a cylinder, and that's what I did on this part. There's a separate cylinder for each spring, with some sloped sides to ensure the springs stay in place. As the springs unroll, they just slide around the cylinders. The rest of this part has some weird geometry in order to clamp around the bed for a solid connection while not interfering with the lead screw or nut. This worked sufficiently well, but I also thought about trying to make the bed assembly lighter. Most of the mass actually comes from the aluminum plate, so I could cut out some sections of it. However I had to be careful, because that plate is the main thing preventing the bed from drooping. I had recently learned about finite element analysis (FEA), which runs a physics simulation to see how much an object deforms when a force is applied to it. There are also optimization algorithms that attempt to reduce one parameter (mass in this case) while maximizing another (stiffness). The SolidWorks license from my university included these features, so I gave it a go! This is what the optimization algorithm came up with: Well, that's certainly interesting! Makes me think of an elephant for some reason... The top is where the Z axis parts are, including the lead screw nut, linear bearings, and springs. The purple dots are the mounting holes for the bed, so those are really the points that need to be supported. What this result shows is there's a lot of unnecessary material in the lower half of the plate between the bed mounting holes. That can all be removed without much effect on the overall stiffness of the assembly. Obviously this optimization isn't perfect, and it's also not easy to manufacture. But I don't need to use the algorithm's exact result, I can just take the general ideas from it. I made some cutouts in the CAD model that looked a bit more reasonable, and ran the FEA simulation to see how much flex there would be with a 1kg load (basically a really big 3D printed part): That's less than 1mm of deflection at the end! For the stuff I do, that's definitely sufficient. Although I never ended up actually making these cuts in the plate, because the springs did a good job of counteracting the weight. I also wasn't certain how much I could trust the FEA results, and removing the plate from the printer is a bit of a hassle. Still, fun to evaluate anyways! MotorsI've not really said much about the motors so far, other than they move the axes and extruder. But I think it's interesting to talk about them, so that's what this section is all about! There's many types of motors to choose from, so what do 3D printers use? Well, we need to know how far each motor has rotated in order to accurately create stuff, which most motors are incapable of measuring. One option is to add an encoder to the output shaft and run a feedback controller on the main processor, but this is relatively complicated and prone to errors. There's a better solution: stepper motors! Each motor has 2 coils of wire and a magnet inside (I'm simplifying a lot, but it gets the idea across). The magnet is attached to the rotating shaft of the motor, called the rotor. The coils are attached to the stationary case of the motor, called the stator. The coils are placed 90 degrees apart from each other inside the case. We'll label the coils A and B for clarity. Inside the motor looks like this: Suppose we run a current through coil A, creating a north pole near the middle. The south pole of the magnet gets pulled towards it, causing the rotor to spin 90 degrees. Now we turn off coil A and run a current through coil B, creating a south pole near the middle. The north pole of the magnet gets pulled towards that, creating another 90 degree rotation. If we repeat these steps with opposite magnetic fields in the coils, the rotor will have made 1 full rotation. The advantage here is that we are controlling the coils in these "steps". Each time we make another step, the motor rotates 90 degrees. That's how we know how far the shaft has rotated! We don't need a sensor attached to the output shaft, because if we know how many steps we've taken, we know the angle of the motor! In this configuration, we have 4 steps per revolution. We can take this a step further too! Suppose in the picture above, we run a current through both coils at the same time! And let's just say both coils create a magnetic north pole near the center. The south pole of the magnet is pulled towards both coils equally, causing it to rotate 45 degrees. Now we have 8 steps per revolution! We can take this idea even further! Rather than our coils being on or off, we could change the amount of current in each coil. If we put, say, half the current through coil A, then we'd rotate the magnet by about 30 degrees. Or even less current, and achieve 15 degrees, or even smaller. This is called microstepping, and gives us much finer resolution than using full steps. As I said, this explanation is greatly simplified. In real stepper motors, there are more coils in the stator, and a lot more magnetic poles on the rotor. Take a look at this one for example, it has 8 coils and 50 magnetic poles! Half of the coils are connected to the A wires, and the other half to the B wires, so we still have 4 wires coming out. This stepper has 200 full steps per revolution, or 1.8 degrees per step. In most 3D printers, when a stepper motor is connected to a belt, this results in a resolution of 80 micrometers per full step, or 12.5 steps per mm. This is usually sufficient for 3D printing, but microstepping can easily get us down to 5 micrometers, or 200 steps per mm! That's way more precise than you would ever need from a 3D printer. Stepper motors are great for knowing how far an axis moved, but only relative to where they started. In reality, the microcontroller in charge of everything doesn't know where the axes are located when it first powers up, so it needs to perform what's called homing. This is where each axis is moved in one direction until it reaches the end. But how does the microcontroller know where the end is? In most systems using stepper motors, a switch is added to the end of the axis. Something on the moving assembly hits this switch, which sends a signal to the microcontroller to indicate the end. There's one other thing to be aware of with stepper motors. While there's current running through the coils, the motor is able to exert a torque on the output shaft. So if you try to rotate a powered stepper by hand, it will resist you. But if you've got a good grip, you can actually force it to rotate anyways, causing it to "skip steps". This can also happen on a 3D printer if one axis is physically blocked (eg. the nozzle runs into something) while the motor tries to move. This is very problematic when it occurs, because it creates a layer shift that can completely ruin a print. Most 3D printers don't have a way to detect this, so you just have to start the print all over. However, it is detectable! When a skip occurs, the magnet suddenly rotates over to the next full step. If you know anything about magnets moving near coils, you'll know this actually creates a voltage across the coil that we can measure! And that's exactly what Prusa printers do using a stepper driver from Trinamic. It closely monitors the voltage on the coils, and if they go out of whack, a step must have been skipped! Prusa actually uses this skip detection for homing the XY axes. This removes the need for physical switches, which reduces the amount of wiring to do. This can also help with reliability, because those switches can move if they get bumped. I think this is such a cool feature, I made it a requirement for my printer. ElectronicsBy this point I had finished most of the mechanical assembly, and the printer was really starting to take shape! (No, the bed isn't attached in this photo, but this post doesn't actually follow the exact order in which I did stuff anyways. Just imagine it's attached!) The last major thing to tackle was the electronics. This would control every aspect of the printer, including the motors, heaters, fans, sensors, and user interface. Usually there's one circuit board with connectors for everything, plus the microcontroller and other circuitry needed for interfacing with the components. For custom 3D printers, it's pretty common to use an Arduino Mega with a RAMPS board plugged into it. The Arduino is the main microcontroller, and the RAMPS board provides connections for all the components, plus a handful of other components like voltage regulators and transistors for high current devices. I could have used this for my printer, however I thought of a better solution. A lot of my design has been inspired by Prusa printers. My printer uses a Prusa print bed. It uses a Prusa motor for the Z axis. It uses a Prusa Z probe. Why not just use Prusa's main control board? As far as it knows, it's controlling a Prusa printer! All I'd need to do is change some configurations in the firmware, and it should function! This would also save me a lot of set up time, since all the hard work has been done by Prusa with things like skipped step detection. The control board that Prusa uses is called the Einsy RAMBo. It uses the ATmega2560, the same microcontroller as the Arduino Mega. The Trinamic stepper drivers are built right into the board, along with all the voltage regulators, transistors, connectors, etc. It does cost more than a RAMPS board, but it's a nice all-in-one package that saved a lot of headache. The user interface is handled by another circuit board connected by a cable to the main board. It contains an LCD screen to give the user information, a knob for the user to control the printer, and an SD card slot for storing print files. It also has a buzzer that can alert the user when they're not looking at the printer, and a reset button in case anything goes wrong. Most printers seem to use the same board design, so they're really easy to buy. And the last major component is the power supply! 12V and 24V systems are most common. Higher voltages are usually more efficient, so that's what I went with. The other important parameter is the maximum power output. Most of the power consumption comes from the bed heater, the nozzle heater, and motors. If everything is running simultaneously, that can easily reach a couple hundred Watts. Just to be safe, I ordered a 400W supply so I had some headroom. IMPORTANT NOTE - a lot of 3D printers use these industrial style power supplies, which require connection to mains power. This can be dangerous if you don't know what you're doing! I've added a standard power connector and power switch to my printer so I can safely power it up without risk of electrocuting myself. If you're not sure of the proper way to handle this, don't do it! And that's all the major parts! I was getting really close to actually printing, just a few things left to do! One of which was mounting the final electronics and wiring everything together. Obviously the LCB board needed to be near the front for easy access, so I 3D printed a bracket to hold it at an angle at the bottom. It made sense for the main board and power supply to be at the bottom as well, so that's where those are located. I also mounted the power connector and power switch in the polycarbonate sheet on the side for easy access. As for wiring, most of the connections came from the extruder assembly. I put some spiral cable wrap around all these wires to make sure they clumped together, and ran the bundle down the back side of the printer to the control board. Some wires were a bit too short, so I spliced in a bit more wire to make them reach. The wires coming off the motors were all separate, so I braided them together to make sure they wouldn't come loose (this also helps with shielding). I also made connections from the control board to the LCB board and power supply. And that was it! The scary part came next: turning on the power. I had been periodically testing components individually, but never all at once like this. What if I connected something to the wrong place? Or what if I flipped wire polarities somewhere? Or what if the microcontroller suddenly moves all the motors? What if there's an explosion or fire? I flipped the power switch. No explosions!!! Yay! I managed to connect everything correctly, and it booted right up with no problems. Woohoo! FirmwareAs I mentioned, there's some firmware running on the microcontroller that controls everything. In 3D printing, the most commonly used firmware is Marlin. It's an open source project that has been developed to work on basically any 3D printer, which is why it's so popular. There's also many forks of Marlin (thousands, actually!) as people have made their own changes and contributions to it. Prusa has their own fork of Marlin that's used on their Einsy RAMBo boards, so that was my starting point. From the microcontroller's point of view, my printer is almost exactly the same as a Prusa printer. There were only a handful of differences: the axis lengths were different, the nozzle was in a slightly different location relative to the bed, and the Z probe was in a different location relative to the nozzle. That's really about it, and those values are really easy to change. In Marlin, there's a couple of .h files that allow you change the configuration of the printer. Just change the numbers, and all the relevant parts of the code automatically update their behavior. Then just flash the microcontroller with the new code, and that's it! I did have to tinker with these numbers a few times, I ran into some weird issues with the Z probe offsets, but I figured it out in the end. Once those were all set, it was time for the first print! I sliced up a calibration cube and sent it to the printer, and it started printing! Success! Well, not for long. The first few layers were fine, but the cube came off the bed part way through. So I tried again. That one also came off. I tried again. And again. And again. It took until the 6th try for the cube to stick all the way through the print, so that was something to fix. But it can print stuff! And the surface texture is substantially better than my old printer, no more weird bulges on the sides! I think the poor sticking had to do with not printing hot enough, and not having cleaned the bed well enough. Once I'd started dialing in those things, parts were sticking much more reliably. As I kept printing stuff, I discovered an issue with the XY axes: friction. I don't exactly what's causing it, but I suspect the bearings may not be perfectly aligned with the rods. They have pretty tight tolerances, and I may not have assembled everything as precisely as needed. I did try tinkering with alignment for a while, but couldn't make any improvements. This friction caused 2 major negative effects: First, the skip detection was getting triggered a lot. The friction was so great that it overcame the torque of the motors. Well, that's one way to verify the skip detection actually works! But obviously that's not good for printing, so I overcame it by increasing the current to the motors. This actually took me a while to figure out how to do. In the firmware, tmc2130.cpp initializes the current settings from a value that's #define'd in the variants folder. I'm not sure exactly what the numbers correspond to, but I just kept increasing them until it stopped getting false positives. Second, there was relatively high backlash, causing parts to come out undersized. On of my biggest goals was to have a printer than made dimensionally accurate parts, so this really bothered me. I created this test print to quantify it, consisting of a square, and a small nub. The backlash wasn't huge, around 0.2mm, but that's enough to cause problems with parts that need accuracy. So I added my own backlash compensation into the firmware. I modified the code that handles G1 commands, which instructs the printer to move the axes. I just added a check to see whether the XY axes were moving in positive or negative directions, and adding or subtracting the backlash amount accordingly. It's really quick and dirty, but worked surprisingly well! The picture above is after I'd implemented the compensation, and my calipers measured 24.00mm on the 24mm circuit. Excellent, that's why I love open source code! ResultsAt this point, I had a fully function 3D printer that I had designed and built from scratch! And it performed a whole lot better than my old printer, so I was really happy with it! Here's a comparison between my new and old printers: You may be thinking the new printer looks bigger than the old one. However the new printer actually has a smaller footprint than the old one! That's because the bed moves so far on the old printer that it required much more space along the Y axis. The X and Z axes are actually about the same size on both printers, and the total print volume is about the same. There was actually one more thing I wanted to add to my new printed: LEDs! Having bright lights near the printer is actually super helpful to ensure it's printing properly, that's something that really annoyed me with my old printer. I designed and printed out these brackets to hold LED strips, which can slot into the extrusions. I printed them in vase mode, meaning there's just 1 wall along the perimeter. This gave them just the right amount of flexibility to snap into the extrusions. Then I got some LED strips, adhered them to the brackets, and wired them up. The final result is awesome! Another neat feature of the Einsy RAMBo is that is supports adding a Pi Zero to the back of it for OctoPrint support. I really liked the idea, so I bought a Pi Zero and set it up. It actually worked really well, OctoPrint is a pretty nice interface for using a 3D printer!
I wanted to give the LEDs smart control, where they'd change color based on the state of the printer. For example, it would be white while printing, green when it finished, and red if there was a problem. OctoPrint actually support this through plugins, so I got that set up. And it worked! Having that kind of feedback from the printer is excellent, I wish more printers had stuff like that. And then I messed it all up by zapping the Pi Zero with 24V. I was fiddling with the LED control circuit while the printer was powered on, and touched a wire to the wrong spot. The Pi Zero was completely dead after that, which made me pretty frustrated. Fortunately the main control board was still fine. Though ever since that happened, I've had intermittent issues with SD cards and USB connections. I suspect some component may have been damaged, but I've got no idea. It works well enough for me to use it regularly, so I've not had to worry about it much, but a replacement main board might help at some point. And that's about it! I've been using this printer ever since, and it's been great! It is a little rough to use at times, such as parts not sticking, or the printer deciding to reboot in the middle of a print. But overall, it's actually been fairly dependable, and made me enjoy 3D printing again! The problems with my old printer sucked the joy away, so this was a welcome change. Knowing what I do know, would I build another 3D printer or buy one? Mmm... in all honesty, I would probably just buy one. Don't get me wrong, this was a fantastic learning experience, it's easily one of the most complicated things I've built! But there's also a lot of time and frustration I would have saved if I just bought a printer in the first place. There's definitely a lot of design improvements to be made. Have you ever built your own 3D printer? I'd be happy to hear about it in the comments below! If you're thinking about building your own, just understand how big of a project it is. I've easily sunk a few hundred hours into this project alone, and you need to have the technical knowledge to address problems that come up. But once it's all said and done, it's a very rewarding experience for sure! IntroductionSo, self-driving cars are cool, right? I know, that doesn't sound related to RFID scanners, but trust me, we'll get there! My university required every freshman to take an introductory engineering class, where teams of students are meant to solve an open-ended problem revolving around some theme. When I took the class, the theme was to "improve infrastructure". Yeah, very open-ended! My team had some long discussions of what exactly we wanted to work on. Somehow we got onto the topic of autonomous vehicles (AV), and we realized that some infrastructure improvements could be made to increase AV reliability. You've probably heard tragic stories of AVs crashing, such as this example where faded lane markers indirectly caused the car to drive straight into a barrier. Obviously some faded lines should never cause an incident like this, but the primary navigation technique is to detect lane markers with a camera. Lane markers get faded all the time, and can even be obstructed by severe weather (rain, snow, etc.), so it's risky to rely on lane markers alone. Our idea was to add some feature to roads as an alternative navigation solution for AVs. The solution we eventually settled on was to embed RFID tags in the roads under the lane markers. Then RFID scanners on the AVs would pick up the signal from the tags, and by measuring the signal strength, they could determine where they were in the lane. Tags embedded into the road won't fade over time, and they can continue to function even when optical obstructions exist. They could even be programmed with data about the roadway, such as which lane they corresponded to, indicate where a freeway entrance/exit is, etc. So that's the premise for how this project came to be. I had the most electronics experience in my team, so I was tasked with creating the scanner prototype. All it had to do was read data off the tag, and measure the signal strength. How hard could it be? RFID Background There's a few different RFID standards, but we focussed on low frequency passive RFID. Low frequency in this case means 125kHz, the high frequency stuff goes above MHz range. And we specifically need a passive system, because an active system requires a power source for each tag. If we're embedding millions of these into roads, it's a lot better if they don't require power! So how does RFID work? I'm glad you asked! Both the scanner and the tag have their own antenna, which is typically a loop of wire acting as an inductor. The inductor is paired with a capacitor to make a resonant circuit, whose frequency is tuned to 125kHz (or whatever frequency is being used). The scanner has its own power source, which it uses to drive the antenna. This is a simplified version of the circuitry antenna: The driving signal is a square wave operating at the resonant frequency of the antenna. This causes the output voltage to begin oscillating with a much higher amplitude than the input amplitude, as shown in this circuit simulation: Because the antenna is an inductor, this also creates an oscillating magnetic field nearby the antenna. When a tag is brought inside this magnetic field, both antennas act like a transformer, causing a small amount of power to be transferred to the tag. This small amount of energy is sufficient to power a tiny chip on the tag, which has been programmed with data from the manufacturer. Once the chip has sufficient energy, it transmits its data to the scanner in a clever way. It short circuits its own antenna! This causes the tag's antenna to draw even more power from the scanner's antenna, which results in a small reduction in the scanner's amplitude. Here's a demonstration of this effect on a real scanner antenna with a real tag: The nominal amplitude in this case is around 20Vpp, but when the tag shorts its own antenna, it reduces the scanner's amplitude to around 19Vpp. The amount of voltage drop depends on a variety of factors, including the distance to the tag. The duration of this short circuit determines the data that's been transmitted. There are several ways of encoding this data, some common techniques are illustrated here: The tags we purchased use Manchester encoding, where the signal continually alternates between high and low logic states. During a single clock interval, the signal transitions either from low to high, or high to low. The direction of that transition determine whether that bit was a 1 or 0. In the case of these tags, one clock interval is set to 64 oscillations of the antenna, or 512us. On top of the encoding scheme, there's a protocol used to determine whether the data was transmitted correctly. In the case of these tags, it's the EM4100 protocol: The idea is for the scanner to wait for the header, which is 9 1's in a row. Once the header is received, read and store the rest of the bits in an 11x5 grid. Sum the data bits across the rows and columns, and check whether those sums match the parity bits. If so, the received data is most likely correct. It's still possible for the data to be wrong even if the parity bits check out, but that's beyond the scope of this project. Circuit DesignSo, the scanner has this oscillating voltage, whose amplitude drops for a few cycles when a tag is present. The duration of that drop determines the data, and the amount of drop determines the distance to the tag. And to keep the project scope in mind, this information should be given to the AV's control software to help it navigate. Sounds like the perfect job for some circuitry and a microcontroller! The main goal is to detect that drop in amplitude from the antenna. There's a circuit called an envelope detector that does this well, consisting of just a diode, capacitor, and resistor. The idea is that as the input signal comes in, the diode allows the capacitor to charge up until the peak of the signal. Once the signal changes direction, the diode prevents the capacitor from discharging, so that voltage is maintained. We need the capacitor to drain slowly in order to detect lower amplitude oscillations, which is the purpose of the resistor. The diode is intentionally placed in reverse to capture the negative side of this voltage, otherwise the logic on the microcontroller would have been inverted. Here's what the resulting signal looks like in practice: The capacitor and resistor values are chosen such that this decaying voltage is fast enough to detect the amplitude drops, but not so fast that it catches the drops in the carrier frequency. This envelope voltage is then put through a high pass filter, which brings the average signal voltage to 0V rather than -10V like before. This also helps filter out any lower frequency signals we don't care about, such as 60Hz from mains power lines. Now we can zoom in on the high pass signal to see what it looks like: Looks like a pretty clear signal to me! Although there's some high frequency noise in that blue trace that could cause issues with low signal strength. That can be cleaned up with a low pass filter to make sure we're getting a smooth signal. That looks like a much cleaner output now! The goal here is to measure the time when those 0V transitions occur, and from that determine what bits were transmitted. The signal doesn't even go above 1V, whereas a microcontroller desires 5V. One simple solution is to use a comparator, which is a device that outputs a high or low logic signal when the input goes above or below some value. It's very easy to set up an op amp for this like so: That results in a fairly decent square wave that can be sent straight to a microcontroller! That's the data signal sorted, but we need to determine the distance to the tag as well. As stated above, the amount of voltage drop on the antenna depends on the distance to the tag. Well, the signal that we just put into our comparator is a direct measurement of that voltage drop! All we need to do is get the envelope of that, and feed that into the analog input of the microcontroller. However the amplitude is a bit low, so we can amplify it using another op amp: In this configuration, only the top half of the signal is amplified, but we were going to ignore the bottom half anyways. Now we just need another envelope detector circuit on this signal like so: And this does a great job of holding the signal amplitude: I ran some tests where I moved the tag towards and away from the antenna while watching the output voltage. As expected, moving the tag further away caused the signal strength voltage to decrease. The measurement distance was relatively short, only a couple inches, but it's plenty for a first prototype! Until this point, I haven't really mentioned what I've been using as an antenna. That's because the antenna has kicked my butt, I definitely don't know much about antenna design! We had ordered a cheap RFID scanner to test with before trying to build our own, and I've just been using the antenna from that for all my experiments. I did make a couple different antennas that do work, they're just not as good as this once. Let's talk about it! As stated above, the antenna is really just a resonant circuit between a capacitor and inductor. This cheap scanner was capable of reading tags from a couple inches away, but we realistically need a few feet at least. So I figured bigger coil means bigger range, right? I made a couple large coils out of some spare wire I had lying around. I then needed to match a capacitor to each coil to make them resonate at 125kHz. Turns out there's a fairly easy way to find the best capacitor value for this. The circuit below is constructed with some arbitrary capacitor size. A function generator drives the circuit at the desired frequency of 125kHz while measuring the input and output signals. There's 3 possible results: the capacitor is too small, too large, or just right. If it's too small, the output signal will be shifted to the right of the input signal (left image below). If it's too big, the output signal is shifted to the left of the input signal (right image below). When the capacitor is just right, the input and output will be aligned with each other, and the output amplitude will decrease (center image below). Ideally the output should be 0V, but there's always some non-zero impedance of the inductor and capacitor. I only really tested with the smaller circular coil, it was much easier to work with. I found the ideal capacitance to be 18.5nF, meaning the coil had an inductance of around 87.5uH. Neat! The next step is to design a circuit that can drive the antenna. The peak current can get quite large, up to 1A in my circuit simulations. That's a lot more than a microcontroller can handle! The solution I found was to use a pair of MOSFETs in a push-pull configuration like so: M1 is N-channel, and M2 is P-channel. When the gate voltage is at ground, M1 turns off, and M2 turns on. This starts driving current through the antenna, causing the output voltage to rise. Once at the peak, the gate voltage needs to switch to 5V to turn M2 off, and M1 on. This drives current in the opposite direction through the antenna until it reaches the negative peak. This repeats indefinitely. Here's a scope trace of what that looks like in practice for each MOSFET: Because the MOSFETs are driving the antenna at its resonant frequency, the voltage increases far beyond the initial 5V we were supplying. In the case of this antenna, I was able to achieve 50Vpp, that's a 10x increase! My simulation showed the antenna drawing up to 1A, however I was only measuring an average of 20mA coming out of my power supply. I suspect the refresh rate of the supply was simply not fast enough to capture the large current spikes, but it's interesting to see such a low average power draw! Everything was going great until this point. I had a much bigger antenna that was getting over twice the amplitude as the cheap one we'd bought. Surely this must be better, right? Saldy, no. I connected the antenna to the rest of the circuit, placed a tag in the middle, and saw this on the outputs of the circuit: That's a lot more noisy than before! I suspect it may have to do with the high switching current from the MOSFETs. That's not a good sign for a microcontroller, voltage spikes like that can cause instability, or even damage under extreme circumstances. On top of that, the signal strength (blue trace) is much lower than before. With the cheap antenna, the signal strength was around 2.5V, whereas now it's not even 500mV. Well, who cares if the signal strength is lower, right? We just want a longer read range than 2 inches! Well, here's the output when the tag was placed 2 inches above the antenna: That is completely unusable. There's no way to grab any useful data from that. I kept experimenting with it, and got some help from a mentor to try and improve its performance. But we were unsuccessful, this was the best performance we could get from the circuit. I'm sure it's possible to improve the design, but we were out of time by that point for this project. So we just stuck with the antenna from the cheap scanner module since it worked more reliably. MicrocontrollerRight, that's all the circuit stuff done, now to actually read some tag data! I needed a microcontroller, so I used the hobbyist favorite: Arduino! Specifically the Arduino Pro Mini, because I could stick it into a breadboard, I'm not a fan of loose Uno's flopping around. Our circuit has 2 outputs: the data signal, and the signal strength voltage. The data signal is digital, making it good for connecting to one of the digital inputs. I specifically chose an input capable of handling interrupts, since I was going to take advantage of that in my code. The signal strength was connected to one of the analog inputs so it could be measured. I also wanted to add a couple outputs to the breadboard to indicate when data was received and the signal strength, since looking at data from the serial monitor isn't super exciting. I chose to add an LED to indicate the signal strength, and a buzzer to indicate when data was read. These made the breadboard a bit more standalone, only requiring power to actually demonstrate its abilities. And I just barely managed to squeeze everything onto a half size breadboard! I would have shared the code here, but that's sadly been lost. Fortunately it's not super complicated logic. The main loop simply measures the signal strength voltage, then sets the LED brightness accordingly. An interrupt is configured on the data pin, which just measures the amount of time since the previous pulse and stores that in an array. Once all 64 bits have been transmitted, the parity bits are checked. If they all check out, the data is logged to the serial monitor, and the buzzer beeps for a short duration. That's pretty much the extent of the code for this project! ConclusionOverall, we were pretty successful in our project! We completed our original goals for this portion of the project, which were to measure the data and signal strength from an RFID tag. We weren't able to get a long range antenna functioning, but the concept is there at least. At the end of the semester, all the teams presented their projects and got ranked by judges. And my team came second of our class! That's actually exactly what we wanted, because first place winners had to go onto a final judging round the next day, and we didn't really care for it. Perfect! As I was constructing this scanner, I also realized the student ID cards my school give out use RFID for building access. And it just so happens that they use 125kHz too! I tinkered a bit with trying to read the data off my card, but it was more difficult than these tags we'd bought. Rather than a clock period of 64 cycles, it was more like 8. This makes the carrier frequency harder to filter out, so there was more noise to fight. Additionally, I wasn't really sure what kind of encoding was present and what protocol was used, so I was never able to figure out exactly what data is stored on them. But still fun nevertheless! A few semesters later, I took another class where my partner and I built a driving robot as our final project. I really wanted to see my RFID scanner in action on a vehicle, so we attached it to the top of the robot. In our code, we implemented a simple line following algorithm based on the signal strength. As a test, I put several tags under a whiteboard, and taped a marker to the robot so it could trace the path. Turned out pretty good! That's all I've got from this project! It was definitely a fun one, I really enjoyed learning about how RFID works and being able to create a scanner from scratch. For anyone looking to have their own scanner, it's really a lot easier to just buy a cheap one. But if you decide to build one from scratch, let me know how it goes for you!
IntroductionUNLIMITED POWER!!! Well, not exactly. But making your own lightning? Absolutely! One of my first major personal projects was a Tesla coil. At the end of my first physics class on electromagnetism, we took a field trip to an electronics museum, and they gave us a demo of a huge Tesla coil. I was fascinated with it, and decided to build one of my own! If you've never seen a Tesla coil before, all they really do is make big sparks. But there's a lot of cool physics that goes into it, and there's some neat demonstrations you can do. High Voltage SafetyBefore we go any further, I think it's important to talk about safety here. Tesla coils generate ridiculously high voltages, which could cause major injuries or even kill you. If you don't have a really good understanding of high voltage systems and how to protect yourself, I would recommend against building your own Tesla coil. This post is intended for educational purposes only. I am not responsible for anything you do based on the information I've provided here. What kind of voltages are we talking about? Well, the outlet in your house is at a couple hundred volts; that's enough to give you serious injuries, or even kill you in some cases. Tesla coils can reach millions of volts, over 1000x higher voltage. Needless to say, they're dangerous! But wait, when I get a static shock, that's thousands of volts! Why doesn't that kill me? Right, well uh... it's complicated. The typical warnings you get about high voltage can be... misleading? Again, if you're not really familiar with high voltage, don't play with it. The information provided here is for education, it is not safety training material. But I do think it's an interesting discussion, which what the rest of this section is about. Let's start with some basics. Voltage really just describes how much energy a charged particle has. The standard unit of measurement is the volt (V), which is equivalent to 1 Joule per Coulomb. A Joule (J) is the standard unit of energy, and the Coulomb (C) is the standard unit of charge. There are many types of charged particles, but we're mostly going to stick with electrons since that's what actually moves around in wires. Electrons are ridiculously tiny, and likewise have a ridiculously tiny charge. In fact, 1 electron has a charge of 1.6*10^(-19) Coulombs, less than a quintillionth of a Coulomb. Suppose you get smacked in the face by an electron with a million volts. How much energy is that? Well, just multiply the voltage by the charge! 1MV times 1.6*10^(-19) C is 1.6*10^(-13) J, less than a trillionth of a Joule. For reference, suppose we replace the electron with a housefly going at full speed. You would probably barely notice it, that's around the threshold of what a person can detect. The housefly has a kinetic energy of around 2.4*10^(-5) J. That's 150 million times more energy than the electron had! There's no way you'd even notice the electron, let alone be harmed by it! So what does it take to be harmed by electricity? Let's take a look at the example when you get a static shock, since that's more relatable. We need to talk about capacitance, which describes how much charge an object can store. The standard unit of measurement is the Farad (F), which is equivalent to 1 Coulomb per volt. In fact, there's this simple equation that describes the relationship between these values: So if you have an object with capacitance C that has been given a voltage V, the amount of charge q on the object is just C times V. In the case where you get a static shock, your body is usually charged to a few thousand volts, let's say 5kV so we have a number. And a quick Google search shows your body has a capacitance of around 100pF, or 10^(-10) F, less than a billionth of a Farad. How much charge is that on your body? 5kV times 100pF is 5*10^(-7) C. That's still a pretty small number, less than a millionth of a Coulomb. However that's way more than just 1 electron, it's actually around 3 trillion electrons! That corresponds to an energy of about 1mJ, or 50 times more energy than the fly had! On top of that, most of those electrons travel through your nerves, because they're much more conductive. This amplifies the amount of pain you that you would otherwise perceive from 1mJ of energy. Ok, so being charged to a few thousand volts is a bit painful. How come a couple hundred volts from a wall outlet is lethal? Shouldn't that result in less charge, and therefore less energy? Great question! When we looked at static shocks, that was only a discussion of electrons sitting on your body. Once you got shocked, all those electrons left your body in just a few microseconds, and that was that. However the danger comes from your outlet being able to charge your body repeatedly and very rapidly. Depending on where you live, your mains power oscillates at 50 or 60 times per second. I'm going to stick with 60Hz, since that's what it is at my house. Suppose you touched a live mains wire. As the voltage rises to a couple hundred volts, your body gets charged up to the same voltage. This gives you a shock. Then the voltage drops until it's a negative couple hundred volts. This gives you another shock. The voltage rises again, giving you another shock, and so on. You're getting shocked 120 times per second! That's painful for sure, but that's not the really dangerous part. The dangerous part is where those electrons go in your body, with the primary concern being your heart. Normally, your heart gets a small electric pulse a couple times per second that tells it to beat. But if you're getting shocked by your outlet 120 times per second, your heart then tries to beat 120 times per second, which it is not physically capable of doing! That's called ventricular fibrillation, where your heart basically just quivers and doesn't pump any blood. Effects on the heart are the primary concerns around high voltage systems. But that's not the only danger! So far we've only discussed alternating current (AC), but direct current (DC) systems can be dangerous too! For that discussion, we need to introduce current. It the rate at which charges flow through an object. The standard unit of measurement is the amp, which is equivalent to 1 Coulomb per second. The danger of DC systems is having a large current travelling through your heart, forcing it to stay contracted and never beat. That occurs when 100mA or so is running through your body. You may be thinking about your stash of AA batteries, those can easily deliver 100mA! Why aren't those dangerous? That's because there's one more concept we need to introduce, resistance. That describes how much an object prevents current from flowing through it. The standard unit of measurement is the Ohm, which is equivalent to 1 volt per amp. In fact, this is the relationship described by Ohm's Law: It's really voltage that drives a current through an object, and the amount of current depends on the resistance of that object. Your body resistance is usually around 100kOhm, though that can vary a lot depending on several conditions. Assuming you grab that 1.5V AA battery, that would result in a current of 15 microamps. You wouldn't even feel that, let alone be hurt by it! So what DC voltage would be lethal? Assuming the 100kOhm body resistance, that would be 10kV. However if something reduces your body resistance, such as being sweaty or having a cut in your skin, even 100V could be lethal! There's other safety concerns with high voltage systems that I've not covered here, such as burns and neurological effects. But this section is long enough as it is, and should give you a good idea for the dangers involved with high voltages. I personally don't like getting zapped, so I avoid touching anything that cause a shock. With dry skin, you really can't feel anything below 25V or so, so that's my personal threshold. But I also know people who willingly touch stuff at thousands of volts. They aren't stupid by any means, they just have different risk tolerances and don't mind getting zapped. They also take precautions to ensure they won't get severely injured. Again, the information I've provided here is intended only for educational purposes, this is not safety training material. If this is your first time learning about high voltage systems, I really would not recommend building a Tesla coil. They are fundamentally dangerous machines, and there's lots of safety information I've not included in this post. If you want to know how to build one safely, I'd recommend getting information from an expert, not a blog post on the internet! TLDR; don't play with high voltage! Tesla Coil PhysicsThe whole idea behind a Tesla coil is to generate a really high voltage. Every electrical insulator has what's called the breakdown voltage, which is where the insulator suddenly becomes conductive. This occurs when the electric field becomes so strong that it starts separating electrons from their atoms, which is no easy feat! In air, this creates free electrons and positively charged ions, which are then accelerated in opposite directions from each other due to the electric field. They crash into other atoms and molecules, causing them to lose electrons too, creating a chain reaction. After just a few microseconds, there's a whole bunch of charged particles flying in opposite directions along a certain path. These events are so energetic that light is emitted along the path. That's what we call a spark! Every material has a breakdown voltage, and in air, it's around 3 million volts per meter, or 3MV/m. So roughly speaking, if you want to create a spark that's 1 meter long, you'd need 3 million volts (it's actually more complicated, but that's the basic idea). When you get a static shock on your finger, it's typically a couple mm long, which corresponds to a few thousand volts like we talked about in the safety section (don't play with high voltage!). So how do we generate such a high voltage? Well there's lots of ways to do that, but the solution that Nikola Tesla originally came up with was to use transformers. A transformer is just 2 inductors placed near each other, called the primary and secondary. An inductor is just a coil of wire. When current passes through the primary, it creates a magnetic field around it (which is how electromagnets work!). The really neat thing is that this works in reverse too; a magnetic field can cause a current to flow in the secondary! Well, almost. It's not actually just a magnetic field that causes current to flow, it requires a changing magnetic field. And it doesn't actually create a current in the inductor, it creates a voltage across the inductor (which can then drive a current). The exact behavior is described by Faraday's Law: Don't worry if you're not familiar with this notation, it's pretty straightforward! It just says the voltage created across the inductor V depends on 2 things: the number of turns of the inductor N, and how quickly the magnetic field changes inside it (actually magnetic flux, but let's keep it simple). This also works in reverse: the voltage across an inductor creates a changing magnetic field inside it. In a transformer, the inductors are placed so they share the same magnetic field between them. We're going to do some algebra with this equation. Let's say the primary has voltage V1 and number of turns N1, and the secondary has voltage V2 and number of turns N2. Both inductors share the same changing magnetic field*, so we can rearrange it to find this relationship: And with a bit more rearranging, we get to the transformer equation: *Actually the field strength in the secondary is less than the primary, so this is not an exact relationship. We can model this with a coupling coefficient between the inductors, but I've omitted it for simplicity. This equation states that voltage ratio between the primary and secondary is the same as the turn ratio between them. So if we want to maximize V2, we want N2 to be large and N1 to be small. It's pretty typical for Tesla coils to have hundreds or thousands of turns on the secondary, and only 10-20 on the primary. Technically we'd get higher voltages with fewer turns on the primary, but there's diminishing returns due to resistive energy loss. In typical Tesla coils, this transformer results in tens or hundreds of thousands of volts at the secondary coil output! But wait, we had talked about millions of volts earlier, how are we not there yet? Well, that's because there's one more trick used to amplify the voltage even more! You remember that big shiny donut at the top of the Tesla coil? That's a toroidal capacitor (often called the top load), and it forms a resonant circuit with the secondary coil. Let me explain: As discussed in the safety section (don't play with high voltage!), a capacitor is a device that stores electric charges. Similarly, you can think of inductors as devices that stores electric current. Assume there's initially some current in the inductor, and 0 charge on the capacitor. As time progresses, the inductor is pushing more and more charges onto the capacitor. Eventually so much charge builds on the capacitor that the inductor is unable to push any more. At this point the inductor has 0 current, and the capacitor has a bunch of charge on it. The capacitor then starts pushing those charges back through the inductor in reverse. Eventually all the charge has left the capacitor, and the inductor has a negative current through it. This forces a negative charge to accumulate on the capacitor until the inductor can't push any more, at which point the capacitor start pulling a positive current back through the inductor. This cycle repeats itself, which is why it's called a resonant circuit. It's a lot like when you're on a swing; the inductor current is analogous to how fast you move at the bottom of the swing, and the capacitor charge is analogous to how high you are at the top of the swing. On a swing, you can go higher by having someone push you, but they have to push you in the right way. Specifically, they have to push you forwards while you're going forwards, otherwise you'll actually lose height. So if you're swinging once per second, they need to push you once per second as well. Similarly, we can "push" the resonant circuit in the right way to amplify its output. In this case, we're "pushing" the circuit by putting current through the primary, which increases the current in the secondary. If done correctly, this is what pushes Tesla coils to millions of volts. But we need to do this at the right frequency, so we need to know the resonant frequency of the circuit. That's given by this equation: L is the inductance, and C is the capacitance. Tesla coils typically have a secondary inductance of 10-100mH, and a toroid capacitance of around 10-100pF. This usually results in a resonant frequency of 100kHz - 1MHz. And that's the basic theory of Tesla coils! It's really just a transformer driven at its resonant frequency. This creates a ridiculously high voltage on the capacitor, which cases the air to break down, resulting in a big spark. So all we need to do is drive the primary coil at the resonant frequency, how hard can that be? Circuit DesignWell, it's not the most trivial problem to solve. Keep in mind the transformer equation, we need a relatively high input voltage if we want a ridiculously high output voltage. And how do you control high voltage electronics? One of the simplest solutions is the spark gap Tesla coil. The idea is to make another resonant circuit with the primary coil by connecting a capacitor to it. The capacitance has to be chosen so both circuits have the same resonant frequency. One more component is added to the circuit: the spark gap. This is just 2 metal pieces placed a short distance apart from each other. When the voltage across the gap becomes large enough, the air breaks down and allows current to flow through. It's like a switch that only closes once a certain voltage has been reached. The idea in this circuit is to charge C1 until the spark gap activates. This completes the circuit between L1 and C1, so they start resonating as described before. And because it's the same resonant frequency as L2 and C2, that creates the ridiculously high voltage, resulting in a large spark from the Tesla coil. Each time C1 is charged up, that creates another large spark from the Tesla coil. Great, so all we need is a high voltage to charge up C1! But wait, our original goal was to create a high voltage, isn't this just moving the problem? Not quite! Our original goal was to create a ridiculously high voltage, but now we just need a very high voltage! We don't need millions of volts, just enough to create a spark in the spark gap. The separation is a few mm, meaning we only need a few thousand volts to create that spark. For this, we can use another transformer that's connected to mains power. Rather than building yet another transformer, it's really common to use a neon sign transformer. Microwave oven transformers are popular too, though they're not always as good for Tesla coils, and there's some safety hazards around taking apart microwave ovens (don't play with high voltage!). These increase the mains voltage from a couple hundred volts to around 10-20kV, which is just what we need for the spark gap! Putting it all together, here's what the final circuit looks like: Now that we've created the circuit from end to start, let's walk through it from start to end. Mains power from an outlet (120V/60Hz for me!) powers a neon sign transformer, which outputs power at 15kV/60Hz. As it the output voltage increases, capacitor C1 is charged up. When the output reaches the 15kV peak, the air in the spark gap breaks down, allowing the capacitor to discharge itself through the primary coil L1. This forms a resonant circuit that oscillates at 100kHz, and thereby creates an oscillating magnetic field from L1. This magnetic field creates a voltage across the secondary coil L2, which charges up the toroid C2. Because the magnetic field oscillates at the resonant frequency of L2 and C2, the voltage on the toroid becomes larger and larger until the air eventually breaks down, resulting in a very large spark! And all that finishes before the transformer reaches its negative peak, at which point the whole cycle repeats. Well, that's quite a lot of theory for a circuit that consists of only 6 components, eh? Let's take a look at how I actually built my first Tesla coil! ConstructionAt the time when I started this project, I understood the theory pretty well, but didn't really have a good idea of how to actually build one. I did some extensive research, and found a couple websites in particular to be very helpful. The first is hvtesla.com, and the other is Loneoceans Laboratories, both of which have very thorough documentation and explanations of how to build Tesla coils. There were many other resources I came across in my research, but I'm unfortunately not able to find them any more. Regardless, there's many more resources available now than when I made my Tesla coil. The first piece I tackled was the secondary coil. A common technique I came across was to buy a spool of magnet wire, and wrap that around a PVC pipe. My design required a 4" diameter, so I bought one from Home Depot. This actually made for a challenge of its own, because those pipes were only sold in 10ft sections, and I couldn't transport that in my Toyota Camry. The staff said I could have it cut to length at the store, but they wouldn't do it for me. They gave me a saw and told me to go at it. Felt pretty weird chopping up a pipe with other customers walking by me, but I got what I needed in the end! One of the mentors from my FIRST Robotics club offered for me to use his lathe to wind the magnet wire, which saved a lot of time! And I managed to order exactly the amount of magnet wire needed, the spool ran out just as we got to the final length. And it turned out beautifully, there were no major defects to speak of. I ended up gluing the ends of the wire to the pip to prevent it from unraveling. There was one more step to finish the secondary: polyurethane. The main purpose of this is to prevent sparks between the windings of the coil. Let's do a quick estimate: a Tesla coil is capable of around 1MV at its top. There are around 1000 windings on the secondary coil. That means there's around 1kV between each winding, which could result in a short! Magnet wire has an enamel coating that can withstand around 1kV before it breaks down, or 2kV in this case because there's 2 layers of enamel between each wire. But that's still pretty close for comfort, some extra insulation can't hurt. The polyurethane helps increase this breakdown voltage a bit, but also prevents the enamel getting worn down from scratches and scuffs. That's the secondary coil down, next I decided to work on the toroid. This was arguably the most tedious part of the whole project, it took over 2 weeks for me to complete. Obviously I wasn't working on this full time during those 2 weeks, but it was many hours of labor. But the end result was pretty awesome, definitely worth it! First off, why a toroid? Well, it doesn't have to be! Many Tesla coils are built with a sphere instead, since that's a lot easier to build. However the electric field becomes stronger in regions of high curvature (that's how lightning rods work!), which we can use to control where the sparks come off the Tesla coil. A sphere has a constant curvature everywhere, meaning the sparks come off in every direction. However a toroid has the greatest curvature along the outside surface, meaning the sparks mostly shoot out sideways. That helps prevent the main sparks from hitting other parts of the Tesla coil, but it also just looks way cooler! Ok, so how do you build a toroid? One common solution is to wrap some flexible tube around a cylindrical object. In my case, I found an aluminum dryer duct at Home Depot, and some aluminum pie pans at Safeway that ended up working really well together. However there's one slight problem. The dryer duct is a pretty bumpy surface, meaning it has pretty high curvature. However we want low curvature, otherwise it discharges early, resulting in shorter sparks. So that surface needs to be smoothed out. My solution was to add layers of Bondo, an automotive body filler, and sand it down until smooth. This smoothing process is what took the longest to complete. The first few layers filled the majority of the cavities, but it was still pretty rough. The general process was to mix up a small batch and spread it on. Wait for it to cure, then sand down any large bumps. Then repeat several times. After a few days, I was finally getting a smooth surface, but there were still lots of small holes that had to be filled in. More Bondo, more sanding, and I eventually had a very smooth surface that the cat approved of! But there was one more step to do: make the surface conductive. For this, I wrapped the toroid in aluminum foil tape. I got a 2" wide roll, but discovered the aluminum wrinkled at the outer surface. So I cut each strip in half, which did a great job at preventing wrinkles from forming. It also did a great job of making this step take twice as long! This was another couple days of work, just adding strips of aluminum tape and smoothing them down. But the end result was excellent, very smooth with no noticeable bumps anywhere. The next major component was the primary coil. It's common for these to have relatively high currents pass through them, requiring thicker wires. I'm not sure why, but copper tubing seems to be the material of choice for Tesla coil primaries. Without questioning it any further, I bought a spool. The primary coil is typically a flat spiral, and I'm still not really sure why that's the most common shape. But never mind that, I needed some way to mount the tubing. I had a mentor help me make a jig consisting of 6 plastic bars, each with notches cut out at regular intervals. I then spent a few hours shaping the tube to fit the desired spiral shape, with some useful feline help of course! Once complete, I mounted this onto a sheet of HDPE, and it was really starting to come together! The next major component I worked on was the primary capacitor. This was actually several capacitors wired together. The specific model number I used was the 942C20P15K-F (catchy name!), which appears to be another common component used by Tesla coil builders. It's a polypropylene film capacitor rated for 2kV, with a capacitance of 150nF. But if you recall, the transformer has an output voltage of around 15kV, much higher than the capacitor is rated for. That's why there are several wired in series, each capacitor only needs to handle a fraction of the transformer voltage. The downside of wiring them in series is a loss in capacitance. If more capacitance is needed, it's common to build multiple capacitor banks and put them in parallel. However for my design, only one bank was necessary. That helped save on cost, they're not cheap components! My design used 20 of these capacitors in series, resulting in a voltage rating of 40kV, and a total capacitance of 7.5nF. I mounted all these capacitors on another sheet of HDPE, each secured by a zip tie. One addition I made to the back side was a bleed resistor for each capacitor. This ensures that when the Tesla coil is turned off, any voltage stored in the capacitors is discharged so no one gets shocked. Only 2 more components to go! And fortunately these were the easiest ones: the spark gap, and the transformer. For the latter, I just ordered a neon sign transformer online, though my wallet wasn't happy about it. The spark gap was constructed from a couple lag bolts in some wooden posts. All 3 of these components (spark gap, transformer, and capacitor bank) we mounted under the primary coil with some plywood and wood posts. And to protect the wood, it was spray painted blue. And that's the majority of the work done! Finally, it took over a month to get to this point, but it looks fantastic! But there's still a few more things to do before it can make sparks. For one, all the components need to be wired up. The wire insulation should be capable of handling the transformer output voltage, since some wires pass right next to each other. Your typical hobbyist wires are usually only rated for 300V or so, which is plenty for a 5V breadboard, but not this! A common suggestion I've seen is to use spark plug wire, which normally connects the spark plugs in your car engine. Those are usually rated for 40kV or so, which is plenty for this application. The guy I talked to at O'Reilly's gave me a weird look when I asked for spark plug wire, but I eventually got what I needed! At the inside end of the primary coil, the end of the tube was fed through the HDPE sheet to make a connection there. However connecting the other end is not as simple. The exact resonant frequency of the secondary can change in various conditions, meaning the resonant frequency of the primary needs to be adjustable. For this, I used a long spark plug wire with an alligator clip to tap the primary at any location. The optimal location for the primary tap ended up being only a quarter rotation from the end, so I got lucky with the amount of tubing I bought! Next, I needed a ground plane, for which I ended up using some chicken wire laid on the floor under the Tesla coil. The main purpose of this is to provide a suitable ground connection for the bottom of the secondary. It would be bad to connect it to the wiring in your house, it could seriously affect anything plugged in due to the high voltages. The last step was adding a power switch. Obviously this needs to be far away from the Tesla coil so you don't get zapped. My solution was to use an old extension cord and splice a light switch into it near the other end. It seems a little sketchy, but it's always worked fine. After that, the Tesla coil was finally done! ResultsAfter adjusting the spark gap distance and finding the optimal primary tap location, I got some fantastic sparks coming out of it! I apologize for the dark and grainy photos below, but it's best to photograph Tesla coils in the dark, and my phone camera wasn't very good in these conditions. And remember, don't play with high voltage if you don't know what you're doing! With the toroid by itself and nothing around, sparks randomly shoot off in all directions around the toroid. One fun modification is to add a thin metal rod to the toroid, which causes all the sparks to come out from there instead. The reason is that the end of it is sharp, meaning it has a high curvature, resulting in a much stronger electric field at the tip of it.
Another really cool demo with Tesla coils is lighting up fluorescent tubes! These require a high voltage to emit light which is exactly what Tesla coils do! In fact, because Tesla coils create such a strong electric field, the fluorescent tubes can actually light up from several feet away! This is a form of wireless energy transfer, which was Nikola Tesla's original purpose for his creation. My final physics class had every student create some physics project, and this was my entry! I even got to demonstrate it, and it was definitely one of the favorite projects there! |
Details
AuthorWrite something about yourself. No need to be fancy, just an overview. Archives
May 2022
Categories |









RSS Feed