Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DigiPots support #108

Open
wants to merge 2 commits into
base: edge
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -33,7 +33,7 @@ CLOCK = 16000000L
PROGRAMMER ?= -c avrisp2 -P usb
SOURCE = main.c motion_control.c gcode.c spindle_control.c coolant_control.c serial.c \
protocol.c stepper.c eeprom.c settings.c planner.c nuts_bolts.c limits.c \
print.c probe.c report.c system.c sleep.c jog.c
print.c probe.c report.c system.c sleep.c jog.c current_control.c
BUILDDIR = build
SOURCEDIR = grbl
# FUSES = -U hfuse:w:0xd9:m -U lfuse:w:0x24:m
Expand Down
3 changes: 3 additions & 0 deletions doc/csv/setting_codes_en_US.csv
Expand Up @@ -33,3 +33,6 @@
"130","X-axis maximum travel","millimeters","Maximum X-axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances."
"131","Y-axis maximum travel","millimeters","Maximum Y-axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances."
"132","Z-axis maximum travel","millimeters","Maximum Z-axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances."
"140","X-axis DigiPot value","integer","Value from 0-255 to send to the digital potentiometer. Determines the amount of current provided by the stepper motor."
"141","Y-axis DigiPot value","integer","Value from 0-255 to send to the digital potentiometer. Determines the amount of current provided by the stepper motor."
"142","Z-axis DigiPot value","integer","Value from 0-255 to send to the digital potentiometer. Determines the amount of current provided by the stepper motor."
3 changes: 3 additions & 0 deletions doc/markdown/interface.md
Expand Up @@ -314,6 +314,9 @@ ok
| **`130`** | X-axis maximum travel, millimeters |
| **`131`** | Y-axis maximum travel, millimeters |
| **`132`** | Z-axis maximum travel, millimeters |
| **`140`** | X-axis DigiPot setting, integer |
| **`141`** | Y-axis DigiPot setting, integer |
| **`142`** | Z-axis DigiPot setting, integer |


- The other `$Nx=line` message is the print-out of a user-defined startup line, where `x` denotes the startup line order and ranges from `0` to `1` by default. The `line` denotes the startup line to be executed by Grbl upon reset or power-up, except during an ALARM.
Expand Down
4 changes: 4 additions & 0 deletions doc/markdown/settings.md
Expand Up @@ -257,3 +257,7 @@ Again, like the max rate setting, the simplest way to determine the values for t
#### $130, $131, $132 – [X,Y,Z] Max travel, mm

This sets the maximum travel from end to end for each axis in mm. This is only useful if you have soft limits (and homing) enabled, as this is only used by Grbl's soft limit feature to check if you have exceeded your machine limits with a motion command.

#### $140, $141, $142 – [X,Y,Z] DigiPot setting, integer

This is the value sent to the digital potentiometer (if present) to control how much current is provided by the stepper drivers.
7 changes: 7 additions & 0 deletions grbl/config.h
Expand Up @@ -622,6 +622,13 @@
#define RPM_LINE_A4 1.203413e-01 // Used N_PIECES = 4. A and B constants of line 4.
#define RPM_LINE_B4 1.151360e+03

// When HAS_DIGIPOTS is defined in cpu_map.h, these values get sent over SPI during initialization
// to configure the DigiPots, thus programatically setting the stepper current. This code
// has been tested to work with AD5206 DigiPots but may work with other SPI-based DigiPots
// as well.
#define DEFAULT_X_CURRENT 135
#define DEFAULT_Y_CURRENT 135
#define DEFAULT_Z_CURRENT 135

