Thursday, June 2, 2016

A CNC Pickup Winding machine built on an ATmega8

A pickup winding machine it is used to wind a guitar pickup.
You can find my previous ATmega manual pickup winding machine here:
This project is a manual / CNC pickup winding machine, built on top of an ATmega8 microcontroller.

  • wind counter
  • slow startup
  • automatic stop
  • configurable motor speed
  • configurable winds
  • 2 direction
  • CNC automation
  • configurable wire dimension (for CNC)
  • traverse dynamic speed
This winder has an LCD display, it will show:
  • the current motor direction
  • the rotating speed of your pickup
  • the total and current wind counter
  • the direction of the traverse mechanism
  • the speed of the traverse motor
User can choose if enable or not the guide movement, if not, this machine can be use in manual mode.

There are 3 buttons, SELECT, button UP and DOWN.
Short press SELECT to move to make the traverse motor move 1mm.
Long press SELECT to enter / exit programming mode. During the programming mode press button UP and DOWN to edit the selected value, short press SELECT to skip the next value, or long press SELECT to save new values and go back to running mode.
Short press button UP to change direction of the winding.
Long press button UP to reset counter.
Short press button UP to change direction of the guide movement.
Long press button DOWN to reset counter.

If you are in building mode, to make the wind start press the RUN pedal, it will start with a slow startup, to stop the winder release the RUN pedal.

The winding machine will automatically stops when the wind counter reach the configured number.
If you disable the autostop mode, the machine will always count wind, independently by the direction choosen.

The winding motor used is cheap DC motor 12V 1200rpm, the motor driver is L298N chip board.

The traverse mechanism it is built using parts from a (broken) scanner, the guide motor is the stepper motor of the scanner.

Traverse mechanism has two limits. Limits are build using break-beam optosensos mounted on a small cilindric neodymium magnet.
That way guide limits can be moved depending on the pickup to be wired.

The wire tensioner it build using felts and a spring. It is simple but it works quite good.

The winding nozzle it's taken apart from a dental saliva ejector that my father (who is a dentist), gives me. It has a really small hole, and it's also built with plastic. This will not damage the wire we are going to wind.

The counter sensor it is built using a hall effect switch and a small neodymium magnet glued to the pickup holder.

My traverse mechanism has an accuracy of 5.29 um/step. One can mount another guide motor and harware, and will have other accuracy, indeed that mechine need to be calibrated.


There are two calibration steps the user has to do:
  1. Measure the traverse distance moved per step. The GUIDEMOTOR_MEASURESTEP directive has to be set to 1, and the number of step to move has to be set in GUIDEMOTOR_MEASURESTEPSTEPS. Then the hex has to be compiled and uploaded. Now when you startup the machine, the guide will move for the desired number of steps. We measure the distance traveled. We compute the steps/mm as steps moved / total distance traveled. Than um/step is 1000 / steps/mm. Let's suppose we have set 20000 as step to move. If we have measured a traveled distance of 106mm, the step/mm is 188.879, and um/step is 1000/188.879, so 5.29. When done, set GUIDEMOTOR_MEASURESTEP to 0 again. Now we can set GUIDEMOTOR_1MMSTEP to step/mm value and GUIDEMOTOR_1STEPUM to um/step value.
  2. Measure the traverse maximum / minimum speed. The GUIDEMOTOR_MEASURESPEED directive has to be set to 1. Then the hex has to be compiled and uploaded. Now when you startup the machine, the LCD will show the max and min speed the guide motor takes to move 1cm. When done, set GUIDEMOTOR_MEASURESPEED to 0 again. Now we can set GUIDEMOTOR_1CMMAXSPEEDTIMEMS and GUIDEMOTOR_1CMMINSPEEDTIMEMS to the values shown on the display.
After that calibration steps is been execute, other values has to be set.
A guide step helper spreadsheet it is provided to help compute that values. The GUIDEMOTOR_FIXEDSPEED_DEFAULT, WIRE_MINGAUGE and WIRE_MAXGAUGE dimensions can be computed using this sheet.
You just has to fill values you already know, the values of your hardware.

The math to compute that values is also described as comments in the source files.

The maximum and minimum wire gauge it is an important parameter that defines what your pickup winder can wrap.

The winding pattern implement in this machine, is a simple traverse winding that places each wire wind next to the previous one.
See below and example of a pickup winded with this machine.

Things get's intereseting here, because the wiring motor doesn't always spin the same speed, take as example the "slow startup" stage, or when you decide to wire your pickup at a lower speed.

The guide motor is driven in a TIMER interrupt.
Here we set the steps that motor walk to position the cable,
We know:
  • the number winds made from the last motor movement
  • the current pickup rotation speed
  • the wire gauge
  • how many distance the guide motor travel for every step done
  • the maximum and minimum time the guide motor takes to walk 1cm

We can compute how much space the traverse mechanism has to travel in order to place the wire next to the previus one, that's pretty simple.

number_of_winds = current_number_of_winds - current_number_of_winds
distance_to_wire = wire_gauge * number_of_winds
step_to_move = distance_to_wire / guide_motor_distance_traveled_for_1_step

