Michael Matczynski

6.115 Final Project

May 13, 2004


Monet Goes Digital



Ever since I was small I’ve been fascinated with art and painting.  This past IAP I bought a set of paints and learned to paint.  I have always enjoyed the paintings of Claude Monet, primarily because I love impressionism, which is a style of painting that uses short strokes of bold, primary colors to create “impressions.”  Thus, I thought it would be thrilling to create a machine, PaintDude, that could paint!

Introducing PaintDude – Mechanical Structure

Being a past participant and teaching assistant of 6.270, I was very familiar with Legos.  However, I was told that using a Lego structure as my base would be a risky decision.  Thus, I simplified my original design for the painting arm and made the structure as simple as possible with the fewest number of moving parts.  See Figure 1 for details.


Text Box:  
Figure 1: PaintDude Mechanical Structure

I needed to create 2 planes of motion to allow the brush tip to hit any point on the canvas.  Thus, I made a unit, PaintHand, which slid along a track in the X direction (see Figure 2).  The track itself was stationary and attached to the base.  To allow movement in the Y direction I created a mechanism that rolled the 9”x7” canvas.  By using both in combination I could position the brush above any point on the canvas.


PaintHand, see Figure 3, slides on the stationary track in the X direction.  A “Bright 6” style paintbrush was attached to a brush platform mechanism that raised and lowered.  A servo was positioned and connected with a bent paper clip.  A ribbon cable with enough slack was then attached to the base.







Figure 2: PaintDude Coordinate System – Top View


Figure 3: PaintHand – Side View

PaintHand was attached to a chain that ran the entire length of the track.  A gearbox was added to make PaintHand easier to move and provide more precision.  Finally a stepper motor was added and meshed with the chain.  The gearbox was designed so that one complete rotation of either stepper motor moved the brush the same physical amount.  Specifically, this meant that one full rotation of either the X or Y stepper motor would move the canvas a distance of 8 gear teeth.  To facilitate brush changes PaintHand held onto the paintbrush using only a rubber band, making cleanup easy.


Blobs of paint are put on a stationary platform adjacent to the canvas.  This area is attached to the main base.  The palette does not move when the canvas moves in the y direction.  This allows the brush to reach the paint by just moving in the X direction.  See Figure 2 for details.


Moving the Canvas – Stepper Motors

The two stepper motors that control the X and Y position of the paintbrush needed to be controlled by the R31JP.  Each stepper motor was connected to its own LM18293.  These two chips were connected to Port A and Port B of an 8255.  The common terminals on the stepper motor were tied to ground.  Thus, raising any one of the remaining four lines in order made the motor rotate.  Eight freewheeling diodes were added for protection.  Routines to control the stepper motors were written and tested independently.  In order to allow precise movements of one step at a time, the state of each stepper motor was saved in a position in memory. 

Appendix A shows the code I used to test the stepper motors.


Making a Brush Stroke – Servo

Once the stepper motors were moving the arm properly, it was time to automate the brush stroke mechanism.  I attached a servo to the PaintHand using double sided sticky tape.  I then used an unbent paperclip to attach the servo to the moving paintbrush-holding platform and made sure that the servo could move the brush platform up and down.

Figure 5: Servo Pulse


A servo is driven by sending a pulse to the signal lead of the servo once every 20.0ms (Figure 5).  This pulse can range from 1.0 to 2.0 ms and the position of the servo is linearly related to this pulse width.  A pulse width of 1.5 ms will center the servo in its range of motion.  Two timers on an 8254 were used to create this waveform.  Timer 0 was configured in mode 2 (rate generator) to provide a 20.0ms period.  The output of this timer was connected to the gate of Timer 1, which was operating in mode 1 (hardware retriggerable one-shot).  The output from Timer 1 was passed through an LM358 op-amp buffer and then to the white signal lead from the servo.  To make the servo configuration more portable and not dependent on a lab power supply, I connected the red and ground leads to three Hawker lead-acid batteries in series.  This battery pack provided approximately 6 volts and 1.0 amps.


A test program was written for the servo (Appendix B).  Once this was working both the stepper motors and servo were combines into one program (Appendix C).


Learning to Paint – Control Program

A control program was written to direct the movement of the canvas and the position of the brush.  The program flow is as shown in Figure 6.  This code is listed in Appendix D.  The program has a PC, or Paint Counter, that points to a position in memory containing the next painting instruction to be executed.  This is very similar in function to a Program Counter in a microprocessor.  This point has been arbitrarily set to 3000h.  To paint the program begins reading memory at PC.  The first 4 bits are similar to an opcode in that they tell the program what the instruction does and how to interpret the following bits.