/* ---------------------------------------------------------------------------------------
OEM Single File Configuration Option
Expand Down
17 changes: 17 additions & 0 deletions grbl/cpu_map.h
Expand Up @@ -130,6 +130,23 @@
#define SPINDLE_PWM_PORT PORTH
#define SPINDLE_PWM_BIT 4 // MEGA2560 Digital Pin 7

// DigiPot pins
// #define HAS_DIGIPOTS
// DigiPot Slave Select (SS) pin configuration
#define DIGIPOTSS_DDR DDRD
#define DIGIPOTSS_PORT PORTD
#define DIGIPOTSS_BIT 7
#define SPI_DDR DDRB
#define SPI_PORT PORTB
#define MOSI_BIT 2
#define SCK_BIT 1
#define SS_BIT 0

// X Y Z digipot channels to stepper driver mapping
#define DIGIPOT_CHANNELS { 4,5,3 }
#ifndef DIGIPOT_MOTOR_CURRENT
#define DIGIPOT_MOTOR_CURRENT { 135,135,135 } // Values 0-255
#endif
#endif

#ifdef CPU_MAP_2560_RAMPS_BOARD // (Arduino Mega 2560) with Ramps 1.4 Board
Expand Down
66 changes: 66 additions & 0 deletions grbl/current_control.c
@@ -0,0 +1,66 @@
/*
current_control.c - methods for setting DigiPots over SPI
Part of Grbl

Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC

Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Grbl is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
*/

#include "current_control.h"
#include "grbl.h"

#ifdef HAS_DIGIPOTS

void current_init()
{
static const uint8_t digipot_motor_current[] = DIGIPOT_MOTOR_CURRENT;
// Set the SS pin to high
SPI_DDR |= (1<<SS_BIT);

// Set DIGIPOTSS_PIN as output
DIGIPOTSS_DDR |= 1<<DIGIPOTSS_BIT;
// Set MOSI, SCK as Output
SPI_DDR |= (1<<MOSI_BIT)|(1<<SCK_BIT);

// Initialize SPI as master
SPCR = (1<<SPE)|(1<<MSTR);

uint8_t i;
for (i = 0; i < N_AXIS; i++) {
set_current(i, digipot_motor_current[i]);
}
}

inline static uint8_t spi_transfer(uint8_t data)
{
SPDR = data;
while (!(SPSR & (1<<SPIF))); // wait
return SPDR;
}

void set_current(uint8_t motor, uint8_t value)
{
const uint8_t digipot_ch[] = DIGIPOT_CHANNELS;

// Take the SS pin low to select the chip
DIGIPOTSS_PORT &= ~(1<<DIGIPOTSS_BIT);
// Send the address and value via SPI
spi_transfer(digipot_ch[motor]);
spi_transfer(value);
// Take the SS pin high to de-select the chip
DIGIPOTSS_PORT |= (1<<DIGIPOTSS_BIT);
}

