Compare commits

..

12 Commits

Author SHA1 Message Date
devdesk
baebeb436f Add T.A.M.I Drawbot modifications changelog to README
- Added changelog section documenting all modifications since forking
- Documented December 4, 2025 changes (inverted servo PWM, M5 fix)
- Listed earlier modifications (servo mode, homing fix)
2025-12-04 14:46:13 +02:00
devdesk
67a98b78b4 Invert servo PWM mapping and fix M5 behavior
- M5 now disables PWM completely in both standard and servo modes
- Inverted servo mapping: S0=pen up (16 ticks), S1000=pen down (31 ticks)
- Updated SERVO_MODE.md documentation to reflect new behavior
- Changed config defaults: MIN_PULSE=16, MAX_PULSE=31
2025-12-04 14:42:17 +02:00
devdesk
eddba72e23 Add servo mode support for spindle PWM control
- Implemented USE_SPINDLE_SERVO_MODE configuration option
- Changed Timer2 prescaler from 1/8 to 1/1024 for ~50Hz servo frequency
- Added configurable servo pulse width range (SPINDLE_SERVO_MIN_PULSE/MAX_PULSE)
- M3 S0-S1000 now controls servo position (0-180 degrees)
- M5 positions servo to maximum position (pen up) instead of disabling PWM
- Default configuration supports pen plotter with reversed pulse values (MIN=31, MAX=16)
- Only supports ATmega328p (Arduino Uno) processors

Based on: https://www.buildlog.net/blog/2017/08/using-grbls-spindle-pwm-to-control-a-servo/
2025-12-03 19:08:46 +02:00
Sonny Jeon
9180094b72 Update README.md 2021-01-22 19:15:51 -05:00
Sonny Jeon
3ce1a9d637 Merge pull request #1209 from per1234/fix-header-markdown
Fix header Markdown in README.md
2017-04-14 14:07:15 -06:00
per1234
8efed33a90 Fix header Markdown in README.md
GitHub's Markdown interpreter was recently changed to strictly enforce the GFM spec, which requires a delimiting space in header Markdown. This has caused some Markdown to no longer display as originally intended.
2017-04-14 01:15:09 -07:00
Sonny Jeon
1a3f023d5e Moved Grbl logo files to separate repo. 2017-03-19 09:34:37 -06:00
Sonny Jeon
9198e52d60 Update README.md 2017-03-19 09:22:12 -06:00
Sonny Jeon
ac12e6afd2 Update README.md 2017-03-19 09:12:35 -06:00
Sonny Jeon
003ba2b98b Update README.md 2016-12-09 22:08:45 -07:00
chamnit
658eb6a8b3 Non-CoreXY compiling fix. 2016-07-26 13:16:43 -06:00
chamnit
66a64af239 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.
2016-07-26 11:32:33 -06:00
20 changed files with 746 additions and 192 deletions

3
.gitignore vendored
View File

@@ -3,5 +3,6 @@
*.elf
*.DS_Store
*.d
.pio/
.vscode/
README.md

