Monday, 11 June 2007

Rewire

Well I got dissed at work today for my two line post over the weekend so I thought I had better post something more substantial even though I don't have much news. I spent most of the weekend rewiring HydraRaptor when I wasn't watching the Formula One Grand Prix.

I got a solid state relay from eBay for £16 to control the vacuum cleaner. I have had reliability problems with SSRs in the past so I went for something with plenty of headroom.



It's rated at 660V 25A with 250A 1200V surge capability. It's completely over the top and I know I could have got something a lot cheaper but it looks impressive.

The vacuum cleaner is rated at 1300W so it can theoretically draw 5.4A although it measures a bit less. This plus the rest of HydraRaptor exceeded the rating of my mains inlet which was 5A. If it was a plain socket I might have chanced it with a small overload but it was a cheap filtered inlet from an old PC PSU so I didn't want to risk it. I had to upgrade to a 10A inlet socket and upgrade the mains lead . I installed a 3 pin outlet socket on the back of the machine for the vacuum and I then had to fuse back down to 3A for the rest of the internal wiring.



I also installed the spindle motor speed controller and a 12V 3A power supply. While it may seem wasteful to have two separate power supplies it does have one big advantage. The main controller and the stepper motors are powered from a 24V 100W PSU. All the heads will be powered from the 12V supply and linked to the main controller with an I²C bus. Both PSUs have floating 0V rails so there will be no motor current flowing down the comms ground between the two controllers. This will allow me to use only single ended 3.3V signals rather than differential or RS232 signals which would normally be needed to combat ground bounce. Here is a block diagram. As you can see there are no signal grounds shared with power grounds and there are only four wires from the main machine to the heads. Once I am able to make PCBs I will shrink the motor controller using surface mount components and mount it on the Z axis together with a similarly shrunk extruder controller.



Here is the current state of the machine, getting ever more complicated :-



Just software now to complete the milling machine and then on to extruder.

Saturday, 9 June 2007

Lenz's law

Explain this: I just connected my 1300W vacuum cleaner to a power meter. When running unobstructed it consumes 1100W. When I block the tube so the motor is audibly under more load the power drops to 900W. Power factor remains close to 1. Weird motor?

Thursday, 7 June 2007

Torque talk

I updated my motor control circuit to use a 0.1Ω current sense resistor to give me a full scale current of about 0.6A and then set up the ADC to provide negative feedback to control the speed. I read up on the classical control method which is PID, finding a good article on it here www.embedded.com. Before embarking on that complexity I decided to try a simple more intuitive method. I wrote a program which turns the motor on and monitors the current until it falls to a specified level, indicating that the motor is generating the correct back e.m.f. i.e. running at the correct speed. It then turns the motor off and waits for the start of another cycle.

This algorithm works reasonably well after playing with a few numbers to get it relatively stable. It does however suffer from a beating problem. I am not sure exactly why but I think it must be the PWM pulse rate beating with the commutation of the motor. Here is a video of a scope trace of the current waveform. You can hear the motor in the background as the speed is swept from maximum to minimum and you can see the current pulses getting shorter and higher. Just to to confuse matters the scope trace is beating with the camera frame rate.



I don't think the beating will matter much but it is a bit annoying. Playing with the PWM frequency has a big effect on it. In the end I settled for 200Hz, but I may play about with it a bit more.

One thing that I hadn't realised, but is obvious really, is that when you slow down a motor with PWM it loses a lot of torque at low speeds but when you add feedback it gets it all back again.

Here is the simple piece of code :-
#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)

typedef unsigned int word;
typedef char bool;
#define true 1
#define false 0

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
SD16AE = CURRENT + GND; // Configure analogue inputs
//
// Set up ADC
//
SD16CTL = SD16XDIV_2 + SD16DIV_0 + SD16REFON; // MCLK / 16 = 1MHz
SD16CCTL0 = SD16DF + SD16OSR_32 + SD16IE + SD16SC; // OSR = 32
SD16INCTL0 = SD16INTDLY_0 + SD16INCH_2; // Delay 4 clocks; channel A2
//
// Enable interrupts and wait forever
//
_BIS_SR(GIE);
for(;;);
}

int current;
int target_current = 5000;
#define CYCLE 200

#pragma vector=SD16_VECTOR
__interrupt void ADC_int(void)
{
static int count;

int adc = SD16MEM0;
current += (adc - current) >> 1; // Moving average filter
if(++count >= CYCLE) {
count = 0;
P1OUT &= ~MOTOR; // Motor on
P1OUT |= LED;
if(target_current < 0)
target_current = 5000;
target_current += 10;
}
if(count > 30 && current < target_current) {
P1OUT |= MOTOR; // Turn the motor off
P1OUT &= ~LED;
}
}
Note that in the end I am not using the PWM capability of the MSP430 timer as I did the motor control in the ADC interrupt handler.

The next task is to get it talking to the rest of HydraRaptor using an I²C bus.