Fixed a number of bugs caused by using abs() on floats and long ints. Added support for selectively inverting bits of the stepping port. Debugged, optimized and cleaned up timing code for the step-pulses.
This commit is contained in:
parent
6ac3b3f2e6
commit
a42c03601d
2
Makefile
2
Makefile
@ -35,7 +35,7 @@ FUSES = -U hfuse:w:0xd9:m -U lfuse:w:0x24:m
|
|||||||
|
|
||||||
# Tune the lines below only if you know what you are doing:
|
# Tune the lines below only if you know what you are doing:
|
||||||
|
|
||||||
AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE) -B 10
|
AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE) -B 10 -F
|
||||||
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE) -I.
|
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE) -I.
|
||||||
|
|
||||||
# symbolic targets:
|
# symbolic targets:
|
||||||
|
50
config.h
50
config.h
@ -23,11 +23,13 @@
|
|||||||
|
|
||||||
#define VERSION "0.0"
|
#define VERSION "0.0"
|
||||||
|
|
||||||
#define X_STEPS_PER_MM 128.0
|
#define X_STEPS_PER_MM 94.488188976378
|
||||||
#define Y_STEPS_PER_MM 128.0
|
#define Y_STEPS_PER_MM 94.488188976378
|
||||||
#define Z_STEPS_PER_MM 128.0
|
#define Z_STEPS_PER_MM 94.488188976378
|
||||||
|
|
||||||
#define INCHES_PER_MM 25.4
|
#define STEP_PULSE_MICROSECONDS 30
|
||||||
|
|
||||||
|
#define INCHES_PER_MM (1.0/25.4)
|
||||||
#define X_STEPS_PER_INCH X_STEPS_PER_MM*INCHES_PER_MM
|
#define X_STEPS_PER_INCH X_STEPS_PER_MM*INCHES_PER_MM
|
||||||
#define Y_STEPS_PER_INCH Y_STEPS_PER_MM*INCHES_PER_MM
|
#define Y_STEPS_PER_INCH Y_STEPS_PER_MM*INCHES_PER_MM
|
||||||
#define Z_STEPS_PER_INCH Z_STEPS_PER_MM*INCHES_PER_MM
|
#define Z_STEPS_PER_INCH Z_STEPS_PER_MM*INCHES_PER_MM
|
||||||
@ -35,12 +37,12 @@
|
|||||||
#define RAPID_FEEDRATE 960.0 // in millimeters per minute
|
#define RAPID_FEEDRATE 960.0 // in millimeters per minute
|
||||||
#define DEFAULT_FEEDRATE 960.0
|
#define DEFAULT_FEEDRATE 960.0
|
||||||
|
|
||||||
#define STEPPERS_ENABLE_DDR DDRB
|
#define STEPPERS_ENABLE_DDR DDRD
|
||||||
#define STEPPERS_ENABLE_PORT PORTB
|
#define STEPPERS_ENABLE_PORT PORTD
|
||||||
#define STEPPERS_ENABLE_BIT 6
|
#define STEPPERS_ENABLE_BIT 2
|
||||||
|
|
||||||
#define STEPPING_DDR DDRB
|
#define STEPPING_DDR DDRC
|
||||||
#define STEPPING_PORT PORTB
|
#define STEPPING_PORT PORTC
|
||||||
#define X_STEP_BIT 0
|
#define X_STEP_BIT 0
|
||||||
#define Y_STEP_BIT 1
|
#define Y_STEP_BIT 1
|
||||||
#define Z_STEP_BIT 2
|
#define Z_STEP_BIT 2
|
||||||
@ -48,19 +50,20 @@
|
|||||||
#define Y_DIRECTION_BIT 4
|
#define Y_DIRECTION_BIT 4
|
||||||
#define Z_DIRECTION_BIT 5
|
#define Z_DIRECTION_BIT 5
|
||||||
|
|
||||||
#define LIMIT_DDR DDRC
|
|
||||||
#define LIMIT_PORT PORTC
|
|
||||||
#define X_LIMIT_BIT 0
|
|
||||||
#define Y_LIMIT_BIT 1
|
|
||||||
#define Z_LIMIT_BIT 2
|
|
||||||
|
|
||||||
#define SPINDLE_ENABLE_DDR DDRC
|
#define LIMIT_DDR DDRD
|
||||||
#define SPINDLE_ENABLE_PORT PORTC
|
#define LIMIT_PORT PORTD
|
||||||
#define SPINDLE_ENABLE_BIT 3
|
#define X_LIMIT_BIT 3
|
||||||
|
#define Y_LIMIT_BIT 4
|
||||||
|
#define Z_LIMIT_BIT 5
|
||||||
|
|
||||||
#define SPINDLE_DIRECTION_DDR DDRC
|
#define SPINDLE_ENABLE_DDR DDRD
|
||||||
#define SPINDLE_DIRECTION_PORT PORTC
|
#define SPINDLE_ENABLE_PORT PORTD
|
||||||
#define SPINDLE_DIRECTION_BIT 4
|
#define SPINDLE_ENABLE_BIT 6
|
||||||
|
|
||||||
|
#define SPINDLE_DIRECTION_DDR DDRD
|
||||||
|
#define SPINDLE_DIRECTION_PORT PORTD
|
||||||
|
#define SPINDLE_DIRECTION_BIT 7
|
||||||
|
|
||||||
#define BAUD_RATE 9600
|
#define BAUD_RATE 9600
|
||||||
|
|
||||||
@ -69,4 +72,11 @@
|
|||||||
#define STEPPING_MASK (STEP_MASK | DIRECTION_MASK)
|
#define STEPPING_MASK (STEP_MASK | DIRECTION_MASK)
|
||||||
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT))
|
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT))
|
||||||
|
|
||||||
|
// Use this line for default operation (step-pulses high)
|
||||||
|
#define STEPPING_INVERT_MASK 0
|
||||||
|
// Uncomment this line for inverted stepping (step-pulses low, rest high)
|
||||||
|
// #define STEPPING_INVERT_MASK (STEP_MASK)
|
||||||
|
// Or bake your own like this adding any step-bits or directions you want to invert:
|
||||||
|
// #define STEPPING_INVERT_MASK (STEP_MASK | (1<<Z_DIRECTION_BIT))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
4
gcode.c
4
gcode.c
@ -118,7 +118,7 @@ void gc_init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline float to_millimeters(double value) {
|
inline float to_millimeters(double value) {
|
||||||
return(gc.inches_mode ? value * INCHES_PER_MM : value);
|
return(gc.inches_mode ? (value * INCHES_PER_MM) : value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ uint8_t gc_execute_line(char *line) {
|
|||||||
|
|
||||||
double p = 0, r = 0;
|
double p = 0, r = 0;
|
||||||
int int_value;
|
int int_value;
|
||||||
|
|
||||||
clear_vector(target);
|
clear_vector(target);
|
||||||
clear_vector(offset);
|
clear_vector(offset);
|
||||||
|
|
||||||
|
2670
gcode/braid_two_decimals.gcode
Normal file
2670
gcode/braid_two_decimals.gcode
Normal file
File diff suppressed because it is too large
Load Diff
1674
gcode/miller.gcode
Normal file
1674
gcode/miller.gcode
Normal file
File diff suppressed because it is too large
Load Diff
@ -54,7 +54,7 @@ double theta(double x, double y)
|
|||||||
|
|
||||||
// Find the quadrant of the coordinate
|
// Find the quadrant of the coordinate
|
||||||
int quadrant_of_the_circle(int32_t x, int32_t y) {
|
int quadrant_of_the_circle(int32_t x, int32_t y) {
|
||||||
if (abs(x)<abs(y)){
|
if (labs(x)<labs(y)){
|
||||||
if (y>0) {
|
if (y>0) {
|
||||||
return(0);
|
return(0);
|
||||||
} else {
|
} else {
|
||||||
|
4
main.c
4
main.c
@ -33,12 +33,14 @@
|
|||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
beginSerial(BAUD_RATE);
|
beginSerial(BAUD_RATE);
|
||||||
st_init();
|
st_init(); // initialize the stepper subsystem
|
||||||
mc_init(); // initialize motion control subsystem
|
mc_init(); // initialize motion control subsystem
|
||||||
spindle_init(); // initialize spindle controller
|
spindle_init(); // initialize spindle controller
|
||||||
gc_init(); // initialize gcode-parser
|
gc_init(); // initialize gcode-parser
|
||||||
sp_init(); // initialize the serial protocol
|
sp_init(); // initialize the serial protocol
|
||||||
|
|
||||||
|
st_start(); // start the stepper subsystem
|
||||||
|
|
||||||
for(;;){
|
for(;;){
|
||||||
sleep_mode();
|
sleep_mode();
|
||||||
sp_process(); // process the serial protocol
|
sp_process(); // process the serial protocol
|
||||||
|
@ -93,10 +93,10 @@ void mc_line(double x, double y, double z, float feed_rate, int invert_feed_rate
|
|||||||
|
|
||||||
target[X_AXIS] = round(x*X_STEPS_PER_MM);
|
target[X_AXIS] = round(x*X_STEPS_PER_MM);
|
||||||
target[Y_AXIS] = round(y*Y_STEPS_PER_MM);
|
target[Y_AXIS] = round(y*Y_STEPS_PER_MM);
|
||||||
target[Z_AXIS] = round(z*Z_STEPS_PER_MM);
|
target[Z_AXIS] = round(z*Z_STEPS_PER_MM);
|
||||||
// Determine direction and travel magnitude for each axis
|
// Determine direction and travel magnitude for each axis
|
||||||
for(axis = X_AXIS; axis <= Z_AXIS; axis++) {
|
for(axis = X_AXIS; axis <= Z_AXIS; axis++) {
|
||||||
step_count[axis] = abs(target[axis] - position[axis]);
|
step_count[axis] = labs(target[axis] - position[axis]);
|
||||||
direction[axis] = signof(target[axis] - position[axis]);
|
direction[axis] = signof(target[axis] - position[axis]);
|
||||||
}
|
}
|
||||||
// Find the magnitude of the axis with the longest travel
|
// Find the magnitude of the axis with the longest travel
|
||||||
@ -138,7 +138,9 @@ void mc_line(double x, double y, double z, float feed_rate, int invert_feed_rate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(step_bits) { step_steppers(step_bits); }
|
if(step_bits) {
|
||||||
|
step_steppers(step_bits);
|
||||||
|
}
|
||||||
} while (step_bits);
|
} while (step_bits);
|
||||||
mode = MC_MODE_AT_REST;
|
mode = MC_MODE_AT_REST;
|
||||||
}
|
}
|
||||||
@ -210,11 +212,11 @@ void mc_arc(double theta, double angular_travel, double radius, double linear_tr
|
|||||||
int target_quadrant = quadrant_of_the_circle(target_x, target_y);
|
int target_quadrant = quadrant_of_the_circle(target_x, target_y);
|
||||||
uint32_t arc_steps=0;
|
uint32_t arc_steps=0;
|
||||||
// Will this whole arc take place within the same quadrant?
|
// Will this whole arc take place within the same quadrant?
|
||||||
if (start_quadrant == target_quadrant && (abs(angular_travel) <= (M_PI/2))) {
|
if (start_quadrant == target_quadrant && (fabs(angular_travel) <= (M_PI/2))) {
|
||||||
if(quadrant_horizontal(start_quadrant)) { // a horizontal quadrant where x will be the primary direction
|
if(quadrant_horizontal(start_quadrant)) { // a horizontal quadrant where x will be the primary direction
|
||||||
arc_steps = abs(target_x-start_x);
|
arc_steps = labs(target_x-start_x);
|
||||||
} else { // a vertical quadrant where y will be the primary direction
|
} else { // a vertical quadrant where y will be the primary direction
|
||||||
arc_steps = abs(target_y-start_y);
|
arc_steps = labs(target_y-start_y);
|
||||||
}
|
}
|
||||||
} else { // the start and target points are in different quadrants
|
} else { // the start and target points are in different quadrants
|
||||||
// Lets estimate the amount of steps along half a quadrant
|
// Lets estimate the amount of steps along half a quadrant
|
||||||
@ -234,7 +236,7 @@ void mc_arc(double theta, double angular_travel, double radius, double linear_tr
|
|||||||
|
|
||||||
// Set up the linear interpolation of the "depth" axis -----------------------------------------------------
|
// Set up the linear interpolation of the "depth" axis -----------------------------------------------------
|
||||||
|
|
||||||
int32_t linear_steps = abs(st_millimeters_to_steps(linear_travel, axis_linear));
|
int32_t linear_steps = labs(st_millimeters_to_steps(linear_travel, axis_linear));
|
||||||
int linear_direction = signof(linear_travel);
|
int linear_direction = signof(linear_travel);
|
||||||
// The number of steppings needed to trace this motion is equal to the motion that require the maximum
|
// The number of steppings needed to trace this motion is equal to the motion that require the maximum
|
||||||
// amount of steps: the arc or the line:
|
// amount of steps: the arc or the line:
|
||||||
@ -247,7 +249,7 @@ void mc_arc(double theta, double angular_travel, double radius, double linear_tr
|
|||||||
// Calculate feed rate -------------------------------------------------------------------------------------
|
// Calculate feed rate -------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// We then calculate the millimeters of helical travel
|
// We then calculate the millimeters of helical travel
|
||||||
double millimeters_of_travel = hypot(angular_travel*radius, abs(linear_travel));
|
double millimeters_of_travel = hypot(angular_travel*radius, labs(linear_travel));
|
||||||
// Then we calculate the microseconds between each step as if we will trace the full circle.
|
// Then we calculate the microseconds between each step as if we will trace the full circle.
|
||||||
// It doesn't matter what fraction of the circle we are actually going to trace. The pace is the same.
|
// It doesn't matter what fraction of the circle we are actually going to trace. The pace is the same.
|
||||||
compute_and_set_step_pace(feed_rate, millimeters_of_travel, maximum_steps, invert_feed_rate);
|
compute_and_set_step_pace(feed_rate, millimeters_of_travel, maximum_steps, invert_feed_rate);
|
||||||
@ -288,12 +290,12 @@ void mc_arc(double theta, double angular_travel, double radius, double linear_tr
|
|||||||
direction[axis_1] = dx;
|
direction[axis_1] = dx;
|
||||||
direction[axis_2] = dy;
|
direction[axis_2] = dy;
|
||||||
// Check which axis will be "major" for this stepping
|
// Check which axis will be "major" for this stepping
|
||||||
if (abs(x)<abs(y)) {
|
if (labs(x)<labs(y)) {
|
||||||
// X is major: Step arc horizontally
|
// X is major: Step arc horizontally
|
||||||
error += 1 + 2*x * dx;
|
error += 1 + 2*x * dx;
|
||||||
x+=dx;
|
x+=dx;
|
||||||
diagonal_error = error + 1 + 2*y*dy;
|
diagonal_error = error + 1 + 2*y*dy;
|
||||||
if(abs(error) >= abs(diagonal_error)) {
|
if(labs(error) >= labs(diagonal_error)) {
|
||||||
y += dy;
|
y += dy;
|
||||||
error = diagonal_error;
|
error = diagonal_error;
|
||||||
step_bits |= diagonal_bits; // step diagonal
|
step_bits |= diagonal_bits; // step diagonal
|
||||||
@ -305,7 +307,7 @@ void mc_arc(double theta, double angular_travel, double radius, double linear_tr
|
|||||||
error += 1 + 2*y * dy;
|
error += 1 + 2*y * dy;
|
||||||
y+=dy;
|
y+=dy;
|
||||||
diagonal_error = error + 1 + 2*x * dx;
|
diagonal_error = error + 1 + 2*x * dx;
|
||||||
if(abs(error) >= abs(diagonal_error)) {
|
if(labs(error) >= labs(diagonal_error)) {
|
||||||
x += dx;
|
x += dx;
|
||||||
error = diagonal_error;
|
error = diagonal_error;
|
||||||
step_bits |= diagonal_bits; // step diagonal
|
step_bits |= diagonal_bits; // step diagonal
|
||||||
@ -362,16 +364,7 @@ void set_stepper_directions(int8_t *direction)
|
|||||||
((direction[Z_AXIS]&0x80)>>(7-Z_DIRECTION_BIT)));
|
((direction[Z_AXIS]&0x80)>>(7-Z_DIRECTION_BIT)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step enabled steppers. Enabled should be an array of three bytes. Each byte represent one
|
|
||||||
// stepper motor in the order X, Y, Z. Set the bytes of the steppers you want to step to
|
|
||||||
// 1, and the rest to 0.
|
|
||||||
inline void step_steppers(uint8_t bits)
|
inline void step_steppers(uint8_t bits)
|
||||||
{
|
{
|
||||||
st_buffer_step(direction_bits | bits);
|
st_buffer_step(direction_bits | bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step only one motor
|
|
||||||
inline void step_axis(uint8_t axis)
|
|
||||||
{
|
|
||||||
st_buffer_step(direction_bits | st_bit_for_stepper(axis));
|
|
||||||
}
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
socat -d -d READLINE /dev/tty.usbserial-A4001o6L,clocal=1,nonblock=1,cread=1,cs8,ixon=1,ixoff=1
|
socat -d -d READLINE /dev/tty.usbserial-A9007QcR,clocal=1,nonblock=1,cread=1,cs8,ixon=1,ixoff=1
|
||||||
|
|
||||||
|
@ -24,18 +24,21 @@ if ARGV.empty?
|
|||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
|
|
||||||
SerialPort.open('/dev/tty.usbserial-A4001o6L', 9600) do |sp|
|
SerialPort.open('/dev/tty.usbserial-A9007QcR', 9600) do |sp|
|
||||||
|
sp.write("\r\n\r\n");
|
||||||
|
sleep 5
|
||||||
ARGV.each do |file|
|
ARGV.each do |file|
|
||||||
puts "Processing file #{file}"
|
puts "Processing file #{file}"
|
||||||
prebuffer = $prebuffer ? 10 : 0
|
prebuffer = $prebuffer ? 7 : 0
|
||||||
File.readlines(file).each do |line|
|
File.readlines(file).each do |line|
|
||||||
next if line.strip == ''
|
next if line.strip == ''
|
||||||
puts line.strip
|
puts line.strip
|
||||||
sp.write("#{line.strip}\r\n");
|
sp.write("#{line.strip}\r\n");
|
||||||
if prebuffer == 0
|
if prebuffer == 0
|
||||||
|
sleep 0.1
|
||||||
begin
|
begin
|
||||||
result = sp.gets.strip
|
result = sp.gets.strip
|
||||||
puts result unless result == '' or result == 'ok'
|
puts "Grbl >> #{result}" unless result == '' or result == 'ok'
|
||||||
end while result != 'ok'
|
end while result != 'ok'
|
||||||
else
|
else
|
||||||
prebuffer -= 1
|
prebuffer -= 1
|
||||||
|
@ -26,9 +26,9 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "nuts_bolts.h"
|
#include "nuts_bolts.h"
|
||||||
|
|
||||||
#define BLOCK_BUFFER_SIZE 128
|
#define LINE_BUFFER_SIZE 128
|
||||||
|
|
||||||
char line[BLOCK_BUFFER_SIZE];
|
char line[LINE_BUFFER_SIZE];
|
||||||
uint8_t line_counter;
|
uint8_t line_counter;
|
||||||
|
|
||||||
void prompt() {
|
void prompt() {
|
||||||
@ -79,6 +79,9 @@ void sp_process()
|
|||||||
{
|
{
|
||||||
if((c < 32)) { // Line is complete. Then execute!
|
if((c < 32)) { // Line is complete. Then execute!
|
||||||
line[line_counter] = 0;
|
line[line_counter] = 0;
|
||||||
|
// printString("->");
|
||||||
|
// printString(line);
|
||||||
|
// printString("<-\r\n");
|
||||||
gc_execute_line(line);
|
gc_execute_line(line);
|
||||||
line_counter = 0;
|
line_counter = 0;
|
||||||
prompt();
|
prompt();
|
||||||
|
75
stepper.c
75
stepper.c
@ -25,6 +25,7 @@
|
|||||||
#include "stepper.h"
|
#include "stepper.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <util/delay.h>
|
||||||
#include "nuts_bolts.h"
|
#include "nuts_bolts.h"
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
@ -57,15 +58,14 @@ SIGNAL(SIG_OUTPUT_COMPARE1A)
|
|||||||
// This is not a step-instruction, but a pace-change-marker: change pace
|
// This is not a step-instruction, but a pace-change-marker: change pace
|
||||||
config_pace_timer(next_pace);
|
config_pace_timer(next_pace);
|
||||||
next_pace = 0;
|
next_pace = 0;
|
||||||
} else {
|
} else {
|
||||||
// Set the direction pins a nanosecond or two before you step the steppers
|
popped ^= STEPPING_INVERT_MASK;
|
||||||
|
// Set the direction pins a cuple of nanoseconds before we step the steppers
|
||||||
STEPPING_PORT = (STEPPING_PORT & ~DIRECTION_MASK) | (popped & DIRECTION_MASK);
|
STEPPING_PORT = (STEPPING_PORT & ~DIRECTION_MASK) | (popped & DIRECTION_MASK);
|
||||||
// Then pulse the stepping pins
|
// Then pulse the stepping pins
|
||||||
STEPPING_PORT = (STEPPING_PORT & ~STEP_MASK) | popped;
|
STEPPING_PORT = (STEPPING_PORT & ~STEP_MASK) | popped;
|
||||||
// Reset and start timer 2 which will reset the motor port after 5 microsecond
|
// Reset step pulse reset timer
|
||||||
TCNT2 = 0; // reset counter
|
TCNT2 = -(((STEP_PULSE_MICROSECONDS-4)*TICKS_PER_MICROSECOND)/8);
|
||||||
OCR2A = 5*TICKS_PER_MICROSECOND; // set the trigger time
|
|
||||||
TIMSK2 |= (1<<OCIE2A); // enable interrupt
|
|
||||||
}
|
}
|
||||||
// move the step buffer tail to the next instruction
|
// move the step buffer tail to the next instruction
|
||||||
step_buffer_tail = (step_buffer_tail + 1) % STEP_BUFFER_SIZE;
|
step_buffer_tail = (step_buffer_tail + 1) % STEP_BUFFER_SIZE;
|
||||||
@ -73,11 +73,11 @@ SIGNAL(SIG_OUTPUT_COMPARE1A)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This interrupt is set up by SIG_OUTPUT_COMPARE1A when it sets the motor port bits. It resets
|
// This interrupt is set up by SIG_OUTPUT_COMPARE1A when it sets the motor port bits. It resets
|
||||||
// the motor port after a short period (5us) completing one step cycle.
|
// the motor port after a short period (STEP_PULSE_MICROSECONDS) completing one step cycle.
|
||||||
SIGNAL(SIG_OUTPUT_COMPARE2A)
|
SIGNAL(SIG_OVERFLOW2)
|
||||||
{
|
{
|
||||||
STEPPING_PORT = STEPPING_PORT & ~STEP_MASK; // reset stepping pins (leave the direction pins)
|
// reset stepping pins (leave the direction pins)
|
||||||
TIMSK2 &= ~(1<<OCIE2A); // disable this timer interrupt until next time
|
STEPPING_PORT = (STEPPING_PORT & ~STEPPING_MASK) | (STEPPING_INVERT_MASK & STEPPING_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize and start the stepper motor subsystem
|
// Initialize and start the stepper motor subsystem
|
||||||
@ -85,10 +85,10 @@ void st_init()
|
|||||||
{
|
{
|
||||||
// Configure directions of interface pins
|
// Configure directions of interface pins
|
||||||
STEPPING_DDR |= STEPPING_MASK;
|
STEPPING_DDR |= STEPPING_MASK;
|
||||||
printInteger(STEPPING_DDR);
|
STEPPING_PORT = (STEPPING_PORT & ~STEPPING_MASK) | STEPPING_INVERT_MASK;
|
||||||
LIMIT_DDR &= ~(LIMIT_MASK);
|
LIMIT_DDR &= ~(LIMIT_MASK);
|
||||||
STEPPERS_ENABLE_DDR |= 1<<STEPPERS_ENABLE_BIT;
|
STEPPERS_ENABLE_DDR |= 1<<STEPPERS_ENABLE_BIT;
|
||||||
|
|
||||||
// waveform generation = 0100 = CTC
|
// waveform generation = 0100 = CTC
|
||||||
TCCR1B &= ~(1<<WGM13);
|
TCCR1B &= ~(1<<WGM13);
|
||||||
TCCR1B |= (1<<WGM12);
|
TCCR1B |= (1<<WGM12);
|
||||||
@ -101,17 +101,16 @@ void st_init()
|
|||||||
|
|
||||||
// Configure Timer 2
|
// Configure Timer 2
|
||||||
TCCR2A = 0; // Normal operation
|
TCCR2A = 0; // Normal operation
|
||||||
TCCR2B = 1<<CS20; // Full speed, no prescaler
|
TCCR2B = (1<<CS21); // Full speed, 1/8 prescaler
|
||||||
TIMSK2 = 0; // All interrupts disabled
|
TIMSK2 = 0; // All interrupts disabled
|
||||||
|
|
||||||
sei();
|
sei();
|
||||||
|
|
||||||
// start off with a mellow pace
|
// start off with a mellow pace
|
||||||
config_pace_timer(20000);
|
config_pace_timer(20000);
|
||||||
st_start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void st_buffer_step(uint8_t motor_port_bits)
|
inline void st_buffer_step(uint8_t motor_port_bits)
|
||||||
{
|
{
|
||||||
// Buffer nothing unless stepping subsystem is running
|
// Buffer nothing unless stepping subsystem is running
|
||||||
if (stepper_mode != STEPPER_MODE_RUNNING) { return; }
|
if (stepper_mode != STEPPER_MODE_RUNNING) { return; }
|
||||||
@ -119,7 +118,7 @@ void st_buffer_step(uint8_t motor_port_bits)
|
|||||||
int next_buffer_head = (step_buffer_head + 1) % STEP_BUFFER_SIZE;
|
int next_buffer_head = (step_buffer_head + 1) % STEP_BUFFER_SIZE;
|
||||||
// If the buffer is full: good! That means we are well ahead of the robot.
|
// If the buffer is full: good! That means we are well ahead of the robot.
|
||||||
// Nap until there is room for more steps.
|
// Nap until there is room for more steps.
|
||||||
while(step_buffer_tail == next_buffer_head) { sleep_mode(); }
|
while(step_buffer_tail == next_buffer_head) { sleep_mode(); }
|
||||||
// Push byte
|
// Push byte
|
||||||
step_buffer[step_buffer_head] = motor_port_bits;
|
step_buffer[step_buffer_head] = motor_port_bits;
|
||||||
step_buffer_head = next_buffer_head;
|
step_buffer_head = next_buffer_head;
|
||||||
@ -146,8 +145,10 @@ void st_flush()
|
|||||||
// Start the stepper subsystem
|
// Start the stepper subsystem
|
||||||
void st_start()
|
void st_start()
|
||||||
{
|
{
|
||||||
// Enable timer interrupt
|
// Enable timer interrupts
|
||||||
TIMSK1 |= (1<<OCIE1A);
|
TIMSK1 |= (1<<OCIE1A);
|
||||||
|
TIMSK2 |= (1<<TOIE2);
|
||||||
|
// set enable pin
|
||||||
STEPPERS_ENABLE_PORT |= 1<<STEPPERS_ENABLE_BIT;
|
STEPPERS_ENABLE_PORT |= 1<<STEPPERS_ENABLE_BIT;
|
||||||
stepper_mode = STEPPER_MODE_RUNNING;
|
stepper_mode = STEPPER_MODE_RUNNING;
|
||||||
}
|
}
|
||||||
@ -155,8 +156,12 @@ void st_start()
|
|||||||
// Execute all buffered steps, then stop the stepper subsystem
|
// Execute all buffered steps, then stop the stepper subsystem
|
||||||
inline void st_stop()
|
inline void st_stop()
|
||||||
{
|
{
|
||||||
|
// flush pending operations
|
||||||
st_synchronize();
|
st_synchronize();
|
||||||
|
// disable timer interrupts
|
||||||
TIMSK1 &= ~(1<<OCIE1A);
|
TIMSK1 &= ~(1<<OCIE1A);
|
||||||
|
TIMSK2 &= ~(1<<TOIE2);
|
||||||
|
// reset enable pin
|
||||||
STEPPERS_ENABLE_PORT &= ~(1<<STEPPERS_ENABLE_BIT);
|
STEPPERS_ENABLE_PORT &= ~(1<<STEPPERS_ENABLE_BIT);
|
||||||
stepper_mode = STEPPER_MODE_STOPPED;
|
stepper_mode = STEPPER_MODE_STOPPED;
|
||||||
}
|
}
|
||||||
@ -238,42 +243,6 @@ int check_limit_switch(int axis)
|
|||||||
return((LIMIT_PORT&mask) || (LIMIT_PORT&mask));
|
return((LIMIT_PORT&mask) || (LIMIT_PORT&mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
// void perform_go_home()
|
|
||||||
// {
|
|
||||||
// int axis;
|
|
||||||
// if(stepper_mode.home.phase == PHASE_HOME_RETURN) {
|
|
||||||
// // We are running all axes in reverse until all limit switches are tripped
|
|
||||||
// // Check all limit switches:
|
|
||||||
// for(axis=X_AXIS; axis <= Z_AXIS; axis++) {
|
|
||||||
// stepper_mode.home.away[axis] |= check_limit_switch(axis);
|
|
||||||
// }
|
|
||||||
// // Step steppers. First retract along Z-axis. Then X and Y.
|
|
||||||
// if(stepper_mode.home.away[Z_AXIS]) {
|
|
||||||
// step_axis(Z_AXIS);
|
|
||||||
// } else {
|
|
||||||
// // Check if all axes are home
|
|
||||||
// if(!(stepper_mode.home.away[X_AXIS] || stepper_mode.home.away[Y_AXIS])) {
|
|
||||||
// // All axes are home, prepare next phase: to nudge the tool carefully out of the limit switches
|
|
||||||
// memset(stepper_mode.home.direction, 1, sizeof(stepper_mode.home.direction)); // direction = [1,1,1]
|
|
||||||
// set_direction_bits(stepper_mode.home.direction);
|
|
||||||
// stepper_mode.home.phase == PHASE_HOME_NUDGE;
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// step_steppers(stepper_mode.home.away);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// for(axis=X_AXIS; axis <= Z_AXIS; axis++) {
|
|
||||||
// if(check_limit_switch(axis)) {
|
|
||||||
// step_axis(axis);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // When this code is reached it means all axes are free of their limit-switches. Complete the cycle and rest:
|
|
||||||
// clear_vector(stepper_mode.position); // By definition this is location [0, 0, 0]
|
|
||||||
// stepper_mode.mode = MODE_AT_REST;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
void st_go_home()
|
void st_go_home()
|
||||||
{
|
{
|
||||||
// Todo: Perform the homing cycle
|
// Todo: Perform the homing cycle
|
||||||
|
@ -42,7 +42,7 @@ uint8_t st_bit_for_stepper(int axis);
|
|||||||
void st_buffer_pace(uint32_t microseconds);
|
void st_buffer_pace(uint32_t microseconds);
|
||||||
|
|
||||||
// Buffer a new instruction for the steppers
|
// Buffer a new instruction for the steppers
|
||||||
void st_buffer_step(uint8_t motor_port_bits);
|
inline void st_buffer_step(uint8_t motor_port_bits);
|
||||||
|
|
||||||
// Block until all buffered steps are executed
|
// Block until all buffered steps are executed
|
||||||
void st_synchronize();
|
void st_synchronize();
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
// using a ring buffer (I think), in which rx_buffer_head is the index of the
|
// using a ring buffer (I think), in which rx_buffer_head is the index of the
|
||||||
// location to which to write the next incoming character and rx_buffer_tail
|
// location to which to write the next incoming character and rx_buffer_tail
|
||||||
// is the index of the location from which to read.
|
// is the index of the location from which to read.
|
||||||
#define RX_BUFFER_SIZE 128
|
#define RX_BUFFER_SIZE 256
|
||||||
|
|
||||||
unsigned char rx_buffer[RX_BUFFER_SIZE];
|
unsigned char rx_buffer[RX_BUFFER_SIZE];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user