Customizable CNC Coil Winder
by iandersonsprecher in Workshop > CNC
504 Views, 5 Favorites, 0 Comments
Customizable CNC Coil Winder
If you have ever wound a transformer, electromagnet or guitar pickup by hand, you know how frustrating it can be. I ran into this issue while trying to wind the secondary for my Tesla coil. Due to the size, counting the turns and rotating it to wind the turns were both difficult. Instead of building a specialized jig just for that project, I instead designed a parametric coil winding machine using easily obtainable parts capable of winding coils of all shapes and sizes.
The frame of the winder is built from aluminium extrusions, brackets, and 3D printed parts. Most of the mechanical parts are easily obtainable, while a few parts need to be custom fabricated (access to a cnc/water jet cutter and laser cutter will be helpful). The winder is fully independent and is controlled by an Arduino Nano connected to a user interface and motor drivers.
Supplies
The full parts list, purchasing links, and extrusion lengths can be found in this Google Sheet. This project is fully parametric, meaning that you can change the gantry length to fit your needs. I chose to make a larger gantry to wind tesla coil primaries. I have included a calculator in the parts list to calculate the specific part lengths required for any gantry length.
I used the following tools for this project: drill press and drill bits, saw capable of cutting aluminium (I used a chop saw), angle grinder, screwdrivers, taps and thread dies (M4, M6, ½-20unf), laser cutter and water jet cutter (not mandatory, but helpful), soldering iron, wire stripper, and wire crimper.
Design
My goal of this project was to make something simple and operationally independent. This led me to use off the shelf components and 3d printed parts for the winder and a versatile user interface for control.
I designed the frame of the winder in OnShape using the frame tool. I widened the distance between the frames to accept coils of 12cm diameter. To house the electronics, I used a split case design where the curved outer panel would be clamped between two edge panels with recessed groves. I used two 90 degree brackets mounted to the extrusion with screws to allow the edge panels to be printed flat without supports. I used threaded inserts extensively throughout the project to fasten 3d printed parts together due to their added precision and wear resistance.
I used two stepper motors, one for driving the lead screw and the other through a 0.6 ratio belt reduction to the spindle to increase torque. To drive the stepper motors, I used a drv8825 stepper driver due to its 2.5A per phase output capacity (greater than A4988 and tmc2208 drivers) and microstepping capability. However, the other drivers are pin compatible and will also work.
I used a breadboard for prototyping during the design phase. I later used KiCad to design a PCB for the final design. I went with a single sided design with thick traces to make it easy for etching at home.
For the winding head, I chose to create a condensed version of those used in commercial machines. Instead of expensive winding nozzles, I used two POM blocks with different groove sizes cut inside to lay the wire. While a belt-driven design would be simpler and cheaper, belts are less rigid and precise than lead screws. This led me to use a 2mm pitch lead screw over a gt2 belt (0.01mm accuracy vs 0.16mm accuracy) to improve winding capabilities for smaller magnet wire sizes.
You can find my CAD file here
Theory
The coil winder has a rotational axis for the spindle and a horizontal axis for the winding head. Each axis is connected to independent stepper motors. When the spindle spins a bobbin, for every rotation of the spindle the gantry must move a distance equal to the wire diameter. This allows it to lay consecutive layers that don’t overlap. The winding head can then reverse at the ends of the bobbin for winding multilayer coils.
The magnet wire first gets taken up off the spool into the pickup arm mounted on the gantry. This elevates the magnet wire away from the gantry and prevents it from tangling. This then enters an adjustable magnet wire straightener and tensioner before being picked up by the adjustable (in both length and angle) magnet wire laying arm, going through a cleaning pad, then through the POM guide onto the coil.
In my setup, I used a specialized magnet wire tensioner though this is not required. It is meant to keep a constant tension on the magnet wire and absorb sudden changes in tension. This is best for thinner magnet wire or rectangular bobbins (such as guitar pickups).
Fabrication - 3D Printing
I used a Prusa Mk4 for all the parts with a build volume of 210mm x 250mm. Make sure to use a printer with a similar or larger build plate size. For structural parts, I used generic PETG filament with medium infill and multiple wall loops (4-6 wall loops, <50% infill). For non-structural parts I used generic PLA filament with multiple wall loops and lower infill (2-4 wall loops, <25% infill). For parts that required extra rigidity such as the pickup arm, I used PLA carbon fiber filament. Note that the cone pipe holder prints have embedded nuts. When printing, add a pause layer. For the colors, I used a black and a blue grey filament for a good color match.
All of the thermal inserts are standard m3 screw inserts. There are many good guides online for installing heat inserts into 3d prints, but in general, a soldering iron with a conical tip can be used to press the insert into the plastic. Ensure that you do not push the insert all the way in, leaving a small portion protruding from the surface. While it is still hot, you can use a flat metal surface (I used a furniture barrel nut) to press in the remainder. This ensures that the heat insert is flush against the surface. I found that 350 C works well for PLA.
I have included two coil mounting options. One uses two cones and a 12mm shaft collar for holding a hollow pipe and another specialized bracket for guitar pickups.
Downloads
Fabrication - Electrical
Disclaimer: This project involves working with AC Mains Voltage (110V/220V). Mains voltage is dangerous and can be lethal if handled incorrectly. Do not attempt this project if you are not experienced or comfortable working with high-voltage electricity. Always disconnect the power cord before opening the case or touching any internal components.
How it works
The mains power first passes through an IEC connector, a switch, panel mount fuse, and then into the 24v power supply. This then enters the circuit board and powers both stepper motor driver modules (DRV8825) and is regulated by a 5v regulator (LM7805) to power the Arduino Nano. The Arduino Nano receives digital input from the two limit switches at either end of the gantry, the keypad, and the e-stop button. It then outputs the step (each pulse causes the stepper motor to take one step) and direction signals to each stepper motor plus the serial data line (SDA) and serial clock line (SCL) to control the i2c 4x20 character LCD. The enable pin of each stepper driver (active low) is connected through diodes to the normally closed e-stop button with a pull-up resistor to 5v. This means that while the e-stop is not pressed, it shorts the enable pins to ground, but once pressed the contacts open, allowing the pull-up resistor to pull the enable line up to high and disabling the drivers.
Assembling PCB
There are many ways to fabricate hand-etched circuit boards. Use the PDF file of the mask for etching. I have also included the Gerber files if you want to get them professionally made. Follow the diagram to populate the PCB with components. If possible, it's always best to go from smallest to largest component size. For components such as the stepper motor drivers and Arduino Nano, it's best to socket them in case something gets damaged. This makes replacing it simple.
To wire the back panel, I used spade and fork crimp terminals with some soldering. Make sure to insulate exposed areas. On the bottom of the PCB there are three solder jumpers under each stepper driver. For the gantry stepper, bridge the M1 connection (4 microstepping), and for the spindle stepper, bridge the M0 (2 microstepping) connection.
You can find the Gerber files in the GitHub repository here
Wiring
I used DuPont / mini PV connectors for connecting to pin headers and wafer-style connectors for connecting to the PCB. Because of the locking tab, wafer connectors are generally more reliable and mechanically stable. To make the connector, I first measured and cut out the proper wire lengths, then stripped the ends to reveal around 2 to 3 mm of bare wire. I then removed a crimp terminal and placed it into the crimper tool, noting the direction. Then close the crimper until it holds the terminal in place without crushing. Insert the wire into the terminal. You should feel the insulation stopping after reaching the smaller crimp wings. Keep the wire in place and crimp.
Back Panel wiring
To wire the back panel, follow the photo instructions to connect the parts. I used crimp lugs as they make servicing easier than soldered connections. Make sure to insulate the exposed metal on the lugs or solder joints with heat shrink tubing.
Fabrication - Aluminum Extrusions
Aluminum extrusions
I used 3030 (30mm x 30mm) and 2020 (20mm x 20mm) extrusions for this project. When measuring, make sure to remember which side of the mark is the offcut and actual part. When cutting, orient the blade to compensate for blade thickness. I used a chop saw for this. You can find all the lengths in the parts spreadsheet. After cutting, make sure to clean and debur the parts.
Some parts require additional fabrication.
- 2x 30cm 2020 aluminium extrusion: requires m6 threads in both ends and two countersunk 6mm holes in the side spaced 15mm from each edge.
- 4x 60cm 2020 aluminium extrusion: requires one countersunk 6mm hole 10mm from the bottom edge.
- 2x 2020 gantry extrusion: requires m6 threads in both ends.
- POM nut: use a file and make a chamfer on each of the four corners.
For measuring the drill position, I used a paint pen and a caliper to measure the distance from the edge then made a slight scratch on the surface. Then use a center punch to mark the hole.
When drilling the extrusion, make sure to clamp it down and use a pilot hole before drilling. For the countersink, don’t unclamp it - instead, change the drill bit for one slightly larger than the head of the screw (~10mm). Then use it to drill through the flange bit to create a pocket.
Before tapping, clamp the extrusion in a vice and apply cutting oil to the tap. Then insert into the hole and apply pressure while rotating until the thread starts, then let the tap guide itself. For every turn, back out half a turn to break off chips. For the POM nut, I found that for it to fit between the v wheels, the 4 vertical edges needed to be chamfered. I used a file for this.
Fabrication - 3030 Extrusion Bracket
Four 3030 angled brackets must be drilled and taped to mount the chassis base plate. Use the 3D printed guide to drill a 3mm hole on one face and use a m4 tap to thread the hole. When tapping, make sure to clamp the part in a vice.
Downloads
Fabrication - Motor Bracket
For the 90 degree nema 23 bracket, I used a hack saw and made a straight cut to remove the joining bit between the slots for mounting it to the extrusion. Make sure to cut it straight the first time. Use a file or belt sander to smooth the surface.
Fabrication - Shaft
I used a 12mm stainless steel rod for the shaft. When measuring, add a few millimeters to the length to compensate for sanding later on. An angle grinder can be used for cutting. To thread the shaft with the 20-½ unf thread for the chuck, I first did a large 45 degree chamfer on the end of the shaft with a belt sander. Use cutting oil as a lubricant. Use a lathe to cut the threads if available. The thread should be roughly 30mm long. When cutting, make sure to use consistent pressure and smooth motion to prevent tearing or cross threading.
Fabrication - Aluminium Parts
Both the bottom chassis panel and winding parts require custom sheet aluminium parts. The bottom chassis panel is made from 1mm aluminium plate. I used my school’s waterjet cutter for the 3mm aluminium winding head brackets. I have included printable templates and dxf files for all the parts. Make sure to use a center punch to mark the holes before drilling and debur after cutting. Although not the best, 3d printing these parts can also be used.
Fabrication - Gantry Plate
For the gantry plate to have enough clearance above the gantry extrusion, four of the existing holes on the gantry plate must be countersunk to fit countersunk m5 screw. As I didn't have a countersinking bit, I used a large drill bit instead.
Fabrication - LCD Bezel
I used a laser cutter to cut out the two 3mm acrylic bezel pieces to cover the LCD. Another option is to use a 3D-printed outer bezel, combined with a transparent sheet of plastic, such as from a transparent folder, to protect the LCD. I have included SVG files for laser cutting and stl files for 3D printing.
Downloads
Fabrication - POM Wire Guide
For the wire guide / nozzle, I cut two thin pieces of POM plastic BBB x BBB and drilled two mounting holes through both pieces 15mm from each other. I then used a square file to multiple create matching grooves in both pieces of various sizes for the wire to pass through.
Assembly - Extrusion Frame
Before assembling, check that you have all parts, including hardware, extrusion, brackets, and 3d printed parts.
You can find the complete step by step assembly slide show here
The first step is to assemble the frame with the extrusions. Don’t fully tighten the screws until everything is in place. Don’t forget to insert the t-nuts required for later steps. To make sure the frame was square and flat, I built it on a flat wooden surface and used a 90 degree square for the corners. I started by building the bottom frame, and then added the three vertical posts for the 12mm bearing blocks before finally adding the 2020 extrusion for the gantry. When inserting the screws for the extrusion brackets, it's best to add washers to distribute the load.
Assembly - Gantry Assembly
After assembling the extrusion, start building the gantry assembly. First attach the v wheels then POM nut. Then assemble the winding head and attach it onto the gantry plate with the 4 countersunk screws and spacers. For the wire cleaner, I attached small felt strips and springs to apply tension (not shown in image).
Install the two 3D printed brackets on either end of the gantry extrusion. The protruding end should face up. Screw both in with 15mm m6 screws. Insert the 8mm flat pillow bearing into each bracket and fasten with 15mm m6 screws and m6 nuts inserted into the recessed pocket.
Solder the wire to the limit switch and attach them to either bracket with the limit switch bracket and small screws. Before attaching the left side bracket, first thread the threaded rod through the POM nut and place the gantry assembly on the track.
Assembly - Installing Bearings
To assemble the clamp bearing, take three 626zz bearings and attach with three 20MM M6 screws and nuts. Then attach it onto the right vertical post. Attach the other two 12mm pillow bearings to the other two posts with edge flush with the top of the extrusion. When inserting the shaft through the bearing, add the pulley and the belt. If it sticks, chamfer the edge of the shaft and fully loosen or remove all the set screws.
Assembly - Add Bottom Plate
The bottom plate can be screwed on with 4 5mm m4 screws. Make sure to loop the ground ring around one of the screws before tightening (safety critical).
Assembly - Attach 3d Printed Components
For the 3d printed case, first install the left side 90 degree bracket with m4 screws, then attach the left side panel with m3 screws. The meanwell powersupply, mounting bracket and 90 degree stepper motor bracket can then be installed. Before tightening the screws for the motor bracket, tension the belt by sliding the bracket. Attach the spindle stepper with shock absorber and 45mm spacers and MM screws with shaft coupler onto the threaded rod. The left panel with PCB can then be attached and wire connected before the central panel is installed. Before attaching, remember to program the Arduino Nano.
Programing Code
The code operates around the MenuSystem library and AccelStepper library. The MenuSystem library creates the main user interface similar to a phone by using a menu_system (home page) that contains menus (settings) and menu items (ring tone). Menu items are connected to unique functions that execute a certain action. Functions that have MenuComponent*menu_component as their function parameter are menu item functions.
At the top of the program after pin declaration, custom structs are defined to hold physical machine parameters and settings that are referenced through the program. The blank winding parameter struct is then updated later in the program from user entered parameters through menu item functions (such as wireDia_set or turnNum_set).
The single difference between multilayer coil option and singlelayer coil option is that the multilayer coil has an included end position, while single layer coil only has start position. The end position is calculated later. After run is pressed, it calls the start function that checks if all parameters are valid, prompts for a dry run (gantry moves to start and stop position), then sends the winding parameters struct to the windCoil(const CoilParam& params) function.
While winding, the spindle is treated as the master axis and the gantry as a slave axis. As the spindle rotates, the program continuously measures the number of steps the spindle moves. Based on the desired wire pitch (wire diameter plus spacing), it calculates how much the gantry should move for that amount of spindle rotation (gantryStepPerSpindleStep). Because this movement is usually a fraction of a step, the program uses an accumulator to collect fractional motion until it adds up to a full gantry step and then issues that step. When the gantry reaches the end of the winding width, the pitch direction is flipped so the gantry reverses and starts the next layer, while the spindle continues rotating smoothly. This allows the gantry and stepper to track perfectly while acceleration and direction change.
The accel stepper library has two main ways of running the steppers: runSpeed() and run(). The runSpeed() function drives the motor at a constant speed set by setSpeed() and does not use acceleration. In contrast, run() moves the motor toward a target position, accelerating up to the limit set by setMaxSpeed() and using the acceleration set by setAcceleration(). SetSpeed() has no effect when using run(). The line stepper.setCurrentPosition(stepper.currentPosition) is used to reset the internal motion planer without moving the motor. I used both throughout the program. Note: Currently the code still has issues with saving parameters to EEPROM. I plan to fix this shortly and post a new and refined version of the code. The program and all built files can be found in my github page:
To program the Arduino Nano, the following libraries must be downloaded and added to the Arduino IDE: Keypad.h, AccelStepper.h, LiquidCrystal_I2C.h. The rest should be included by default. If you notice the error arduino out of sync, try changing the bootloader. Different arduino boards may use the new or old bootloader.
You can find the the arduino code in the GitHub repository here
Troubleshooting
Before using the machine, first run a gantry calibration procedure. This tells the microcontroller the gantry distance and is used in internal calculations.
The two DRV8825 stepper motor drivers have current limits to regulate the current through the motor coils. This is important because stepper motors are rated by current, not voltage. Setting the correct current limit prevents the motor and driver from overheating while still providing enough torque to avoid missed steps. This adjustment varies between stepper motors. On the DRV8825, the current limit is set using the small trim potentiometer on the driver. This sets the reference voltage (Vref) that determines maximum coil current through the relation Imax = Vref * 2, where Imax is motor phase current in amps. Vref is measured between the potentiometer and ground. If your stepper motors have a datasheet, use this formula to calculate the reference voltage. Another option is to power it with a lab bench power supply and adjust the limit to minimize stall current and maximize holding strength. Instructions on how to adjust the current limit can be found online here.
Troubleshoot common errors:
Stepper rotating in the wrong direction: swap the connection of one of the stepper motor phases.
No power or strange behavior: check that power is entering the board and inspect for broken or poor solder joints. Also, check that all the connections match the wiring diagram and that the jumper wires have proper crimps and are configured correctly.
Iterations and Future Improvements
This project was definitely my largest and most ambitious project yet. Over the course of the project, I went from no CAD knowledge to creating the full design in CAD. This was also my first Arduino project, and taught me a lot about programming and motion control. Overall, this project took me more than 2 years from start to finish. However, there is still much to improve. I hope to improve the range of the winding head by creating a more elegant extension system. I am still improving the code and ironing out some bugs. I am learning to use a Tormach CNC milling machine and CNC lathe at school, and hope to use these tools and skills to program the lathe to cut better threads for my chuck and cut out solid aluminum gantry brackets.
The iteration aspect of this project was grueling but also a valuable educational experience. I would often print or cut a part just to find I forgot about the placement of a single screw, or spend hours staring at the program finding bugs and improving the code. I tried to embrace this aspect of engineering and see each setback as an opportunity to learn.