From 5b1245e41dee594c7e8b90758e149446dad4f385 Mon Sep 17 00:00:00 2001 From: Michael Moon Date: Wed, 3 Feb 2010 23:11:33 +1100 Subject: [PATCH] solved bug where speed would be seemingly random for moves beyond about 71mm, plus lots of tidying --- mendel/Makefile | 17 ++++++++++----- mendel/dda.c | 55 +++++++++++++++++++++++++++++++------------------ 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/mendel/Makefile b/mendel/Makefile index fc4c870..51f4d24 100644 --- a/mendel/Makefile +++ b/mendel/Makefile @@ -32,16 +32,25 @@ F_CPU = 16000000L ############################################################################## ARCH = avr- +CC = $(ARCH)gcc +OBJDUMP = $(ARCH)objdump +OBJCOPY = $(ARCH)objcopy + OPTIMIZE = -Os -ffunction-sections -finline-functions-called-once -DDEBUG=1 # OPTIMIZE = -O0 CFLAGS = -g -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(F_CPU) $(DEFS) -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -save-temps LDFLAGS = -Wl,--as-needed -Wl,--gc-sections -CC = $(ARCH)gcc -OBJDUMP = $(ARCH)objdump -OBJCOPY = $(ARCH)objcopy AVRDUDE = avrdude +############################################################################## +# # +# udev rule for /dev/arduino (insert into /etc/udev/rules.d/99-local.rules) # +# SUBSYSTEMS=="usb", ATTRS{idProduct}=="6001", ATTRS{idVendor}=="0403", # +# NAME="%k", SYMLINK+="arduino", SYMLINK+="arduino_$attr{serial}", # +# MODE="0660" # +# # +############################################################################## PROGPORT = /dev/arduino PROGBAUD = 19200 @@ -54,8 +63,6 @@ all: $(PROGRAM).hex $(PROGRAM).lst size program: $(PROGRAM).hex stty $(PROGBAUD) raw ignbrk hup < $(PROGPORT) - @sleep 0.2 - @stty $(PROGBAUD) raw ignbrk hup < $(PROGPORT) $(AVRDUDE) -cstk500v1 -b$(PROGBAUD) -p$(MCU_TARGET) -P$(PROGPORT) -C/etc/avrdude.conf -U flash:w:$^ stty 57600 raw ignbrk -hup -echo ixon < $(PROGPORT) diff --git a/mendel/dda.c b/mendel/dda.c index a59dd86..cc27358 100644 --- a/mendel/dda.c +++ b/mendel/dda.c @@ -24,6 +24,13 @@ uint8_t steptimeout = 0; +/* + position tracking +*/ + +TARGET startpoint = { 0, 0, 0, 0, 0 }; +TARGET current_position = { 0, 0, 0, 0, 0 }; + /* move queue */ @@ -32,12 +39,6 @@ uint8_t mb_head = 0; uint8_t mb_tail = 0; DDA movebuffer[MOVEBUFFER_SIZE]; -/* - position tracking -*/ - -TARGET startpoint = { 0, 0, 0, 0, 0 }; -TARGET current_position = { 0, 0, 0, 0, 0 }; uint8_t queue_full() { if (mb_tail == 0) @@ -176,7 +177,7 @@ uint32_t delta32(uint32_t v1, uint32_t v2) { } /* - CREATE + CREATE a dda given current_position and a target, save to passed location so we can write directly into the queue */ void dda_create(TARGET *target, DDA *dda) { @@ -279,12 +280,20 @@ void dda_create(TARGET *target, DDA *dda) { // if (distance < 2) // distance = dda->f_delta; + if (DEBUG) { + serwrite_uint32(distance); serial_writechar(','); + } + // pre-calculate move speed in millimeter microseconds per step minute for less math in interrupt context // mm (distance) * 60000000 us/min / step (total_steps) = mm.us per step.min // note: um (distance) * 60000 == mm * 60000000 // so in the interrupt we must simply calculate // mm.us per step.min / mm per min (F) = us per step - dda->move_duration = distance * 60000 / dda->total_steps; + + // break this calculation up a bit and lose some precision because 300,000um * 60000 is too big for a uint32 + // calculate this with a uint64 if you need the precision, but it'll take longer so routines with lots of short moves may suffer + // 2^32/6000 is about 715mm which should be plenty + dda->move_duration = ((distance * 6000) / dda->total_steps) * 10; if (DEBUG) serwrite_uint32(dda->move_duration); @@ -298,7 +307,7 @@ void dda_create(TARGET *target, DDA *dda) { } /* - START + Start a prepared DDA */ void dda_start(DDA *dda) { @@ -369,11 +378,14 @@ void dda_step(DDA *dda) { #define REAL_MOVE 32 #define F_REAL_STEP 64 - serial_writechar('!'); + if (DEBUG) + serial_writechar('!'); - WRITE(SCK, 0); + // turn 'L' light OFF so it's obvious if we froze in this routine +// if (DEBUG) +// WRITE(SCK, 0); - do { +// do { // WRITE(SCK, 0); step_option &= ~(X_CAN_STEP | Y_CAN_STEP | Z_CAN_STEP | E_CAN_STEP | F_CAN_STEP); @@ -468,6 +480,7 @@ void dda_step(DDA *dda) { } } + // this generates too much debug output for all but the slowest step rates if (0 && DEBUG) { serial_writechar('['); serwrite_hex8(step_option); @@ -484,10 +497,7 @@ void dda_step(DDA *dda) { // } while ( ((step_option & REAL_MOVE ) == 0) && // ((step_option & F_CAN_STEP) != 0) ); - } while (0); - - // turn off step outputs, hopefully they've been on long enough by now to register with the drivers - unstep(); +// } while (0); if (step_option & REAL_MOVE) // we stepped, reset timeout @@ -502,15 +512,20 @@ void dda_step(DDA *dda) { setTimer(dda->move_duration / current_position.F); // if we could do anything at all, we're still running -// dda->live = (step_option != 0)?1:0; // otherwise, must have finished - if (step_option == 0) { + else if (step_option == 0) { dda->live = 0; #ifdef STUPIDLY_HIDE_BUGS - // this magically makes bugs disappear after each move, probably a bad move + // this magically makes bugs disappear after each move, probably a bad idea memcpy(¤t_position, &(dda->endpoint), sizeof(TARGET)); #endif } - WRITE(SCK, 1); + // turn off step outputs, hopefully they've been on long enough by now to register with the drivers + // if not, too bad. or insert a (very!) small delay here, or fire up a spare timer or something + unstep(); + + // turn 'L' light back on again +// if (DEBUG) +// WRITE(SCK, 1); }