Introduction: Homemade Arduino Printer

If you want to make your own high resolution printer (maybe not so high res), you are at the right place. This Instructable will show you how to do with two dead cd/dvd drive and a pen (pilot, whiteboard marker, whatever you have) at the best lego-printer style.

Here is how our printer will work: we type any message in terminal then the message will be printed (as dot matrix) and after the message is printed the program will wait for another message.

For this magnificent printer you will need:
1) 1 x Arduino (I've used the Duemilanove)
2) 2 x H-Bridge (SN754410)
3) 3 x small dc motors from any cd/dvd drive
4) 3 x switches from the same cd/dvd drive
5) A pen or marker
6) Wire
7) Rubber string
8) Sheave
9) Stick with round rubber like the rollers in a real printer, the wheels from a toy car should work.
10) Acrylic, wood or whatever you have to build the structure.
11) 5v and 9v power supply

If you have an old printer you can use its structure and save some time to build one.
Once you have all that is time to build the structure.

Step 1: Build the Structure

   Now you have to build the structure with any materials you want (even with lego), I choose acrylic because it's cheap and easy to work.

   All you have to do is to mount a "U" Structure and add two tubes where our printer's head will move, also add the supports for rollers and the sheave.

   As said before, if you have and old printer you can use it and skip this step.

Step 2: Finish the Structure

   Now it´s time to finish the structure, this is the most painful step because you have to measure, cut, drill, solder, etc...

   You will need 2 x motors with gears from drive's tray and 1 x motor from drive's head.

   You can also use the whole tray, or like I did, cut a circuit board at the same shape of the tray to save some weight. Also add some supports to the head, here I soldered 3 screw nuts to the back of the head.

    Also note that the head have 3 switches taken from the cd/dvd drive. These switches tell us if the head reach the left/right of the structure and if the head motor is down (this means that the pen/marker is touching the paper). One leg of the switch goes to ground and the other goes to one analog pin, no need for external resistors because we will use the internal pull-up resistors.

    Now attach the motors, the head, the roller and the pen/marker to the head. To finish this step attach the rubber string to the motor, to the head and to the sheave.

   Note that all parts will not fit perfectly, so you have to use your skills to make this work, but, probably, some hot glue is the answer for most of our problems.

Step 3: Connect Everything Together

   Let's connect everything to the Arduino. First of all, connect the switches as shown in the previous step.
  
   Then connect the motors to the H-Bridge and the H-Bridge to Arduino. The schematic bellow is a little messy but, thats the way it is, you can also take a look at this simple tutorial (http://itp.nyu.edu/physcomp/Labs/DCMotorControl ).

Step 4: It's Time for a Little Code.

   First thing to do is to define where the switches and the H-Bridge control pins are connected:

const int moveA = 3; //pin 1 of the motor to move the head horizontally
const int moveB = 2;  //pin 2 of the motor to move the head horizontally
const int headA = 4;  //pin 1 of the motor to move the head vertically
const int headB = 5;  //pin 2 of the motor to move the head vertically
const int rollerA = 7;  //pin 1 of the motor to move the roller
const int rollerB = 6;  //pin 2 of the motor to move the roller
const int enableMove = 8; // to enable the motor that moves the head horizontally
const int enableRoller = 9;  // to enable the motor that moves the roller
const int enableHead = 10; // to enable the motor that moves the head vertically
const int leftButton = 14; //the left switch
const int rightButton = 15; //the right switch
const int bottomButton = 16; //the bottom switch

   Now in setup() we must set the motor control pins as output and the switches pins as input (a) , then we have to set the enable pins as HIGH (b) and enable the pull-up resistors from switches pins (c) .

     (a) set the output and input pins
           pinMode(moveA, OUTPUT);
           pinMode(moveB, OUTPUT);
           pinMode(headA, OUTPUT);
           pinMode(headB, OUTPUT);
           pinMode(rollerA, OUTPUT);
           pinMode(rollerB, OUTPUT);
           pinMode(enableMove, OUTPUT);
           pinMode(enableRoller, OUTPUT);
           pinMode(enableHead, OUTPUT);
           pinMode(leftButton, INPUT);
           pinMode(rightButton, INPUT);
           pinMode(bottomButton, INPUT);

     (b) set the enable pins
           digitalWrite(enableMove, HIGH);
           digitalWrite(enableRoller, HIGH);
           analogWrite(enableHead, HEAD_VERTICAL_SPEED);

           Note that our vertical head's motor is enabled through analogWrite, that's because this motor was super-fast and didn't had gears, so, using the analogWrite with a value near to 400 the motor is behaving properly. You can use the mos suitable value (between 0 and 1023) for your motor.

     (c) enable the pull-up resistors
          digitalWrite(leftButton, HIGH);//enable pullup resistor to this pin
          digitalWrite(rightButton, HIGH);//enable pullup resistor to this pin
          digitalWrite(bottomButton, HIGH);
           
   Now we must have a ASCII glyph table, fortunately we can get it here: http://www.arduino.cc/playground/Code/PCD8544
   If you want to draw and print you own glyph you can do that here: http://www.carlos-rodrigues.com/projects/pcd8544/  then just paste the generated glyph into the code and print that.
   The algorythm to control the printer is quite simple and you can download the full source code at the end of this instructable.

Step 5: Calibration and Considerations

   Now is the final step, at this point you have to consider some values in order to make your printer work properly. You have to test each value accordingly to each motor you're using.

   Note that higher resolutions can be achieved with a thinner tip. Generally a thin tip requires the values to be smaller and thick tip requires bigger values. Also according to your motor/gears lower and higher resolutions are possible.

   Another thing to notice is the direction of the motor. If the motor is spinning in wrong direction you can either change its terminals in the circuit or change the pins in the code.

   Calibrate your printer based on this values:

const int TIME_TO_EJECT_PAPER = 3000;
   -the time that takes to eject all the paper
const int TIME_TO_MOVE_PAPER = 40 ;
   -the time that takes to move the paper between each column
const int TIME_TO_MOVE_HEAD_HORIZONTALLY = 40 ;
   -the time that takes to move the head between each dot
const int WAIT_TIME_TO_MOVE_HEAD_HORIZONTALLY = 50;
   -the time to wait until move the head again to draw another dot
const int TIME_TO_MOVE_HEAD_VERTICALLY = 30;
   -the time that takes to move the head up/down; this affects the speed of writing
const int WAIT_TIME_TO_MOVE_HEAD_VERTICALLY = 400;
   -the time to hold the pen/marker down when writing a dot
const int HEAD_VERTICAL_SPEED = 400;
   -the speed of the head up/down motor, this may be necessary because this motor generally doesn't have gears.

You can download the full source code below, as well, see two pics before and after calibrate the system with a very thick tip whiteboard marker.