Things get's a little complicated because i'm not using float math, so i've to record the remnant of the division.

number_of_winds =
  current_number_of_winds - current_number_of_winds
distance(um)_to_wire =
  wire_gauge(um) * number_of_winds + remntant_distance(um)_to_wire
step_to_move =
  distance(um)_to_wire / guide_motor_distance(um)_traveled_for_1_step
remntant_distance(um)_to_wire =
  distance(um)_to_wire % guide_motor_distance(um)_traveled_for_1_step

But that's not all folks, we also have to move the guide motor at such a speed that every wire is placed next to the other right when the pickup has done a full loop, I mean, we do not want a rapid guide motor travel, then a motor stop, then a rapid travel again, that movement has to be continous, and smooth, related to the pickup winding speed.

So, let's try to estimate that guide motor speed.

rotation_per_seconds = motor_rpm / 60
distance(um)_to_wire_in_1second = rotation_per_seconds * wire_gauge(um);
time(ms)_to_wire_1cm = (10000*1000) / distance(um)_to_wire_in_1second;

Now, the trick here it that we have previously recorded the maximum and minimum time in ms that the guide motor takes to move 1cm, so we can map the time we need, with that max and min speed.


That way we obtain a speed value from 1 to 100 for the guide motor to run smooth.

Enabling GUIDEMOTOR_DEBUGSTEPANDSPEED will display the current speed and steps left to run for the guide motor. This is a usefull during the debug stage. The speed will never exceed 100, and the steps left will never grow up. It it happens, it means that the guide is going too slow.

Future improvements will be implement an UART protocol to drive this machine by a PC, that way multiple wiring pattern can be simply performed.

This project was developed on Eclipse, built with avr-gcc on ATmega8 @ 16MHz.


  • read risk disclaimer
  • excuse my bad english


  1. Great job! I am very interested in PC-controlled version...

    1. Thank you!
      At present I'm fully involved in other stuff. But, i will go back to this project as soon as possible.
      The todo list will be: 3D printed parts, PC control version.

    2. Hi! Great work!
      Is it possible to convert to an arduino board easily?

    3. Hello,
      yes but it will not be so easy. You can easly convert it to a ATmega328 project and use a Arduino board, it will take more time to convert it to a .ino sketch.

    4. This comment has been removed by the author.

  2. Really nice work! How to implement this for Arduino? You said that it should be quite easy to convert to ATmega328?

    1. Hello and thank you. You have to change the timer interrupt to ATmega328. That one is for ATmega8, there should be just a few change. Then my suggestion is not to use the Arduino framework for this project, but compile on avrgcc, but if you want, you can even compile it for Arduino, which also compile on avrgcc.

  3. This comment has been removed by the author.

  4. This comment has been removed by the author.

  5. This comment has been removed by the author.

    1. Hello, for a coil winder you have to slighlty change the code. But his will work on ATmega8 cause this was made on that micro. You just have to download the code, compile that using avrgcc and upload to your microcontroller.

    2. Hi again,

      Is the hex, Intel hex? and what settings is needed for the fuses?

    3. Is the hex file. About the fuse you have to set it to external crystal, and attach an external 16Mhz crystal. You can find a lot of information about fuses and how to compile an avr project on avrfreaks.

  6. Replies
    1. Happy to hear that! Good winding!

    2. thanks but it is very solo. is it posible to uplode the code on atmega328p. and how?

    3. Hello, what's "very solo"? Porting code to ATmega328p will not be so difficult, it should be just a matter of timers settings, at present I've no plan to port it to ATmega328, but if you do it, please share the code link here, thank you.

    4. sorry. It will be very slow. that means the project work very slow. what to do now?

    5. What do you mean with slow? The winding speed is very fast to me, I also have to limit that with the max speed option, faster will break the wire.

    6. No brother. I means the button is working Slow. And The Select button don,t work. When the Select button press it start from first. The connection diagram was OK.

    7. I will double check the wiring, also i will check just the button code. Something like this may help (not tested)

  7. Hello, sir .....
    I almost succumbed to the failure that I experienced.

    Can you send Hex file to me ..... ???
    because i will try it again.

    1. Hello, you can find it there: (link expires in 2 days)

    2. it is the same file that I have.

      and how to burn the file into the atmega 8 chip......????

    3. You can use avrdude and a avr programmer. You can find further information on how to upload a firmware online, there are a lot of tutorial about that. Also remember to properly set ATmega8 fuses to match the required frequency.

    4. This comment has been removed by the author.

    5. the number of files has confused me.

      I do not know which one to choose :-D :-D

    6. You have to upload the .hex file


    7. Is this the file you are referring to.....????
      in the Release directory "avr_pickupw-03.hex"


    9. Yes, and also you have to set fuses according to the 16Mhz freq. may help. Note: pay attention in settings fuse, you may "brick" your ATmega, then you will need something like Atmega fusebit doctor to restore that.

    10. thank you for the information and success for you :-D :-D