Dammit, I tried writing the best darn paper I could in hopes of scoring a free trip to Vegas on university money, but costs a lot of money to have you paper submitted to the conference being held there. Oh well, I guess I ended up learning something, if that’s worth anything.
So the class project I did was to make a 4-bit full adder using threshold gates and written in Verilog HDL so it can be loaded onto an FPGA. A threshold gate is sort of a model of a neuron cell from the brain. Basically, the binary inputs (1 or 0) are multiplied by individual weights (positive or negative integers) and summed. Then the gate output is “1″ if the sum is greater than a threshold value, or “0″ is less. The benefit of this is the ability to reduce a complex Boolean function to one gate (certain restrictions apply). To find the weights and threshold value Dertouzos’ method is used, which surprisingly was not googleable.
Even if a function can’t be reduced to a single gate, multiple threshold gates can be connected together to form a neural network or cascaded to still be realized. The sum function for a full adder can’t be realized as one, but the carry out can be. Luckily another method, called IMS (Implied Minterm Structure), does the trick and groups the minterms so Dertouzos’ method works. Using IMS, three threshold gates are needed to cover the sum minterms and then connected together with a forth.
Now that the number crunching is done, its time to code this into Verilog. Supposedly real numbers can be used, but the old version in the lab couldn’t, so I had to settle for integers. To get the code to compile, all of the threshold values needed to be rounded up and then the threshold inequality needs to be changed to greater or equal. Since each threshold gate has a different combo of weights and threshold, each one was written separately, then combined as a full adder module and finally into a 4-bit full adder. It even worked when loaded into an FPGA (Spartan variety). Below is the code so you can claim it as original for you’re next class project or perhaps for some nerdy shits and giggles.
module threshold1(f, A, B, C); output f; input A,B,C; reg f; parameter integer w1 = 1, w2 = 1, w3 = 1, t = 1; integer out; always@(A or B or C) begin out = A*w1 + B*w2 + C*w3; if (out >= t) f = 1'b1; else f = 1'b0; end endmodule module threshold2(f, A, B, C); output f; input A,B,C; reg f; parameter integer w1 = 1, w2 = 1, w3 = 1, t = 2; integer out; always@(A or B or C) begin out = A*w1 + B*w2 + C*w3; if (out >= t) f = 1'b1; else f = 1'b0; end endmodule module threshold3(f, A, B, C); output f; input A,B,C; reg f; parameter integer w1 = 1, w2 = 1, w3 = 1, t = 3; integer out; always@(A or B or C) begin out = A*w1 + B*w2 + C*w3; if (out >= t) f = 1'b1; else f = 1'b0; end endmodule module threshold4(f, A, B, C); output f; input A,B,C; reg f; parameter integer w1 = 1, w2 = -1, w3 = 1, t = 1; integer out; always@(A or B or C) begin out = A*w1 + B*w2 + C*w3; if (out >= t) f = 1'b1; else f = 1'b0; end endmodule module threshold5(f, A, B, C); output f; input A,B,C; reg f; parameter integer w1 = 1, w2 = 1, w3 = 1, t = 2; integer out; always@(A or B or C) begin out = A*w1 + B*w2 + C*w3; if (out >= t) f = 1'b1; else f = 1'b0; end endmodule module fulladder (sum, c_out, A, B, c_in); output sum, c_out; input A, B, c_in; wire x, y, z; threshold1 n1 (x, A, B, c_in); threshold2 n2 (y, A, B, c_in); threshold3 n3 (z, A, B, c_in); threshold4 n4 (sum, x, y, z); threshold5 n5 (c_out, A, B, c_in); endmodule module full_4bit_adder (sum, c_out, A, B, c_in); output [3:0] sum; output c_out; input [3:0] A; input [3:0] B; input c_in; wire x, y, z; fulladder a1 (sum, x, A, B, c_in); fulladder a2 (sum, y, A, B, x); fulladder a3 (sum, z, A, B, y); fulladder a4 (sum, c_out, A, B, z); endmodule
I hope my neighbors don’t mind me milling things late at night. The vacuum is the loudest over the router and stepper motors, so they’ll probably just think I like my house really clean. To kick off my CNC adventures, I’m making a fixture to hold PCBs for isolation routing.
It’s nothing fancy, it mainly helped me understand the CAM portion making stuff. I ended up not using the Sketchup model because of added learning involved to use a script or something, but it can be done. Instead I used CAD to draw the square with the rounded out corner reliefs, then used the CAM software CamBam to setup the stock size and generate G-code. My worst problem was trying to make the coordinate systems jive between the CamBam and my machine. In standard drawing coordinates, the +x goes to the right, while my machine’s +x moves left. This was corrected with an option to set a separate machining origin, and also using offsets in the machines software.
I made the pocket for the PCB slightly larger than the width and length of the raw stock and to a depth of .060″ to match the thickness. The corners were over cut to allow the PCB’s square corners to fit. Next I’ll be drawing up some various clamps to go over the edges to press down. By using some double sided tape underneath, the PCB should be a little higher to give the clamps something to press into. I’m also going to add two locator pins so the fixture can be taken off and put back on in the same place. Built into G-code are places to store fixture locations and makes having multiple fixtures even easier. I milled the main pocket and corners separate and both programs aligned perfectly, Yay!
Yay, three times is the charm. My CNC machine finally milled it’s table flat without motors stalling or random nuts coming loose. Since the second attempt, I tweaked the bearing adjustments on the Y-axis and upped the current to all the motors for more torque. The motors got slightly hotter, but not so much that I couldn’t touch them. I also ran the table cutting program a few times without a tool to work out any other kinks.
Cutting the table seemed to take out the inaccuracies from building and you can see in the corners where the high sides were cut shallower than the low side. When I glued the table together I didn’t notice it was twisted slightly on one end. Luckily it could be compensated for in the end.
The run wasn’t without its problems though. Being so pleased with the dust extractor I built, I got a new filter for the shop vac for maximum performance. It was too much for the all-purpose bucket, and the vacuum imploded it slightly and let all the wood dust through to the vacuum. Once the vacuum filter clogged it quit working and the dust went everywhere. Oh well, I bought a new bucket and some extra filtering material and it seems to be working again.
So now I can start making stuff on it, but since I’ve been putting my energy into building it, I’m not sure how to do that. I’ll probably start by making a fixture and hold-down clamps for circuit boards and plastic sheet. I’ve already read some webpages that I’ll try and emulate, so I just need to put it all together.
I took a second shot at planing the table on my DIY CNC machine, but had to abort after several passes. All the new systems were working well, new router, dust extractor and vacuum system, but a rouge nut and washer appeared on the far side of the table. Once the machine was stopped with the E-stop button I found the nuts holding the bottom Z-axis drive shaft bearing mount were vibrating off.
I added some lock washers to all six bolts on the bottom side of the Z-axis carriage to prevent that from happening again. I suppose I should start checking things like nuts coming loose before firing up to cut, so lesson learned. It was lucky the nut and washer fell off out of the way of the router and that I noticed it.
Actually, I needed to restart from the beginning of the program with an offset down to correct a step between the first and second attempts. This also let me check if the new cyclone dust extractor worked on the fine saw dust produced from cutting the MDF board. The shroud made from a CD spindle cover worked rather well for its first real test. I’ll think about adding some brushes around the perimeter later, but was satisfied at how well it controlled the dust cloud that I’ll continue without for now.
Before I start cutting again, I need a dust extractor to go along with the vacuum. The filter on the shop-vac was clogged with the dust I created from the first run so much it lost suction. Instead of spending $10 every few minutes on filters, I made a cyclonic dust extractor for the same amount. Since anyone with a CNC machine that cuts has one, there are plenty of plans online. I looked at a couple using a 5 gal. bucket and some PVC fittings that looked easy and went with that.
The input to the extractor comes from the CNC machine and to a 90 degree elbow pointed toward the inside wall of the bucket. Then the output to the shop-vac is a single straight piece of PVC pipe, with the end inside the bucket higher than the elbow. Nothing complicated and parts were easily found at the big box store; 2″ PVC pipe section, elbow and two couplings and a general purpose bucket with lid. The hard part was trying to match the two different hose diameters.
After gaining a third section of hose, sacrificed from a junk vacuum in the basement, I was able to make a permanent connection to the shroud and bungee cords. The shop-vac hose hooked to this new hose like it was meant to be, but was a trick to find a compatible PVC piece for the opposite end. I used my dremel tool and ground a step into the inner diameter of a section of 2″ PVC pipe to allow the shop-vac hose to fit into. I’ll still be able to disconnect this section to use the shop-vac for cleaning elsewhere. The last section of hose was an extension kit I bought for a different brand of shop-vacs and was naturally incompatible. One end fits into the vacuum’s input well enough, but the opposite end to the extractor wasn’t near anything. I wound up cutting a slot on one end of a section of 2″ pipe and squeezed the end together with a pipe clamp till the hose fit over. Once the hose was on, the pipe clamp was released and any remaining holes taped over.
With the all the fittings made, they need to be connected through the bucket lid. The two holes were cut with a craft knife and care needs to be taken not to rip the material, because it’s easy to do. I scrapped a lid trying to epoxy the two PVC pipes in place, with both times breaking off immediately when moved side to side. Next I sandwiched the lid between two edges of pipe coupling that worked well. For the output section I cut a coupling in half, then cut through perpendicularly on only one of those halves (just one cut so it stays a ring, but opens wider). The solid coupling half goes on the straight pipe section, inside the bucket. On top of the lid, the cut coupling half can expand around the pipe to go all the way down easily. The PVC cement seems to melt the lid material to the pipe and fuses everything securely (and gives off some bonus fumes). The input side also needs a coupling cut in half, but only the piece with the extra cut like before; the edge of the elbow serves as the bottom part of the sandwich.
Once the glue dried and the hoses were connected, I fired up the vacuum to test for leaks. Where hoses met, I sealed with duct tape. Then sealed leaks in the PVC/lid area with some silicone. While the vacuum was on, the wet silicone sucked into holes. I also revised the bungee cord rigging to hold the hose off of the work surface. With the gantry at is furthest position, the bungee cord was wrapped around the hose a few times and held in places with zip ties. When the gantry moved back to home, the hose naturally coils against the wall and out of the way. From the pic below, it looks like the cord is pulling hard on the hook in the wall, but there is still some slack left.
Eventually, I’ll move both the dust extractor and vacuum in the basement, with the switch controlled by the CNC software. But that will have to wait till I actually make something.