menu
 
H-Grbl

Po polsku – patrz tutaj.

If You like my work, please donate by PayPal or directly.

Modified files:

 H-Grbl v1.0 – original GRBL grbl-1.1h.20190825 modified as described below.

diff_v1.0 – diff between my and original version.

Please do not copy this files on other sites.

This project is intended to run Grbl on a system based on H bridges.

Grbl is a no-compromise, high performance, low cost alternative to parallel-port-based motion control for CNC milling. It will run on a vanilla Arduino (Duemillanove / Uno) as long as it sports an Atmega 328.

Screenshot_20191107_141513

There is already such an attempt on the network, but based on Grbl version 0.7. At the time of writing this page, version 1.1h already exists. A lot of changes that are worth having in your own projects. Because I tried to make changes in the „portable” way as possible, here’s how to do it:

– First, we need to download the current version of the software from the grbl site and extract it anywhere (I assume you are using the „original” version of the driver for other projects, so the library does NOT end up in the library catalog).
– In the grbl directory we search and edit the cpu_map.h file. The purpose of modification is to „disable” the use of ports STEPPERS_DISABLE_BIT and Z_LIMIT_BIT – ports that we will use to control H-bridges. To do this, we search for the lines:

#define STEPPERS_DISABLE_BIT 0 and change it to #define STEPPERS_DISABLE_BIT 10
and
#define Z_LIMIT_BIT 3 // Uno Digital Pin 12 and change it to #define Z_LIMIT_BIT 13 // Uno Digital Pin 12
and
#define Z_LIMIT_BIT 4 // Uno Digital Pin 12 and change it to #define Z_LIMIT_BIT 14 // Uno Digital Pin 12

Generally, you have to change it to a value above 7, then arduino „modifies” the bit out of the port range.

It’s worth, but you don’t have to, change the grbl.h file:

#define GRBL_VERSION "1.1h" na #define GRBL_VERSION "1.1h for H-bridge by San Zamoyski"

…thanks to which we will have clear information from Arduino which version we are dealing with and who made it;)

And now the hardest part. Add to the stepper.c file (e.g. before the ISR function (TIMER1_COMPA_vect)):

// B (digital pin 8 to 13)
// C (analog input pins)
// D (digital pins 0 to 7)
#define STEPPER_X_A1 (0x01<<PIND2)
#define STEPPER_X_A2 (0x01<<PIND3)
#define STEPPER_X_B1 (0x01<<PIND4)
#define STEPPER_X_B2 (0x01<<PIND5)
#define STEPPER_Y_A1 (0x01<<PIND6)
#define STEPPER_Y_A2 (0x01<<PIND7)
#define STEPPER_Y_B1 (0x01<<PINB0)
#define STEPPER_Y_B2 (0x01<<PINB4)
/*#define STEPPER_Z_A1 (0x01<<PINC0)
#define STEPPER_Z_A2 (0x01<<PINC1)
#define STEPPER_Z_B1 (0x01<<PINC2)
#define STEPPER_Z_B2 (0x01<<PINC3)*/
//#define STEPPING_PORT_Z PORTC
#define STEPPING_PORT_Y0 PORTD
#define STEPPING_PORT_Y1 PORTB
#define STEPPING_PORT_X PORTD
//#define STEPPING_DDR_Z DDRC
//#define STEPPING_DDR_Y DDRD
//#define STEPPING_DDR_X DDRB
#define ALL_STEPPER_PINS_X (STEPPER_X_A1|STEPPER_X_A2|STEPPER_X_B1|STEPPER_X_B2)
#define ALL_STEPPER_PINS_Y (STEPPER_Y_A1|STEPPER_Y_A2|STEPPER_Y_B1|STEPPER_Y_B2)
//#define ALL_STEPPER_PINS_Z (STEPPER_Z_A1 |STEPPER_Z_A2|STEPPER_Z_B1|STEPPER_Z_B2)
const int stepper_pins[2][4] = {
{STEPPER_X_A1, STEPPER_X_A2, STEPPER_X_B1, STEPPER_X_B2},
{STEPPER_Y_A1, STEPPER_Y_A2, STEPPER_Y_B1, STEPPER_Y_B2},
//{STEPPER_Z_A1, STEPPER_Z_A2, STEPPER_Z_B1, STEPPER_Z_B2},
};
//void convert_step(int dirs, int steps){
void convert_step(){
static unsigned int crrnt_step_x = 0;
static unsigned int crrnt_step_y = 0;
//st.dir_outbits, st.step_outbits
if(st.step_outbits & (1<<X_STEP_BIT)) {
if(st.dir_outbits & (1<<X_DIRECTION_BIT)) {
crrnt_step_x ++;
if (crrnt_step_x >= 4)
crrnt_step_x = 0;
}
else{
if(crrnt_step_x == 0)
crrnt_step_x = 4;
crrnt_step_x -= 1;
}
switch(crrnt_step_x) {
case 0:
STEPPING_PORT_X &= ~(stepper_pins[X_AXIS][0]|stepper_pins[X_AXIS][2]);
STEPPING_PORT_X |= stepper_pins[X_AXIS][3] | stepper_pins[X_AXIS][1];
break;
case 1:
STEPPING_PORT_X &= ~(stepper_pins[X_AXIS][1] | stepper_pins[X_AXIS][2]);
STEPPING_PORT_X |= stepper_pins[X_AXIS][0] | stepper_pins[X_AXIS][3];
break;
case 2:
STEPPING_PORT_X &= ~(stepper_pins[X_AXIS][1] | stepper_pins[X_AXIS][3]);
STEPPING_PORT_X |= stepper_pins[X_AXIS][2] | stepper_pins[X_AXIS][0];
break;
case 3:
STEPPING_PORT_X &= ~(stepper_pins[X_AXIS][0] | stepper_pins[X_AXIS][3]);
STEPPING_PORT_X |= (stepper_pins[X_AXIS][1] | stepper_pins[X_AXIS][2]);
break;
return;
}
}
if(st.step_outbits & (1<<Y_STEP_BIT)) {
if(st.dir_outbits & (1<<Y_DIRECTION_BIT)) {
crrnt_step_y ++;
if (crrnt_step_y >= 4)
crrnt_step_y = 0;
}
else{
if(crrnt_step_y == 0)
crrnt_step_y = 4;
crrnt_step_y -= 1;
}
switch(crrnt_step_y) {
case 0:
STEPPING_PORT_Y0 &= ~(stepper_pins[Y_AXIS][0]);
STEPPING_PORT_Y0 |= stepper_pins[Y_AXIS][1];
STEPPING_PORT_Y1 &= ~(stepper_pins[Y_AXIS][2]);
STEPPING_PORT_Y1 |= stepper_pins[Y_AXIS][3];
break;
case 1:
STEPPING_PORT_Y0 &= ~(stepper_pins[Y_AXIS][1]);
STEPPING_PORT_Y0 |= stepper_pins[Y_AXIS][0];
STEPPING_PORT_Y1 &= ~(stepper_pins[Y_AXIS][2]);
STEPPING_PORT_Y1 |= stepper_pins[Y_AXIS][3];
break;
case 2:
STEPPING_PORT_Y0 &= ~(stepper_pins[Y_AXIS][1]);
STEPPING_PORT_Y0 |= stepper_pins[Y_AXIS][0];
STEPPING_PORT_Y1 &= ~(stepper_pins[Y_AXIS][3]);
STEPPING_PORT_Y1 |= stepper_pins[Y_AXIS][2];
break;
case 3:
STEPPING_PORT_Y0 &= ~(stepper_pins[Y_AXIS][0]);
STEPPING_PORT_Y0 |= (stepper_pins[Y_AXIS][1]);
STEPPING_PORT_Y1 &= ~(stepper_pins[Y_AXIS][3]);
STEPPING_PORT_Y1 |= (stepper_pins[Y_AXIS][2]);
break;
return;
}
}
}

