Compare commits
12 Commits
85ca858f47
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
baebeb436f | ||
|
|
67a98b78b4 | ||
|
|
eddba72e23 | ||
|
|
9180094b72 | ||
|
|
3ce1a9d637 | ||
|
|
8efed33a90 | ||
|
|
1a3f023d5e | ||
|
|
9198e52d60 | ||
|
|
ac12e6afd2 | ||
|
|
003ba2b98b | ||
|
|
658eb6a8b3 | ||
|
|
66a64af239 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -3,5 +3,6 @@
|
|||||||
*.elf
|
*.elf
|
||||||
*.DS_Store
|
*.DS_Store
|
||||||
*.d
|
*.d
|
||||||
|
.pio/
|
||||||
|
.vscode/
|
||||||
README.md
|
README.md
|
||||||
|
|||||||
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
|
||||||
|
```
|
||||||
33
README.md
33
README.md
@@ -1,5 +1,29 @@
|
|||||||

|

|
||||||
|
***
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
@@ -22,7 +46,7 @@ Grbl includes full acceleration management with look ahead. That means the contr
|
|||||||
***
|
***
|
||||||
|
|
||||||
### Official Supporters of the Grbl CNC Project
|
### Official Supporters of the Grbl CNC Project
|
||||||

|

|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
@@ -102,8 +126,3 @@ List of Supported G-Codes in Grbl v0.9 Master:
|
|||||||
- Spindle Control: M3, M4, M5
|
- Spindle Control: M3, M4, M5
|
||||||
- Valid Non-Command Words: F, I, J, K, L, N, P, R, S, T, X, Y, Z
|
- Valid Non-Command Words: F, I, J, K, L, N, P, R, S, T, X, Y, Z
|
||||||
```
|
```
|
||||||
|
|
||||||
-------------
|
|
||||||
Grbl is an open-source project and fueled by the free-time of our intrepid administrators and altruistic users. If you'd like to donate, all proceeds will be used to help fund supporting hardware and testing equipment. Thank you!
|
|
||||||
|
|
||||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CUGXJHXA36BYW)
|
|
||||||
|
|||||||
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
|
||||||
51
debug.md
Normal file
51
debug.md
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
this is my curennt grbl state
|
||||||
|
|
||||||
|
when homing the first limit switch encoutnered always retrun from homing.
|
||||||
|
it can be either the x or y
|
||||||
|
how to fix
|
||||||
|
```
|
||||||
|
*** Connecting to jserialcomm://ttyUSB0:115200
|
||||||
|
*** Fetching device status
|
||||||
|
>>> ?
|
||||||
|
<Alarm,MPos:0.000,0.000,0.000,WPos:1.002,-209.000,0.000>
|
||||||
|
*** Fetching device version
|
||||||
|
*** Fetching device settings
|
||||||
|
>>> $$
|
||||||
|
$0 = 10 (step pulse, usec)
|
||||||
|
$1 = 25 (step idle delay, msec)
|
||||||
|
$2 = 0 (step port invert mask:00000000)
|
||||||
|
$3 = 2 (dir port invert mask:00000010)
|
||||||
|
$4 = 0 (step enable invert, bool)
|
||||||
|
$5 = 0 (limit pins invert, bool)
|
||||||
|
$6 = 0 (probe pin invert, bool)
|
||||||
|
$10 = 3 (status report mask:00000011)
|
||||||
|
$11 = 0.010 (junction deviation, mm)
|
||||||
|
$12 = 0.002 (arc tolerance, mm)
|
||||||
|
$13 = 0 (report inches, bool)
|
||||||
|
$20 = 1 (soft limits, bool)
|
||||||
|
$21 = 0 (hard limits, bool)
|
||||||
|
$22 = 1 (homing cycle, bool)
|
||||||
|
$23 = 6 (homing dir invert mask:00000110)
|
||||||
|
$24 = 25.000 (homing feed, mm/min)
|
||||||
|
$25 = 500.000 (homing seek, mm/min)
|
||||||
|
$26 = 250 (homing debounce, msec)
|
||||||
|
$27 = 1.000 (homing pull-off, mm)
|
||||||
|
$100 = 113.821 (x, step/mm)
|
||||||
|
$101 = 100.000 (y, step/mm)
|
||||||
|
$102 = 100.000 (z, step/mm)
|
||||||
|
$110 = 8000.000 (x max rate, mm/min)
|
||||||
|
$111 = 8000.000 (y max rate, mm/min)
|
||||||
|
$112 = 8000.000 (z max rate, mm/min)
|
||||||
|
$120 = 1200.000 (x accel, mm/sec^2)
|
||||||
|
$121 = 1200.000 (y accel, mm/sec^2)
|
||||||
|
$122 = 3800.000 (z accel, mm/sec^2)
|
||||||
|
$130 = 310.000 (x max travel, mm)
|
||||||
|
$131 = 210.000 (y max travel, mm)
|
||||||
|
$132 = 100.000 (z max travel, mm)
|
||||||
|
ok
|
||||||
|
*** Fetching device state
|
||||||
|
*** Connected to GRBL 0.9i
|
||||||
|
>>> $G
|
||||||
|
[G0 G54 G17 G21 G90 G94 M0 M5 M9 T0 F0. S0.]
|
||||||
|
ok
|
||||||
|
```
|
||||||
@@ -1,3 +1,43 @@
|
|||||||
|
----------------
|
||||||
|
Date: 2016-07-26
|
||||||
|
Author: chamnit
|
||||||
|
Subject: Fixed homing on CoreXY machines only.
|
||||||
|
|
||||||
|
- The homing routine for CoreXY/H-Bot CNC machines has been fixed.
|
||||||
|
|
||||||
|
- Version date bumped, but this update does NOT effect any normal
|
||||||
|
users. Only CoreXY users.
|
||||||
|
|
||||||
|
|
||||||
|
----------------
|
||||||
|
Date: 2016-07-26
|
||||||
|
Author: chamnit
|
||||||
|
Subject: Merge branch 'master-corexy'
|
||||||
|
|
||||||
|
|
||||||
|
----------------
|
||||||
|
Date: 2016-07-25
|
||||||
|
Author: chamnit
|
||||||
|
Subject: CoreXY homing bug fix attempt 2.
|
||||||
|
|
||||||
|
|
||||||
|
----------------
|
||||||
|
Date: 2016-07-25
|
||||||
|
Author: chamnit
|
||||||
|
Subject: CoreXY homing fix attempt.
|
||||||
|
|
||||||
|
|
||||||
|
----------------
|
||||||
|
Date: 2016-03-17
|
||||||
|
Author: Sonny Jeon
|
||||||
|
Subject: No variable spindle and spindle speed fix.
|
||||||
|
|
||||||
|
- When VARIABLE_SPINDLE output is disabled in config.h, the last commit
|
||||||
|
would keep the spindle enable pin disabled when spindle speed is not
|
||||||
|
defined (S0). This is now ignored and will enable with S0, as spindle
|
||||||
|
speed is ignored in this mode.
|
||||||
|
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
Date: 2016-03-16
|
Date: 2016-03-16
|
||||||
Author: Sonny Jeon
|
Author: Sonny Jeon
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
|
|
||||||
Copyright (c) 2015 Gnea Research LLC. All Rights Reserved.
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 41 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 57 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 48 KiB |
Binary file not shown.
@@ -1,134 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="744.094488189"
|
|
||||||
height="1052.36220472"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="Grbl Logo.svg">
|
|
||||||
<metadata
|
|
||||||
id="metadata97">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title />
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<sodipodi:namedview
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1"
|
|
||||||
objecttolerance="10"
|
|
||||||
gridtolerance="10"
|
|
||||||
guidetolerance="10"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-width="1000"
|
|
||||||
inkscape:window-height="751"
|
|
||||||
id="namedview95"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="0.89702957"
|
|
||||||
inkscape:cx="393.978"
|
|
||||||
inkscape:cy="560.38231"
|
|
||||||
inkscape:window-x="0"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="0"
|
|
||||||
inkscape:current-layer="g21" />
|
|
||||||
<desc
|
|
||||||
id="desc4">/Users/chamnit/Dropbox/documents/OHS/Logo/Grbl.DXF - scale = 58.043118, origin = (0.000000, 0.000000), auto = True</desc>
|
|
||||||
<defs
|
|
||||||
id="defs6">
|
|
||||||
<marker
|
|
||||||
id="DistanceX"
|
|
||||||
orient="auto"
|
|
||||||
refX="0.0"
|
|
||||||
refY="0.0"
|
|
||||||
style="overflow:visible">
|
|
||||||
<path
|
|
||||||
d="M 3,-3 L -3,3 M 0,-5 L 0,5"
|
|
||||||
style="stroke:#000000; stroke-width:0.5"
|
|
||||||
id="path9" />
|
|
||||||
</marker>
|
|
||||||
<pattern
|
|
||||||
height="8"
|
|
||||||
id="Hatch"
|
|
||||||
patternUnits="userSpaceOnUse"
|
|
||||||
width="8"
|
|
||||||
x="0"
|
|
||||||
y="0">
|
|
||||||
<path
|
|
||||||
d="M8 4 l-4,4"
|
|
||||||
linecap="square"
|
|
||||||
stroke="#000000"
|
|
||||||
stroke-width="0.25"
|
|
||||||
id="path12" />
|
|
||||||
<path
|
|
||||||
d="M6 2 l-4,4"
|
|
||||||
linecap="square"
|
|
||||||
stroke="#000000"
|
|
||||||
stroke-width="0.25"
|
|
||||||
id="path14" />
|
|
||||||
<path
|
|
||||||
d="M4 0 l-4,4"
|
|
||||||
linecap="square"
|
|
||||||
stroke="#000000"
|
|
||||||
stroke-width="0.25"
|
|
||||||
id="path16" />
|
|
||||||
</pattern>
|
|
||||||
<symbol
|
|
||||||
id="*Model_Space" />
|
|
||||||
<symbol
|
|
||||||
id="*Paper_Space" />
|
|
||||||
<symbol
|
|
||||||
id="*Paper_Space0" />
|
|
||||||
</defs>
|
|
||||||
<g
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
inkscape:label="0"
|
|
||||||
id="g21">
|
|
||||||
<g
|
|
||||||
id="g3562"
|
|
||||||
transform="matrix(0.74854703,0,0,0.74854703,93.578346,130.5299)">
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="ccscccccc"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path45"
|
|
||||||
style="fill:#000000;stroke:#000000;stroke-linecap:round"
|
|
||||||
d="m 666.97027,519.20619 0,-204.22494 c 0,-14.19819 -11.5099,-25.70806 -25.70807,-25.70806 -14.19818,0 -25.70808,11.50987 -25.70808,25.70806 l 0,204.22494 c 0,56.79271 46.03958,102.83229 102.83229,102.8323 l 25.70808,-25.70808 -25.70808,-25.70807 c -28.39635,0 -51.41614,-23.0198 -51.41614,-51.41615 z" />
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="ccsccccccc"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path61"
|
|
||||||
style="fill:#000000;stroke:#000000;stroke-linecap:round"
|
|
||||||
d="m 230.65284,519.20619 0,77.12422 c 0,14.19819 11.5099,25.70806 25.70807,25.70806 14.19818,0 25.70808,-11.50987 25.70808,-25.70806 l 0,-77.12422 c 0,-28.39635 23.01979,-51.41615 51.41614,-51.41615 l 38.92203,0 0,-51.41614 -38.92203,0 c -56.7927,1e-5 -102.83228,46.03959 -102.83229,102.83229" />
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="ccccssscccccsssc"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path73"
|
|
||||||
style="fill:#000000;stroke:#000000;stroke-linecap:round"
|
|
||||||
d="m 487.73358,416.3739 -38.92203,0 0,51.41614 38.92203,0 c 20.79587,0 39.54419,12.52721 47.50197,31.73975 7.95777,19.21249 3.55772,41.32642 -11.14711,56.03126 -14.70484,14.70483 -36.81877,19.10488 -56.03126,11.14711 -19.21254,-7.95778 -31.73975,-26.7061 -31.73975,-47.50197 l 0,-204.22494 -25.70808,-25.70807 -25.70807,25.70807 0,204.22494 c 0,41.59174 25.05442,79.08838 63.47948,95.00395 38.42499,15.91554 82.65286,7.11546 112.06254,-22.29421 29.40967,-29.40968 38.20976,-73.63755 22.29423,-112.06254 -15.91557,-38.42506 -53.41221,-63.47949 -95.00395,-63.47949" />
|
|
||||||
<path
|
|
||||||
sodipodi:nodetypes="cssscccscccsssccccc"
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path81"
|
|
||||||
style="fill:#000000;stroke:#000000;stroke-linecap:round"
|
|
||||||
d="m 102.8323,570.62234 c -20.795869,0 -39.544189,-12.52721 -47.501976,-31.73974 -7.95777,-19.21249 -3.557731,-41.32643 11.147104,-56.03126 14.704835,-14.70484 36.818772,-19.10489 56.031262,-11.14712 19.21254,7.95778 31.73975,26.7061 31.73975,47.50197 l 0,127.10072 c 0,28.39635 -23.01979,51.41615 -51.41614,51.41615 -14.192584,0.008 -25.693722,11.51549 -25.693722,25.70807 0,14.19258 11.501138,25.70007 25.693722,25.70807 56.7927,-10e-6 102.83228,-46.03959 102.83229,-102.83229 l 0,-127.10072 c 0,-41.59174 -25.05443,-79.08838 -63.47949,-95.00395 C 103.76011,408.28671 59.532236,417.0868 30.122564,446.49647 0.712891,475.90615 -8.0871904,520.13402 7.8283485,558.55901 23.74392,596.98407 61.240561,622.03849 102.8323,622.03849 l 25.70807,0 25.70807,-25.70808 -25.70807,-25.70807 -25.70807,0" />
|
|
||||||
<path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path91"
|
|
||||||
style="fill:none;stroke:#000000;stroke-linecap:round"
|
|
||||||
d="m 744.09449,596.33041 -25.70808,25.70808" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 5.6 KiB |
@@ -72,9 +72,11 @@
|
|||||||
// on separate pin, but homed in one cycle. Also, it should be noted that the function of hard limits
|
// on separate pin, but homed in one cycle. Also, it should be noted that the function of hard limits
|
||||||
// will not be affected by pin sharing.
|
// will not be affected by pin sharing.
|
||||||
// NOTE: Defaults are set for a traditional 3-axis CNC machine. Z-axis first to clear, followed by X & Y.
|
// NOTE: Defaults are set for a traditional 3-axis CNC machine. Z-axis first to clear, followed by X & Y.
|
||||||
#define HOMING_CYCLE_0 (1<<X_AXIS) // REQUIRED: First move Z to clear workspace.
|
#define HOMING_CYCLE_0 (1<<Z_AXIS) // REQUIRED: First move Z to clear workspace.
|
||||||
#define HOMING_CYCLE_1 (1<<Y_AXIS) // OPTIONAL: Then move X,Y at the same time.
|
// #define HOMING_CYCLE_1 ((1<<X_AXIS)|(1<<Y_AXIS)) // OPTIONAL: Then move X,Y at the same time.
|
||||||
// #define HOMING_CYCLE_2 // OPTIONAL: Uncomment and add axes mask to enable
|
// #define HOMING_CYCLE_2 // OPTIONAL: Uncomment and add axes mask to enable
|
||||||
|
#define HOMING_CYCLE_0 (1<<X_AXIS)
|
||||||
|
#define HOMING_CYCLE_1 (1<<Y_AXIS)
|
||||||
|
|
||||||
// Number of homing cycles performed after when the machine initially jogs to limit switches.
|
// Number of homing cycles performed after when the machine initially jogs to limit switches.
|
||||||
// This help in preventing overshoot and should improve repeatability. This value should be one or
|
// This help in preventing overshoot and should improve repeatability. This value should be one or
|
||||||
@@ -147,7 +149,7 @@
|
|||||||
// #define HOMING_CYCLE_0 (1<<X_AXIS) and #define HOMING_CYCLE_1 (1<<Y_AXIS)
|
// #define HOMING_CYCLE_0 (1<<X_AXIS) and #define HOMING_CYCLE_1 (1<<Y_AXIS)
|
||||||
// NOTE: This configuration option alters the motion of the X and Y axes to principle of operation
|
// NOTE: This configuration option alters the motion of the X and Y axes to principle of operation
|
||||||
// defined at (http://corexy.com/theory.html). Motors are assumed to positioned and wired exactly as
|
// defined at (http://corexy.com/theory.html). Motors are assumed to positioned and wired exactly as
|
||||||
// described, if not, motions may move in strange directions. Grbl assumes the CoreXY A and B motors
|
// described, if not, motions may move in strange directions. Grbl requires the CoreXY A and B motors
|
||||||
// have the same steps per mm internally.
|
// have the same steps per mm internally.
|
||||||
#define COREXY // Default disabled. Uncomment to enable.
|
#define COREXY // Default disabled. Uncomment to enable.
|
||||||
|
|
||||||
@@ -260,6 +262,23 @@
|
|||||||
// spindle RPM output lower than this value will be set to this value.
|
// spindle RPM output lower than this value will be set to this value.
|
||||||
// #define MINIMUM_SPINDLE_PWM 5 // Default disabled. Uncomment to enable. Integer (0-255)
|
// #define MINIMUM_SPINDLE_PWM 5 // Default disabled. Uncomment to enable. Integer (0-255)
|
||||||
|
|
||||||
|
// Enable servo mode for spindle PWM output. This changes the PWM frequency from ~1kHz to ~50Hz
|
||||||
|
// and adjusts the duty cycle range to control hobby servos (1-2ms pulses). When enabled, the
|
||||||
|
// spindle RPM values are mapped to servo positions (S0-S180 or configured min/max).
|
||||||
|
// This is useful for pen plotters, drag knives, or other applications requiring servo control.
|
||||||
|
// Based on: https://www.buildlog.net/blog/2017/08/using-grbls-spindle-pwm-to-control-a-servo/
|
||||||
|
// NOTE: Only works with VARIABLE_SPINDLE enabled and ATmega328p (Uno) processors.
|
||||||
|
// NOTE: This changes Timer2 prescaler from 1/8 to 1/1024, resulting in ~61Hz PWM frequency.
|
||||||
|
// NOTE: Connect servo signal wire to Arduino Pin D11 (same as spindle PWM output).
|
||||||
|
// Servo power (5V) and ground must be connected to appropriate power source.
|
||||||
|
#define USE_SPINDLE_SERVO_MODE // Default disabled. Uncomment to enable.
|
||||||
|
|
||||||
|
// Servo pulse width range (in timer ticks). Only used with USE_SPINDLE_SERVO_MODE enabled.
|
||||||
|
// At 1/1024 prescaler on 16MHz, each tick = 64μs. Default values: 16 ticks = 1.024ms, 31 ticks = 1.984ms
|
||||||
|
// Adjust these if your servo requires different pulse widths for 0° and 180° positions.
|
||||||
|
#define SPINDLE_SERVO_MIN_PULSE 31 // Servo position at minimum RPM (S0) - pen DOWN - ~2ms pulse
|
||||||
|
#define SPINDLE_SERVO_MAX_PULSE 16 // Servo position at maximum RPM (S1000/M5) - pen UP - ~1ms pulse
|
||||||
|
|
||||||
// By default on a 328p(Uno), Grbl combines the variable spindle PWM and the enable into one pin to help
|
// 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
|
// 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.
|
// the spindle direction pin(D13) as a separate spindle enable pin along with spindle speed PWM on pin D11.
|
||||||
@@ -407,6 +426,18 @@
|
|||||||
#error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with a 328p processor"
|
#error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with a 328p processor"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_SPINDLE_SERVO_MODE) && !defined(VARIABLE_SPINDLE)
|
||||||
|
#error "USE_SPINDLE_SERVO_MODE may only be used with VARIABLE_SPINDLE enabled"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_SPINDLE_SERVO_MODE) && !defined(CPU_MAP_ATMEGA328P)
|
||||||
|
#error "USE_SPINDLE_SERVO_MODE may only be used with a 328p processor"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_SPINDLE_SERVO_MODE) && (SPINDLE_SERVO_MIN_PULSE == SPINDLE_SERVO_MAX_PULSE)
|
||||||
|
#error "SPINDLE_SERVO_MIN_PULSE and SPINDLE_SERVO_MAX_PULSE cannot be equal"
|
||||||
|
#endif
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
// Grbl versioning system
|
// Grbl versioning system
|
||||||
#define GRBL_VERSION "0.9j"
|
#define GRBL_VERSION "0.9j"
|
||||||
#define GRBL_VERSION_BUILD "20160317"
|
#define GRBL_VERSION_BUILD "20160726"
|
||||||
|
|
||||||
// Define standard libraries used by Grbl.
|
// Define standard libraries used by Grbl.
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ void spindle_init()
|
|||||||
|
|
||||||
void spindle_stop()
|
void spindle_stop()
|
||||||
{
|
{
|
||||||
// On the Uno, spindle enable and PWM are shared. Other CPUs have seperate enable pin.
|
// Disable PWM output (both servo and standard modes)
|
||||||
#ifdef VARIABLE_SPINDLE
|
#ifdef VARIABLE_SPINDLE
|
||||||
TCCRA_REGISTER &= ~(1<<COMB_BIT); // Disable PWM. Output voltage is zero.
|
TCCRA_REGISTER &= ~(1<<COMB_BIT); // Disable PWM. Output voltage is zero.
|
||||||
#if defined(CPU_MAP_ATMEGA2560) || defined(USE_SPINDLE_DIR_AS_ENABLE_PIN)
|
#if defined(CPU_MAP_ATMEGA2560) || defined(USE_SPINDLE_DIR_AS_ENABLE_PIN)
|
||||||
@@ -83,7 +83,6 @@ void spindle_set_state(uint8_t state, float rpm)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VARIABLE_SPINDLE
|
#ifdef VARIABLE_SPINDLE
|
||||||
// TODO: Install the optional capability for frequency-based output for servos.
|
|
||||||
#ifdef CPU_MAP_ATMEGA2560
|
#ifdef CPU_MAP_ATMEGA2560
|
||||||
TCCRA_REGISTER = (1<<COMB_BIT) | (1<<WAVE1_REGISTER) | (1<<WAVE0_REGISTER);
|
TCCRA_REGISTER = (1<<COMB_BIT) | (1<<WAVE1_REGISTER) | (1<<WAVE0_REGISTER);
|
||||||
TCCRB_REGISTER = (TCCRB_REGISTER & 0b11111000) | 0x02 | (1<<WAVE2_REGISTER) | (1<<WAVE3_REGISTER); // set to 1/8 Prescaler
|
TCCRB_REGISTER = (TCCRB_REGISTER & 0b11111000) | 0x02 | (1<<WAVE2_REGISTER) | (1<<WAVE3_REGISTER); // set to 1/8 Prescaler
|
||||||
@@ -91,12 +90,50 @@ void spindle_set_state(uint8_t state, float rpm)
|
|||||||
uint16_t current_pwm;
|
uint16_t current_pwm;
|
||||||
#else
|
#else
|
||||||
TCCRA_REGISTER = (1<<COMB_BIT) | (1<<WAVE1_REGISTER) | (1<<WAVE0_REGISTER);
|
TCCRA_REGISTER = (1<<COMB_BIT) | (1<<WAVE1_REGISTER) | (1<<WAVE0_REGISTER);
|
||||||
TCCRB_REGISTER = (TCCRB_REGISTER & 0b11111000) | 0x02; // set to 1/8 Prescaler
|
#ifdef USE_SPINDLE_SERVO_MODE
|
||||||
|
// Servo mode: Set to 1/1024 prescaler for ~50Hz frequency (actually ~61Hz on 16MHz)
|
||||||
|
// Timer formula: Freq = F_CPU / (Prescaler * 256) = 16MHz / (1024 * 256) = 61.04Hz
|
||||||
|
// This provides the ~20ms period needed for servo control (50Hz ideal, 61Hz acceptable)
|
||||||
|
TCCRB_REGISTER = (TCCRB_REGISTER & 0b11111000) | 0x07; // CS22=1, CS21=1, CS20=1 = 1/1024 prescaler
|
||||||
|
#else
|
||||||
|
// Standard spindle mode: Set to 1/8 prescaler for ~7.8kHz frequency
|
||||||
|
TCCRB_REGISTER = (TCCRB_REGISTER & 0b11111000) | 0x02; // CS21=1 = 1/8 prescaler
|
||||||
|
#endif
|
||||||
uint8_t current_pwm;
|
uint8_t current_pwm;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (rpm <= 0.0) { spindle_stop(); } // RPM should never be negative, but check anyway.
|
#ifdef USE_SPINDLE_SERVO_MODE
|
||||||
|
// Servo mode: Allow rpm=0 as valid position (0 degrees), only stop on negative
|
||||||
|
if (rpm < 0.0) { spindle_stop(); }
|
||||||
else {
|
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 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
|
||||||
|
|
||||||
|
// On the Uno, spindle enable and PWM are shared, unless otherwise specified.
|
||||||
|
#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: Stop on zero or negative RPM
|
||||||
|
if (rpm <= 0.0) { spindle_stop(); }
|
||||||
|
else {
|
||||||
|
// Standard spindle mode: Map RPM range to full PWM range (0-255)
|
||||||
#define SPINDLE_RPM_RANGE (SPINDLE_MAX_RPM-SPINDLE_MIN_RPM)
|
#define SPINDLE_RPM_RANGE (SPINDLE_MAX_RPM-SPINDLE_MIN_RPM)
|
||||||
if ( rpm < SPINDLE_MIN_RPM ) { rpm = 0; }
|
if ( rpm < SPINDLE_MIN_RPM ) { rpm = 0; }
|
||||||
else {
|
else {
|
||||||
@@ -118,6 +155,7 @@ void spindle_set_state(uint8_t state, float rpm)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// NOTE: Without variable spindle, the enable bit should just turn on or off, regardless
|
// NOTE: Without variable spindle, the enable bit should just turn on or off, regardless
|
||||||
|
|||||||
@@ -265,9 +265,9 @@ float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx)
|
|||||||
float pos;
|
float pos;
|
||||||
#ifdef COREXY
|
#ifdef COREXY
|
||||||
if (idx==X_AXIS) {
|
if (idx==X_AXIS) {
|
||||||
pos = (float)system_convert_corexy_to_x_axis_steps(steps) / settings.steps_per_mm[idx];
|
pos = (float)system_convert_corexy_to_x_axis_steps(steps) / settings.steps_per_mm[A_MOTOR];
|
||||||
} else if (idx==Y_AXIS) {
|
} else if (idx==Y_AXIS) {
|
||||||
pos = (float)system_convert_corexy_to_y_axis_steps(steps) / settings.steps_per_mm[idx];
|
pos = (float)system_convert_corexy_to_y_axis_steps(steps) / settings.steps_per_mm[B_MOTOR];
|
||||||
} else {
|
} else {
|
||||||
pos = steps[idx]/settings.steps_per_mm[idx];
|
pos = steps[idx]/settings.steps_per_mm[idx];
|
||||||
}
|
}
|
||||||
@@ -289,6 +289,7 @@ void system_convert_array_steps_to_mpos(float *position, int32_t *steps)
|
|||||||
|
|
||||||
|
|
||||||
// CoreXY calculation only. Returns x or y-axis "steps" based on CoreXY motor steps.
|
// CoreXY calculation only. Returns x or y-axis "steps" based on CoreXY motor steps.
|
||||||
|
#ifdef COREXY
|
||||||
int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps)
|
int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps)
|
||||||
{
|
{
|
||||||
return( (steps[A_MOTOR] + steps[B_MOTOR])/2 );
|
return( (steps[A_MOTOR] + steps[B_MOTOR])/2 );
|
||||||
@@ -297,4 +298,5 @@ int32_t system_convert_corexy_to_y_axis_steps(int32_t *steps)
|
|||||||
{
|
{
|
||||||
return( (steps[A_MOTOR] - steps[B_MOTOR])/2 );
|
return( (steps[A_MOTOR] - steps[B_MOTOR])/2 );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,9 @@ float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx);
|
|||||||
void system_convert_array_steps_to_mpos(float *position, int32_t *steps);
|
void system_convert_array_steps_to_mpos(float *position, int32_t *steps);
|
||||||
|
|
||||||
// CoreXY calculation only. Returns x or y-axis "steps" based on CoreXY motor steps.
|
// CoreXY calculation only. Returns x or y-axis "steps" based on CoreXY motor steps.
|
||||||
|
#ifdef COREXY
|
||||||
int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps);
|
int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps);
|
||||||
int32_t system_convert_corexy_to_y_axis_steps(int32_t *steps);
|
int32_t system_convert_corexy_to_y_axis_steps(int32_t *steps);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
41
platformio.ini
Normal file
41
platformio.ini
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
; PlatformIO Project Configuration File for Grbl
|
||||||
|
;
|
||||||
|
; This configuration builds Grbl v0.9j for Arduino Uno (ATmega328P)
|
||||||
|
; Based on the original Makefile settings
|
||||||
|
;
|
||||||
|
; Please visit documentation for options and examples
|
||||||
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
|
[platformio]
|
||||||
|
src_dir = src
|
||||||
|
lib_dir = .
|
||||||
|
include_dir = grbl
|
||||||
|
|
||||||
|
[env:uno]
|
||||||
|
platform = atmelavr
|
||||||
|
board = uno
|
||||||
|
framework = arduino
|
||||||
|
|
||||||
|
; Build configuration matching Makefile
|
||||||
|
build_flags =
|
||||||
|
-DF_CPU=16000000L
|
||||||
|
-DBAUD_RATE=115200
|
||||||
|
-Wall
|
||||||
|
-Os
|
||||||
|
-ffunction-sections
|
||||||
|
-fdata-sections
|
||||||
|
-Wl,--gc-sections
|
||||||
|
-lm
|
||||||
|
-Igrbl
|
||||||
|
-Igrbl/cpu_map
|
||||||
|
-Igrbl/defaults
|
||||||
|
|
||||||
|
; Add Grbl source files to build
|
||||||
|
build_src_filter =
|
||||||
|
+<*>
|
||||||
|
+<../grbl/*.c>
|
||||||
|
-<../grbl/examples/>
|
||||||
|
|
||||||
|
; Upload configuration
|
||||||
|
upload_speed = 115200
|
||||||
|
monitor_speed = 115200
|
||||||
Reference in New Issue
Block a user