81
HOMING_FIX.md Normal file
View 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
View 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
```

View File

@@ -1,5 +1,29 @@
![GitHub Logo](/doc/media/Grbl Logo 250px.png)
![GitHub Logo](https://github.com/gnea/gnea-Media/blob/master/Grbl%20Logo/Grbl%20Logo%20250px.png?raw=true)
***
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](https://dl.dropboxusercontent.com/u/2221997/Contributors.png)
![Official Supporters](https://github.com/gnea/gnea-Media/blob/master/Contributors.png?raw=true)
***
@@ -46,12 +70,12 @@ _**Archives:**_
***
##Update Summary for v0.9j
## Update Summary for v0.9j
- **Restore EEPROM feature:** A new set of restore EEPROM features to help OEMs and users reset their Grbl installation to the build defaults. See Configuring Grbl Wiki for details.
- **More configuration options for input pins**
- **Bug fixes including:** Soft limit error handling, disable spindle when S0, g-code reporting of G38.x.
##Update Summary for v0.9i
## Update Summary for v0.9i
- **IMPORTANT:**
- **Homing cycle updated. Locates based on trigger point, rather than release point.**
- **System tweaks: $14 cycle auto-start has been removed. No more QUEUE state.**
@@ -61,7 +85,7 @@ _**Archives:**_
- **Full Limit and Control Pin Configurability**
- **Additional Compile-Time Feature Options**
##Update Summary for v0.9h from v0.8
## Update Summary for v0.9h from v0.8
- **IMPORTANT:**
- **Default serial baudrate is now 115200! (Up from 9600)**
- **Z-limit(D12) and spindle enable(D11) pins have switched to support variable spindle!**
@@ -102,8 +126,3 @@ List of Supported G-Codes in Grbl v0.9 Master:
- Spindle Control: M3, M4, M5
- 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!
[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CUGXJHXA36BYW)

203
SERVO_MODE.md Normal file
View 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
View 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
```

View File

@@ -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
Author: Sonny Jeon

View File

@@ -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.

View File

@@ -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

View File

@@ -72,9 +72,11 @@
// 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.
// 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_1 (1<<Y_AXIS) // OPTIONAL: Then move X,Y at the same time.
#define HOMING_CYCLE_0 (1<<Z_AXIS) // REQUIRED: First move Z to clear workspace.
// #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_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.
// 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)
// 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
// 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.
#define COREXY // Default disabled. Uncomment to enable.
@@ -260,6 +262,23 @@
// 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)
// 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
// 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.
@@ -407,6 +426,18 @@
#error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with a 328p processor"
#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
// ---------------------------------------------------------------------------------------

View File

@@ -23,7 +23,7 @@
// Grbl versioning system
#define GRBL_VERSION "0.9j"
#define GRBL_VERSION_BUILD "20160317"
#define GRBL_VERSION_BUILD "20160726"
// Define standard libraries used by Grbl.
#include <avr/io.h>

View File

@@ -45,7 +45,7 @@ void spindle_init()
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
TCCRA_REGISTER &= ~(1<<COMB_BIT); // Disable PWM. Output voltage is zero.
#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
#ifdef VARIABLE_SPINDLE
// TODO: Install the optional capability for frequency-based output for servos.
#ifdef CPU_MAP_ATMEGA2560
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
@@ -91,12 +90,50 @@ void spindle_set_state(uint8_t state, float rpm)
uint16_t current_pwm;
#else
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;
#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 {
// 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)
if ( rpm < SPINDLE_MIN_RPM ) { rpm = 0; }
else {
@@ -118,6 +155,7 @@ void spindle_set_state(uint8_t state, float rpm)
#endif
#endif
}
#endif
#else
// NOTE: Without variable spindle, the enable bit should just turn on or off, regardless

View File

@@ -265,9 +265,9 @@ float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx)
float pos;
#ifdef COREXY
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) {
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 {
pos = steps[idx]/settings.steps_per_mm[idx];
}
@@ -289,12 +289,14 @@ 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.
int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps)
{
#ifdef COREXY
int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps)
{
return( (steps[A_MOTOR] + steps[B_MOTOR])/2 );
}
int32_t system_convert_corexy_to_y_axis_steps(int32_t *steps)
{
}
int32_t system_convert_corexy_to_y_axis_steps(int32_t *steps)
{
return( (steps[A_MOTOR] - steps[B_MOTOR])/2 );
}
}
#endif

View File

@@ -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);
// CoreXY calculation only. Returns x or y-axis "steps" based on CoreXY motor 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);
#ifdef COREXY
int32_t system_convert_corexy_to_x_axis_steps(int32_t *steps);
int32_t system_convert_corexy_to_y_axis_steps(int32_t *steps);
#endif
#endif

41
platformio.ini Normal file
View 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