The above is a function that „translates” the instructions for controllers into „instructions” for H.

In addition, we must call this function where necessary and turn off what may bother us. Therefore, we look for all instances of `DIRECTION_PORT =` and `DIRECTION_PORT_DUAL =` and comment on the lines in which it occurs with two slesze (//) or remove them (primarily in the ISR function (TIMER1_COMPA_vect)).
Then we search for places where `STEP_PORT =` occurs and replace it with the function convert_step () ;.

In the void stepper_init () function, we comment everything before // Configure Timer 1: Stepper Driver Interrupt and add (after what is commented out):

DDRD = DDRD | 0b11111100; // sets pins 2 to 7 as outputs
DDRB = DDRB | 0b00010001; // sets pins 0 (pin 8) and 4 (pin 12)

Additionally:

we search for the ISR function (TIMER0_OVF_vect) and comment on everything in its body except the line TCCR0B = 0 ;.
in the ISR function (TIMER0_COMPA_vect) you can replace everything with convert_step ();
in the void st_reset () function we comment everything from // Initialize step and direction port pins. to #endif

Finally, we create a new file in this directory called H-Grbl.ino, paste it into:

/* ~ GRBL with L293d (H-Bridge) and DC Motor Pen mechanism ~
╦═╗╔╗ ╦╔═
By-- ╠╦╝╠╩╗╠╩╗ - 2016 Rakshith BK
╩╚═╚═╝╩ ╩
*
* No licences no copyrights, well may be MIT.
* Use modify distribute and do whatever you want
* And even though this code will not launch any Nukes,
* I'm not responsible for any destruction caused by it.!
*
* X-axis stepper --> 8, 9, 10, 11
* Y-axis stepper --> 4, 5, 6, 7
* DC motor pin for Pen --> 12 for Pen Up - M4
* for Pen Down - M3
*
*
* For Details and working --
*/

/*
* Moved to v1.1 by San Zamoyski 11-2019
* */

#include „grbl.h”

void setup() {

}

void loop() {

}

We run in arduino, upload and should work immediately. To start the spindle (M3 command), remember to set its speed (e.g. S500).

In general, you could clean this code of things that are made without sense, but they do not threaten the program, and facilitate the possible transfer of modifications to the next versions of GRBL.