An attempt at making an X-Y plotter from scraps (GhettoPlotter)

The plotter in action ( kind of )

Picture with helpful arrows :
picture outlining the various parts of the plotter

The x-direction was working perfectly, the strip encoder was being read by the pic using interrupts, the number of pulses that the printer head traveled could be set in code. In the above video, the printer head was moving one direction by 20 pulses, then stopping then moving forward again by 20 pulses. This process repeats until 100 pulses have passed. The printer head then travels in the reverse direction by 100 pulses. The reason it was doing this was to ensure that the microcontroller was not missing any pulses because this would introduce drift, causing unreliable operation. After running the above sequence for several minutes, the printer did not seem to have drifted at all.

Circuit Diagram
Circuit Diagramn

It was all going fairly well until I blew the pic, the driver chip and most importantly, the strip encoder on the printer. All of those parts are easily replaced except for the strip encoder. It was part of the printer and is most likely built to work with a certain strip with, so it is not easily replaced.

The whole reason for trying out this project was to eventually try and make a 2d laser cutter. Possibly using a usb stick to store the list of coordinates to cut out the required shape. Another idea was maybe using a tablet running linux and CAD software to quickly draw up simple shapes that could then be translated to a list of coordinates and sent to the plotter using Bluetooth. This list would be read by the pic microcontroller and it would translate that into pulse distances for the DC motor, and steps for the stepper motor. This project will have to be scrapped for the time being. A GhettoPlotter V2 is definitely on the cards though.

Plotter Source Code:

// dsPIC30F4011 Printer Head control program.
// Written by Shane Ormonde
// Last updated 27-8-2013

#include <xc.h>
#include <stdio.h>
#include <libpic30.h>

// Configuration settings
_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16x7.5MHz, Fcy=30MHz
_FWDT(WDT_OFF); // Watchdog timer off
_FBORPOR(MCLR_DIS); // Disable reset pin

void setup(void);
void _ISR _INT0Interrupt(void);
void step(int);

unsigned int counter = 0;

int main()
int n;

LATD = 0;
for (n=0 ; n<10 ; ++n) // flashing led start sequence, to make sure the pic isnt resetting itself.
_LATD1 = 1;
_LATD1 = 0;

step(20); __delay32(6000000); //forward by 20, wait for a bit
step(20); __delay32(6000000); //forward by 20, wait for a bit
step(20); __delay32(6000000); //forward by 20, wait for a bit
step(20); __delay32(6000000); //forward by 20, wait for a bit
step(20); __delay32(6000000); //forward by 20, wait for a bit
step(-100); __delay32(30000000);//back for 100, wait for a bit


void step(int n)
if (n > 0) LATD = 0b0110; // forwards, LED on
else LATD = 0b0011; // backwards, LED on
if (n < 0) n = -n;
counter = 0;
while (counter < n);
LATD = 0b0000; // stop, LED off

void setup(void)
IFS0bits.INT0IF = 0; // int0 flag bit
IEC0bits.INT0IE = 1; //int0 interrupt enabled
IPC0bits.INT0IP = 3; // int0 prority is 7

// Configure PWM for free running mode
// PWM period = Tcy * prescale * PTPER = 0.33ns * 64 * PTPER
// PWM pulse width = (Tcy/2) * prescale * PDCx
PWMCON1 = 0x00FF; // Enable all PWM pairs in complementary mode
PTCONbits.PTCKPS = 3; // prescale=1:64 (0=1:1, 1=1:4, 2=1:16, 3=1:64)
PTPER = 5000; // 20ms PWM period (15-bit period value)
PTMR = 0; // Clear 15-bit PWM timer counter
PTCONbits.PTEN = 1; // Enable PWM time base

//PDC1 = PTPER / 2; // 25% duty cycle
PDC1 = PTPER; // 50% duty cycle

TRISD = 0b00000000;

void _ISR _INT0Interrupt(void)
IFS0bits.INT0IF = 0; // int0 flag bit
//_LATD1 = 0;

Leave a Reply

%d bloggers like this: