Go Down

Topic: Can anyone help me get a couple of stepper motors to run from this shield? (Read 179 times) previous topic - next topic

matelot

I am trying to find a sketch that will allow me to experiment with GRBL to run stepper motors with this shield.

I have uploaded the sketch 'grblUpload' from the library software I downloaded called grbl-master, this one
Code: [Select]
/***********************************************************************
This sketch compiles and uploads Grbl to your 328p-based Arduino!

To use:
- First make sure you have imported Grbl source code into your Arduino
  IDE. There are details on our Github website on how to do this.

- Select your Arduino Board and Serial Port in the Tools drop-down menu.
  NOTE: Grbl only officially supports 328p-based Arduinos, like the Uno.
  Using other boards will likely not work!

- Then just click 'Upload'. That's it!

For advanced users:
  If you'd like to see what else Grbl can do, there are some additional
  options for customization and features you can enable or disable.
  Navigate your file system to where the Arduino IDE has stored the Grbl
  source code files, open the 'config.h' file in your favorite text
  editor. Inside are dozens of feature descriptions and #defines. Simply
  comment or uncomment the #defines or alter their assigned values, save
  your changes, and then click 'Upload' here.

Copyright (c) 2015 Sungeun K. Jeon
Released under the MIT-license. See license.txt for details.
***********************************************************************/

#include <grbl.h>

// Do not alter this file!

and using the universal gcode sender I can jog the motors. I can also put sinple instructions into the grbl sender such as y-5 and the y motor moves.
I would like to be able to build a set of instructions to set up and drive the motors using GRBL so I can learn how it works.

I can load this sketch that looks as if it will do this
Code: [Select]
// Arduino G-code Interpreter
// v1.0 Carlos guilarte y diego colonnello...
// Modificado para manejar tres ejes en un cnc chimbo... jejeje

#include <HardwareSerial.h>

//our command string
#define COMMAND_SIZE 128
char palabra[COMMAND_SIZE];
byte serial_count;
int no_data = 0;

void setup()
{
//Do startup stuff here
Serial.begin(115200);
Serial.println("start");

//other initialization.
init_process_string();
init_steppers();

}

void loop()
{
char c;

//keep it hot!


//read in characters if we got them.
if (Serial.available() > 0)
{
c = Serial.read();
no_data = 0;

//newlines are ends of commands.
if (c != '\n')
{
palabra[serial_count] = c;
serial_count++;
}
}
//mark no data.
else
{
no_data++;
delayMicroseconds(100);
}

//if theres a pause or we got a real command, do it
if (serial_count && (c == '\n' || no_data > 100))
{
//process our command!
process_string(palabra, serial_count);

//clear command.
init_process_string();
}

//no data?  turn off steppers
if (no_data > 1000)
  disable_steppers();
}

With this sketch in the arduino, if I open the monitor I get
start
if I put an instruction in like y-5 I get a pause then the word
ok
but nothing happens to the motors?
What I would like to get hold of is a sketch that allows me to input a list of instructions that can be saved within the sketch so I don't lose them every time I send them to the shield and that activates the motors when I run it.
Is there such a thing?

matelot

I have also found this sketch in the same folder? not in its own folder.
Code: [Select]
//init our variables
long max_delta;
long x_counter;
long y_counter;
long z_counter;
bool x_can_step;
bool y_can_step;
bool z_can_step;
int milli_delay;

void init_steppers()
{
//turn them off to start.
disable_steppers();

//init our points.
  current_unitsx = 0.0;
  current_unitsy = 0.0;
  current_unitsz = 0.0;
  target_unitsx = 0.0;
  target_unitsy = 0.0;
  target_unitsz = 0.0;

pinMode(X_STEP_PIN, OUTPUT);
pinMode(X_DIR_PIN, OUTPUT);
pinMode(X_ENABLE_PIN, OUTPUT);
pinMode(X_MIN_PIN, INPUT);
pinMode(X_MAX_PIN, INPUT);

pinMode(Y_STEP_PIN, OUTPUT);
pinMode(Y_DIR_PIN, OUTPUT);
pinMode(Y_ENABLE_PIN, OUTPUT);
pinMode(Y_MIN_PIN, INPUT);
pinMode(Y_MAX_PIN, INPUT);

pinMode(Z_STEP_PIN, OUTPUT);
pinMode(Z_DIR_PIN, OUTPUT);
pinMode(Z_ENABLE_PIN, OUTPUT);
pinMode(Z_MIN_PIN, INPUT);
pinMode(Z_MAX_PIN, INPUT);

//figure our stuff.
calculate_deltas();
}

