Laser Electronics

From Hacklab.TO Public Wiki
Revision as of 17:45, 26 February 2018 by Atrain (talk | contribs) (remove unimplemented power control mod.... irrelevent)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Laser Cutter Electronics

File:Laser-control board.pdf

File:Laser-motor driver.pdf


Laser control board pinout

Left Header: (Top to Bottom)

  • GND (Shield)
  • SW_1 (Yellow)
  • SW_2 ( Green)
  • SW_4 (Blue)
  • SW_8 (Lt Purple)
  • Disable (Lt Brown)
  • ...

Top Header: (left to right)

  • Output to LEDs
  • PWM output to laser tube (2 pins - black, red)

Bottom Header: (Left to right)

  • Laser EN (Black)
  • ...
  • (I/O to parallel port here)

Right Header: (Top to bottom)

  • ...
  • (Power Input & output to stepper driver)

Laser Power controller board pinout

Long header:

  • yellow = switch input
  • blue = parallel input
  • green = output to PIC (where switches used to go)

Top header:

  • Pin 1 (Orange wire) LASER_EN
  • Pin 3,4 - (Purple) Mode Switch
  • Pin 5 - Ground
  • Pin 6 - 5V


Code

/*
 * Laser Engraver Controller - ver. 1.0
 *
 * Written by: Andrew Kilpatrick
 * Copyright: 2009
 *
 * Runs on PIC16F877A
 *
 * Functional Description:
 *  - support for connection to emc2 or similar host-driven CNC software
 *  - parallel port or other type of bit-bang connection to PC
 *  - E-stop and system run control support (amp enable, charge pump, etc.)
 *  - controls 3 stepper motors (X, Y, Z)
 *  - controls laser PWM control
 *
 * Hardware I/O:
 *  - RA0	- laser power bit 0		- input - active high
 *  - RA1	- laser power bit 1		- input - active high
 *  - RA2	- laser power bit 2		- input - active high
 *  - RA3	- laser power bit 3		- input - active high
 *  - RA4	- laser defeat			- input - active high
 *
 *  - RB0	- E stop loop			- input - 0 = run, 1 = stop
 *  - RB1	- Z dir					- input - 0 = back, 1 = forward
 *  - RB2	- Y dir					- input - 0 = back, 1 = forward
 *  - RB3	- X dir					- input - 0 = back, 1 = forward
 *  - RB4	- laser activate		- input - 0 = off, 1 = on
 *  - RB5	- Z step				- input - rising edge - move one step
 *  - RB6	- Y step				- input - rising edge - move one step
 *  - RB7	- X step				- input - rising edge - move one step
 *
 *  - RC0	- amp enable LED		- output - 0 = off, 1 = on
 *  - RC1	- laser LED				- output - 0 = off, 1 = on
 *  - RC2	- laser PWM				- output - 0 = off, 1 = on
 *  - RC4	- Z motor phase A		- output
 *  - RC5	- Z motor phase B		- output
 *	- RC6	- Z motor phase C		- output
 *  - RC7	- Z motor phase D		- output
 *
 *  - RD0	- X motor phase A		- output
 *  - RD1	- X motor phase B		- output
 *  - RD2 	- X motor phase C		- output
 *  - RD3	- X motor phase D		- output
 *  - RD4	- Y motor phase A		- output
 *  - RD5	- Y motor phase B		- output
 *  - RD6	- Y motor phase C		- output
 *  - RD7	- Y motor phase D		- output
 *
 *  - RE0	- E stop output			- output - 0 = stop, 1 = run
 *  - RE1	- amp enable input		- input - 0 = disable, 1 = enable
 *  - RE2	- charge pump input		- input - high pulses to charge
 *
 */
#include <system.h>

#pragma CLOCK_FREQ 20000000

#pragma DATA 0x2007, _CP_OFF & _DEBUG_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _HS_OSC & _WDT_ON & _PWRTE_ON

// inputs
#define LASER_POWER_1_IN porta.0
#define LASER_POWER_2_IN porta.1
#define LASER_POWER_4_IN porta.2
#define LASER_POWER_8_IN porta.3
#define LASER_DEFEAT_IN porta.4
#define E_STOP_IN portb.0
#define X_DIR_IN portb.3
#define Y_DIR_IN portb.2
#define Z_DIR_IN portb.1
#define X_STEP_IN portb.7
#define Y_STEP_IN portb.6
#define Z_STEP_IN portb.5
#define LASER_IN portb.4
#define AMP_ENABLE_IN porte.1
#define CHARGE_PUMP_IN porte.2

// outputs
#define AMP_ENABLE_LED portc.0
#define LASER_ON_LED portc.1
#define E_STOP_OUT porte.0