#endif // HAS_DIGIPOTS
24 changes: 24 additions & 0 deletions grbl/current_control.h
@@ -0,0 +1,24 @@
/*
current_control.h - methods for setting DigiPots over SPI
Part of Grbl

Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC

Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Grbl is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdint.h>

void current_init();
void set_current(uint8_t motor, uint8_t value);
3 changes: 2 additions & 1 deletion grbl/grbl.h
Expand Up @@ -41,10 +41,10 @@
// Define the Grbl system include files. NOTE: Do not alter organization.
#include "config.h"
#include "nuts_bolts.h"
#include "cpu_map.h"
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I needed to move this up so that cpu_map.h got processed before settings.h so that settings.h could know if HAS_DIGIPOTS was defined

#include "settings.h"
#include "system.h"
#include "defaults.h"
#include "cpu_map.h"
#include "planner.h"
#include "coolant_control.h"
#include "eeprom.h"
Expand All @@ -61,6 +61,7 @@
#include "stepper.h"
#include "jog.h"
#include "sleep.h"
#include "current_control.h"

// ---------------------------------------------------------------------------------------
// COMPILE-TIME ERROR CHECKING OF DEFINE VALUES:
Expand Down
3 changes: 3 additions & 0 deletions grbl/main.c
Expand Up @@ -41,6 +41,9 @@ int main(void)
// Initialize system upon power-up.
serial_init(); // Setup serial baud rate and interrupts
settings_init(); // Load Grbl settings from EEPROM
#ifdef HAS_DIGIPOTS
current_init(); // Configure stepper driver current
#endif // HAS_DIGIPOTS
stepper_init(); // Configure stepper pins and interrupt timers
system_init(); // Configure pinout pins and pin-change interrupt

Expand Down
3 changes: 3 additions & 0 deletions grbl/report.c
Expand Up @@ -214,6 +214,9 @@ void report_grbl_settings() {
case 1: report_util_float_setting(val+idx,settings.max_rate[idx],N_DECIMAL_SETTINGVALUE); break;
case 2: report_util_float_setting(val+idx,settings.acceleration[idx]/(60*60),N_DECIMAL_SETTINGVALUE); break;
case 3: report_util_float_setting(val+idx,-settings.max_travel[idx],N_DECIMAL_SETTINGVALUE); break;
#ifdef HAS_DIGIPOTS
case 4: report_util_float_setting(val+idx,settings.current[idx],N_DECIMAL_SETTINGVALUE); break;
#endif // HAS_DIGIPOTS
}
}
val += AXIS_SETTINGS_INCREMENT;
Expand Down
14 changes: 13 additions & 1 deletion grbl/settings.c
Expand Up @@ -57,7 +57,13 @@ const __flash settings_t defaults = {\
.acceleration[Z_AXIS] = DEFAULT_Z_ACCELERATION,
.max_travel[X_AXIS] = (-DEFAULT_X_MAX_TRAVEL),
.max_travel[Y_AXIS] = (-DEFAULT_Y_MAX_TRAVEL),
.max_travel[Z_AXIS] = (-DEFAULT_Z_MAX_TRAVEL)};
.max_travel[Z_AXIS] = (-DEFAULT_Z_MAX_TRAVEL),
#ifdef HAS_DIGIPOTS
.current[X_AXIS] = DEFAULT_X_CURRENT,
.current[Y_AXIS] = DEFAULT_Y_CURRENT,
.current[Z_AXIS] = DEFAULT_Z_CURRENT,
#endif // HAS_DIGIPOTS
};


// Method to store startup lines into EEPROM
Expand Down Expand Up @@ -215,6 +221,12 @@ uint8_t settings_store_global_setting(uint8_t parameter, float value) {
break;
case 2: settings.acceleration[parameter] = value*60*60; break; // Convert to mm/min^2 for grbl internal use.
case 3: settings.max_travel[parameter] = -value; break; // Store as negative for grbl internal use.
#ifdef HAS_DIGIPOTS
case 4:
settings.current[parameter] = value;
set_current(parameter, settings.current[parameter]);
break;
#endif // HAS_DIGIPOTS
}
break; // Exit while-loop after setting has been configured and proceed to the EEPROM write call.
} else {
Expand Down
7 changes: 7 additions & 0 deletions grbl/settings.h
Expand Up @@ -79,7 +79,11 @@
// #define SETTING_INDEX_G92 N_COORDINATE_SYSTEM+2 // Coordinate offset (G92.2,G92.3 not supported)

// Define Grbl axis settings numbering scheme. Starts at START_VAL, every INCREMENT, over N_SETTINGS.
#ifdef HAS_DIGIPOTS
#define AXIS_N_SETTINGS 5
#else
#define AXIS_N_SETTINGS 4
#endif // HAS_DIGIPOTS
#define AXIS_SETTINGS_START_VAL 100 // NOTE: Reserving settings values >= 100 for axis settings. Up to 255.
#define AXIS_SETTINGS_INCREMENT 10 // Must be greater than the number of axis settings

Expand All @@ -90,6 +94,9 @@ typedef struct {
float max_rate[N_AXIS];
float acceleration[N_AXIS];
float max_travel[N_AXIS];
#ifdef HAS_DIGIPOTS
float current[N_AXIS];
#endif // HAS_DIGIPOTS

// Remaining Grbl settings
uint8_t pulse_microseconds;
Expand Down