This instruction set was designed with enough primitive functionality to allow users to paint in a number of different ways.  For example, to paint in the style of impressionism with small dabs of color I would use a series of MOVE instructions with the A bit set, see Table 1, to lower and raise the paint brush after the destination X and Y were reached.  An alternate painting style may involve long strokes of solid color.  This can be achieved by calling the PEN instruction to lower the brush, followed by a MOVE instruction to drag the brush across the canvas.  Thus, my design allows for unlimited artistic creativity.



The following example program demonstrates basic functions:


db 00010000b, 11111111b           ; set x position of color 0000 to 11111111b

db 00010001b, 11110000b           ; set x position of color 0001 to 11110000b

db 01000000b                      ; raise arm

db 00100000b                      ; pickup color 0000

db 00110010b, 10000000b, 01000000b ; dabs at location 10000000b, 010000000b

Variable Length Instructions

I decided to create a variable length instruction set to save memory.  Each painting command is represented by an instruction that is between one and three bytes long.  In hindsight I would have used extra memory to make the instructions a fixed length as this would have been easier to program and would also have been more tolerant to errors.  This current implementation is prone to failure because if an opcode is off by just one bit the number of bytes in the instruction may be wrong and will cause an unrecoverable error.  If the PC points into the middle of an instruction PaintDude will not operate properly.


* indicates unused bits that are ignored by PaintDude





Signals end of painting instructions and stops PaintDude







Saves X location of color in memory



CCCC is a color number ranging from 0-15

XXXX… is the X coordinate of the specified color






Moves PaintHand to the X location of color in memory and moves the brush up and down



CCCC is a color number ranging from 0-15





Moves PaintHand to the specified X and Y position and optionally moves the brush up and down at that location



A: if set the brush will move up and down at the dest pos

B: if set PaintHand will only move in the X direction

XXXX... is the destination X coordinate

YYYY... is the destination Y coordinate





Sets the brush position to either up or down



A: if set the brush will move down to touch the canvas and if not set the brush will move up


Table 1: PaintDude Variable Length Instruction Set


Figure 6: Program Flow

Serial Communication

The control program has a few simple painting instructions hard-coded into the address space reserved for instructions.  However, it would get very irritating if PaintDude’s control program had to be reassembled every time a new painting was desired.  Thus, serial communication was enabled to allow PaintDude to receive painting instructions from a computer.  This means that any computer supporting serial communication can interface with PaintDude.  The coding of this mechanism was relatively straightforward and is very similar to MINMON’s download command.  When PaintDude is turned on, the initial mode is download mode.  Thus, a user only needs to send a sequence of painting instructions followed by a terminating “.” and PaintDude does the rest.


USB Communication

Text Box:  
Figure 7: USB Interface
I attached PaintDude to a FT232BM USB interface chip, Figure 7, as an alternate way to transfer data to PaintDude.  The FT232BM chip worked great and was very simple to use.  One disadvantage of the R31JP is that Ports 3.0 and 3.1 are not available on the protoboard ribbon cable connection.  These two pins are needed for transmitting and receiving data on a serial cable.  Thus, I wound up having to connect the USB cable to the FT232BM, which connected to one end of a serial cable and finally terminated at the serial connector on the R31JP.  This resulted in many dangling wires so I decided to stick with a simple serial connection.


For a computer to communicate with the FT232BM, drivers needed to be installed.  I opted to go with the Virtual Comm Port (VCP) drivers.  When installed, the USB devices appears as a COM4 in Device Manager under Ports and functioned identically to a regular serial COM port. 


Two major advantages of using USB would be the ability to transfer data at higher rates and the ability to connect to computers lacking a serial connection.  Although the FT232BM supports transfer rates up to 3Mbits per second, sending a relatively small list of painting instructions via serial port worked well enough.



Learn from the Masters – Java Program to Import BMP Files

Entering pixel information by hand is a very tedious task.  I have fortunately created a program in Java that will read a 200x150 pixel, 256 color BMP file and translate the color information into commands for PaintDude.  To do this the program proceeds sequentially through the color information, processing one color at a time.  Commands are written to the file “output.txt” and are then ready to be sent directly to PaintDude.


Examples of use:

“java FinalProject 6115rules.bmp”

“java FinalProject 6115rules.bmp 2 2”


One issue that arises is what to do with the incredible resolution PaintDude’s mechanical system allows.  PaintDude can paint every one of the 200x150 pixels on the canvas, but with a large brush many of these pixels will overlap.  To solve this problem I added parameters that control the distance between X and Y samples.  The program defaults to 4 pixel spacing in each direction, meaning that every fourth pixel will be drawn.  This technique is very successful for preventing overlap and has the added bonuses of decreasing the total number of instructions.



I enjoyed this project enormously and believe the complete project was a success!  I was able to successfully transform a relatively simple Lego structure into a printer using a wide range of techniques and strategies 6.115 taught me during the semester.  I achieved all the goals I set for myself at the beginning of the project and even took the project to the next level by implementing the Java translation program.  The ability to take an arbitrary bitmap and have PaintDude actually paint it is incredible and extremely rewarding!