// laser setting
#define LASER_TICKLE 0x01

// motor step size - 1 = half-step, 2 = full step
#define X_STEP_SIZE 1
#define Y_STEP_SIZE 1
#define Z_STEP_SIZE 1

// run state machine
#define STATE_IDLE 1
#define STATE_RUN 2
#define STATE_E_STOP 3
unsigned char run_state;

// globals
unsigned char x_phase;			// the X motor step phase
unsigned char y_phase;			// the Y motor step phase
unsigned char z_phase;			// the Z motor step phase
unsigned char run;				// 1 = normal, 0 = stopped
unsigned char charge_pump;		// 0 = stopped, >0 = run
unsigned char old_ch_pump;
unsigned char laser_init;		// 1 = laser initialized, 0 = not initialized
unsigned char laser_power;		// laser power level
unsigned char laser_on;			// 1 = laser on, 0 = laser off
unsigned char flash;			// temp flasher variable
unsigned char x_step;			// temp x step state
unsigned char y_step;			// temp y step state
unsigned char z_step;			// temp z step state

// function prototypes
void step_laser(void);

// main loop
void main() {
	// set up IO
	porta = 0x00;
	trisa = 0xff;  // inputs
	adcon1 = 0x06;  // all digital pins
	
	portb = 0x00;
	trisb = 0xff;  // inputs
	option_reg.NOT_RBPU = 0;  // weak pullups
	
	portc = 0x00;
	trisc = 0x00;  // outputs
	AMP_ENABLE_LED = 0;
	LASER_ON_LED = 0;
	ccpr1l = 0x00;
	ccp1con = 0x0c;  // PWM mode
	t2con = 0x05;  // prescaler 4, timer on
	
	portd = 0x00;
	trisd = 0x00;  // outputs
	trise.PSPMODE = 0;  // no data port
	
	porte = 0x00;
	trise &= 0xfe;  // RE0 = output, RE1-2 = input 
	E_STOP_OUT = 1;  // no E stop

	t1con = 0x21;  // 1:4 prescaler, internal clock, timer on

	// reset temp vars
	x_phase = 0;
	y_phase = 0;
	z_phase = 0;
	run = 0;
	laser_init = 0;
	laser_on = 0;
	flash = 0;
	x_step = 0;
	y_step = 0;
	z_step = 0;
	run_state = STATE_IDLE;
	charge_pump = 0;
	old_ch_pump = 0;

	// bootup light dance
	AMP_ENABLE_LED = 0;
	LASER_ON_LED = 1;
	delay_ms(250);
	delay_ms(250);
	AMP_ENABLE_LED = 1;
	LASER_ON_LED = 0;
	delay_ms(250);
	delay_ms(250);
	AMP_ENABLE_LED = 0;

	// loop
	while(1) {
		clear_wdt();
		
		// do stuff every 50ms
		if(pir1.TMR1IF) {
			pir1.TMR1IF = 0;
			
			// charge pump
			if(charge_pump) charge_pump --;
			
			// EMERGENCY STOP!
			if(E_STOP_IN) {			
				run_state = STATE_E_STOP;				
				E_STOP_OUT = 0;
				
				// turn off the laser
				ccpr1l = 0x00;  // power level to 0
				ccp1con &= 0xcf;  // power level to 0
				laser_power = 0;
				laser_on = 0;
				LASER_ON_LED = 0;
			
				// turn off motors
				portd = 0;
				portc &= 0x0f;

				// LED flashing
				flash = (flash + 1) & 0x07;
				if(flash & 0x04) {
					AMP_ENABLE_LED = 1;
				}
				else {
					AMP_ENABLE_LED = 0;
				}
			}
			// E STOP cleared - enter idle state
			if(run_state == STATE_E_STOP && !E_STOP_IN) {
				run_state = STATE_IDLE;
				AMP_ENABLE_LED = 0;
				E_STOP_OUT = 1;
			}
			// amplifier enabled - enter run state
			if(run_state == STATE_IDLE && AMP_ENABLE_IN && charge_pump > 0x7f) {
				run_state = STATE_RUN;
				AMP_ENABLE_LED = 1;
				ccpr1l = LASER_TICKLE;  // make tickle puses for the laser
				ccp1con |= 0x30;  // PWM mode
			}
			// amplifier disabled - enter idle state
			if(run_state == STATE_RUN && (!AMP_ENABLE_IN || charge_pump < 0x80)) {
				run_state = STATE_IDLE;
				AMP_ENABLE_LED = 0;

				// turn off the laser
				ccpr1l = 0x00;  // power level to 0
				ccp1con &= 0xcf;  // power level to 0
				laser_power = 0;
				laser_on = 0;
				LASER_ON_LED = 0;
			
				// turn off motors
				portd = 0;
				portc &= 0x0f;
			}
			
			// handle laser power adjustments in run state
			if(run_state == STATE_RUN) {
				// laser power adjust
				if(LASER_DEFEAT_IN) {
					// force laser into tickle
					ccpr1l = LASER_TICKLE;
					laser_power = 0;
					LASER_ON_LED = 0;
				}
				else {
					laser_power = (porta & 0x0f) << 4;
					// if laser is on, change power immediately
					if(laser_on) {
						ccpr1l = laser_power;
						LASER_ON_LED = 1;
					}
				}
			}			
		}
		
		// handle realtime run stuff
		if(run_state == STATE_RUN) {
			step_laser();
		}
		
		// handle charge pump on rising edge
		if(CHARGE_PUMP_IN && !old_ch_pump) {
			if(charge_pump != 0xff) charge_pump ++;
		}
		old_ch_pump = CHARGE_PUMP_IN;
	}
}

