Buildbotics CNC Controller Firmware Changelog
==============================================
+## v0.3.28
+ - Show step rate on motor configuration page.
+ - Limit motor max-velocity such that step rate cannot exceed 250k.
+ - Fixed deceleration bug at full 250k step rate.
+
+## v0.3.27
+ - Fixed homing in imperial mode.
+
+## v0.3.26
+ - Removed VFD test.
+ - Show VFD status on configuration page.
+ - Show VFD commands fail counts.
+ - Marked some VFD types as beta.
+
## v0.3.25
- Error on home if max-soft-limit <= min-soft-limit + 1. #139
- Decrease boot time networking delay.
{
"name": "bbctrl",
- "version": "0.3.26",
+ "version": "0.3.28",
"homepage": "http://buildbotics.com/",
"repository": "https://github.com/buildbotics/bbctrl-firmware",
"license": "GPL-3.0+",
float ticks_per_step = round(seg_clocks / steps);
// Limit clock if step rate is too fast, disable if too slow
- if (ticks_per_step < STEP_PULSE_WIDTH * 2)
- ticks_per_step = STEP_PULSE_WIDTH * 2; // Too fast
- if (0xffff <= ticks_per_step) m->timer_period = 0; // Too slow
- else m->timer_period = ticks_per_step; // Just right
+ // We allow a slight fudge here (i.e. 1.9 instead 2) because the motor driver
+ // seems to be able to handle it and otherwise we could not actually hit
+ // an average rate of 250k usteps/sec.
+ if (ticks_per_step < STEP_PULSE_WIDTH * 1.9)
+ m->timer_period = STEP_PULSE_WIDTH * 1.9; // Too fast
+ else if (0xffff <= ticks_per_step) m->timer_period = 0; // Too slow
+ else m->timer_period = ticks_per_step; // Just right
if (!steps) m->timer_period = 0;
VAR(status_strings, ds, flags, MOTORS, 0, 1) // Motor driver status
VAR(driver_stalled, sl, b8, MOTORS, 0, 1) // Motor driver status
VAR(encoder, en, s32, MOTORS, 0, 0) // Motor encoder
-VAR(error, ee, s32, MOTORS, 0, 0) // Motor position error
+VAR(error, ee, s32, MOTORS, 0, 1) // Motor position error
VAR(motor_fault, fa, b8, 0, 0, 1) // Motor fault status
void vfd_spindle_init() {
memset(&vfd, 0, sizeof(vfd));
+ for (int i = 0; i < VFDREG; i++) regs[i].fails = 0;
modbus_init();
switch (spindle_get_type()) {
templated-input(v-for="templ in category", :name="$key",
:model.sync="motor[$key]", :template="templ")
+ label.extra(v-if="$key == 'microsteps'", slot="extra",
+ :class="{error: invalidMaxVelocity}",
+ title="Microsteps per second")
+ | ({{ustepPerSec / 1000 | fixed 1}}k µstep/sec)
+
label.extra(v-if="$key == 'max-velocity'", slot="extra",
title="Revolutions Per Minute") ({{rpm | fixed 0}} RPM)
motor: function () {return this.config.motors[this.index]},
+ invalidMaxVelocity: function () {
+ return this.maxMaxVelocity < this.motor['max-velocity'];
+ },
+
+
+ maxMaxVelocity: function () {
+ return 15 * this.umPerStep / this.motor['microsteps'];
+ },
+
+
+ ustepPerSec: function () {
+ return this.rpm * this.stepsPerRev * this.motor['microsteps'] / 60;
+ },
+
+
rpm: function () {
return 1000 * this.motor['max-velocity'] / this.motor['travel-per-rev'];
},
events: {
'input-changed': function() {
+ // Limit max-velocity
+ if (this.invalidMaxVelocity)
+ this.motor['max-velocity'] = this.maxMaxVelocity;
+
this.$dispatch('config-changed');
return false;
}
# Axis homing procedure:
#
# Mark axis unhomed
-# Seek closed (home_dir * (travel_max - travel_min) * 1.5) at search_velocity
-# Seek open (home_dir * -latch_backoff) at latch_vel
-# Seek closed (home_dir * latch_backoff * 1.5) at latch_vel
-# Rapid to (home_dir * -zero_backoff + position)
+# Set feed rate to search_vel
+# Seek closed by search_dist
+# Set feed rate to latch_vel
+# Seek open latch_backoff
+# Seek closed latch_backoff * -1.5
+# Rapid to zero_backoff
# Mark axis homed and set absolute position
axis_homing_procedure = '''
- G28.2 %(axis)s0 F[#<_%(axis)s_sv> * 1000]
- G38.6 %(axis)s[#<_%(axis)s_hd> * [#<_%(axis)s_tm> - #<_%(axis)s_tn>] * 1.5]
- G38.8 %(axis)s[#<_%(axis)s_hd> * -#<_%(axis)s_lb>] F[#<_%(axis)s_lv> * 1000]
- G38.6 %(axis)s[#<_%(axis)s_hd> * #<_%(axis)s_lb> * 1.5]
- G91 G0 G53 %(axis)s[#<_%(axis)s_hd> * -#<_%(axis)s_zb>]
- G90 G28.3 %(axis)s[#<_%(axis)s_hp>]
+ 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]
+ G91 G0 G53 %(axis)s[#<_%(axis)s_zero_backoff>]
+ G90 G28.3 %(axis)s[#<_%(axis)s_home_position>]
'''
self.cmdq.release(id)
- def _get_var_cb(self, name):
+ def _get_var_cb(self, name, units):
value = 0
if len(name) and name[0] == '_':
value = self.ctrl.state.get(name[1:], 0)
+ if units == 'IMPERIAL': value /= 25.4 # Assume metric
+
+ log.info('Get: %s=%s (units=%s)' % (name, value, units))
- log.info('Get: %s=%s' % (name, value))
return value
'speed': 0,
}
+ # Add computed variable callbacks for each motor.
+ #
+ # NOTE, variable callbacks must return metric values only because
+ # the planner will scale returned values when in imperial mode.
for i in range(4):
- # Add home direction callbacks
- self.set_callback(str(i) + 'hd',
- lambda name, i = i: self.motor_home_direction(i))
-
- # Add home position callbacks
- self.set_callback(str(i) + 'hp',
+ self.set_callback(str(i) + 'home_position',
lambda name, i = i: self.motor_home_position(i))
+ self.set_callback(str(i) + 'home_travel',
+ lambda name, i = i: self.motor_home_travel(i))
+ self.set_callback(str(i) + 'latch_backoff',
+ lambda name, i = i: self.motor_latch_backoff(i))
+ self.set_callback(str(i) + 'zero_backoff',
+ lambda name, i = i: self.motor_zero_backoff(i))
+ self.set_callback(str(i) + 'search_velocity',
+ lambda name, i = i: self.motor_search_velocity(i))
+ self.set_callback(str(i) + 'latch_velocity',
+ lambda name, i = i: self.motor_latch_velocity(i))
self.reset()
if mode == 'switch-min': return self.vars['%dtn' % motor]
if mode == 'switch-max': return self.vars['%dtm' % motor]
return 0 # Disabled
+
+
+ def motor_home_travel(self, motor):
+ tmin = self.get(str(motor) + 'tm')
+ tmax = self.get(str(motor) + 'tn')
+ hdir = self.motor_home_direction(motor)
+
+ # (travel_max - travel_min) * 1.5 * home_dir
+ return (tmin - tmax) * 1.5 * hdir
+
+
+ def motor_latch_backoff(self, motor):
+ lb = self.get(str(motor) + 'lb')
+ hdir = self.motor_home_direction(motor)
+ return -(lb * hdir) # -latch_backoff * home_dir
+
+
+ def motor_zero_backoff(self, motor):
+ zb = self.get(str(motor) + 'zb')
+ hdir = self.motor_home_direction(motor)
+ return -(zb * hdir) # -zero_backoff * home_dir
+
+
+ def motor_search_velocity(self, motor):
+ return 1000 * self.get(str(motor) + 'sv')
+
+
+ def motor_latch_velocity(self, motor):
+ return 1000 * self.get(str(motor) + 'lv')