Sunday 19 February 2012

All 3 axes working with limit sensing


The repstrap was tested with a program that "exercises" each axis between its limiting points detected by the opto-endstops. For us, this is the only way to be sure that the axes will operate properly when used by the reprap software. It also allows us to look for any wires that might snag or parts that are moving in undesirable ways. The program is included at the bottom in case anyone else wants to use it ...

We did find an issue with using pin 13 for the max-Y sensor; swapping this to pin 15 solved the problem, but is concerning as we know no reason why pin 13 should not work. Luckily we'd plugged everything into a breadboard with jumper wires so this change took all of 30 seconds.

I've included some more photos of the device as it stands now. During this fine-tuning session we've started to benefit from using Lego - wherever moving parts risked hitting each other, or needed some reinforcement, it was easy to alter the Lego construction to fix things up.So you will notice some changes in construction compared to earlier photos, and there will be more to come.






// remember to select board - ladyada adafruit is atmega168

//which opto enstop are we using?
//this is for the H21LOB
//#define INVERTED 1
//this is for the H21LOI
#define INVERTED 0

#define USE_MOTORS 1

// Stepper X
#define  gndPinX 0
#define stepPinX 2
#define  dirPinX 3
#define  minPinX 4
#define  maxPinX 9

// Stepper Y
#define  gndPinY 0
#define stepPinY 10
#define  dirPinY 7
#define  minPinY 8
#define  maxPinY 15//13 for some reason doesn't work with pin 13!?

// Stepper Z
#define  gndPinZ 0
#define stepPinZ 19 // a5  (a0 = d14)
#define  dirPinZ 18 // a4
#define  minPinZ 17 // a3
#define  maxPinZ 16 // a2

void setup() {
  Serial.begin(9600);
  Serial.println("Starting stepper exerciser.");

  pinMode(minPinX, INPUT);
  pinMode(maxPinX, INPUT);

  pinMode(minPinY, INPUT);
  pinMode(maxPinY, INPUT);

  pinMode(minPinZ, INPUT);
  pinMode(maxPinZ, INPUT);

#if USE_MOTORS
  pinMode(stepPinX, OUTPUT);
  pinMode(stepPinY, OUTPUT);
  pinMode(stepPinZ, OUTPUT);

  digitalWrite(stepPinX, LOW );
  digitalWrite(stepPinY, LOW );
  digitalWrite(stepPinZ, LOW );
#endif 
 
  pinMode(dirPinX, OUTPUT);
  pinMode(dirPinY, OUTPUT);
  pinMode(dirPinZ, OUTPUT);

  digitalWrite( dirPinX, HIGH );
  digitalWrite( dirPinY, HIGH );
  digitalWrite( dirPinZ, HIGH );
}

void loop() {

  int stepperSpeed = 400;

  Serial.print("Speed: ");
  Serial.println(stepperSpeed);

  while( true ) {
 
#if USE_MOTORS
      digitalWrite(stepPinX, HIGH);
      digitalWrite(stepPinY, HIGH);
      digitalWrite(stepPinZ, HIGH);
      delayMicroseconds( stepperSpeed );
      digitalWrite(stepPinX, LOW);
      digitalWrite(stepPinY, LOW);
      digitalWrite(stepPinZ, LOW);
      delayMicroseconds( stepperSpeed );
#endif 

      if( isBlocked( minPinX ) ) increase( dirPinX );
      if( isBlocked( maxPinX ) ) decrease( dirPinX );
      if( isBlocked( minPinY ) ) increase( dirPinY );
      if( isBlocked( maxPinY ) ) decrease( dirPinY );
      if( isBlocked( minPinZ ) ) decrease( dirPinZ );
      if( isBlocked( maxPinZ ) ) increase( dirPinZ );
  }
}

boolean isBlocked( int optoPin ) {
//  Serial.print("pin ");
//  Serial.print( optoPin );
 
  boolean blocked = true;
 
  if( digitalRead( optoPin ) ) {
     if( INVERTED ) {
       blocked = false;
     }
  }
  else { // read false
    if( INVERTED ) {

    }
    else {
       blocked = false;
    }
  } 

//  if( blocked ) {   
//    Serial.println(" is blocked." );
//  }
//  else {
//    Serial.println(" is open." );
//  }
 
  return blocked;
}