void step_laser(void) {
	// step inputs are low - reset the flags
	if(!X_STEP_IN) {
		x_step = 0;
	}
	if(!Y_STEP_IN) {
		y_step = 0;
	}
	if(!Z_STEP_IN) {
		z_step = 0;
	}	
				
	// x step
	if(!x_step && X_STEP_IN) {
		x_step = 1;
		// forward
		if(X_DIR_IN) {
			x_phase = (x_phase - X_STEP_SIZE) & 0x07;
		}
		// reverse
		else {
			x_phase = (x_phase + X_STEP_SIZE) & 0x07;
		}			
		// phases
		if(x_phase == 0) portd = (portd & 0xf0) | 0x05;
		if(x_phase == 1) portd = (portd & 0xf0) | 0x0d;
		if(x_phase == 2) portd = (portd & 0xf0) | 0x09;
		if(x_phase == 3) portd = (portd & 0xf0) | 0x0b;
		if(x_phase == 4) portd = (portd & 0xf0) | 0x0a;
		if(x_phase == 5) portd = (portd & 0xf0) | 0x02;
		if(x_phase == 6) portd = (portd & 0xf0) | 0x06;
		if(x_phase == 7) portd = (portd & 0xf0) | 0x04;
	}
	// y step
	if(!y_step && Y_STEP_IN) {
		y_step = 1;
		// forward
		if(Y_DIR_IN) {
			y_phase = (y_phase - Y_STEP_SIZE) & 0x07;
		}
		// reverse
		else {
			y_phase = (y_phase + Y_STEP_SIZE) & 0x07;
		}
		// phases
		if(y_phase == 0) portd = (portd & 0x0f) | 0x50;
		if(y_phase == 1) portd = (portd & 0x0f) | 0xd0;
		if(y_phase == 2) portd = (portd & 0x0f) | 0x90;
		if(y_phase == 3) portd = (portd & 0x0f) | 0xb0;
		if(y_phase == 4) portd = (portd & 0x0f) | 0xa0;
		if(y_phase == 5) portd = (portd & 0x0f) | 0x20;
		if(y_phase == 6) portd = (portd & 0x0f) | 0x60;
		if(y_phase == 7) portd = (portd & 0x0f) | 0x40;
	}
	// z step
	if(!z_step && Z_STEP_IN) {
		z_step = 1;
		// forward
		if(Z_DIR_IN) {
			z_phase = (z_phase - Z_STEP_SIZE) & 0x07;
		}
		// reverse
		else {
			z_phase = (z_phase + Z_STEP_SIZE) & 0x07;
		}
		// phases
		if(z_phase == 0) portc = (portc & 0x0f) | 0x50;
		if(z_phase == 1) portc = (portc & 0x0f) | 0xd0;
		if(z_phase == 2) portc = (portc & 0x0f) | 0x90;
		if(z_phase == 3) portc = (portc & 0x0f) | 0xb0;
		if(z_phase == 4) portc = (portc & 0x0f) | 0xa0;
		if(z_phase == 5) portc = (portc & 0x0f) | 0x20;
		if(z_phase == 6) portc = (portc & 0x0f) | 0x60;
		if(z_phase == 7) portc = (portc & 0x0f) | 0x40;
	}
	// laser
	if(LASER_IN) {
		ccpr1l = laser_power;
		LASER_ON_LED = 1;
		laser_on = 1;
	}
	else {
		ccpr1l = LASER_TICKLE;
		LASER_ON_LED = 0;
		laser_on = 0;
	}
}

Tube

The tube on the laser cutter is a 25W Synrad F48-2S

Manual for that version does not appear online, but here are manuals for newer ones: