From c2c3d5f2875fc74695641d5845f87a2b982a155a Mon Sep 17 00:00:00 2001 From: Joseph Coffland Date: Tue, 30 Oct 2018 05:08:55 -0700 Subject: [PATCH] Increased max switch backoff search, Increased AVR baudrate, Implemented syncronous speeds, Fixed major bug in command queue --- CHANGELOG.md | 3 +++ src/avr/src/command.c | 48 ++++++++++++++++++++++++--------------- src/avr/src/command.def | 1 + src/avr/src/command.h | 2 ++ src/avr/src/config.h | 2 +- src/avr/src/line.c | 40 ++++++++++++++++++++++++++++++++ src/avr/src/messages.def | 4 ++++ src/avr/src/pwm_spindle.c | 4 ++-- src/avr/src/stepper.c | 2 +- src/py/bbctrl/Cmd.py | 13 +++++++++-- src/py/bbctrl/Mach.py | 2 +- src/py/bbctrl/Planner.py | 2 +- src/py/bbctrl/__init__.py | 2 +- 13 files changed, 98 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca2b519..6b7bb2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ Buildbotics CNC Controller Firmware Changelog - Check that axis dimensions fit path plan dimensions. - Show machine working envelope in path plan viewer. - Don't reload browser view on reconnect unless controller has reloaded. + - Increased max switch backoff search distance. + - Improvements for LASER raster GCodes. + - Fixed major bug in command queuing. ## v0.3.28 - Show step rate on motor configuration page. diff --git a/src/avr/src/command.c b/src/avr/src/command.c index 9dec5d3..a4c4ea7 100644 --- a/src/avr/src/command.c +++ b/src/avr/src/command.c @@ -70,9 +70,7 @@ static struct { bool active; uint32_t id; uint32_t last_empty; - unsigned count; - stat_t parse_error; - int col; + volatile uint16_t count; float position[AXES]; } cmd = {0,}; @@ -93,9 +91,6 @@ static struct { #undef CMD -static uint16_t _space() {return sync_q_space();} - - static bool _is_synchronous(char code) { switch (code) { #define CMD(CODE, NAME, SYNC, ...) case COMMAND_##NAME: return SYNC; @@ -124,7 +119,6 @@ static unsigned _size(char code) { IF(SYNC)(case COMMAND_##NAME: return command_##NAME##_size();) #include "command.def" #undef CMD - default: break; } return 0; @@ -137,7 +131,6 @@ static void _exec_cb(char code, uint8_t *data) { IF(SYNC)(case COMMAND_##NAME: command_##NAME##_exec(data); break;) #include "command.def" #undef CMD - default: break; } } @@ -176,6 +169,9 @@ void command_push(char code, void *_data) { uint8_t *data = (uint8_t *)_data; unsigned size = _size(code); + if (!_is_synchronous(code)) estop_trigger(STAT_Q_INVALID_PUSH); + if (sync_q_space() <= size) estop_trigger(STAT_Q_OVERRUN); + sync_q_push(code); for (unsigned i = 0; i < size; i++) sync_q_push(*data++); @@ -195,7 +191,7 @@ bool command_callback() { if (_is_synchronous(*block)) { if (estop_triggered()) status = STAT_MACHINE_ALARMED; else if (state_is_flushing()) status = STAT_NOP; // Flush command - else if (state_is_resuming() || _space() < _size(*block)) + else if (state_is_resuming() || sync_q_space() <= _size(*block)) return false; // Wait } @@ -240,6 +236,29 @@ void command_reset_position() { } +char command_peek() {return (char)(cmd.count ? sync_q_peek() : 0);} + + +uint8_t *command_next() { + if (!cmd.count) return 0; + cmd.count--; + + if (sync_q_empty()) estop_trigger(STAT_Q_UNDERRUN); + + static uint8_t data[INPUT_BUFFER_LEN]; + + data[0] = sync_q_next(); + + if (!_is_synchronous((char)data[0])) estop_trigger(STAT_INVALID_QCMD); + + unsigned size = _size((char)data[0]); + for (unsigned i = 0; i < size; i++) + data[i + 1] = sync_q_next(); + + return data; +} + + // Returns true if command queued // Called by exec.c from low-level interrupt bool command_exec() { @@ -254,17 +273,10 @@ bool command_exec() { if (!exec_get_velocity() && cmd.count < EXEC_FILL_TARGET && !rtc_expired(cmd.last_empty + EXEC_DELAY)) return false; - char code = (char)sync_q_next(); - unsigned size = _size(code); - - static uint8_t data[INPUT_BUFFER_LEN]; - for (unsigned i = 0; i < size; i++) - data[i] = sync_q_next(); - - cmd.count--; + uint8_t *data = command_next(); state_running(); - _exec_cb(code, data); + _exec_cb((char)*data, data + 1); return true; } diff --git a/src/avr/src/command.def b/src/avr/src/command.def index 093445c..7416595 100644 --- a/src/avr/src/command.def +++ b/src/avr/src/command.def @@ -31,6 +31,7 @@ CMD('#', sync_var, 1) // Set variable synchronous CMD('s', seek, 1) // [switch][flags:active|error] CMD('a', set_axis, 1) // [axis][position] Set axis position CMD('l', line, 1) // [targetVel][maxJerk][axes][times] +CMD('%', sync_speed, 1) // [offset][speed] CMD('I', input, 1) // [a|d][port][mode][timeout] Read input CMD('d', dwell, 1) // [seconds] CMD('P', pause, 1) // [type] Pause control diff --git a/src/avr/src/command.h b/src/avr/src/command.h index f6c8a3f..2ddcae7 100644 --- a/src/avr/src/command.h +++ b/src/avr/src/command.h @@ -52,4 +52,6 @@ void command_set_axis_position(int axis, const float p); void command_set_position(const float position[AXES]); void command_get_position(float position[AXES]); void command_reset_position(); +char command_peek(); +uint8_t *command_next(); bool command_exec(); diff --git a/src/avr/src/config.h b/src/avr/src/config.h index d8bb92d..15cf514 100644 --- a/src/avr/src/config.h +++ b/src/avr/src/config.h @@ -191,7 +191,7 @@ enum { // Serial settings -#define SERIAL_BAUD USART_BAUD_115200 +#define SERIAL_BAUD USART_BAUD_230400 #define SERIAL_PORT USARTC0 #define SERIAL_DRE_vect USARTC0_DRE_vect #define SERIAL_RXC_vect USARTC0_RXC_vect diff --git a/src/avr/src/line.c b/src/avr/src/line.c index fbd0d9b..be5b708 100644 --- a/src/avr/src/line.c +++ b/src/avr/src/line.c @@ -29,6 +29,7 @@ #include "exec.h" #include "axis.h" #include "command.h" +#include "spindle.h" #include "util.h" #include "SCurve.h" @@ -51,6 +52,12 @@ typedef struct { } line_t; +typedef struct { + float offset; + float speed; +} speed_t; + + static struct { line_t line; @@ -62,6 +69,8 @@ static struct { float iA; // Initial section acceleration float jerk; float lV; // Last velocity + + speed_t speed; } l; @@ -132,6 +141,15 @@ static stat_t _line_exec() { // Don't allow overshoot if (l.line.length < d) d = l.line.length; + // Handle syncronous speeds + if (l.speed.offset < 0 && command_peek() == COMMAND_sync_speed) + l.speed = *(speed_t *)(command_next() + 1); + + if (0 <= l.speed.offset && l.speed.offset <= d) { + spindle_set_speed(l.speed.speed); + l.speed.offset = -1; + } + // Check if section complete if (t == section_time) { if (_section_next()) { @@ -239,6 +257,8 @@ unsigned command_line_size() {return sizeof(line_t);} void command_line_exec(void *data) { l.line = *(line_t *)data; + l.speed.offset = -1; + // Setup first section l.seg = 0; l.iD = 0; @@ -268,3 +288,23 @@ void command_line_exec(void *data) { // Set callback exec_set_cb(_line_exec); } + + +stat_t command_sync_speed(char *cmd) { + speed_t s; + + cmd++; // Skip command code + + // Get target velocity + if (!decode_float(&cmd, &s.offset)) return STAT_BAD_FLOAT; + if (!decode_float(&cmd, &s.speed)) return STAT_BAD_FLOAT; + + // Queue + command_push(COMMAND_sync_speed, &s); + + return STAT_OK; +} + + +unsigned command_sync_speed_size() {return sizeof(speed_t);} +void command_sync_speed_exec(void *data) {} // Should not get here diff --git a/src/avr/src/messages.def b/src/avr/src/messages.def index 8aceadd..0615e34 100644 --- a/src/avr/src/messages.def +++ b/src/avr/src/messages.def @@ -54,3 +54,7 @@ STAT_MSG(STEPPER_NULL_MOVE, "Null move in stepper driver") STAT_MSG(STEPPER_NOT_READY, "Stepper driver not ready for move") STAT_MSG(SHORT_SEG_TIME, "Short segment time") STAT_MSG(MODBUS_BUF_LENGTH, "Modbus invalid buffer length") +STAT_MSG(INVALID_QCMD, "Invalid command in queue") +STAT_MSG(Q_OVERRUN, "Command queue overrun") +STAT_MSG(Q_UNDERRUN, "Command queue underrun") +STAT_MSG(Q_INVALID_PUSH, "Invalid command pushed to queue") diff --git a/src/avr/src/pwm_spindle.c b/src/avr/src/pwm_spindle.c index e863881..512b348 100644 --- a/src/avr/src/pwm_spindle.c +++ b/src/avr/src/pwm_spindle.c @@ -61,7 +61,7 @@ static void _update_pwm() { // Disable if (!speed || estop_triggered()) { - TIMER_PWM.CTRLA = 0; + TIMER_PWM.CTRLB = 0; // Disable clock control of pin OUTCLR_PIN(SPIN_PWM_PIN); _set_enable(false); return; @@ -70,7 +70,7 @@ static void _update_pwm() { // 100% duty if (speed == 1 && spindle.max_duty == 1) { - TIMER_PWM.CTRLB = 0; + TIMER_PWM.CTRLB = 0; // Disable clock control of pin OUTSET_PIN(SPIN_PWM_PIN); return; } diff --git a/src/avr/src/stepper.c b/src/avr/src/stepper.c index 9424d84..f59866e 100644 --- a/src/avr/src/stepper.c +++ b/src/avr/src/stepper.c @@ -118,7 +118,7 @@ ISR(STEP_LOW_LEVEL_ISR) { case STAT_OK: // Move executed if (!st.move_queued) - estop_trigger(STAT_EXPECTED_MOVE); // No move was queued + estop_trigger(STAT_EXPECTED_MOVE); // No move was queued st.move_queued = false; st.move_ready = true; break; diff --git a/src/py/bbctrl/Cmd.py b/src/py/bbctrl/Cmd.py index 8bb3d9b..f82fea4 100644 --- a/src/py/bbctrl/Cmd.py +++ b/src/py/bbctrl/Cmd.py @@ -42,6 +42,7 @@ MODBUS_WRITE = 'M' SEEK = 's' SET_AXIS = 'a' LINE = 'l' +SYNC_SPEED = '%' INPUT = 'I' DWELL = 'd' PAUSE = 'P' @@ -100,7 +101,7 @@ def modbus_write(addr, value): return MODBUS_WRITE + '%d=%d' % (addr, value) def set_axis(axis, position): return SET_AXIS + axis + encode_float(position) -def line(target, exitVel, maxAccel, maxJerk, times): +def line(target, exitVel, maxAccel, maxJerk, times, speeds): cmd = LINE cmd += encode_float(exitVel) @@ -113,10 +114,18 @@ def line(target, exitVel, maxAccel, maxJerk, times): if times[i]: cmd += str(i) + encode_float(times[i] / 60000) # to mins + # Speeds + for speed in speeds: + cmd += '\n' + sync_speed(speed[0], speed[1]) + return cmd -def speed(speed): return '#s=:' + encode_float(speed) +def speed(speed): return set_float('s', speed) + + +def sync_speed(offset, speed): + return SYNC_SPEED + encode_float(offset) + encode_float(speed) def input(port, mode, timeout): diff --git a/src/py/bbctrl/Mach.py b/src/py/bbctrl/Mach.py index 91e0474..65ce235 100644 --- a/src/py/bbctrl/Mach.py +++ b/src/py/bbctrl/Mach.py @@ -50,7 +50,7 @@ axis_homing_procedure = ''' G28.2 %(axis)s0 F[#<_%(axis)s_search_velocity>] G38.6 %(axis)s[#<_%(axis)s_home_travel>] G38.8 %(axis)s[#<_%(axis)s_latch_backoff>] F[#<_%(axis)s_latch_velocity>] - G38.6 %(axis)s[#<_%(axis)s_latch_backoff> * -1.5] + G38.6 %(axis)s[#<_%(axis)s_latch_backoff> * -8] G91 G0 G53 %(axis)s[#<_%(axis)s_zero_backoff>] G90 G28.3 %(axis)s[#<_%(axis)s_home_position>] ''' diff --git a/src/py/bbctrl/Planner.py b/src/py/bbctrl/Planner.py index c406388..459619f 100644 --- a/src/py/bbctrl/Planner.py +++ b/src/py/bbctrl/Planner.py @@ -216,7 +216,7 @@ class Planner(): if type == 'line': return Cmd.line(block['target'], block['exit-vel'], block['max-accel'], block['max-jerk'], - block['times']) + block['times'], block.get('speeds', [])) if type == 'set': name, value = block['name'], block['value'] diff --git a/src/py/bbctrl/__init__.py b/src/py/bbctrl/__init__.py index 098a80f..d18c7fa 100644 --- a/src/py/bbctrl/__init__.py +++ b/src/py/bbctrl/__init__.py @@ -91,7 +91,7 @@ def parse_args(): help = 'HTTP address to bind') parser.add_argument('-s', '--serial', default = '/dev/ttyAMA0', help = 'Serial device') - parser.add_argument('-b', '--baud', default = 115200, type = int, + parser.add_argument('-b', '--baud', default = 230400, type = int, help = 'Serial baud rate') parser.add_argument('--i2c-port', default = 1, type = int, help = 'I2C port') -- 2.27.0