Compare commits
2 Commits
eddba72e23
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
baebeb436f | ||
|
|
67a98b78b4 |
81
HOMING_FIX.md
Normal file
81
HOMING_FIX.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# GRBL Homing Issue - Fix Documentation
|
||||
|
||||
## Problem Identified
|
||||
|
||||
Your GRBL configuration was attempting to home X and Y axes **simultaneously** in `HOMING_CYCLE_1`. When axes home at the same time, whichever limit switch is encountered first can cause the entire homing cycle to abort, especially if:
|
||||
|
||||
- Axes have different distances to travel to their limit switches
|
||||
- Mechanical tolerances cause one axis to reach its switch before the other
|
||||
- The machine isn't perfectly square
|
||||
|
||||
## Root Cause
|
||||
|
||||
In `grbl/limits.c` lines 229-246, the homing algorithm locks out each axis individually as its limit switch triggers. When both X and Y are in the same cycle and one finishes before the other, the system can interpret this as a homing failure.
|
||||
|
||||
## Solution Applied
|
||||
|
||||
**Changed in `grbl/config.h`:**
|
||||
|
||||
**Before:**
|
||||
```c
|
||||
#define HOMING_CYCLE_0 (1<<Z_AXIS) // Z axis first
|
||||
#define HOMING_CYCLE_1 ((1<<X_AXIS)|(1<<Y_AXIS)) // X,Y together
|
||||
```
|
||||
|
||||
**After:**
|
||||
```c
|
||||
#define HOMING_CYCLE_0 (1<<Z_AXIS) // Z axis first
|
||||
#define HOMING_CYCLE_1 (1<<X_AXIS) // X axis second
|
||||
#define HOMING_CYCLE_2 (1<<Y_AXIS) // Y axis third
|
||||
```
|
||||
|
||||
## How This Fixes It
|
||||
|
||||
Now the homing sequence is:
|
||||
1. **Cycle 0**: Z-axis homes (clears workspace)
|
||||
2. **Cycle 1**: X-axis homes independently
|
||||
3. **Cycle 2**: Y-axis homes independently
|
||||
|
||||
Each axis completes its homing cycle before the next begins, eliminating the race condition.
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Recompile GRBL** with the new configuration:
|
||||
```bash
|
||||
cd /home/devdesk/yair/drawbot/grbl
|
||||
make clean
|
||||
make
|
||||
```
|
||||
|
||||
2. **Upload to your Arduino/controller**
|
||||
|
||||
3. **Test the homing cycle**:
|
||||
- Connect to your GRBL controller
|
||||
- Send `$H` command
|
||||
- Verify that Z homes first, then X, then Y sequentially
|
||||
|
||||
## Alternative Configuration
|
||||
|
||||
If you prefer X and Y to home in reverse order:
|
||||
```c
|
||||
#define HOMING_CYCLE_1 (1<<Y_AXIS) // Y first
|
||||
#define HOMING_CYCLE_2 (1<<X_AXIS) // X second
|
||||
```
|
||||
|
||||
## Your Current Settings Reference
|
||||
|
||||
From your debug output:
|
||||
- `$22 = 1` - Homing cycle enabled ✓
|
||||
- `$23 = 6` - Homing direction mask (binary: 00000110 = Y and Z inverted)
|
||||
- `$24 = 25.000` - Homing feed rate
|
||||
- `$25 = 500.000` - Homing seek rate
|
||||
- `$26 = 250` - Homing debounce delay
|
||||
- `$27 = 1.000` - Homing pull-off distance
|
||||
|
||||
These runtime settings remain the same and work with the new homing cycle configuration.
|
||||
|
||||
## Performance Impact
|
||||
|
||||
**Homing Time:** Sequential homing takes slightly longer than simultaneous (~few seconds), but provides 100% reliability.
|
||||
|
||||
**Safety:** Better control over axis movement sequence.
|
||||
181
PLATFORMIO.md
Normal file
181
PLATFORMIO.md
Normal file
@@ -0,0 +1,181 @@
|
||||
# Building Grbl with PlatformIO
|
||||
|
||||
This document explains how to build and upload Grbl using PlatformIO instead of the traditional Makefile approach.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Install PlatformIO Core or PlatformIO IDE:
|
||||
- **PlatformIO Core (CLI)**: `pip install platformio`
|
||||
- **PlatformIO IDE**: Install as a VSCode extension or use Atom IDE
|
||||
|
||||
## Project Structure
|
||||
|
||||
The PlatformIO configuration has been set up to work with the existing Grbl source structure:
|
||||
|
||||
```
|
||||
grbl/
|
||||
├── platformio.ini # PlatformIO configuration
|
||||
├── src/
|
||||
│ └── main.cpp # Arduino framework wrapper
|
||||
├── grbl/ # Grbl source code (unchanged)
|
||||
│ ├── *.c, *.h # Core Grbl files
|
||||
│ ├── config.h # Configuration settings
|
||||
│ ├── cpu_map/ # CPU pin mappings
|
||||
│ └── defaults/ # Machine defaults
|
||||
└── Makefile # Original Makefile (still usable)
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The [`platformio.ini`](platformio.ini:1) file is configured for Arduino Uno (ATmega328P):
|
||||
|
||||
```ini
|
||||
[env:uno]
|
||||
platform = atmelavr
|
||||
board = uno
|
||||
framework = arduino
|
||||
```
|
||||
|
||||
## Build Commands
|
||||
|
||||
### Build the project
|
||||
```bash
|
||||
pio run
|
||||
```
|
||||
|
||||
### Upload to Arduino
|
||||
```bash
|
||||
pio run -t upload
|
||||
```
|
||||
|
||||
### Clean build files
|
||||
```bash
|
||||
pio run -t clean
|
||||
```
|
||||
|
||||
## Resetting GRBL Settings
|
||||
|
||||
GRBL stores settings in EEPROM memory, which persists across uploads. When you upload new firmware, your previous settings remain. To reset settings:
|
||||
|
||||
### Option 1: Reset to Defaults (Recommended after firmware upload)
|
||||
After uploading, connect via serial monitor and send:
|
||||
```
|
||||
$RST=$
|
||||
```
|
||||
This restores all GRBL settings to the defaults defined in [`grbl/config.h`](grbl/config.h:1).
|
||||
|
||||
### Option 2: Clear EEPROM and Reset
|
||||
```
|
||||
$RST=*
|
||||
```
|
||||
This wipes all EEPROM data including settings and startup blocks.
|
||||
|
||||
### Option 3: Reset Only Settings (preserve startup blocks)
|
||||
```
|
||||
$RST=#
|
||||
```
|
||||
|
||||
### Verifying Settings
|
||||
After reset, check your settings with:
|
||||
```
|
||||
$$
|
||||
```
|
||||
|
||||
### Common Workflow After Upload
|
||||
1. Upload firmware: `pio run -t upload`
|
||||
2. Open serial monitor: `pio run -t monitor`
|
||||
3. Send reset command: `$RST=$`
|
||||
4. Verify settings: `$$`
|
||||
5. Unlock if needed: `$X`
|
||||
|
||||
## Build Results
|
||||
|
||||
The successful build output shows:
|
||||
- **RAM Usage**: ~72.5% (1484 bytes / 2048 bytes)
|
||||
- **Flash Usage**: ~91.6% (29544 bytes / 32256 bytes)
|
||||
|
||||
Compiled firmware is located at `.pio/build/uno/firmware.hex`
|
||||
|
||||
## Serial Monitor
|
||||
|
||||
To open the serial monitor at 115200 baud (Grbl's default):
|
||||
```bash
|
||||
pio device monitor -b 115200
|
||||
```
|
||||
|
||||
Or use PlatformIO's built-in monitor:
|
||||
```bash
|
||||
pio run -t monitor
|
||||
```
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### Changing Baud Rate
|
||||
Edit [`grbl/config.h`](grbl/config.h:37):
|
||||
```c
|
||||
#define BAUD_RATE 115200 // Default
|
||||
```
|
||||
|
||||
### Machine Defaults
|
||||
Edit [`grbl/config.h`](grbl/config.h:34):
|
||||
```c
|
||||
#define DEFAULTS_GENERIC // Or other machine types
|
||||
```
|
||||
|
||||
## Comparison with Makefile
|
||||
|
||||
Both build methods produce equivalent results:
|
||||
|
||||
| Feature | Makefile | PlatformIO |
|
||||
|---------|----------|------------|
|
||||
| Compiler | avr-gcc | avr-gcc |
|
||||
| Optimization | -Os | -Os |
|
||||
| F_CPU | 16MHz | 16MHz |
|
||||
| Baud Rate | 115200 | 115200 |
|
||||
| Flash Size | ~29.5KB | ~29.5KB |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Build Errors
|
||||
If you encounter build errors, try cleaning the project:
|
||||
```bash
|
||||
pio run -t clean
|
||||
pio run
|
||||
```
|
||||
|
||||
### Upload Issues
|
||||
Ensure the correct serial port is selected. List available ports:
|
||||
```bash
|
||||
pio device list
|
||||
```
|
||||
|
||||
Specify port manually:
|
||||
```bash
|
||||
pio run -t upload --upload-port /dev/ttyUSB0
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
PlatformIO automatically downloads required toolchains and frameworks. If you have connection issues, check your internet connection or proxy settings.
|
||||
|
||||
## Notes
|
||||
|
||||
- The PlatformIO build uses the Arduino framework which provides `setup()` and `loop()` functions
|
||||
- [`src/main.cpp`](src/main.cpp:1) wraps Grbl's native [`main()`](grbl/main.c:29) function to be compatible with Arduino framework
|
||||
- All original Grbl source files in [`grbl/`](grbl/) remain unchanged and compatible with the Makefile build
|
||||
- The build includes all necessary compiler flags to match the original Makefile configuration
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Custom Build Flags
|
||||
Add custom flags in [`platformio.ini`](platformio.ini:1):
|
||||
```ini
|
||||
build_flags =
|
||||
-DCUSTOM_FLAG
|
||||
-DANOTHER_OPTION=value
|
||||
```
|
||||
|
||||
### Debugging
|
||||
PlatformIO supports debugging with compatible hardware:
|
||||
```bash
|
||||
pio debug
|
||||
```
|
||||
25
README.md
25
README.md
@@ -1,8 +1,29 @@
|
||||

