- Much improved camera support.
- Camera hotpluging.
- Move camera video to header.
- - Click to switch through three video sizes.
+ - Click to switch video size.
- Automount/unmount USB drives.
- Automatically install ``buildbotics.gc`` when no other GCode exists.
- Preplan GCode and check for errors.
- 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.
+ - Major improvements for LASER raster GCodes.
- Fixed major bug in command queuing.
+ - Ignore Program Number O-Codes.
+ - Improved planning of colinear line segments.
+ - Allow PWM output up to 320kHz and no slower than 8Hz.
## v0.3.28
- Show step rate on motor configuration page.
ex.seg.max_accel, ex.seg.max_jerk);
v = ex.velocity + SEGMENT_TIME * a;
t *= ex.seg.vel / v;
- if (v <= 0) t = v = 0;
if (v < MIN_VELOCITY) {
t = v = 0;
}
+static void _set_sync_speeds(float d) {
+ float speed = FLT_MAX;
+
+ while (true) {
+ // Load new sync speed if needed and available
+ if (l.speed.offset < 0 && command_peek() == COMMAND_sync_speed)
+ l.speed = *(speed_t *)(command_next() + 1);
+
+ // Exit if we don't have a speed or it's not ready to be set
+ if (l.speed.offset < 0 || d < l.speed.offset) break;
+
+ // Set speed
+ speed = l.speed.speed;
+ l.speed.offset = -1; // Mark done
+ }
+
+ if (speed != FLT_MAX) spindle_set_speed(speed);
+}
+
+
static stat_t _line_exec() {
// Compute times
float section_time = l.line.times[l.section];
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;
- }
+ _set_sync_speeds(d);
// Check if section complete
if (t == section_time) {
l.line = *(line_t *)data;
l.speed.offset = -1;
+ _set_sync_speeds(0);
// Setup first section
l.seg = 0;
unsigned command_sync_speed_size() {return sizeof(speed_t);}
-void command_sync_speed_exec(void *data) {} // Should not get here
+
+
+void command_sync_speed_exec(void *data) {
+ speed_t s = *(speed_t *)data;
+ spindle_set_speed(s.speed);
+}
typedef struct {
- uint16_t freq; // base frequency for PWM driver, in Hz
+ float freq; // base frequency for PWM driver, in Hz
float min_duty;
float max_duty;
float duty;
return;
}
+ // Compute duty cycle
+ spindle.duty =
+ speed * (spindle.max_duty - spindle.min_duty) + spindle.min_duty;
+
+ // Configure clock
+ TIMER_PWM.CTRLB = TC1_CCAEN_bm | TC_WGMODE_SINGLESLOPE_gc;
+ TIMER_PWM.CCA = TIMER_PWM.PER * spindle.duty;
+}
+
+
+static void _update_freq() {
// Set clock period and optimal prescaler value
- float prescale = (float)(F_CPU >> 16) / spindle.freq;
+ float prescale = (F_CPU >> 16) / spindle.freq;
+
if (prescale <= 1) {
TIMER_PWM.PER = F_CPU / spindle.freq;
TIMER_PWM.CTRLA = TC_CLKSEL_DIV1_gc;
} else TIMER_PWM.CTRLA = 0;
- // Compute duty cycle
- spindle.duty =
- speed * (spindle.max_duty - spindle.min_duty) + spindle.min_duty;
-
- // Configure clock
- TIMER_PWM.CTRLB = TC1_CCAEN_bm | TC_WGMODE_SINGLESLOPE_gc;
- TIMER_PWM.CCA = TIMER_PWM.PER * spindle.duty;
+ _update_pwm();
}
// Configure IO
_set_dir(true);
_set_enable(false);
+ _update_freq();
// PWM output
OUTCLR_PIN(SPIN_PWM_PIN);
float get_pwm_duty() {return spindle.duty;}
-uint16_t get_pwm_freq() {return spindle.freq;}
-void set_pwm_freq(uint16_t value) {spindle.freq = value; _update_pwm();}
+float get_pwm_freq() {return spindle.freq;}
+
+
+void set_pwm_freq(float value) {
+ if (value < 8) value = 8;
+ if (320000 < value) value = 320000;
+ spindle.freq = value; _update_freq();
+}
+
+
bool get_pwm_invert() {return PINCTRL_PIN(SPIN_PWM_PIN) & PORT_INVEN_bm;}
VAR(pwm_min_duty, nd, f32, 0, 1, 1) // Minimum PWM duty cycle
VAR(pwm_max_duty, md, f32, 0, 1, 1) // Maximum PWM duty cycle
VAR(pwm_duty, pd, f32, 0, 0, 1) // Current PWM duty cycle
-VAR(pwm_freq, sf, u16, 0, 1, 1) // Spindle PWM frequency in Hz
+VAR(pwm_freq, sf, f32, 0, 1, 1) // Spindle PWM frequency in Hz
// Modbus spindle
VAR(modbus_debug, hb, b8, 0, 1, 1) // Modbus debugging
"pwm-freq": {
"type": "int",
"unit": "Hz",
- "min": 0,
- "max": 65535,
+ "min": 8,
+ "max": 320000,
"default": 1000,
"code": "sf"
}