This is a work in progress! I’m currently editing this write-up, and by publishing it before it’s done I’ve got more motivation to finish it. 😉
Here’s a project that was spawned as a necessity for another project. In building my CNC mill/router I had a lot of trouble finding a suitable spindle. The homebrew ones I’ve seen were too small, and the ones available on eBay were just too big. So I did the hacker thing and built my own.
The spindle consists of a few parts: an ER collet holder as the rotor, two angular contact bearings, a machined aluminum housing, two 12L14 steel flywheels, and a timing belt sprocket. I machined the aluminum housing on my lathe. I turned both bearing seats at the same time so that they would be in precise alignment. The top one was easy because I could see it and check the fit periodically by trying to insert a bearing. When I did the bottom one I was boring from inside the lathe chuck, so I couldn’t see anything; I had to rely on the dials. This took a few tries, and I created two paperweights along the way. What I was left with, however was a perfectly aligned, perfectly fitting bearing housing.
I had to purchase 3 collet extensions until I was happy that they fit inside the ID of the bearings well. The bearings are 10mm, as are the precision ground collet extensions, but variance of even a few ten-thousandths caused vibration at 10k+ rpms.
I planned to use set screws to hold it all together, but I found by accident that a tight interference fit of the flywheels worked better to keep it together.
The spindle is driven via timing belt by a 30v rated brushed Pittman DC motor that I had in a parts box. I experimented a lot with measuring the RPMs of this motor under load with various driving currents to figure out the proper gearing for a 10k rpm spindle. Actually it can go faster than this, but I only run it at 8k rpm max because of the torque drop-off and poles that causes vibrations of the spindle, but I’ll get to that.
I had decent results powering this motor with a constant voltage source, but rpms would vary wildly which is not good for setting feeds and speeds on a mill. Since I could not find one, the solution was to build a custom motor controller.
I wanted to get this one-off project done fast so I settled on using the Arduino platform. This allowed me to keep the parts low, and cheap, and use a familiar debugging platform, namely sending data over UART to view with Processing. This was WAY handy for tuning the PID loop.
The motor controller is fairly simple. The AVR is the brain of course, which sends a PWM signal through an opto-isolator to a switching MOSFET. This mosfet drives the motor directly (with the appropriate back EMF protection in place). Feedback is achieved by a 1 pulse-per-revolution opto-interruptor on the motor shaft. User interface consists of a 16×2 character LCD, a couple pushbuttons and a rotary encoder. The AVR displays a menu, processes the user interface, and then sets the PWM output. The PWM signal is adjusted via PID control by the feedback it gets from the opto-interruptor.
I had to drill and tap the motor’s shaft in order to mount this piece of delrin that I machined. To do this I mounted the motor in the lathe, but instead of tuning on the lathe, turned on the motor to make sure the hole was drilled in the shaft’s center.
I breadboarded the circuit and when I was happy with the design, etched this pre-sensitized PCB using the UV LED lightbox that I made as a previous project.
If you look closely you can see the serial port at the top (accessed using a USB -> TTL adapter), the AVR programming header just to the right of the LCD’s contrast pot, and at the bottom right are the MOSFETS. After apparent issues with my MOSFET driver chip, I swapped it out for a simple dual-transistor configuration. In fact the issue wasn’t the driver, but I’ll get to that.
To tune the PID variables I sent a bunch of data over serial and interpreted it graphically using Processing.
The controller seemed to work well at low torque, but when a lot of force was applied it would always go into a terrible oscillation. I spent the good part of two weeks changing PID values, adjusting code, and even replacing my MOSFET driver trying to fix this problem. I finally created a new variable, “load”, which I calculated from the applied voltage (PWM % value) and observed motor speed. This had the clue to my problem – the oscillations occurred at a certain motor LOAD! Still it wasn’t until I thought to hook up my oscilloscope to the MOSFET gate that I discovered the issue…
See the images below. This should look just like the square wave being sent through the opto-isolator to the gate driver circuit.
Notice the small blip, a plateau as it were, when the voltage is rising on the gate. When I reached a PWM signal that was too high, this small delay meant that the MOSFET stayed fully on. The motor was jumping from 80% voltage to 100% voltage with nothing in between. In fact, it was amazing that the PID algorithm handled this as well as it did. Since it couldn’t apply any value in between, the motor oscillated wildly at high RPMs or high load, when the PWM signal approached 80%.
The solution was a simple one, and it just took a tweak in code. I lowered my PWM frequency and set the max PWM value to be around 90%. This meant I had to limit my maximum RPM or motor load because I couldn’t apply the full supply voltage available, but otherwise it proved to be an excellent solution. In the future I could just apply a higher supply voltage to get more work out of my spindle.
Incidentally, this plateau has a name: the Miller Plateau. It’s an effect of the inherent capacitance of a MOSFET’s gate, and something all EE’s know about and design around. I probably read about this at one point and dismissed it as one of those things you only have to worry about in extreme cases – cases I would never encounter in my hobbyist designs. Well, gee. I’ll tell you, though, figuring out stuff this way is way more rewarding than just reading about it, and it will definitely stick with me now.