CNC Plotter/Engraver – Atari Joystick Control Port Schematic

faq_controller_pinout

Our project revolved around the input from a user. In order to transfer user input to our plotter we needed a familiar physical object that could tell our device how to move on an X and Y axis grid. In this case we chose a joystick from an Atari game system. We then found this input schematic and soldered an adapter from the joystick to our breadboard where we then tested it out using LED’s. This joystick would then be hardwired into our A3BU to tell it when to send a voltage to the different motors.

CNC Plotter/Engraver: The Big Picture

Overview

For our final project in the embedded systems class we decided to take on creating a laser engraver controlled by user input through a joystick. To do this we first decided what would be needed to hold all of the equipment required to make the engraver work. We decided to create a wooden structure with a dual rail system. This rail system would then allow us to move our laser on the X and Y axis. We then attached a 3 stage stepper motor to the sliding board that would hold our workspace and a band to a stepper motor on the top rail which would guide the laser back and forth.

CNC Plotter: Code Snippet for Joystick Control

Peripheral Configuration Click here to get an outline of our code.
<o:p></o:p></pre>
<pre>/*
 * FinalProject.c
 *
 * Authors : Andrew Combs and Alex Judy
 */ 

#include <asf.h>

// Define pins for each of the switches in the joystick
#define UP_PIN  IOPORT_CREATE_PIN(PORTB, 0)
#define DN_PIN  IOPORT_CREATE_PIN(PORTB, 1)
#define LT_PIN  IOPORT_CREATE_PIN(PORTB, 2)
#define RT_PIN  IOPORT_CREATE_PIN(PORTB, 3)
#define TG_PIN  IOPORT_CREATE_PIN(PORTA, 0)

// Define some LCD parameters
#define LCD_MAX_X		16
#define LCD_MAX_Y		4

// Main (Entry Point)
int main(void)
{
	// Initialize the board.
	board_init();
	sysclk_init();
	gfx_mono_init();
	// Enable interrupts
	pmic_enable_level(PMIC_LVL_LOW | PMIC_LVL_MEDIUM | PMIC_LVL_HIGH);
	// Turn on the LCD backlight
	gpio_set_pin_high(NHD_C12832A1Z_BACKLIGHT);
	
	// Draw labels on the LCD for each of the joystick pins
	gfx_mono_draw_string("Up", 0,0,&sysfont);
	gfx_mono_draw_string("Dn", 24,0,&sysfont);
	gfx_mono_draw_string("Lt", 0,8,&sysfont);
	gfx_mono_draw_string("Rt", 24,8,&sysfont);
	gfx_mono_draw_string("Tg", 48,0,&sysfont);
	
	// Set pins 0-3 on port B to input / pullup
	ioport_set_port_dir(IOPORT_PORTB, 0b00001111, IOPORT_DIR_INPUT);
	ioport_set_port_mode(IOPORT_PORTB, 0b00001111, IOPORT_MODE_PULLUP);
	// Set pins 0-3 to input
	PORTA.DIRCLR = 0b00001111;
	// Set pins 0-3 to trigger port B interrupt 0
	PORTB.INT0MASK |= 0b00001111;
	// Turn on interrupt 0 and set to medium priority
	PORTB.INTCTRL |= 0b00000010;
	// Set each pin 0-3 to pull up falling edge triggered
	PORTB_PIN0CTRL |= 0b00011010;
	PORTB_PIN0CTRL &= 0b11011010;
	PORTB_PIN1CTRL |= 0b00011010;
	PORTB_PIN1CTRL &= 0b11011010;
	PORTB_PIN2CTRL |= 0b00011010;
	PORTB_PIN2CTRL &= 0b11011010;
	PORTB_PIN3CTRL |= 0b00011010;
	PORTB_PIN3CTRL &= 0b11011010;
	// Do all that stuff over for port A pin 0
	ioport_set_port_dir(IOPORT_PORTA, 0b00000001, IOPORT_DIR_INPUT);
	ioport_set_port_mode(IOPORT_PORTA, 0b00000001, IOPORT_MODE_PULLUP);
	PORTA.DIRCLR = 0b00000001;
	PORTA.INT0MASK |= 0b00000001;
	PORTA.INTCTRL |= 0b00000010;
	PORTA_PIN0CTRL |= 0b00011010;
	PORTA_PIN0CTRL &= 0b11011010;
	
	// Globally enable interrupts
	cpu_irq_enable();
	
	// Don't die
	while (true)
	{
		// (would be replaced with a sleep mode in finished code)
	}
}

// Interrupt Service Routine for Port B Interrupt 0
ISR(PORTB_INT0_vect)
{
	// Wait 50 ms for debouncing
	delay_ms(50);
	// Check to see which pins are active
	// If a pin is active, draw a mark on the LCD by it's label
	// If it isn't active, clear it's mark from the LCD
	if(ioport_get_pin_level(UP_PIN)) {
		gfx_mono_draw_string("X", 16,0,&sysfont);
	} else {
		gfx_mono_draw_string(" ", 16,0,&sysfont);
	}
	if(ioport_get_pin_level(DN_PIN)) {
		gfx_mono_draw_string("X", 40,0,&sysfont);
	} else {
		gfx_mono_draw_string(" ", 40,0,&sysfont);
	}
	if(ioport_get_pin_level(LT_PIN)) {
		gfx_mono_draw_string("X", 16,8,&sysfont);
	} else {
		gfx_mono_draw_string(" ", 16,8,&sysfont);
	}
	if(ioport_get_pin_level(RT_PIN)) {
		gfx_mono_draw_string("X", 40,8,&sysfont);
	} else {
		gfx_mono_draw_string(" ", 40,8,&sysfont);
	}
}

// Interrupt Service Routine for Port B Interrupt 0
ISR(PORTA_INT0_vect)
{
	// Wait 50 ms for debouncing
	delay_ms(50);
	// Check to see which pins are active
	// If a pin is active, draw a mark on the LCD by it's label
	// If it isn't active, clear it's mark from the LCD
	if(ioport_get_pin_level(TG_PIN)) {
		gfx_mono_draw_string("X", 80,0,&sysfont);
	} else {
		gfx_mono_draw_string(" ", 80,0,&sysfont);
	}
}</pre>
<pre>