A site dedicated to CNC of Mini lathes - the 7x10, 7x12, 7x14, and 7x16

Spindle Encoder

Posted by  7xCNC  Nov 3, 2012

You can build an accurate spindle speed sensor for less than $10.

Mach3 uses a single pulse per revolution to determine speed and index for threading - this works but doesn't deal well with fluctuations in rpm (inevitable), meaning threads may not be as clean as possible.

LinuxCNC uses a spindle index (one pulse per revolution) and a spindle phase A (many pulses per revolution - I used 60). For this you need two sensors. Fortunately two optical sensors can be bought very cheaply from ebay (search for "slotted optical switch"). You can also use a quadrature encoder which uses two phases as well as an index.

It cost me US$5.88 (including shipping) for two optical sensors on PCBs with a voltage input of 3.3-12V. The main PCB has a power LED (red) and a green LED for each sensor that indicate the state - making it easy to see when it's working. My version has two trimpots that adjust the sensitivity.

I lasercut a slotted disk in 3mm MDF. The disk has 60 equal slots for spindle phase A. One of these slots is longer and is the spindle index. The disk is a push fit on the existing gear on the spindle (used for leadscrew drive on stock lathe)


My DXF of the spindle encoder wheel is here

I removed all the change gear hardware and used bent sheet metal as mounts for the sensors, bolted to existing holes. I made slots in the sheet metal so I can adjust the exact position of the sensor to get it sensing right.

Spindle encoder.jpg


For those new to LinuxCNC it may be easiest to get the spindle encoder working is via stepconf. Remember that stepconf overwrites any changes you have made directly to your hal and ini files. I create a new config so I can use stepconf to set pins and use the in built encoder setup steps. Just follow through the wizard. Select the inputs you have for index and phase a (if you are using a quadrature encoder I believe you'll have a phase B also). Remember to generate a custom panel so that you can actually see the spindle readout. Once you've gone through the wizard you'll need to copy the relevant parts from the new hal file to your hal file.

The other option is to edit your hal directly. Don't be afraid to get your hands dirty, a lot of the power of LinuxCNC lies in customisation and can be done relatively easily with a few lines of code. Remember to create a backup before you make changes. I always create a backup when I've got a good working config. Relevant hal lines are below:

### This code goes in your main .hal file
############# Spindle Encoder #############
# add scale and lowpass, these will be used in custom_postgui.hal
loadrt scale count=1
loadrt lowpass count=1
# add the encoder to HAL and attach it to threads.
loadrt encoder num_chan=1
addf encoder.update-counters base-thread
addf encoder.capture-position servo-thread
# set the HAL encoder to 60 pulses per revolution.
setp encoder.0.position-scale 60
# set the HAL encoder to non-quadrature simple counting using A only.
setp encoder.0.counter-mode true
#setp encoder.0.counter-mode 1 - alternative line
# connect the HAL encoder outputs to LinuxCNC.
net spindle-position encoder.0.position => motion.spindle-revs
net spindle-velocity encoder.0.velocity => motion.spindle-speed-in
net spindle-index-enable encoder.0.index-enable <=> motion.spindle-index-enable
# connect the HAL encoder inputs to the real encoder.
net spindle-phase-a encoder.0.phase-A <= parport.0.pin-13-in
net spindle-phase-b encoder.0.phase-B
net spindle-index encoder.0.phase-Z <= parport.0.pin-12-in
############# End Spindle Encoder #############
  1. #### The following code goes in custom_postgui.hal
  3. # **** Setup of spindle speed display using pyvcp -START ****
  4. # **** Use ACTUAL spindle velocity from spindle encoder
  5. # **** spindle-velocity bounces around so we filter it with lowpass
  6. # **** spindle-velocity is signed so we use absolute component to remove sign
  7. # **** ACTUAL velocity is in RPS not RPM so we scale it.
  9. setp scale.0.gain 60
  10. setp lowpass.0.gain 0.010000
  11. net spindle-velocity => lowpass.0.in
  12. net spindle-fb-filtered-rps lowpass.0.out => abs.0.in
  13. net spindle-fb-filtered-abs-rps abs.0.out => scale.0.in
  14. net spindle-fb-filtered-abs-rpm scale.0.out => pyvcp.spindle-speed
  16. # **** set up spindle at speed indicator ****
  18. net spindle-cmd => near.6.in1
  19. net spindle-velocity => near.6.in2
  20. net spindle-at-speed <= near.6.out
  21. setp near.6.scale 1.500000
  22. net spindle-at-speed => pyvcp.spindle-at-speed-led
### The following code goes in custompanel.xml
<?xml version='1.0' encoding='UTF-8'?>
                        <text>"Spindle Speed:"</text>
                            <text>"             "</text>