Showing posts with label PWM. Show all posts
Showing posts with label PWM. Show all posts

Friday 31 August 2007

RPM

While testing my extruder I found that the filament diameter seems to vary with temperature and pressure. I wanted to investigate this further so I decided to add a shaft encoder to the output of the small gear motor which drives the polymer pump. This would allow me to regulate the speed precisely because the micro would know the exact position of the shaft at any instant.

My first thought was to use a magnetic shaft encoder such as the AS5035 but then I remembered I had an evaluation kit for some HP reflective optical encoders which I had saved since 1995. HP are no longer in the semiconductor business, that part of the business became Agilent and these chips have been passed on to Avago. The kit had a linear encoder strip, a rotary encoder wheel and three sensor chips.




One of the advantages of magnetic encoders is that they don't need such precise alignment as the optical ones. However, in my case I would have needed to build a raised mounting to hold it over the end of the shaft, whereas the optical encoder can be mounted flush against the gearbox. Here is another bizarre mix of surface mount and through hole components. Can you spot the SMT decoupling cap?



I doubt that I have complied with the strict mounting tolerances but it seems to work well enough for this purpose. Here it is with the code wheel in place :-



Here is what the outputs look like when the shaft is turning :-



Two square waves are produced which are 90° out of phase with each other. This is known as quadrature encoding and it allows both the distance and direction of movement to be determined. I would have expected the mark space ratio to be more equal but it is probably out of spec due to me not meeting the alignment tolerances.

Notice also the nasty glitches on the bottom trace. These are commutation noise from the DC motor despite having a 100n capacitor close to it and using screened cables. Here is what the noise looks like close up without the capacitor :-



And this is the improvement with the capacitor fitted:-



I also tried adding a resistor to form an RC snubber and adding a ferrite ring around the motor cable, but both made it worse. The only way to effectively suppress DC motors is to mount suppression components directly across the armature windings, i.e. the other side of the brushes.

So stuck with that much noise, it was impossible to use an edge triggered interrupt approach, so I polled the inputs from a fast interrupt and debounced them in software. Here is the code :-
//
// Process the shaft encoder signals
//
#define DEBOUNCE 3
static void scan_optos(void)
{
static byte last_raw = 0;
static byte debounce_count = DEBOUNCE;
byte delta;

//
// Debounce the inputs
//
byte bits = P1IN & (SHAFT_A | SHAFT_B);
if(bits != last_raw) {
last_raw = bits;
debounce_count = DEBOUNCE;
return; // Still changing
}
if(debounce_count) // Still debouncing
if(--debounce_count != 0)
return; // Not stable long enough
delta = bits ^ optos; // Which bits changed
if(delta) {
int dir = 1;
optos = bits; // New state
if(delta & SHAFT_A) { // Was it A or B that changed
while(delta & SHAFT_B) // If both not scanning fast enough
;
dir = -dir;
}
if(bits & SHAFT_A) // Work out the direction
dir = -dir;
if(bits & SHAFT_B)
dir = -dir;
motor_pos += dir; // update position
}
}
This keeps track of the shaft position: motor_pos increases as the filament advances. I then use a timer interrupt to decrement motor_pos at the rate I want the shaft to move at. motor_pos then becomes the error signal for my feed back loop. If it is positive the shaft is ahead of where it should be, if it is negative it is lagging. On-off control was too aggressive so I used PWM to give proportional control. Here is the code, called from the same fast interrupt :-
//
// Control the motor
//
#define MCYCLE 16
static void do_motor(void)
{
static int mcount = 0;
static int on_time = 0;

if(mcount >= MCYCLE) { // At end of cycle?
if(motor_pos <= 0) { // If lagging
on_time = -motor_pos >> 3; // Set PWM for next cycle proportional to the lag
mcount = 0;
}
}
else
++mcount;
if(motor_pos > 0 || mcount >= on_time)
P2OUT &= ~MOTOR; // Motor off
else
P2OUT |= MOTOR; // Motor on
}
This is the resulting PWM waveform and one shaft encoder signal, my scope only has two channels! :-



The speed control works well, no loss of torque as the speed is reduced. It has a bit of a damped oscillation with no load due to the slop in the gearbox but it is fine in the extruder where it has a constant load to hide the backlash.

Tuesday 5 June 2007

RTFM

I made a start on my PWM control software this evening. The first thing that I discovered was that I had connected the motor drive to the wrong pin on the MSP430F2013. There are two pins that can be driven from the timer, TA0 and TA1, but only TA1 is capable of PWM. I should have studied the datasheet more carefully! Easily fixed but a bit of a time waster.

I wrote a small test program to try different PWM duty cycles and frequencies :-
#include "msp430x20x3.h"

#define LED BIT0
#define MOTOR BIT2
#define FLOATING (BIT1 + BIT3)
#define CURRENT BIT4
#define GND BIT5
#define I2CPINS (BIT6 + BIT7)

#define OUTPUTS (I2CPINS + MOTOR + LED + FLOATING)

