Increased max switch backoff search, Increased AVR baudrate, Implemented syncronous...
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Tue, 30 Oct 2018 12:08:55 +0000 (05:08 -0700)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Tue, 30 Oct 2018 12:08:55 +0000 (05:08 -0700)
13 files changed:
CHANGELOG.md
src/avr/src/command.c
src/avr/src/command.def
src/avr/src/command.h
src/avr/src/config.h
src/avr/src/line.c
src/avr/src/messages.def
src/avr/src/pwm_spindle.c
src/avr/src/stepper.c
src/py/bbctrl/Cmd.py
src/py/bbctrl/Mach.py
src/py/bbctrl/Planner.py
src/py/bbctrl/__init__.py

index ca2b519ff5c5e8fe2c255c2a37cd829c48ed2606..6b7bb2fb8c023e796f92c6570e5f397db870afc1 100644 (file)
@@ -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.
index 9dec5d313a50cb4f4056355b4840ac69c3f60da4..a4c4ea7730e6c162dfb6a41091f40f3e0295de31 100644 (file)
@@ -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;
 }
index 093445c4763ad9e97687c3b3cc4a875da21bd9b8..74165954ee4df8b694b04f1da72b579443ed26ea 100644 (file)
@@ -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
index f6c8a3f9da6b855db8a628f47e98a4accc6546d9..2ddcae7621ab8240ab726a05f95c90b3319e9247 100644 (file)
@@ -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();
index d8bb92dd2a6b3a0e2576261e5d804ace1b443f73..15cf51474a2977e669e8caaa9577c540ecb91ef4 100644 (file)
@@ -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
index fbd0d9b78c78c9acc83087ff22f1d32b91e12d0c..be5b708c5749b4dd24f0c95a211306df9b14957e 100644 (file)
@@ -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
index 8aceadd251a01b40a207c9aa417452953cd578be..0615e34d39da8e20fc63f7a90aef0d391685c127 100644 (file)
@@ -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")
index e86388177b7288fa4c3355224a58bad30252838a..512b348020c8cadcf565f2bbd59ae25b4bde2f45 100644 (file)
@@ -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;
   }
index 9424d8472fc29483ef2e991e44b8d17ab7798914..f59866ee4d1b19214337b9aecea53a97b46343eb 100644 (file)
@@ -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;
index 8bb3d9be57c272077a7193c771cae282fc069c17..f82fea44c4763bf373166ff3e91e711c67d3c083 100644 (file)
@@ -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):
index 91e04744379a1e64ae2c96222f85b83f16a8ca0a..65ce23529116f1c42bc82e830f5866c5fc4e59ac 100644 (file)
@@ -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>]
 '''
index c40638889c3685f1b8f556cd78bda534af363afd..459619f4b9672bb7c23fdc8293fdb30424454d7f 100644 (file)
@@ -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']
index 098a80fe8e81431be8cd2c65b337be3f1da2a1dc..d18c7fa2e4432e857ad3825d88392baaf6246363 100644 (file)
@@ -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')