Friday 29 June 2007

Bob on

Here is the first RepRap part that HydraRaptor has milled :-



It is the extruder barrel clamp as shown in the previous post. As you can see it is dimensionally correct to two decimal places! It's not a fluke, the height is bob on 45.00mm as well. I have been getting pretty good accuracy with my previous milling attempts but this is astonishing.

I used a smaller end mill (2.22mm) in a collet chuck which is more accurate than the three jaw chuck I used before. The plastic is a sheet of 9mm Delrin or Acetal which I used because I read somewhere that it was a good plastic for machining. It did machine well but all the edges were left with a thin burr. This was fairly easy to remove with a fingernail.

This is not the latest version of the RepRap design but I decided it would fit my machine better. I added two more mounting holes and changed the central hole diameter to match my PTFE barrel which is 12mm rather than 10 or 16mm in the original design. The central slot is 2.5mm rather than 2mm because my bit was too big. Obviously I will have to drill the horizontal hole for the clamping bolt with a drill press.

Here is an edited video of it being made, it took around 20 minutes to make the part :-



And here is an amusing out-take if you listen to the sound :-



So having achieved perfection on this first part, things can only get worse when I attempt to make the rest of the extruder.

Tuesday 26 June 2007

End of play

You may recall that I said my replacement spindle motor, AKA Minicraft drill, had a bit of end play due to the bearing moving. This evening I made some shim washers by milling a thin piece of hard plastic that I got from the inside of a PC power supply. They are 11mm diameter with a 8.5mm hole and about 0.2mm thick. They were a bit ragged round the edges due to the plastic burring quite badly but it didn't really matter. I made three but two were enough to stop the bearing moving.



This is what the inside of the drill looks like. I added the capacitor myself to keep the radiated emissions from the cable to a minimum.



The result was very pleasing and I now have a working milling machine again. My next job will be to mill an FDM extruder. I plan to start with the clamp as this looks the easiest part.




Obviously I will have to modify it a bit. For example I can't do sharp internal right angles due to the tool's radius.

Monday 25 June 2007

Bodge it and move on

The I²C nightmare continues. I thought slowing the clock of the MSP430 had fixed the problem. However, it still locks up after a few packets. The symptoms are that the MC9S12NE64 decides that the MSP430 has not ACKed the address byte. At this point both clock and data are low. The MC9S12NE64 sends a stop and both lines go high. It then thinks the bus is permanently busy. If I reset the MC9S12NE64 then it works for a while again so the MSP430 is not locked up.

So my first bodge was to detect the MC9S12NE64 thinking the bus is busy when it should not be and reset its I²C module. This caused it to lock up thinking the bus was not busy when it should have been. In desperation I added a 100us delay after the reset and now it works.

It looks like my digital scope will not arrive for at least a couple of weeks so I can't really get to the bottom of this until then but at least it is working with retries. I haven't done a lot of I²C stuff in my career but it looks like a really clever protocol. Less wires than SPI but has defined start and stop codes, multi-master arbitration and auto clocking down to the slowest device. As both ends implement it in hardware I just expected it to work. I should have known better as most hardware has bugs these days like all software.

Thursday 21 June 2007

The day the music died

Although I am fortunate enough to have a project room which is nearly 3m by 4m, as you can see it almost completely full of junk.



The large glass fronted MDF box on the far left next to HydraRaptor is a 400 CD jukebox that I designed and made in 1990. I used it for about 10 years until the CD player's laser wore out. At that point I ripped all the discs and stored them on my PC as mp3s. I haven't used it since but I could never bring myself to dismantle it as it is probably the best thing I have ever made. However, this week I got fed up of not having enough work space so I decided it had to go.

This is what it looked like. It had a sealed glass door on the front which is hard to photograph.



Here it is with the door open.



The discs were stacked 10 high on wooden pegs arranged in semi circles of six on seven shelves, i.e. 42 sites. The bottom shelf had a hole in it above the open CD player drawer and an empty peg used to store the next disc to be played.