void reverse( int dirPin ) {
  digitalWrite(dirPin, !digitalRead(dirPin) );
}

void increase( int dirPin ) {
//  if( axis == MIN2MAX ) {
    digitalWrite( dirPin, HIGH );
//  }
//  else {  // max2min
//    digitalWrite( dirPin, LOW );
//  }
}

void decrease( int dirPin ) {//, int axis ) {
//  if( axis == MIN2MAX ) {
    digitalWrite( dirPin, LOW );
//  }
//  else {  // max2min
//    digitalWrite( dirPin, HIGH );
//  }
}

Monday 13 February 2012


Improved Lego Z axis. There's still that corkscrew motion; I think that's something wrong with the end of the threaded rod. I will try to file it flat... But overall much happier with the mechanism. Key improvements included moving the sliding part closer to the captive nut, use of the gears to hold the toothed track in place, and putting the flat sliding surface on the side nearest the point at which the force is applied by the captive nut.

I'm hopeful that bolting everything down tightly (it's roughly assembled right now, everything is hand-tight) will make it serviceable. Now moving on to testing the opto-endstops and writing a program to exercise with limit-sensing.


Thursday 9 February 2012

Z axis redesign

So the original Z axis wasn't good enough. After dismantling to diagnose, the flexing problem is due to the uneven end of the threaded rod where it meets the motor and the seat for the bearing needs to be more secure. This is relatively easy to fix I think.

The play in the Z axis needs a more fundamental rethink. The original design used a pair of interlocked cages that slid against each other.

After some experimentation, I found that the Technic toothed track part with some medium sized gears can produce a very tight fit, but still move smoothly. Again, the moving part is surrounded by other lego beams giving a smooth surface for it to slide on. It is more compact than my original version.

This is the new design, with a total movement of 17 lego studs. In the following pictures you can see the sliding part in different extreme positions and from different sides; the main negative aspect is that it looks like a sub-machine gun!

Here's a video showing that there is no visible play in any direction:

Extruder details

I've taken some shots to show how the extruder will (hopefully) work. The hot parts will be milled from brass and insulated with a nylon barrel as normal. Lego won't take the heat. The extruder insulator will be bolted into a lego assembly, and the feed rod will be drawn in using lego gears, motor, and a pair of pulley wheels that pinch the rod. The lego motor also needs a reduction gearbox (easy to make with lego). In these images, the extruder is shown partly dismantled because I'm rebuilding the Z axis and the way the extruder is mounted.

The extruder is basically a sandwich of about 7 layers. From the motor, we reduce the rotation speed then use gears to drive 2 pulley wheels in opposite directions with a small gap between them. The gap is a great fit for my plastic feed rod (a short piece is shown, I have a reel) but I had planned to put rubber bands on the pulley wheels if it was not a tight fit.

In this video you can see that the mechanism pulls the rod through the extruder and is quite stiff (I can lift the extruder via its grip on the rod). With luck, this will be stiff enough to extrude. If I need to change the gearing, this is easy in Lego. The Reprap electronics allow speed control, and according to this page my Technic motor will not draw too much current at 9v in the worst case (a stall) (however, I might be running it at 12v, but the rod will slip before the motor will stall? I hope.)


XYZ exerciser program

In case anyone finds it useful, here's the program I wrote / amended to "exercise" the 3 axes. The pin connections match the single-arduino setup for the final program so you won't need to rearrange them later:

// remember to select com port & board - ladyada adafruit is atmega168
// Stepper X
#define gndPinX 0
#define stepPinX 2
#define dirPinX 3
#define minPinX 4
#define maxPinX 9

// Stepper Y
#define gndPinY 0
#define stepPinY 10
#define dirPinY 7
#define minPinY 8
#define maxPinY 13

// Stepper Z
#define gndPinZ 0
#define stepPinZ 19 // a5 (a0 = d14)
#define dirPinZ 18 // a4
#define minPinZ 17 // a3
#define maxPinZ 16 // a2