int main( void )
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
//
// Set MCLK to 16 MHz, SMCLK = 2 MHz
//
BCSCTL2 = SELM_0 | DIVM_0 | DIVS_3; // MCLK = DCO, SMCLK = DCO / 8
BCSCTL1 = CALBC1_16MHZ | XT2OFF;
DCOCTL = CALDCO_16MHZ;
//
// Set up I/0
//
P1OUT = MOTOR; // Motor off
P1DIR = OUTPUTS; // Define output pins
P1SEL = MOTOR; // Motor = TA2 output
//
// Set up timer
//
TACCR0 = 20000; // 2 MHz / 100
TACCR1 = 15000; // 25%
TACCTL1 = OUTMOD_7; // Reset / set
TAR = 0; // Start counting from zero
TACTL = TASSEL_2 + MC_1 + TACLR; // SMCLK, upmode, clear
}
I found that 50-100 Hz seems to work well. 1KHz is too fast as the current doesn't have chance the build up to its full value due to the motor winding inductance.

Here is a graph of motor current versus duty cycle with no mechanical load :-


As the duty cycle gets smaller the motor slows down so it generates less back e.m.f. making the current increase.

I chose a current sense resistor of 0.27Ω which gives voltages up to 1.75V however the full scale voltage of the ADC is only 0.6V so I could do with it being smaller. I could just attenuate it with a potential divider but as it gets hot and wastes power it is better to reduce its value to 0.1Ω. Again, I should have paid more attention to the datasheet. I guess I will be taking a trip to Maplin tomorrow lunch time.

Sunday 3 June 2007

Less speed more torque

This weekend I built a speed controller for my milling spindle motor, AKA Minicraft drill, after attending and recovering from the Stockport Beer & Cider Festival . I used one of the MSP430F2013 micros I described in the previous post. I built it on Veroboard, but hopefully all my future boards will be milled PCBs.



I never plan my Veroboard layouts in advance, I just make it up as I go along. In fact this circuit was so simple I didn't even draw a schematic. I did come a cropper this time though. I started on a board that was too small!



I only realised this after I had put on a regulator, LED and connector, so I had to desolder them and start again. The LED did not survive the ordeal. In my experience, they are one of the most fragile electronic components. They certainly don't like stress on their legs while being soldered.

The circuit is very simple, I will publish a schematic and the software when I complete it, assuming it works, which I have no reason to think it won't.

You may think "how is that puny little micro controlling a 40W motor"? What you can't see in the picture above are two surface mount FETs on the underside.



The big one is a BTS134D "smart low side power switch" with over voltage, over current, thermal and ESD protection. It has an on resistance of only 50mΩ so I can get away without a heatsink. With devices like these I don't know why anybody uses Darlingtons for switching nowadays. Darlingtons have a fundamental flaw in that they cannot be saturated so the on voltage is over a volt leading to significant power dissipation, and hence a large heatsink, for these sorts of currents.

The tiny FET next to it simply boosts the gate drive from the 3V output of the micro up to 12V to ensure the big FET delivers the smallest possible on resistance.

The picture below shows the board being tested. It is connected to a 39W PSU, the drill motor and a scope.



I have verified that it can turn the motor on and off OK. It just needs some software now. The micro has a timer with a PWM facility so controlling the speed of the motor should be pretty simple. The large resistor at the bottom left is for sensing the motor current. The micro has an ADC so I should be able to measure the speed to allow some feedback and also shut it off if it stalls. The unpopulated connector is the I²C link which will go to HydraRaptor's main controller.

Wednesday 30 May 2007

Underpowered

I have done quite a bit of milling with my Minicraft drill attached to HydraRaptor. I always considered it a bit underpowered for the job but it mills plastic and copper clad board reasonably well. Recently I started using it for drilling plastic. The first thing I drilled was 6mm Perspex. I programmed a pecking action to avoid the drill clogging as Perspex tends to melt when it is drilled at high speed. Again this worked reasonably well. The next thing I tried was drilling 25mm metal loaded resin. No matter how slowly I went I could not stop the drill from stalling once it got to a certain depth.

I decided the only way to solve the problem was to monitor the drill speed, detect when it was about to stall and automatically back off until it speeded up again. To this end I started investigating ways to monitor the speed. Off the top of my head I came up with four alternatives :-

  1. Monitor the current, because it increases as the speed reduces.
  2. Turn it off occasionally and monitor the generated voltage.
  3. Measure the frequency of the commutation noise.
  4. Put a black spot on the chuck and use a reflective opto detector to count shaft revolutions.
I attached the drill to a 12V switch mode PSU in order to take some voltage and current measurements and look at the current waveform on a scope. To my surprise the drill went much faster on the 12V PSU. The PSU that came with it is labelled 11.5V 400ma 4.6W but when loaded by the drill it was only giving about 8V. Then I looked at the drill and saw it was labelled 12V 40W. A bit of a mismatch! When driven from 12V it takes about one amp with no load. No wonder it was stalling so easily. It also explained why when it does stall it does not seem to care. Most drills start smoking pretty quickly if you stall them.

So it looks like the drill is ten times more powerful than I thought. The only problem is that it could do with some speed control as it goes a bit fast for plastic when running from 12V.

So now my next task is to tame it with PWM and monitor the speed somehow. I also want to control the vacuum cleaner with software as I am too lazy to switch it on and off.