spindle pwm
This commit is contained in:
parent
6f13d0d18b
commit
4e9d5f78b4
@ -209,7 +209,7 @@
|
||||
// NOTE: If VARIABLE_SPINDLE is enabled(default), this option has no effect as the PWM output and
|
||||
// spindle enable are combined to one pin. If you need both this option and spindle speed PWM,
|
||||
// uncomment the config option USE_SPINDLE_DIR_AS_ENABLE_PIN below.
|
||||
// #define INVERT_SPINDLE_ENABLE_PIN // Default disabled. Uncomment to enable.
|
||||
// not ported #define INVERT_SPINDLE_ENABLE_PIN // Default disabled. Uncomment to enable.
|
||||
|
||||
// Inverts the selected coolant pin from low-disabled/high-enabled to low-enabled/high-disabled. Useful
|
||||
// for some pre-built electronic boards.
|
||||
@ -333,12 +333,37 @@
|
||||
// tool length offset value is subtracted from the current location.
|
||||
#define TOOL_LENGTH_OFFSET_AXIS Z_AXIS // Default z-axis. Valid values are X_AXIS, Y_AXIS, or Z_AXIS.
|
||||
|
||||
// Enables variable spindle output voltage for different RPM values. On the Arduino Uno, the spindle
|
||||
// enable pin will output 5V for maximum RPM with 256 intermediate levels and 0V when disabled.
|
||||
// NOTE: IMPORTANT for Arduino Unos! When enabled, the Z-limit pin D11 and spindle enable pin D12 switch!
|
||||
// The hardware PWM output on pin D11 is required for variable spindle output voltages.
|
||||
// Enables variable spindle output voltage for different RPM values.
|
||||
#define VARIABLE_SPINDLE // Default enabled. Comment to disable.
|
||||
|
||||
// RPM Scaling on LPC17xx
|
||||
//
|
||||
// 0 SPINDLE_PWM_OFF_VALUE SPINDLE_PERIOD
|
||||
// | | |
|
||||
// |---|---|--------------------------|----|
|
||||
// | |
|
||||
// SPINDLE_PWM_MIN_VALUE SPINDLE_PWM_MAX_VALUE
|
||||
//
|
||||
// settings.rpm_min settings.rpm_max
|
||||
// |--------------------------|
|
||||
// ^
|
||||
// gcode S value
|
||||
//
|
||||
// if(S <= 0)
|
||||
// pwm = SPINDLE_PWM_OFF_VALUE;
|
||||
// else if(S <= settings.rpm_min)
|
||||
// pwm = SPINDLE_PWM_MIN_VALUE;
|
||||
// else if(S >= settings.rpm_max)
|
||||
// pwm = SPINDLE_PWM_MAX_VALUE;
|
||||
// else
|
||||
// pwm = scaled value. settings.rpm_min scales to SPINDLE_PWM_MIN_VALUE. settings.rpm_max
|
||||
// scales to SPINDLE_PWM_MAX_VALUE.
|
||||
|
||||
#define SPINDLE_PWM_PERIOD (SystemCoreClock / 40000) // SystemCoreClock / frequency
|
||||
#define SPINDLE_PWM_OFF_VALUE (SPINDLE_PWM_PERIOD * 0.0) // SPINDLE_PWM_PERIOD * fraction
|
||||
#define SPINDLE_PWM_MIN_VALUE (SPINDLE_PWM_PERIOD * 0.0) // SPINDLE_PWM_PERIOD * fraction
|
||||
#define SPINDLE_PWM_MAX_VALUE (SPINDLE_PWM_PERIOD * 1.0) // SPINDLE_PWM_PERIOD * fraction
|
||||
|
||||
// Used by variable spindle output only. This forces the PWM output to a minimum duty cycle when enabled.
|
||||
// The PWM pin will still read 0V when the spindle is disabled. Most users will not need this option, but
|
||||
// it may be useful in certain scenarios. This minimum PWM settings coincides with the spindle rpm minimum
|
||||
@ -348,7 +373,7 @@
|
||||
// in mind that you will begin to lose PWM resolution with increased minimum PWM values, since you have less
|
||||
// and less range over the total 255 PWM levels to signal different spindle speeds.
|
||||
// NOTE: Compute duty cycle at the minimum PWM by this equation: (% duty cycle)=(SPINDLE_PWM_MIN_VALUE/255)*100
|
||||
// #define SPINDLE_PWM_MIN_VALUE 5 // Default disabled. Uncomment to enable. Must be greater than zero. Integer (1-255).
|
||||
// define now lives above. #define SPINDLE_PWM_MIN_VALUE 5 // Default disabled. Uncomment to enable. Must be greater than zero. Integer (1-255).
|
||||
|
||||
// By default on a 328p(Uno), Grbl combines the variable spindle PWM and the enable into one pin to help
|
||||
// preserve I/O pins. For certain setups, these may need to be separate pins. This configure option uses
|
||||
@ -358,7 +383,7 @@
|
||||
// NOTE: BEWARE! The Arduino bootloader toggles the D13 pin when it powers up. If you flash Grbl with
|
||||
// a programmer (you can use a spare Arduino as "Arduino as ISP". Search the web on how to wire this.),
|
||||
// this D13 LED toggling should go away. We haven't tested this though. Please report how it goes!
|
||||
// #define USE_SPINDLE_DIR_AS_ENABLE_PIN // Default disabled. Uncomment to enable.
|
||||
// not ported #define USE_SPINDLE_DIR_AS_ENABLE_PIN // Default disabled. Uncomment to enable.
|
||||
|
||||
// With this enabled, Grbl sends back an echo of the line it has received, which has been pre-parsed (spaces
|
||||
// removed, capitalized letters, no comments) and is to be immediately executed by Grbl. Echoes will not be
|
||||
@ -626,6 +651,7 @@
|
||||
// hard limits not ported #define LIMIT_PCMSK PCMSK0 // Pin change interrupt register
|
||||
|
||||
// Define spindle enable and spindle direction output pins.
|
||||
/* not ported
|
||||
#define SPINDLE_ENABLE_DDR DDRB
|
||||
#define SPINDLE_ENABLE_PORT PORTB
|
||||
// Z Limit pin and spindle PWM/enable pin swapped to access hardware PWM on Pin 11.
|
||||
@ -644,6 +670,7 @@
|
||||
#define SPINDLE_DIRECTION_PORT PORTB
|
||||
#define SPINDLE_DIRECTION_BIT 5 // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.)
|
||||
#endif
|
||||
*/
|
||||
|
||||
// Define flood and mist coolant enable output pins.
|
||||
#define COOLANT_FLOOD_DDR DDRC
|
||||
@ -675,31 +702,16 @@
|
||||
#define PROBE_BIT 5 // Uno Analog Pin 5
|
||||
#define PROBE_MASK (1<<PROBE_BIT)
|
||||
|
||||
// Variable spindle configuration below. Do not change unless you know what you are doing.
|
||||
// NOTE: Only used when variable spindle is enabled.
|
||||
#define SPINDLE_PWM_MAX_VALUE 255 // Don't change. 328p fast PWM mode fixes top value as 255.
|
||||
#ifndef SPINDLE_PWM_MIN_VALUE
|
||||
#define SPINDLE_PWM_MIN_VALUE 1 // Must be greater than zero.
|
||||
#endif
|
||||
#define SPINDLE_PWM_OFF_VALUE 0
|
||||
#define SPINDLE_PWM_RANGE (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)
|
||||
#define SPINDLE_TCCRA_REGISTER TCCR2A
|
||||
#define SPINDLE_TCCRB_REGISTER TCCR2B
|
||||
#define SPINDLE_OCR_REGISTER OCR2A
|
||||
#define SPINDLE_COMB_BIT COM2A1
|
||||
|
||||
// Prescaled, 8-bit Fast PWM mode.
|
||||
#define SPINDLE_TCCRA_INIT_MASK ((1<<WGM20) | (1<<WGM21)) // Configures fast PWM mode.
|
||||
// #define SPINDLE_TCCRB_INIT_MASK (1<<CS20) // Disable prescaler -> 62.5kHz
|
||||
// #define SPINDLE_TCCRB_INIT_MASK (1<<CS21) // 1/8 prescaler -> 7.8kHz (Used in v0.9)
|
||||
// #define SPINDLE_TCCRB_INIT_MASK ((1<<CS21) | (1<<CS20)) // 1/32 prescaler -> 1.96kHz
|
||||
#define SPINDLE_TCCRB_INIT_MASK (1<<CS22) // 1/64 prescaler -> 0.98kHz (J-tech laser)
|
||||
|
||||
// NOTE: On the 328p, these must be the same as the SPINDLE_ENABLE settings.
|
||||
#define SPINDLE_PWM_DDR DDRB
|
||||
#define SPINDLE_PWM_PORT PORTB
|
||||
#define SPINDLE_PWM_BIT 3 // Uno Digital Pin 11
|
||||
// The LPC17xx has 6 PWM channels. Each channel has 2 pins. It can drive both pins simultaneously to the same value.
|
||||
//
|
||||
// PWM Channel PWM1_CH1 PWM1_CH2 PWM1_CH3 PWM1_CH4 PWM1_CH5 PWM1_CH6
|
||||
// Primary pin P1.18 P1.20 P1.21 P1.23 P1.24 P1.26
|
||||
// Secondary pin P2.0 P2.1 P2.2 P2.3 P2.4 P2.6
|
||||
#define SPINDLE_PWM_CHANNEL PWM1_CH5
|
||||
#define SPINDLE_PWM_USE_PRIMARY_PIN false
|
||||
#define SPINDLE_PWM_USE_SECONDARY_PIN true
|
||||
|
||||
// Stepper current control
|
||||
#define CURRENT_I2C Driver_I2C1 // I2C driver for current control. Comment out to disable.
|
||||
#define CURRENT_MCP44XX_ADDR 0b0101100 // Address of MCP44XX
|
||||
#define CURRENT_WIPERS {0, 1, 6, 7}; // Wiper registers (X, Y, Z, A)
|
||||
@ -722,7 +734,7 @@
|
||||
#define DEFAULT_X_MAX_TRAVEL 200.0 // mm
|
||||
#define DEFAULT_Y_MAX_TRAVEL 200.0 // mm
|
||||
#define DEFAULT_Z_MAX_TRAVEL 200.0 // mm
|
||||
#define DEFAULT_SPINDLE_RPM_MAX 1000.0 // rpm
|
||||
#define DEFAULT_SPINDLE_RPM_MAX 1.0 // rpm
|
||||
#define DEFAULT_SPINDLE_RPM_MIN 0.0 // rpm
|
||||
#define DEFAULT_STEP_PULSE_MICROSECONDS 1
|
||||
#define DEFAULT_STEPPING_INVERT_MASK 0
|
||||
|
@ -84,11 +84,13 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* restriction removed
|
||||
#if defined(SPINDLE_PWM_MIN_VALUE)
|
||||
#if !(SPINDLE_PWM_MIN_VALUE > 0)
|
||||
#error "SPINDLE_PWM_MIN_VALUE must be greater than zero."
|
||||
#endif
|
||||
#endif
|
||||
*/
|
||||
|
||||
#if (REPORT_WCO_REFRESH_BUSY_COUNT < REPORT_WCO_REFRESH_IDLE_COUNT)
|
||||
#error "WCO busy refresh is less than idle refresh."
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "grbl.h"
|
||||
#include "pwm_driver.h"
|
||||
|
||||
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
@ -30,26 +31,27 @@
|
||||
void spindle_init()
|
||||
{
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
pwm_init(&SPINDLE_PWM_CHANNEL, SPINDLE_PWM_USE_PRIMARY_PIN, SPINDLE_PWM_USE_SECONDARY_PIN, SPINDLE_PWM_PERIOD, 0);
|
||||
pwm_enable(&SPINDLE_PWM_CHANNEL);
|
||||
|
||||
/* not ported
|
||||
// Configure variable spindle PWM and enable pin, if requried. On the Uno, PWM and enable are
|
||||
// combined unless configured otherwise.
|
||||
SPINDLE_PWM_DDR |= (1<<SPINDLE_PWM_BIT); // Configure as PWM output pin.
|
||||
SPINDLE_TCCRA_REGISTER = SPINDLE_TCCRA_INIT_MASK; // Configure PWM output compare timer
|
||||
SPINDLE_TCCRB_REGISTER = SPINDLE_TCCRB_INIT_MASK;
|
||||
#ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
|
||||
SPINDLE_ENABLE_DDR |= (1<<SPINDLE_ENABLE_BIT); // Configure as output pin.
|
||||
#else
|
||||
SPINDLE_DIRECTION_DDR |= (1<<SPINDLE_DIRECTION_BIT); // Configure as output pin.
|
||||
#endif
|
||||
*/
|
||||
|
||||
pwm_gradient = SPINDLE_PWM_RANGE/(settings.rpm_max-settings.rpm_min);
|
||||
pwm_gradient = (SPINDLE_PWM_MAX_VALUE-SPINDLE_PWM_MIN_VALUE)/(settings.rpm_max-settings.rpm_min);
|
||||
|
||||
#else
|
||||
|
||||
/* not ported
|
||||
// Configure no variable spindle and only enable pin.
|
||||
SPINDLE_ENABLE_DDR |= (1<<SPINDLE_ENABLE_BIT); // Configure as output pin.
|
||||
SPINDLE_DIRECTION_DDR |= (1<<SPINDLE_DIRECTION_BIT); // Configure as output pin.
|
||||
|
||||
*/
|
||||
#endif
|
||||
|
||||
spindle_stop();
|
||||
@ -58,6 +60,7 @@ void spindle_init()
|
||||
|
||||
uint8_t spindle_get_state()
|
||||
{
|
||||
/* not ported
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
#ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
|
||||
// No spindle direction output pin.
|
||||
@ -82,6 +85,7 @@ uint8_t spindle_get_state()
|
||||
else { return(SPINDLE_STATE_CW); }
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
return(SPINDLE_STATE_DISABLE);
|
||||
}
|
||||
|
||||
@ -92,7 +96,8 @@ uint8_t spindle_get_state()
|
||||
void spindle_stop()
|
||||
{
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
SPINDLE_TCCRA_REGISTER &= ~(1<<SPINDLE_COMB_BIT); // Disable PWM. Output voltage is zero.
|
||||
pwm_set_width(&SPINDLE_PWM_CHANNEL, 0);
|
||||
/* not ported
|
||||
#ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
|
||||
#ifdef INVERT_SPINDLE_ENABLE_PIN
|
||||
SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT); // Set pin to high
|
||||
@ -100,12 +105,15 @@ void spindle_stop()
|
||||
SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT); // Set pin to low
|
||||
#endif
|
||||
#endif
|
||||
*/
|
||||
#else
|
||||
/* not ported
|
||||
#ifdef INVERT_SPINDLE_ENABLE_PIN
|
||||
SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT); // Set pin to high
|
||||
#else
|
||||
SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT); // Set pin to low
|
||||
#endif
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -113,48 +121,34 @@ void spindle_stop()
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
// Sets spindle speed PWM output and enable pin, if configured. Called by spindle_set_state()
|
||||
// and stepper ISR. Keep routine small and efficient.
|
||||
void spindle_set_speed(uint8_t pwm_value)
|
||||
void spindle_set_speed(uint32_t pwm_value)
|
||||
{
|
||||
if (pwm_value == SPINDLE_PWM_OFF_VALUE) {
|
||||
spindle_stop();
|
||||
} else {
|
||||
SPINDLE_OCR_REGISTER = pwm_value; // Set PWM output level.
|
||||
SPINDLE_TCCRA_REGISTER |= (1<<SPINDLE_COMB_BIT); // Ensure PWM output is enabled.
|
||||
|
||||
#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN)
|
||||
#ifdef INVERT_SPINDLE_ENABLE_PIN
|
||||
SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT);
|
||||
#else
|
||||
SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
pwm_set_width(&SPINDLE_PWM_CHANNEL, pwm_value);
|
||||
}
|
||||
|
||||
|
||||
// Called by spindle_set_state() and step segment generator. Keep routine small and efficient.
|
||||
uint8_t spindle_compute_pwm_value(float rpm) // 328p PWM register is 8-bit.
|
||||
uint32_t spindle_compute_pwm_value(float rpm)
|
||||
{
|
||||
uint8_t pwm_value;
|
||||
uint32_t pwm_value;
|
||||
rpm *= (0.010*sys.spindle_speed_ovr); // Scale by spindle speed override value.
|
||||
// Calculate PWM register value based on rpm max/min settings and programmed rpm.
|
||||
if ((settings.rpm_min >= settings.rpm_max) || (rpm >= settings.rpm_max)) {
|
||||
// No PWM range possible. Set simple on/off spindle control pin state.
|
||||
if (rpm <= 0) {
|
||||
sys.spindle_speed = 0;
|
||||
pwm_value = SPINDLE_PWM_OFF_VALUE;
|
||||
}
|
||||
else if (rpm <= settings.rpm_min) {
|
||||
sys.spindle_speed = settings.rpm_min;
|
||||
pwm_value = SPINDLE_PWM_MIN_VALUE;
|
||||
}
|
||||
else if (rpm >= settings.rpm_max) {
|
||||
sys.spindle_speed = settings.rpm_max;
|
||||
pwm_value = SPINDLE_PWM_MAX_VALUE;
|
||||
} else if (rpm <= settings.rpm_min) {
|
||||
if (rpm == 0.0) { // S0 disables spindle
|
||||
sys.spindle_speed = 0.0;
|
||||
pwm_value = SPINDLE_PWM_OFF_VALUE;
|
||||
} else { // Set minimum PWM output
|
||||
sys.spindle_speed = settings.rpm_min;
|
||||
pwm_value = SPINDLE_PWM_MIN_VALUE;
|
||||
}
|
||||
} else {
|
||||
// Compute intermediate PWM value with linear spindle speed model.
|
||||
// NOTE: A nonlinear model could be installed here, if required, but keep it VERY light-weight.
|
||||
pwm_value = SPINDLE_PWM_MAX_VALUE - 1;
|
||||
}
|
||||
else {
|
||||
sys.spindle_speed = rpm;
|
||||
pwm_value = floor((rpm-settings.rpm_min)*pwm_gradient) + SPINDLE_PWM_MIN_VALUE;
|
||||
pwm_value = floor((rpm - settings.rpm_min) * pwm_gradient) + SPINDLE_PWM_MIN_VALUE;
|
||||
if(pwm_value >= SPINDLE_PWM_MAX_VALUE)
|
||||
pwm_value = SPINDLE_PWM_MAX_VALUE - 1;
|
||||
}
|
||||
return(pwm_value);
|
||||
}
|
||||
@ -181,11 +175,13 @@ void spindle_stop()
|
||||
} else {
|
||||
|
||||
#ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN
|
||||
/* not ported
|
||||
if (state == SPINDLE_ENABLE_CW) {
|
||||
SPINDLE_DIRECTION_PORT &= ~(1<<SPINDLE_DIRECTION_BIT);
|
||||
} else {
|
||||
SPINDLE_DIRECTION_PORT |= (1<<SPINDLE_DIRECTION_BIT);
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
@ -197,11 +193,13 @@ void spindle_stop()
|
||||
#else
|
||||
// NOTE: Without variable spindle, the enable bit should just turn on or off, regardless
|
||||
// if the spindle speed value is zero, as its ignored anyhow.
|
||||
/* not ported
|
||||
#ifdef INVERT_SPINDLE_ENABLE_PIN
|
||||
SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT);
|
||||
#else
|
||||
SPINDLE_ENABLE_PORT |= (1<<SPINDLE_ENABLE_BIT);
|
||||
#endif
|
||||
#endif
|
||||
*/
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@ -48,11 +48,10 @@ uint8_t spindle_get_state();
|
||||
void spindle_set_state(uint8_t state, float rpm);
|
||||
|
||||
// Sets spindle PWM quickly for stepper ISR. Also called by spindle_set_state().
|
||||
// NOTE: 328p PWM register is 8-bit.
|
||||
void spindle_set_speed(uint8_t pwm_value);
|
||||
void spindle_set_speed(uint32_t pwm_value);
|
||||
|
||||
// Computes 328p-specific PWM register value for the given RPM for quick updating.
|
||||
uint8_t spindle_compute_pwm_value(float rpm);
|
||||
// Computes PWM register value for the given RPM for quick updating.
|
||||
uint32_t spindle_compute_pwm_value(float rpm);
|
||||
|
||||
#else
|
||||
|
||||
|
@ -81,7 +81,7 @@ typedef struct {
|
||||
uint8_t prescaler; // Without AMASS, a prescaler is required to adjust for slow timing.
|
||||
#endif
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
uint8_t spindle_pwm;
|
||||
uint32_t spindle_pwm;
|
||||
#endif
|
||||
} segment_t;
|
||||
static segment_t segment_buffer[SEGMENT_BUFFER_SIZE];
|
||||
@ -158,7 +158,7 @@ typedef struct {
|
||||
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
float inv_rate; // Used by PWM laser mode to speed up segment calculations.
|
||||
uint8_t current_spindle_pwm;
|
||||
uint32_t current_spindle_pwm;
|
||||
#endif
|
||||
} st_prep_t;
|
||||
static st_prep_t prep;
|
||||
|
@ -289,7 +289,7 @@
|
||||
#define PLL1CFG_Val 0x00000023
|
||||
#define CCLKCFG_Val 0x00000003
|
||||
#define USBCLKCFG_Val 0x00000000
|
||||
#define PCLKSEL0_Val 0x00000014
|
||||
#define PCLKSEL0_Val 0x00001014
|
||||
#define PCLKSEL1_Val 0x00005000
|
||||
#define PCONP_Val 0x04E887DE
|
||||
#define CLKOUTCFG_Val 0x00000000
|
||||
|
Loading…
Reference in New Issue
Block a user