void setup() {
Serial.begin(9600);
Serial.println("Starting stepper exerciser.");

pinMode(stepPinX, OUTPUT);
pinMode(stepPinY, OUTPUT);
pinMode(stepPinZ, OUTPUT);

pinMode(dirPinX, OUTPUT);
pinMode(dirPinY, OUTPUT);
pinMode(dirPinZ, OUTPUT);

digitalWrite( dirPinX, HIGH );
digitalWrite( dirPinY, HIGH );
digitalWrite( dirPinZ, HIGH );
digitalWrite(stepPinX, LOW );
digitalWrite(stepPinY, LOW );
digitalWrite(stepPinZ, LOW );
}

void loop() {
int i, j;

// for (i=1000; i>=200; i-=100) {
while( true ) {
i = 400;
Serial.print("Speed: ");
Serial.println(i);

for (j=0; j<6000; j++) {
digitalWrite(stepPinX, HIGH);
digitalWrite(stepPinY, HIGH);
digitalWrite(stepPinZ, HIGH);
delayMicroseconds(i);
digitalWrite(stepPinX, LOW);
digitalWrite(stepPinY, LOW);
digitalWrite(stepPinZ, LOW);
delayMicroseconds(i);
}

delay(500);
digitalWrite(dirPinX, !digitalRead(dirPinX));
digitalWrite(dirPinY, !digitalRead(dirPinY));
digitalWrite(dirPinZ, !digitalRead(dirPinZ));

for (j=0; j<6000; j++) {
digitalWrite(stepPinX, HIGH);
digitalWrite(stepPinY, HIGH);
digitalWrite(stepPinZ, HIGH);
delayMicroseconds(i);
digitalWrite(stepPinX, LOW);
digitalWrite(stepPinY, LOW);
digitalWrite(stepPinZ, LOW);
delayMicroseconds(i);
}

delay(1000);
Serial.println("Switching directions.");
digitalWrite(dirPinX, !digitalRead(dirPinX));
digitalWrite(dirPinY, !digitalRead(dirPinY));
digitalWrite(dirPinZ, !digitalRead(dirPinZ));
}
}

First test!

Here's the machine ready for its first test:



Another angle:



A video:


Observations:
The XY stage seems to move smoothly with very little play. The gearing produced by the threaded rod seems plenty. It does hesitate sometimes - I'm not sure if this is because the stepper motor output is set to pretty much minimum causing a stall, or if something is catching or slipping.

The Z stage has two problems. Most severely, the frame is being flexed excessively. This is partly due to too a corkscrewing action in the threaded rod (unsure of cause) and partly due to a lack of rigidity in the frame. Less severe is some play in the sliding frame, which might be fatal to useful printing.

At this stage it seems sensible to redesign the Z axis.

Wiring & assembly



We (well, mostly my wife) then spent several evenings and two full days over a weekend making up all the looms and connectors, mounting the reprap electronics, and assembling the machine.

In this shot you can clearly see the cantilever arm:



Finished electronics box:

Mock-up



Some more developments. The Z axis and printing head will be supported by a cantilever arm from a sturdy post. The post is made of 2 boat seat pedestals, because they're ideally shaped and very stiff.

You can see here the extruder is made of lego too - driven by a Technic motor. This will be covered in more detail later, when I've tested that it works. It works like the later Mendel extruders, pinching the plastic feedstock between a pair of Lego pulley wheels.

Other lego reprap

I thought I'd put all the lego attempts I could find here:

The competition: Lego Mendel system. This is by far the most advanced Lego reprap/repstrap I've seen. Also, looking at the timing it looks like we're in for a race to see who can finish a Lego reprap first!

Lego reprap XY stage. It's clear how to build this, but how would you secure the moving stages? It can't float on one beam; it would twist and flex too much.

Youtube video of a working Lego reprap XY stage. This is the only one I've seen actually doing anything. The same guy seems to have had less success with the Z axis.

Remnants of a Lego reprap? Just ruins here, can't find any info on it actually working.

3D lego chocolate printer (not a reprap, but similar).

There's some lego in here, but it's only a small fraction of a machine that looks pretty shaky.

A closer look



Here you can see the finished XY stage. In this one shot you can see the Y bearing-block, the captive nut in its blue truck, attached to the Y stage which is rolling on Lego railway wheels on tracks. The other blue beams are points to attach L section pieces to slot into the Opto-endstops. The endstops themselves will be bolted to the white posts. You can also see the rubber hose connecting the Y axis stepper motor to the threaded rod and how the motor is bolted into place. The top of the box-frame supporting the Y motor has been removed - as shown it is too weak.