void dda_move(long micro_delay)
{
//enable our steppers
digitalWrite(X_ENABLE_PIN, HIGH);
digitalWrite(Y_ENABLE_PIN, HIGH);
digitalWrite(Z_ENABLE_PIN, HIGH);

//figure out our deltas
max_delta = max(delta_steps.x, delta_steps.y);
max_delta = max(delta_steps.z, max_delta);

//init stuff.
long x_counter = -max_delta/2;
long y_counter = -max_delta/2;
long z_counter = -max_delta/2;

//our step flags
bool x_can_step = 0;
bool y_can_step = 0;
bool z_can_step = 0;

if (micro_delay >= 16383)
milli_delay = micro_delay / 1000;
else
milli_delay = 0;

//do our DDA line!
do
{
x_can_step = can_step(X_MIN_PIN, X_MAX_PIN, current_steps.x, target_steps.x, x_direction);
y_can_step = can_step(Y_MIN_PIN, Y_MAX_PIN, current_steps.y, target_steps.y, y_direction);
z_can_step = can_step(Z_MIN_PIN, Z_MAX_PIN, current_steps.z, target_steps.z, z_direction);

if (x_can_step)
{
x_counter += delta_steps.x;

if (x_counter > 0)
{
do_step(X_STEP_PIN, X_DIR_PIN, x_direction);
x_counter -= max_delta;

if (x_direction)
current_steps.x++;
else
current_steps.x--;
}
}

if (y_can_step)
{
y_counter += delta_steps.y;

if (y_counter > 0)
{
do_step(Y_STEP_PIN, Y_DIR_PIN, y_direction);
y_counter -= max_delta;

if (y_direction)
current_steps.y++;
else
current_steps.y--;
}
}

if (z_can_step)
{
z_counter += delta_steps.z;

if (z_counter > 0)
{
do_step(Z_STEP_PIN, Z_DIR_PIN, z_direction);
z_counter -= max_delta;

if (z_direction)
current_steps.z++;
else
current_steps.z--;
}
}



//wait for next step.
if (milli_delay > 0)
delay(milli_delay);
else
delayMicroseconds(micro_delay);
}
while (x_can_step || y_can_step || z_can_step);

//set our points to be the same
current_units.x = target_units.x;
current_units.y = target_units.y;
current_units.z = target_units.z;
calculate_deltas();
}

bool can_step(byte min_pin, byte max_pin, long current, long target, byte direction)
{
//stop us if we're on target
if (target == current)
return false;
//stop us if we're at home and still going
else if (read_switch(min_pin) && !direction)
return false;
//stop us if we're at max and still going
else if (read_switch(max_pin) && direction)
return false;

//default to being able to step
return true;
}

void do_step(byte pinA, byte pinB, byte dir)
{
        switch (dir << 2 | digitalRead(pinA) << 1 | digitalRead(pinB)) {
            case 0: /* 0 00 -> 10 */
            case 5: /* 1 01 -> 11 */
                digitalWrite(pinA, HIGH);
                break;
            case 1: /* 0 01 -> 00 */
            case 7: /* 1 11 -> 10 */
                digitalWrite(pinB, LOW);
                break;
            case 2: /* 0 10 -> 11 */
            case 4: /* 1 00 -> 01 */   
                digitalWrite(pinB, HIGH);
                break;
            case 3: /* 0 11 -> 01 */
            case 6: /* 1 10 -> 00 */
                digitalWrite(pinA, LOW);
                break;
        }
delayMicroseconds(5);
}


bool read_switch(byte pin)
{
//dual read as crude debounce

if ( SENSORS_INVERTING )
return !digitalRead(pin) && !digitalRead(pin);
else
return digitalRead(pin) && digitalRead(pin);
}

long to_steps(float steps_per_unit, float units)
{
return steps_per_unit * units;
}

void set_target(float x, float y, float z)
{
target_units.x = x;
target_units.y = y;
target_units.z = z;

calculate_deltas();
}

void set_position(float x, float y, float z)
{
current_units.x = x;
current_units.y = y;
current_units.z = z;

calculate_deltas();
}

void calculate_deltas()
{
//figure our deltas.
delta_units.x = abs(target_units.x - current_units.x);
delta_units.y = abs(target_units.y - current_units.y);
delta_units.z = abs(target_units.z - current_units.z);

//set our steps current, target, and delta
current_steps.x = to_steps(x_units, current_units.x);
current_steps.y = to_steps(y_units, current_units.y);
current_steps.z = to_steps(z_units, current_units.z);

target_steps.x = to_steps(x_units, target_units.x);
target_steps.y = to_steps(y_units, target_units.y);
target_steps.z = to_steps(z_units, target_units.z);

delta_steps.x = abs(target_steps.x - current_steps.x);
delta_steps.y = abs(target_steps.y - current_steps.y);
delta_steps.z = abs(target_steps.z - current_steps.z);

//what is our direction
x_direction = (target_units.x >= current_units.x);
y_direction = (target_units.y >= current_units.y);
z_direction = (target_units.z >= current_units.z);

//set our direction pins as well
digitalWrite(X_DIR_PIN, x_direction);
digitalWrite(Y_DIR_PIN, y_direction);
digitalWrite(Z_DIR_PIN, z_direction);
}


