I have an XController driving an XCarve 750.
The 0-5V spindle speed pin is routed to an IOT relay for controlling the spindle, and the PWM pin is routed to a JTech Photonics laser controller. This works fine.
However, I wanted direct router speed control, so I bought a VHipe SuperPID AC motor controller.
The SuperPID will take either a PWM or 0-5V speed control signal, so no worries there. However, it also wants a +5V SPINDLE ENABLE signal.
The ugly hack to get that working would be to connect the MIST COOLANT output to the SuperPID SPINDLE ENABLE, and then add the mist coolant on/off gcode to any spindle control lines via the postprocessor. That will work, but it’s a terrible, terrible idea because it’s non-obvious from the code how to actually turn the spindle on or off.
So what I want looks like a custom GRBL build that assigns the SPINDLE DIRECTION to the mist coolant pin.
Looking in the GRBL code, I see this:
// 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
// the spindle direction pin(D13) as a separate spindle enable pin along with spindle speed PWM on pin D11.
// NOTE: This configure option only works with VARIABLE_SPINDLE enabled and a 328p processor (Uno).
// NOTE: Without a direction pin, M4 will not have a pin output to indicate a difference with M3.
// 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.
OK, so if I define this, D13 will become the enable pin, with the caveat that it will flash high during bootup, potentially starting the spindle. If I ensure to always power cycle the XController with the SuperPID turned off, this won’t be a problem. I can live with that.
It isn’t clear to me though if the XController has D13 wired to anything.
So if I turn off M7 by commenting out the define:
// Enables a second coolant control pin via the mist coolant g-code command M7 on the Arduino Uno
// analog pin 4. Only use this option if you require a second coolant control pin.
// NOTE: The M8 flood coolant control pin on analog pin 3 will still be functional regardless.
#define ENABLE_M7 // Disabled by default. Uncomment to enable.
That should free up analogue pin 4.
This bit of code in spindle_control.c
void spindle_init()
{
#ifdef VARIABLE_SPINDLE
// 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);
#else
// 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();
}
specifically, the line
SPINDLE_DIRECTION_DDR |= (1<<SPINDLE_DIRECTION_BIT); // Configure as output pin.
sets the output pin
cpu_map.h has the following:
// Define spindle enable and spindle direction output pins.
#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.
#ifdef VARIABLE_SPINDLE
#ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
// If enabled, spindle direction pin now used as spindle enable, while PWM remains on D11.
#define SPINDLE_ENABLE_BIT 5 // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.)
#else
#define SPINDLE_ENABLE_BIT 3 // Uno Digital Pin 11
#endif
#else
#define SPINDLE_ENABLE_BIT 4 // Uno Digital Pin 12
#endif
#ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN
#define SPINDLE_DIRECTION_DDR DDRB
#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
#define COOLANT_FLOOD_PORT PORTC
#define COOLANT_FLOOD_BIT 3 // Uno Analog Pin 3
#define COOLANT_MIST_DDR DDRC
#define COOLANT_MIST_PORT PORTC
#define COOLANT_MIST_BIT 4 // Uno Analog Pin 4
So I feel like taking the DDR, port and bit for mist cooling and assigning it to spindle direction should work?
Like this:
#define SPINDLE_DIRECTION_DDR DDRC // using mist coolant DDR for SuperPID
#define SPINDLE_DIRECTION_PORT PORTC // using mist coolant port for SuperPID
#define SPINDLE_DIRECTION_BIT 4 // Uno Analog port 4 - was D13
The two big unknowns are:
- Does the XController use D13 for anything?
- Does the code that sets a digital output high also work for an analog output?
Is there anyone around who understands how the XController is physically wired? Or docs published somewhere?