That left 40 pegs of ten discs giving a maximum capacity of 400 discs. Worst case, to play a disc at the bottom of a peg, involved moving the nine discs above it to three nearest neighbours. This took about 40 seconds but as long as the playlist was not empty it would get the next disc ready and place it on the peg next to the player. It would then move the discs it had moved out of the way back onto their home pegs. Then it would hover above the player waiting for the disc being played to finish. When it did it would lift it out of the drawer and stash it on an the adjacent peg. It would then insert the new disc and while that was playing it would return the previous disc to the top of its home peg. That way the most popular discs tended to be at the top of their pegs for fast access.

The discs were moved by a robotic arm with a rubber suction cup on the end made out of a toy dart.



This was moved radially by a stepper motor with a gear box. It was attached to a trolley on steel rails which was moved vertically by a toothed timing belt driven by a large 12V DC motor with a gear box. As you can see the end of the arm has three micro switches. The left hand one was used during initialisation to find the home position of the arm. The other two were just for safety. The vertical motor is so powerful it could easily snap the arm off so I wired the limit switches in series with the motor so if the software crashed and left the motor running it would do no damage.

The arm is actually made of two pieces of perspex clamped together at the hub. When the arm descends onto a disc the top piece bends way from the bottom piece and a pair of switch contacts between them part. Again this was in series with motor for safety.

Here is a view of the electronics shelf after I removed the top :-



On the far left is a mains modem which allowed my PC upstairs to communicate with it when it was in its original home in an under stairs cupboard.



Next to that is a small switch mode PSU which powered everything.

In the middle is an aquarium pump which I used to generate the vacuum to lift the discs. I converted it from blowing to sucking by sealing the case and connecting a pipe to the air inlet underneath.

On the right is the controller :-



This is a Motorola MC6809 microprocessor with 32K battery backed RAM, 32K EPROM, a timer, a UART and two PIAs. Nowadays this would be a single chip. Here are the circuits, no free ECAD programs in those days :-



Here is a view with the electronics removed :-



Here is a close up of the mechanics :-



The vacuum pump took a while to build up pressure and release it again so I made a solenoid operated 3 way valve to turn the suction on and off quickly.

The top circuit board is an opto detector which looked at tabs on the right hand rail to know where the shelves were. The board below it is a vacuum pressure sensor to enable it to know if it had failed to pick up or dropped a disc. That only happened during development really but it was vital to detect it otherwise it would lose track of which discs were on which pegs. Originally there was just one vacuum sensor but about twice a year I had to recalibrate it. Eventually I realised this was because the change in atmospheric pressure, due to weather, was greater than the vacuum level. I fixed it by adding a second sensor and measuring the difference between the vacuum pipe and atmospheric pressure. Not a very cost effective solution as the sensors were about £13 each.



Here is a video of it moving some discs. I had to drive it manually from the test routine as it would not run without a working CD player.


You probably will have noticed that each time it picks up a disc it pauses over the peg for a while. This was because the discs tended to stick together by suction after being pressed by the weight of the ones above. This was mainly cured by putting a small circular spot label near the centre of the disc to break the seal. The delay gave time for the second disc to drop back onto the peg if it did initially lift.

So now it is no more, but perhaps I might reuse the vacuum system and the metre long axis for some sort of pick and place machine.

Monday 18 June 2007

Disaster, frustration, success, disaster

Not posted for a while because I couldn't get the I²C link between my main controller and the spindle controller working. Before that I had a minor disaster when I crashed the drill chuck into a block of plastic. It appears to have bent the shaft out of true as the tool runs a little eccentrically now. The drill was made by Minicraft but they seem to have gone out of business. This made me realise how precarious it is to make something out of surplus components and things you have to hand rather than readily available parts. If I break anything then it might be impossible to get a drop-in replacement. Something like the $4000 XY table I got for $400 would be virtually irreplaceable.

Fortunately the drills seem to crop up on eBay fairly often. I got one almost identical except that it has a collet chuck rather than a three jaw one. It seems to have a bit of end play but this appears to be due to the bearing being loose in the housing rather than having play itself. I should be able to fix it with glue or shim it with a washer.