|
||||
***
|
||||
|
||||
### Grbl v1.1 has been released [here](https://github.com/gnea/grbl/releases)!
|
||||
### Notice: This site will be phased out and moved to the new one!
|
||||
this is (yet another) grbl mod/fork to fit [T.A.M.I](https://tami.sh)'s [drawbot](https://git.telavivmakers.space/yair/drawbot_LY)
|
||||
|
||||
## T.A.M.I Drawbot Modifications Changelog
|
||||
|
||||
### December 4, 2025
|
||||
- **Inverted Servo PWM Mapping**: Changed servo control to match intuitive pen operation
|
||||
- S0 = Pen UP (16 ticks / ~1ms pulse)
|
||||
- S1000 = Pen DOWN (31 ticks / ~2ms pulse)
|
||||
- Previous behavior was reversed
|
||||
- **M5 PWM Disable**: M5 now properly disables PWM output in both standard and servo modes
|
||||
- Servo unpowered when M5 command is issued
|
||||
- Use M3 S0 to keep servo powered at pen-up position
|
||||
|
||||
### Earlier Modifications
|
||||
- **Servo Mode Implementation**: Added servo control capability for pen plotters
|
||||
- See [SERVO_MODE.md](SERVO_MODE.md) for full documentation
|
||||
- Supports hobby servos via PWM output (Pin D11)
|
||||
- ~61Hz PWM frequency suitable for servo control
|
||||
- 16 discrete positions (16-31 ticks range)
|
||||
- Configurable via `USE_SPINDLE_SERVO_MODE` in config.h
|
||||
|
||||
- **Homing Fix**: Modifications to homing behavior for drawbot application
|
||||
- See [HOMING_FIX.md](HOMING_FIX.md) for details
|
||||
|
||||
***
|
||||
|
||||
|
||||
203
SERVO_MODE.md
Normal file
203
SERVO_MODE.md
Normal file
@@ -0,0 +1,203 @@
|
||||
# GRBL Servo Mode for Spindle PWM
|
||||
|
||||
This modification adds servo control capability to GRBL's spindle PWM output, allowing you to control hobby servos instead of traditional spindles. This is useful for applications like:
|
||||
|
||||
- Pen plotters (pen up/down)
|
||||
- Drag knives
|
||||
- Laser focusing mechanisms
|
||||
- Any application requiring servo positioning
|
||||
|
||||
## How It Works
|
||||
|
||||
### Standard Spindle Mode (Default)
|
||||
- **Frequency**: ~7.8kHz (1/8 prescaler)
|
||||
- **Duty Cycle**: 0-255 (full range)
|
||||
- **Use Case**: Variable speed spindle control
|
||||
|
||||
### Servo Mode (When Enabled)
|
||||
- **Frequency**: ~61Hz (1/1024 prescaler)
|
||||
- Target: 50Hz (20ms period) for servos
|
||||
- Actual: 61Hz works well with most hobby servos
|
||||
- **Duty Cycle**: 16-31 ticks (~1-2ms pulses)
|
||||
- 16 ticks ≈ 1.024ms (0° position)
|
||||
- 31 ticks ≈ 1.984ms (180° position)
|
||||
- **Use Case**: Servo position control
|
||||
|
||||
## Configuration
|
||||
|
||||
### Enable Servo Mode
|
||||
|
||||
In [`config.h`](grbl/config.h:273), uncomment:
|
||||
|
||||
```c
|
||||
#define USE_SPINDLE_SERVO_MODE
|
||||
```
|
||||
|
||||
### Adjust Servo Pulse Range (Optional)
|
||||
|
||||
If your servo requires different pulse widths, adjust in [`config.h`](grbl/config.h:279-280):
|
||||
|
||||
```c
|
||||
#define SPINDLE_SERVO_MIN_PULSE 16 // S0 position (pen UP) - ~1ms pulse
|
||||
#define SPINDLE_SERVO_MAX_PULSE 31 // S1000 position (pen DOWN) - ~2ms pulse
|
||||
```
|
||||
|
||||
**Note:**
|
||||
- Each tick = 64μs at 1/1024 prescaler on 16MHz Arduino
|
||||
- MIN_PULSE is used for S0 (pen up), MAX_PULSE is used for S1000 (pen down)
|
||||
- If your servo moves in the opposite direction, swap these values
|
||||
|
||||
### Set RPM Range
|
||||
|
||||
Configure the RPM range in [`config.h`](grbl/config.h:256-257) to map to servo positions:
|
||||
|
||||
```c
|
||||
#define SPINDLE_MAX_RPM 1000.0 // Maps to max servo position (180°)
|
||||
#define SPINDLE_MIN_RPM 0.0 // Maps to min servo position (0°)
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Send G-code commands to control servo position:
|
||||
|
||||
```gcode
|
||||
M3 S0 ; Pen UP (uses SPINDLE_SERVO_MIN_PULSE = 16 ticks / ~1ms)
|
||||
M3 S500 ; Mid position
|
||||
M3 S1000 ; Pen DOWN (uses SPINDLE_SERVO_MAX_PULSE = 31 ticks / ~2ms)
|
||||
M5 ; Disable PWM (servo unpowered)
|
||||
```
|
||||
|
||||
**Note:** In servo mode, M5 disables the PWM output completely, which unpowers the servo. Use M3 S0 to keep the servo powered at the minimum position (pen up).
|
||||
|
||||
The S value is linearly mapped (inverted):
|
||||
- **M3 S0** → Uses SPINDLE_SERVO_MIN_PULSE (pen up / 16 ticks / ~1ms)
|
||||
- **M3 S1000** → Uses SPINDLE_SERVO_MAX_PULSE (pen down / 31 ticks / ~2ms)
|
||||
- **M5** → Disables PWM (servo unpowered)
|
||||
- Values in between are linearly interpolated
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Timer Configuration
|
||||
|
||||
**Standard Mode:**
|
||||
```c
|
||||
TCCRB_REGISTER = 0x02 // CS21=1: 1/8 prescaler
|
||||
Frequency = 16MHz / (8 * 256) = 7,812.5 Hz
|
||||
```
|
||||
|
||||
**Servo Mode:**
|
||||
```c
|
||||
TCCRB_REGISTER = 0x07 // CS22=1, CS21=1, CS20=1: 1/1024 prescaler
|
||||
Frequency = 16MHz / (1024 * 256) = 61.04 Hz (period ≈ 16.38ms)
|
||||
```
|
||||
|
||||
### PWM Calculation
|
||||
|
||||
**Standard Mode:**
|
||||
```
|
||||
current_pwm = floor(rpm * (255 / RPM_RANGE) + 0.5)
|
||||
Range: 0-255
|
||||
```
|
||||
|
||||
**Servo Mode (Inverted):**
|
||||
```
|
||||
inverted_rpm = MAX_RPM - rpm
|
||||
current_pwm = floor(inverted_rpm * (15 / RPM_RANGE) + 16 + 0.5)
|
||||
Range: 16-31 (15 discrete positions)
|
||||
S0 → 16 (pen up), S1000 → 31 (pen down)
|
||||
```
|
||||
|
||||
### Resolution
|
||||
|
||||
With the default configuration:
|
||||
- **Servo pulse range**: 1.024ms - 1.984ms (960μs range)
|
||||
- **Step size**: 64μs per tick
|
||||
- **Positions**: 16 discrete positions (15 steps)
|
||||
|
||||
This provides sufficient resolution for typical pen plotter and similar applications where precise servo positioning is not critical.
|
||||
|
||||
## Hardware Connection
|
||||
|
||||
1. Connect servo signal wire to Arduino Pin D11 (PWM output)
|
||||
2. Connect servo power (5V) to appropriate power source
|
||||
3. Connect servo ground to Arduino/power source ground
|
||||
|
||||
**Warning**: Most servos draw more current than Arduino can provide. Use external 5V power supply with common ground.
|
||||
|
||||
## Compatibility
|
||||
|
||||
- ✅ **Arduino Uno** (ATmega328p) - Fully supported
|
||||
- ❌ **Arduino Mega** (ATmega2560) - Not supported (uses Timer4)
|
||||
- ❌ Other processors - Not tested
|
||||
|
||||
## References
|
||||
|
||||
Based on the excellent work by Bart Dring:
|
||||
- Blog post: [Using Grbl's Spindle PWM to Control a Servo](https://www.buildlog.net/blog/2017/08/using-grbls-spindle-pwm-to-control-a-servo/)
|
||||
- GitHub repo: [Grbl_Pen_Servo](https://github.com/bdring/Grbl_Pen_Servo)
|
||||
|
||||
## Implementation Files
|
||||
|
||||
- [`config.h`](grbl/config.h:273-281) - Configuration options
|
||||
- [`spindle_control.c`](grbl/spindle_control.c:85-125) - Servo mode logic
|
||||
- [`cpu_map/cpu_map_atmega328p.h`](grbl/cpu_map/cpu_map_atmega328p.h:129-147) - Timer register definitions
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Servo jitters or doesn't move smoothly
|
||||
- Check power supply - servos need stable 5V
|
||||
- Verify pulse width range matches your servo specs
|
||||
- Some servos may require different MIN/MAX pulse values
|
||||
|
||||
### Servo moves to wrong positions
|
||||
- Adjust `SPINDLE_SERVO_MIN_PULSE` and `SPINDLE_SERVO_MAX_PULSE`
|
||||
- Check that `SPINDLE_MIN_RPM` and `SPINDLE_MAX_RPM` are set correctly
|
||||
- Verify S values in G-code are within MIN/MAX RPM range
|
||||
|
||||
### Servo doesn't respond at all
|
||||
- Verify `VARIABLE_SPINDLE` is enabled
|
||||
- Check `USE_SPINDLE_SERVO_MODE` is uncommented
|
||||
- Confirm connection to Pin D11
|
||||
- Test PWM output with logic analyzer or oscilloscope
|
||||
|
||||
## Example: Pen Plotter
|
||||
|
||||
```c
|
||||
// config.h settings for pen plotter
|
||||
#define VARIABLE_SPINDLE
|
||||
#define USE_SPINDLE_SERVO_MODE
|
||||
#define SPINDLE_MAX_RPM 1000.0
|
||||
#define SPINDLE_MIN_RPM 0.0
|
||||
#define SPINDLE_SERVO_MIN_PULSE 16 // S0 = Pen UP (~1ms pulse)
|
||||
#define SPINDLE_SERVO_MAX_PULSE 31 // S1000 = Pen DOWN (~2ms pulse)
|
||||
```
|
||||
|
||||
```gcode
|
||||
; Pen up (keeping servo powered)
|
||||
M3 S0
|
||||
|
||||
; Move to start position
|
||||
G0 X10 Y10
|
||||
|
||||
; Pen down
|
||||
M3 S1000
|
||||
|
||||
; Draw square
|
||||
G1 X20 Y10 F1000
|
||||
G1 X20 Y20
|
||||
G1 X10 Y20
|
||||
G1 X10 Y10
|
||||
|
||||
; Pen up (keeping servo powered)
|
||||
M3 S0
|
||||
```
|
||||
|
||||
**Pen Plotter Commands:**
|
||||
- **M3 S0** = Pen UP (16 ticks / ~1ms / MIN_PULSE - servo powered)
|
||||
- **M3 S1000** = Pen DOWN (31 ticks / ~2ms / MAX_PULSE - servo powered)
|
||||
- **M5** = Disable PWM (servo unpowered)
|
||||
|
||||
**Servo Direction:**
|
||||
- Default configuration: S0 = pen up (MIN_PULSE), S1000 = pen down (MAX_PULSE)
|
||||
- If your servo moves backwards, swap the MIN and MAX pulse values
|
||||
- Fine-tune the exact pulse values (16-31 range) to match your servo's physical limits
|
||||
@@ -253,7 +253,7 @@
|
||||
// equally divided voltage bins between the maximum and minimum spindle speeds. So for a 5V pin, 1000
|
||||
// max rpm, and 250 min rpm, the spindle output voltage would be set for the following "S" commands:
|
||||
// "S1000" @ 5V, "S250" @ 0.02V, and "S625" @ 2.5V (mid-range). The pin outputs 0V when disabled.
|
||||
#define SPINDLE_MAX_RPM 1200.0 // Max spindle RPM. This value is equal to 100% duty cycle on the PWM.
|
||||
#define SPINDLE_MAX_RPM 1000.0 // Max spindle RPM. This value is equal to 100% duty cycle on the PWM.
|
||||
#define SPINDLE_MIN_RPM 0.0 // Min spindle RPM. This value is equal to (1/256) duty cycle on the PWM.
|
||||
|
||||
// Used by variable spindle output only. This forces the PWM output to a minimum duty cycle when enabled.
|
||||
|
||||
@@ -45,22 +45,7 @@ void spindle_init()
|
||||
|
||||
void spindle_stop()
|
||||
{
|
||||
#ifdef USE_SPINDLE_SERVO_MODE
|
||||
// Servo mode: M5 moves servo to maximum position (e.g., pen up) instead of disabling PWM
|
||||
// This keeps the servo powered and in position
|
||||
TCCRA_REGISTER = (1<<COMB_BIT) | (1<<WAVE1_REGISTER) | (1<<WAVE0_REGISTER);
|
||||
TCCRB_REGISTER = (TCCRB_REGISTER & 0b11111000) | 0x07; // 1/1024 prescaler
|
||||
OCR_REGISTER = SPINDLE_SERVO_MAX_PULSE; // Set to maximum position
|
||||
|
||||
#if defined(CPU_MAP_ATMEGA2560) || 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
|
||||
#else
|
||||
// Standard spindle mode: Disable PWM output
|
||||
// Disable PWM output (both servo and standard modes)
|
||||
#ifdef VARIABLE_SPINDLE
|
||||
TCCRA_REGISTER &= ~(1<<COMB_BIT); // Disable PWM. Output voltage is zero.
|
||||
#if defined(CPU_MAP_ATMEGA2560) || defined(USE_SPINDLE_DIR_AS_ENABLE_PIN)
|
||||
@@ -77,7 +62,6 @@ void spindle_stop()
|
||||
SPINDLE_ENABLE_PORT &= ~(1<<SPINDLE_ENABLE_BIT); // Set pin to low
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -124,12 +108,15 @@ void spindle_set_state(uint8_t state, float rpm)
|
||||
else {
|
||||
// Servo mode: Map RPM range to servo pulse width (16-31 ticks = ~1-2ms pulses)
|
||||
// Each tick at 1/1024 prescaler = 64μs, so 16 ticks ≈ 1.024ms, 31 ticks ≈ 1.984ms
|
||||
// INVERTED: S1000 = pen down (max pulse), S0 = pen up (min pulse)
|
||||
#define SPINDLE_SERVO_RANGE (SPINDLE_SERVO_MAX_PULSE - SPINDLE_SERVO_MIN_PULSE)
|
||||
#define SPINDLE_RPM_RANGE (SPINDLE_MAX_RPM-SPINDLE_MIN_RPM)
|
||||
if ( rpm < SPINDLE_MIN_RPM ) { rpm = SPINDLE_MIN_RPM; }
|
||||
if ( rpm > SPINDLE_MAX_RPM ) { rpm = SPINDLE_MAX_RPM; }
|
||||
// Invert RPM mapping: S1000 → max pulse (pen down), S0 → min pulse (pen up)
|
||||
rpm = SPINDLE_MAX_RPM - rpm;
|
||||
rpm -= SPINDLE_MIN_RPM;
|
||||
// Map RPM to servo pulse range
|
||||
// Map inverted RPM to servo pulse range
|
||||
current_pwm = floor( rpm * (SPINDLE_SERVO_RANGE / SPINDLE_RPM_RANGE) + SPINDLE_SERVO_MIN_PULSE + 0.5);
|
||||
OCR_REGISTER = current_pwm; // Set PWM pin output
|
||||
|
||||
|
||||
Reference in New Issue
Block a user