Showing posts with label shaft encoder. Show all posts
Showing posts with label shaft encoder. Show all posts

Friday 22 August 2008

Shaft encoder, second attempt

I made a right mess of the first design, not only did I get the angle wrong but the second opto is also at the wrong radial distance, which is why its amplitude was less. So I had to redesign the bracket, here is my second attempt: -



The correct angle for quadrature needs to be (K + 0.5)(180 / n) where n is the number of slots in the wheel and K is an arbitrary integer. The first convenient angle which straddles the bolt through the motor is 45°.



A single coat of BBQ paint seems adequate to block the IR beam.



A bit of a pain to wire up! If it proves to be a useful encoder I will design a pair of PCBs.

The waveforms are now both full amplitude and in quadrature: -



The edges are slow because I am using 4 pin optos, Zach seems to have bought up the world's supply of the five pin ones for the RRRF! The five pin versions have a built in Schmitt trigger to square up the waveform before it goes down the cable. Most micros have Schmitt trigger inputs these days but the disadvantage is that any noise in the cable will advance or delay the edge slightly, giving a timing error. Given the imprecise nature of this encoder I don't think it will make much difference.

Monday 11 August 2008

RepRapped Shaft Encoder

I have started making an extruder for my Darwin but I am running out of ABS. I bought some more from Tempatron but it is very oval, up to 3.5mm, so it wont fit through HydraRaptor's extruder. So it is a race against plastic to make a new one with a bigger bore! I will try making the filament guide out of HDPE as that is the most slippery of the four plastics I have.

One thing I definitely wanted to try in ABS before it ran out was to make a shaft encoder. The latest RepRap V1.1 design has one with a single opto but it needs support material and gears. I am happy with the older design now that I have got it to run reliably, so I needed an encoder that mounts directly on the motor. I also prefer two optos in quadrature to avoid errors from backlash and stopping exactly on the edge of a slot. I want to experiment with backing up the filament as well, so I will make this version reversible.

I knocked up a design which uses a pair of slotted optos in CoCreate : -



The wheel is the same as Ed's design except that I have added a boss which mates with the top shaft of the GM3 gearmotor. It has 18 teeth which gives 72 steps per rev with quadrature encoding. One turn of the extruder feeds 0.8mm of plastic with an M5 drive screw. That will extrude about 0.4mm of filament per step, so not great resolution.

When making the opto flags for my Darwin I realised that quite thin walled objects come out OK and are still reasonably strong. I think the bracket is the thinnest thing I have designed so far, its walls are only 2.4mm thick. Its shape really requires support material for the slots and holes but it came out fine without any. It was particularly hairy though when it came off the machine: -



A bit of whittling with a penknife soon cleaned it up :-





Here it is installed on the motor :-





I wired up to an oscilloscope to test it: -



As you can it is very noisy because I have not made a new suppressor for the GM3 yet. Also the top trace does not go high properly. This is because quite a lot of IR light gets through the ABS when it is so thin. Not surprising as you can see visible light through it. I painted the top surface black with BBQ paint and that improved it a lot.



I think a second coat on the underside will improve it further. The waves are not in quadrature because somehow I managed to get the angle wrong, so I will have to make another bracket. It will function fine at half the resolution so I might press on with the extruder first.

So a cheap and cheerful shaft encoder, but not very high resolution. Since slotted optos are just LEDs and photo transistors in a bit of plastic, I think I will make another one with the raw components that will be even cheaper. I could put some more teeth on but that would make it harder for people to make and I want people to be able to upgrade their machine with their machine. Another way to do it is by printing onto film with a laser printer. There is a good site about that here.

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.