long calculate_feedrate_delay(float feedrate)
{
//how long is our line length?
float distance = sqrt(delta_units.x*delta_units.x + delta_units.y*delta_units.y + delta_units.z*delta_units.z);
long master_steps = 0;

//find the dominant axis.
if (delta_steps.x > delta_steps.y)
{
if (delta_steps.z > delta_steps.x)
master_steps = delta_steps.z;
else
master_steps = delta_steps.x;
}
else
{
if (delta_steps.z > delta_steps.y)
master_steps = delta_steps.z;
else
master_steps = delta_steps.y;
}

//calculate delay between steps in microseconds.  this is sort of tricky, but not too bad.
//the formula has been condensed to save space.  here it is in english:
// distance / feedrate * 60000000.0 = move duration in microseconds
// move duration / master_steps = time between steps for master axis.

return ((distance * 600000000.0) / feedrate) / master_steps;
}

long getMaxSpeed()
{
if (delta_steps.z > 0)
return calculate_feedrate_delay(FAST_Z_FEEDRATE);
else
return calculate_feedrate_delay(FAST_XY_FEEDRATE);
}

void disable_steppers()
{
//enable our steppers
digitalWrite(X_ENABLE_PIN, LOW);
digitalWrite(Y_ENABLE_PIN, LOW);
digitalWrite(Z_ENABLE_PIN, LOW);
}

When I gave it its own folder I was able to load it into the IDE but when I tried to compile it I got a lot of
 'XXX was not declared in this scope.'
I started to declare them but there are so many I am wondering if this is intentional and it is used in some other way?
Has anyone had any experience with these programs and can someone help me get some way of sending GRBL to the shield that I can build from.

I can open a txt reader, build a program and then load it into the gcode sender but it is very long winded.

Robin2

I am trying to find a sketch that will allow me to experiment with GRBL to run stepper motors with this shield.
I don't really understand your question.

In Arduino-speak "sketch" means "program" and GRBL is a program that you upload to an Arduino. When you have GRBL uploaded to your Arduino you need to send GCode to it. I believe people commonly use a PC program called gcodeSender to do that,

If what I have said does not make sense to you then please explain more clearly what you are trying to do.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

matelot

The universal gcode sender is nearly there.
I can't find any way of saving what I put into the sender. I can build a txt file using word or the notepad and that allows me to build a list of instructions but it is much slower than using the ide to experiment with the commands of an arduino sketch.
I was looking for something similar to the universal gcode sender that would allow me to keep and rerun the instructions without having to keep saving them from the notepad as txt files and loading them into the sender.

matelot

There is a 'save' button so I am assuming there is some way of building a file but I can't find one?

Robin2

The universal gcode sender is nearly there.
I can't find any way of saving what I put into the sender. I can build a txt file using word or the notepad and that allows me to build a list of instructions but it is much slower than using the ide to experiment with the commands of an arduino sketch.
This is still very confusing. There is a lot of stuff in your head that you are not telling us.

What sort of experiment do you want to do?

If you just want some means to send a single line of Gcode to the Arduino you could always write a PC program that allows you to do that. But you would need to research the interface that GRBL requires. Because of the complexity of controlling a CNC machine reliably GRBL probably has a protocol that must be followed when Gcode is sent to it.

To be honest I can't see how it takes much effort to type some some stuff into a file with an editor, save the file and then using a different program send the file to GRBL.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

matelot

I have a small number of stepper motors taken from old printers. Some work fine on the universal gcode sender jog, some sound rough and others just judder.
It looks as if the settings are wrong for some of them.
I can alter the settings by adding the alterations in a txt file and then test the motors but if the change is marginal then it is hard to see it when it takes five minutes to alter the program.
With the IDE and an arduino you can do a minor alteration to the program and quickly see the result.
I was just hoping there was some way of doing it in a similar fashion with gcode.
I was hoping if I could send gcode within an arduino program then I could add switches and change setting back and forth with switches to see differences.
I am only playing and learning about gcode and stepper motors.

Robin2

I was hoping if I could send gcode within an arduino program then I could add switches and change setting back and forth with switches to see differences.
I am still lost.

Are you trying to say that you have a second Arduino (ArduinoB) and you would like to use it to send GCode to the Arduino that is running the GRBL program (ArduinoA) rather than sending the GCode from your PC to ArduinoA.

Yes you could write a program for a second Arduino to send GCode. But, as I said earlier, you would need to know the protocols required by GRBL.

However I can't see how changing a program on ArduinoB would be any quicker than editing a GCode file and sending it to ArduinoA with your PC.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up