The 4 black posts will support the printing table, not shown.

Captive nut





The next question was: How can the captive nut be attached to Lego?

If turns out a Lego structure as shown can hold the nut securely. Wrapping duct tape around the nut enlarges it (and is slightly deformable) making it a tight fit and avoiding any play.

I've tried to make all the captive nut attachments out of blue lego.

Having added the captive nuts, bearings, threaded rods and motors to the XY stage it now looks like this:



Note the arrangement motor----captive nut----bearing in both axes.

Bearings



The bearings are made as simply as I could manage. They need hard-wearing surfaces (compared to lego!) both as a sleeve around the threaded rod, and at the end of the rod to resist the end of the rod being pushed through. The method of construction I chose was to buy:

- some hollow metal pipe just large enough to act as a sleeve around the threaded rod
- some L-section metal stock
- some square section wood

I drilled holes in the wood just large enough to fit the metal pipe and then hammered the pipe into the holes. The pipe was cut to length, then a piece of L-section was screwed onto the back of the wooden blocks to close off one side. Finally I wrapped the whole thing in duct tape and punched a hole for the threaded rod; the tape acts as a rough seal so I can pack the metal sleeve (bushing?) with grease.

XY stage in Lego

Here's a photo of an XY stage made in Lego:



It's much bigger than I'd wanted, largely due to the weight of the Keling stepper motors I'm using. The lego beams can't support the motors unless they're assembled into a box-structure around the motor mounting face.

I've used Lego railway tracks and wheels to allow the axes to roll. The white parts are mounts for the opto-endstops (they simply bolt on). Since the gap in the endstop sensors is too small for lego, I will simply bolt short pieces of L-section aluminium to the lego such that it slides through the gap and triggers the sensor.

XY stages general design

The X and Y axes will be moved by a captive nut on a piece of threaded rod. The nut is attached to a moving stage, and cannot turn. Therefore, when the motor turns, the nut is forced to move along the rod. To provide some flexibility in the system, the threaded rob is attached to the motor shaft by a tightly-fitting piece of rubber hose that I cut off my car.

These principles were all set out in the original McWire Cartesian Bot. I notice with chagrin construction of this is now considered a "death march"!

Some other design issues arose. The threaded rods in X and Y must be anchored in a thrust bearing. Now lego will never be able to survive having a threaded steel rod screwed into it for long. So the end bearings will be made of aluminium (because it's easy for me to work).

The actual rails and bearings for the XY stages to move on will be made of lego. They only have to support their own weight plus the object being printed.

About the lego repstrap project

We decided to build a reprap a couple of years ago; at the time I shared an office space with 3 friends, so "we" means Matt, Nick, Travis and myself (Dave). We built the electronics and started making a cartesian bot, but got distracted by other things...

Recently I retrieved all the lego (pretty much the only toy I wanted or got for my entire childhood) from my Dad's loft and decided to put it to use in a repstrap machine. My hope was that using lego would be easier than building all the mechanical parts from metal and wood. I was encouraged by some posts such as http://reprap.org/wiki/MendeLego but surprised that no-one seems to have yet built a reprap / repstrap from lego.

Soon I realised why. Lego has many advantages, but for building a structure the size of a reprap you need a vast quantity of lego. To reduce play and the counter the natural plasticity of lego beams, you need even more lego. To have a large working area .. yet more lego.

However, I'm now motivated by the idea that this will be (as far as I can tell) the world's first EVER lego rep(strap/rap). As a result my objectives have solidified as follows:

- to make the lego machine a fully functional reprap (not merely a bodgy repstrap) with a precision of 0.5mm in all axes
- to build all moving, complex mechanical parts from lego; this includes the extruder drive, and 3 axes of motion
- not to damage or modify the lego parts
- to have a working area of at least 15x15x15cm
- to only use the lego parts I happen to own already (well, I might buy one or two bits if really needed)

My electronics are the old Darwin set (Stepper motor 1.1). The design for the machine will be based on the cartesian bot that has platform moving in X and Y and a printing head that moves in Z only.

Enough for now..