Sunday, February 10, 2019

Plotter Attachment for Laser Cutter

Long story short, I had an old inkjet printer. I've seen some DIY plotter machines made from old printers, so I thought, why not? how hard could it be

Data warning: ~76MB in GIFs on this post.

 Turns out, there's a reason to keep the old gantry inside the original printer case. The paper feeder can be out of alignment to the rollers, and it causes the paper to shift as it goes back and forth. Even well made plotters can suffer from alignment issues. Let's start with the first design: 


It's basically an enclosure for all the electronics and rolling mechanics. This took several iterations before I had all the dimensions where I wanted them. When I was happy, I started making the wood version.


 Partially assembled, I added the printer gantry. The electronics worked with the open source software I found (some GRBL controller for Arduino). Confident it would work, I put a piece of paper in. The result was paper that would rotate slightly with each back and forth movement. I thought a slight design change would fix it, but I also knew this would always be a problem, no matter how fine I tune it.


So, it sank into the swamp.

I decided a standalone plotter was too much effort, since my laser cutter already has an XY transit system I could use. After some fiddling around, I found some pins on the control board that indicates the laser firing, even when the laser power is off. This was my trigger for a solenoid. The idea was to use maybe one or two transistors, a relay, and some passive components for the entire system.


I didn't like how oddball the device was looking. It was unpredictable, sometimes the solenoid would get stuck, it was wobbly in places, got hot real fast. Sank into the swamp.

Next version involved the same nozzle clamp system as the last, but that's the only similarity besides the red color. It's Arduino controlled, so I can set exactly how far it moves, how much power it's getting, when it triggers, all the good stuff. 


The only problem is the device was also wobbly; the only thing keeping it level was the drive screw. At slow speeds it was alright. Unfortunately, I have aspirations, so this too sank into the swamp.

There was another...

This final version was designed to be much beefier. I added rails to keep the whole system rock solid, while adding features that didn't impact stability. This one has it all. It's got a rotating head that can be adjusted for calligraphy pens or simply drawing with a slanted pencil. I've also added a set of rails so the tool can sit on top of the material, not be forced to puncture it. This way I can roughly set the height of the tool, and it'll still work just fine. 


Here's a test of the up/down action, tripped by the laser trigger. All the electronics were in the design phase, so breadboard and Arduino 2560 still in the picture.

 Here's the final shape based on my redesign. Nice big knob for changing out tools. I'd like to say the hardware cost $3, but this is Seattle. Each of those two collars by the motor cost over $3 each. Total of about $25, not including the motor and hardware I already had. No idea where everyone is getting their $3 hardware from, but I guess I'm supporting my local businesses this way.
 

Shot of the attachment on the laser.


I have a bag of blank through-hole circuit boards, so I designed the electronics around that. Using an Adafruit Metro Mini as the brains and a Pololu stepper driver for the brawn.


Solder traces are not fun with a blunt tip. 


 Here's how I tied everything into the exiting circuitry of the laser. The power supply gives 24 volts and about 2.5 amps. I figured it could spare an extra half amp. Worst case, I know where to find a new one. The TTL trigger from the M2 Nano board needed a 100,000 ohm resistor to block any rouge signals. The 5v for the logic was supplied with a small transformer I installed to the right of the power line filter, out of frame. I can tap into that if I add anything else later on. The custom board is currently mounted neatly next to the power supply. Paired wires are twisted and hidden within the rail. I promise it doesn't look this messy right now.


After painstakingly threading all the wires through the drag chains, I added a connector for quickly releasing the plotter attachment. I'll have to add a switch for deactivating the electronics when not in use. Everything works. I'll want to avoid drawings where the stepper is moving constantly because of heat issues, but I can always run it slower. There's a "test" button I can use to raise the pen higher than during normal operation, so I can change out tooling easily.


"But the fourth one stayed up. And that’s what you’re going to get, Son, the strongest castle in all of England."
          -King of Swamp Castle


Weird code for reference:


const int testPin = 7;
const int limitPin = 6;
const int inputPin = 5;
const int motordir = 3;
const int motorstep = 4;
const int motoroff = 10;

int test = LOW;
int limit = LOW;
int input = LOW;

int var_busyup = 0; //busy 1 or idle 0
int var_busydown = 0; //busy 1 or idle 0
int var_direction = 0; //down 0 or up 1 direction
int var_running = 0; //indicates that it's in running mode, for when listening to the input
int var_updistance = 0; //variable to control the up travel distance depending on mode


void setup() {

pinMode(testPin, INPUT);
pinMode(limitPin, INPUT);
pinMode(inputPin, INPUT);
pinMode(motordir, OUTPUT);
pinMode(motorstep, OUTPUT);
pinMode(motoroff, OUTPUT);

digitalWrite(motoroff, HIGH);

delay(1000);
}

void loop() {
 
test = digitalRead(testPin);
limit = digitalRead(limitPin);
input = digitalRead(inputPin);


digitalWrite(motoroff, HIGH);

if (input == LOW){
  var_running = 1;
}

if (test == HIGH){
  var_running = 0;
}

if (((test == HIGH) && (limit == LOW) && (var_busyup == 0)) || ((input == LOW) && (limit == LOW) && (var_running == 1) && (var_busyup == 0))){
  var_busydown = 1;
  for (int x = 0; x <= 150; x++){
    digitalWrite(motoroff, LOW);
    delay(1);
    digitalWrite(motordir, LOW);
    digitalWrite(motorstep, HIGH);
    delay(5);
    digitalWrite(motorstep,LOW);
    limit = digitalRead(limitPin);
    digitalWrite(motoroff, HIGH);
    if (limit == HIGH){
      break;
      }
    } 
  }
var_busyup = 0;
limit = digitalRead(limitPin);
input = digitalRead(inputPin);

if (((test == HIGH) && (limit == HIGH) && (var_busydown == 0)) || ((input == HIGH) && (limit == HIGH) && (var_busydown == 0) && (var_running == 1))){
  var_busyup = 1;
  if (var_running == 1){
    var_updistance = 10;
  }
  if (var_running == 0){
    var_updistance = 90;
  }
  digitalWrite(motoroff, LOW);
  for (int y =0; y <= var_updistance; y++){
    digitalWrite(motoroff, LOW);
    delay(1);
    digitalWrite(motordir, HIGH);
    digitalWrite(motorstep, HIGH);
    delay(5);
    digitalWrite(motorstep,LOW);
    test = digitalRead(testPin);
    input = digitalRead(inputPin);
    digitalWrite(motoroff, HIGH);
    if (input == LOW){
      break;
    }
  }
}

var_busydown = 0;


}