Laser cutter software
Dependencies: EthernetNetIf mbed SDFileSystem
Diff: LaosMotion/LaosMotion.cpp
- Revision:
- 0:18ead85c200b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LaosMotion/LaosMotion.cpp Thu Aug 11 09:33:15 2011 +0000 @@ -0,0 +1,285 @@ +/** + * LaosMotion.cpp + * Motion Controll functions for Laos system + * + * Copyright (c) 2011 Peter Brier + * + * This file is part of the LaOS project (see: http://wiki.protospace.nl/index.php/LaOS) + * + * LaOS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LaOS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LaOS. If not, see <http://www.gnu.org/licenses/>. + * + * + * + */ +#include "LaosMotion.h" + + +// status leds +extern DigitalOut led1,led2,led3,led4; + +// Inputs; +DigitalIn xhome(p8); +DigitalIn yhome(p17); +DigitalIn zmin(p15); +DigitalIn zmax(p16); + +// motors +DigitalOut enable(p7); +DigitalOut xdir(p23); +DigitalOut xstep(p24); +DigitalOut ydir(p25); +DigitalOut ystep(p26); +DigitalOut zdir(p27); +DigitalOut zstep(p28); + +// laser + +// DigitalOut laser(p22); // O1: PWM (Yellow) +PwmOut pwm(p22); +DigitalOut laser_enable(p21); // O2: enable laser +DigitalOut o3(p6); // 03: NC +DigitalOut laser(p5); // O4: LaserON (White) + + +// Analog in/out (cover sensor) + NC +DigitalIn cover(p19); + +// globals +Ticker ticker; // Timer +int ctr; + +int step, prevcommand, command; +volatile int state, laseron; + +// Besenham variables +int x0,y0,x1,y1,z0,z1; // positions: 0=current, 1=new +int dx, sx; // step +int dy, sy; // delta +int err, e2; // error + + +#define LASEROFF 1 +#define LASERON 0 + +#define LOW_SPEED 400 +#define HIGH_SPEED 90 + + +/** +*** ticker: implement timer ticker, step if required +**/ +void tick() +{ + ctr++; + // Control X,Y: line tracker + switch ( state ) + { + case 0: // idle (make sure laser is off) + laser=LASEROFF; + break; + case 1: // init + dx = abs(x1-x0); + sx = x0<x1 ? 1 : -1; + dy = abs(y1-y0); + sy = y0<y1 ? 1 : -1; + err = (dx>dy ? dx : -dy)/2; + xdir = sx > 0; + ydir = sy > 0; + if ( laseron ) + laser = LASERON; + else + laser = LASEROFF; + state++; + break; + case 2: // moving + if (x0==x1 && y0==y1) + state = 0; + else + { + e2 = err; + if (e2 >-dx) { err -= dy; x0 += sx; xstep = 1;} + if (e2 < dy) { err += dx; y0 += sy; ystep = 1;} + } + break; + } + // Controll Z: tracking controller (independent of XY motion, not queued) + if ( z1 != z0 ) + { + zdir = z1 > z0; + wait_us(5); + zstep= 1; + if ( z1 > z0 ) z0++; + else z0--; + } + + if ( xstep == 1 || ystep == 1 || zstep == 1 ) + { + wait_us(5); + xstep = ystep = zstep = 0; + } + + // diagnostic info + led1 = xdir; + led2 = ydir; + led3 = laseron; + led4 = ctr & 4096; +} // ticker + + +/** +*** LaosMotion() Constructor +*** Make new motion object +**/ +LaosMotion::LaosMotion() +{ + reset(); + laser=LASEROFF; + pwm.period(0.0005); + pwm = 0.5; + //start.mode(PullUp); + xhome.mode(PullUp); + yhome.mode(PullUp); + isHome = false; + ticker.attach_us(&tick, HIGH_SPEED); // the address of the function to be attached (flip) and the interval (microseconds) +} + +/** +***Destructor +**/ +LaosMotion::~LaosMotion() +{ + +} + +/** +*** reset() +*** reset the state +**/ +void LaosMotion::reset() +{ + step = prevcommand = command = state = laseron = xstep = xdir = ystep = ydir = zstep = zdir = 0; + laser=LASEROFF; +} + + + +/** +*** ready() +*** ready to receive new commands +**/ +int LaosMotion::ready() +{ + return state == 0; +} + +/** +*** write() +*** Write command to motion controller +**/ +void LaosMotion::write(int i) +{ + // printf("m:%d %d %d %d\n", state, step, i, command); + if ( step == 0 ) + { + prevcommand = command; + command = i; + step++; + } + else + { + switch( command ) + { + case 0: // move x,y (laser off) + case 1: // line x,y (laser on) + switch ( step ) + { + case 1: x1 = i; break; + case 2: + y1 = i; + if ( prevcommand != command ) + ticker.attach_us(&tick, (command ? LOW_SPEED : HIGH_SPEED)); // the address of the function to be attached (flip) and the interval (microseconds) + laseron = (command == 1); state = 1; step = 0; + break; + } + break; + case 2: // move z + switch(step) + { + case 1: z1 = i; step = 0; break; + } + case 3: // set t (1/v) + switch(step) + { + case 1: ticker.attach_us(&tick, i); step=0; break; + } + case 4: // set x,y,z absolute + switch ( step ) + { + case 1: x0 = i; break; + case 2: y0 = i; break; + case 3: z0=z1 = i; step=0; break; + } + case 5: // nop + step=0; + break; + default: // I do not understand: stop motion + state = 0; + step = 0; + break; + } + if ( step ) step++; + } +} + + +/** +*** Return true if start button is pressed +**/ +bool LaosMotion::isStart() +{ + return cover; +} + + +/** +*** Home the axis, stop when button is pressed +**/ +void LaosMotion::home() +{ + int i=0; + xdir = 0; + ydir = 0; + zdir = 0; + led1 = 0; + isHome = false; + while ( 1 ) + { + xstep = ystep = 0; + wait(0.0001); + xstep = xhome; + ystep = yhome; + wait(0.0001); + + led2 = !xhome; + led3 = !yhome; + led4 = ((i++) & 0x10000); + if ( (!xhome) && (!yhome) ) return; + // if ( i > 2000 && !isStart() ) return; // debounce, and quit if key pressed again + } + isHome = true; +} + + + +