The I²C problem was a nightmare. I could get it to work if I stepped through the code at either end but not if I ran it. I was fairly sure the software was right because I had used the MSP430F2013 code before on a very similar device and it was based on an app note. The code at the MC9S12NE64 end was a translation of some code I used recently on a Coldfire which seems to have an almost identical I²C module. Not surprising as they are both Freescale devices.

Obviously it was a timing issue but all the timing should be done by the hardware. I am only running it at 100K baud and with 1K pullup resistors over 4 inches of cable I should have no problems. Looking round the Web I found an errata for the MSP430 which seemed to have lots of I²C bugs in the B revision of the chip with no workarounds. Mosts of these are fixed by revision C but my chip seems to have an X where the die revision should be.

Because the problem manifested itself as a lockup it wasn't possible to get a repetitive signal to look at on my analogue scope. I decided I should really have a digital storage scope for these types of problem so I ordered a cheap USB scope front end made in China from a company in the US. $360 plus shipping for 100MHz bandwidth, two channels, 250 MSps. Not bad if it works and the software is half decent. Most software to support hardware seems to be complete rubbish these days. I have had four PC TV cards so far each with decent hardware but software that is utter crap.

While waiting for it to arrive I decided in desperation to try reducing the clock speed of the MSP430. To my amazement dropping it from 16MHz to 8 MHz appeared to fix the problem. So definitely hardware not software then.

Flushed with success I added a Python function to control the drill speed by sending a command via Ethernet to the main controller which forwards it by I²C to the head controller. This worked fine but as soon as the drill made contact with the tool height sensor for the first time the sensor stopped working. I thought the shaft of the drill was ground but actually it was +12V. Now that the power supplies are linked by the comms cable it stuffed 12V into two of the 3.3V inputs of the MC9S12NE64 and not surprisingly they don't work anymore! In fact I am surprised any of it still works but most of it does.

So, major disaster. It will be very difficult to replace the chip as it is fine pitch surface mount. I do have some spare inputs I could use providing the rest of the chip holds out. I can probably still buy another demo board but its starting to get expensive repairing my mistakes.

Curiously the replacement drill seems to have an isolated shaft. I knew the first one wasn't but I assumed it was ground not +12V. However, it wouldn't have made any difference because foolishly I switched it with a low side driver so when it is off both wires are at 12V!

So now I have to rewire the tool sensor inputs, add some protection and cobble the two drills together to make one good one, preferably using the motor with the isolated shaft. The I²C comms need beefing up a bit with a CRC, packet sequence flag and an acknowledgment / retry mechanism. I also want to add drill stall detection and employ the shaft encoders on the XY table to detect that stalling as well. Hopefully then I will avoid any more costly tool crashes and move on to making the RepRap extruder.

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.

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.

PIC your micro

The official RepRap project uses Microchip PIC micro controllers. I have done several projects at work with these because they have such a wide range of parts that they often have the best fit price wise. However, I have never liked them very much. They have a horrible instruction set which does not lend itself to running C efficiently. Also, the development kit is a bit primitive by today's standards. When doing a home project ease of use and development kit cost becomes more important than part price. I have been following the RepRap forums and people are having lots of problems with a buggy open source PIC compiler and programmer.

I recently did a project at work which needed a micro with a very low power consumption so we used a Texas Instruments MSP430 series micro. I was very impressed with the USB key development kit which only costs $20. For that you get an IAR C compiler, assembler, simulator and debugger. The instruction set of the chip is very small but has just the right instructions to run C efficiently and the C compiler does a good job of using them. The code size is limited to 4K but, as I am only using a 2K part, that doesn't matter. The USB key contains a programmer / "Spy Bi-Wire" in circuit debugger and a little detachable target board. The chip is surface mount but the target board brings all the pins out to a 0.1 inch header so you can incorporate it into a through-hole board and you can get additional target boards at $10 for three.





So for $30 I get a development kit and micros to control four of HydraRaptor's heads.

The smaller parts don't have UARTs but they do have I²C which is easier to make a multi-drop bus with.