Laser Electronics: Difference between revisions
Jump to navigation
Jump to search
(Initial Commit) |
(No difference)
|
Revision as of 18:17, 6 January 2015
Laser Cutter Electronics
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; } }