Modifying GRBL to Run Unipolar Steppers?

Okay, so I recently purchased an Arduino Mega and have been playing around with some decent sized unipolar steppers that I salvaged from old 5 1/4" floppy drives. My intention is to someday build a CNC run off the Arduino. It seems that the GRBL project would be the best way to go about controlling the steppers, apart from one small problem: GRBL only sends out pulse and direction signals intended for bipolar motors. I realize that there are hardware drivers out there that can solve this and I could always just use a few binary counters to convert the signals to unipolar steps, however it just seems wrong to use (Buy) extra hardware just to solve a seemingly simple software limitation. (After all, my Mega has plenty of GPIO pins and memory available, unlike the Uno, which GRBL was designed for). Although I am willing to put in some effort to change the relevant source code to make GRBL unipolar-compatable, my knowledge of it's inner workings and C code in general are still very limited, so it would take me a great deal of time.

So, my question is: Has anyone already successfuly modified the GRBL source to include unipolar stepping capabilities? If not, maybe someone with more experience than I could at least point me in the right direction as to where I should start modifying GRBL? From a quick glance at the source on GitHub, I noticed a "stepper.c" file. I'm wondering if all the code relevant to my problem could be found there? When I briefly read through the file, I didn't understand the majority of it and could definitely use some guidance there. Any suggestions would be greatly appreciated!

a unipolar motor can be used as bipolar so that is easy.
in a motordriver is a currentlimiterr.
it means you can step a lot faster
so i would advise drivers as you will always need some sort of amplifier, simple fets are working but current will heat the motor excessive.

You could always write your own code for the whole thing and not bother with GRBL. That way you would understand it.

You would still need stepper motor driver boards.

...R

Hey guys, thanks for the suggestions. I decided to go with writing my own code for now, just to keep it simple. As for the driver boards, I just ordered some uln2003 Darlingtons (like 20 cents apiece) to amplify the Arduino signals to 12 volts to power the steppers.

Now I modified little gbrl code from arduino from here GitHub - grbl/grbl: An open source, embedded, high performance g-code-parser and CNC milling controller written in optimized C that will run on a straight Arduino (file stepper.c) and now can command directly my 5v unipolar steppers motors , but all functions is disables...work only arduino out 4,5,6,7 axe x and 8,9,10,11 axe y.
See my recent video...

costy35:
Now I modified little gbrl code from arduino from here GitHub - grbl/grbl: An open source, embedded, high performance g-code-parser and CNC milling controller written in optimized C that will run on a straight Arduino (file stepper.c) and now can command directly my 5v unipolar steppers motors , but all functions is disables...work only arduino out 4,5,6,7 axe x and 8,9,10,11 axe y.

You have added your post to a very old Thread.
I'm not sure if you are looking for assistance, but if you are please just try a 30 second youTube clip.
And, of course, explain what assistance you need.

...R

costy35:
Now I modified little gbrl code from arduino from here GitHub - grbl/grbl: An open source, embedded, high performance g-code-parser and CNC milling controller written in optimized C that will run on a straight Arduino (file stepper.c) and now can command directly my 5v unipolar steppers motors , but all functions is disables...work only arduino out 4,5,6,7 axe x and 8,9,10,11 axe y.
See my recent video...

http://youtu.be/gwifi2o-HYk?list=UUgZyZAxu2SkYqpyaNQ018Wg

http://youtu.be/5amsLfg5WUI?list=UUgZyZAxu2SkYqpyaNQ018Wg

Hi there,

I have a question.. Which part of the stepper.c did you modified to make it work with ULN2003?

I know, I know .... I mutilated the program ... but works !!!

You can firmware with GRBL_PD2_PC0.bat file, you need only insert the port number like "COM3"

Compare with original and see the differnces!

config.h

/*
  config.h - compile time configuration
  Part of Grbl

 

#ifndef config_h
#define config_h

// IMPORTANT: Any changes here requires a full re-compiling of the source code to propagate them.

// Default settings. Used when resetting EEPROM. Change to desired name in defaults.h
#define DEFAULTS_GENERIC

// Serial baud rate
#define BAUD_RATE 9600

// Define pin-assignments
// NOTE: All step bit and direction pins must be on the same port.
#define STEPPING_DDR       DDRB
#define STEPPING_PORT      PORTB
#define X_STEP_BIT         0  // Uno Digital Pin 2
#define Y_STEP_BIT         0  // Uno Digital Pin 3
#define Z_STEP_BIT         0//4  // Uno Digital Pin 4
#define X_DIRECTION_BIT    6//5  // Uno Digital Pin 5
#define Y_DIRECTION_BIT    7//6  // Uno Digital Pin 6
#define Z_DIRECTION_BIT    0//7  // Uno Digital Pin 7
#define STEP_MASK ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT)) // All step bits
#define DIRECTION_MASK ((1<<X_DIRECTION_BIT)|(1<<Y_DIRECTION_BIT)|(1<<Z_DIRECTION_BIT)) // All direction bits
#define STEPPING_MASK (STEP_MASK | DIRECTION_MASK) // All stepping-related bits (step/direction)

#define STEPPERS_DISABLE_DDR    DDRB
#define STEPPERS_DISABLE_PORT   PORTB
#define STEPPERS_DISABLE_BIT    5//0  // Uno Digital Pin 8
#define STEPPERS_DISABLE_MASK (1<<STEPPERS_DISABLE_BIT)

// NOTE: All limit bit pins must be on the same port
#define LIMIT_DDR       DDRB
#define LIMIT_PIN       PINB
#define LIMIT_PORT      PORTB
#define X_LIMIT_BIT     1//1  // Uno Digital Pin 9
#define Y_LIMIT_BIT     1//2  // Uno Digital Pin 10
#define Z_LIMIT_BIT     1//3  // Uno Digital Pin 11
#define LIMIT_INT       PCIE0  // Pin change interrupt enable pin
#define LIMIT_INT_vect  PCINT0_vect 
#define LIMIT_PCMSK     PCMSK0 // Pin change interrupt register
#define LIMIT_MASK ((1<<X_LIMIT_BIT)|(1<<Y_LIMIT_BIT)|(1<<Z_LIMIT_BIT)) // All limit bits

#define SPINDLE_ENABLE_DDR   DDRB
#define SPINDLE_ENABLE_PORT  PORTB
#define SPINDLE_ENABLE_BIT   0//4  // Uno Digital Pin 12

#define SPINDLE_DIRECTION_DDR   DDRB
#define SPINDLE_DIRECTION_PORT  PORTB
#define SPINDLE_DIRECTION_BIT   0  // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.)

#define COOLANT_FLOOD_DDR   DDRB
#define COOLANT_FLOOD_PORT  PORTB
#define COOLANT_FLOOD_BIT   0  // Uno Analog Pin 3

// NOTE: Uno analog pins 4 and 5 are reserved for an i2c interface, and may be installed at
// a later date if flash and memory space allows.
// #define ENABLE_M7  // Mist coolant disabled by default. Uncomment to enable.
#ifdef ENABLE_M7
  #define COOLANT_MIST_DDR   DDRB
  #define COOLANT_MIST_PORT  PORTB
  #define COOLANT_MIST_BIT   0 // Uno Analog Pin 4
#endif  

// NOTE: All pinouts pins must be on the same port
#define PINOUT_DDR       DDRB
#define PINOUT_PIN       PINB
#define PINOUT_PORT      PORTB
#define PIN_RESET        1  // Uno Analog Pin 0
#define PIN_FEED_HOLD    1  // Uno Analog Pin 1
#define PIN_CYCLE_START  1  // Uno Analog Pin 2
#define PINOUT_INT       PCIE1  // Pin change interrupt enable pin
#define PINOUT_INT_vect  PCINT1_vect
#define PINOUT_PCMSK     PCMSK1 // Pin change interrupt register
#define PINOUT_MASK ((1<<PIN_RESET)|(1<<PIN_FEED_HOLD)|(1<<PIN_CYCLE_START))

line 177 from stepper.cpp

/*
  stepper.c - stepper motor driver: executes motion plans using stepper motors
  Part of Grbl

  Copyright (c) 2009-2011 Simen Svale Skogsrud
  Copyright (c) 2011-2012 Sungeun K. Jeon
  
  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/>.
*/

/* The timer calculations of this module informed by the 'RepRap cartesian firmware' by Zack Smith
   and Philipp Tiefenbacher. */

#include <avr/interrupt.h>
#include "stepper.h"
#include "config.h"
#include "settings.h"
#include "planner.h"
int costyx=1;
int costyy=1;


if (sys.state == STATE_CYCLE) {
        // During feed hold, do not update rate and trap counter. Keep decelerating.
        st.trapezoid_adjusted_rate = current_block->initial_rate;
        set_step_events_per_minute(st.trapezoid_adjusted_rate); // Initialize cycles_per_step_event
        st.trapezoid_tick_cycle_counter = CYCLES_PER_ACCELERATION_TICK/2; // Start halfway for midpoint rule.
      }
      st.min_safe_rate = current_block->rate_delta + (current_block->rate_delta >> 1); // 1.5 x rate_delta
      st.counter_x = -(current_block->step_event_count >> 1);
      st.counter_y = st.counter_x;
      st.counter_z = st.counter_x;
      st.event_count = current_block->step_event_count;
      st.step_events_completed = 0;     
    } else {
      st_go_idle();
      bit_true(sys.execute,EXEC_CYCLE_STOP); // Flag main program for cycle end
    }    
  } 

  if (current_block != NULL) {
    // Execute step displacement profile by bresenham line algorithm
    out_bits = current_block->direction_bits;
    st.counter_x += current_block->steps_x;
    if (st.counter_x > 0) {
      out_bits |= (1<<X_STEP_BIT);
      st.counter_x -= st.event_count;
      if (out_bits & (1<<X_DIRECTION_BIT)  ) { sys.position[X_AXIS]--;
      //
      //UDR0=65;
      //DDRD=255;
      costyx=costyx-1;
     if (costyx < 1) costyx=8;
     if (costyx==1)   PORTD=0B100000;
     if (costyx==2)   PORTD=0B110000;
     if (costyx==3)   PORTD=0B010000;
     if (costyx==4)   PORTD=0B011000;
     if (costyx==5)  PORTD=0B001000;
     if (costyx==6)  PORTD=0B001100;
     if (costyx==7)  PORTD=0B000100;
     if (costyx==8) PORTD=0B100100;
      }
      else { sys.position[X_AXIS]++;
     // UDR0=66;
      //DDRD=255;
      costyx=costyx+1;
     if (costyx > 8) costyx=1;
     if (costyx==1)   PORTD=0B100000;
     if (costyx==2)   PORTD=0B110000;
     if (costyx==3)   PORTD=0B010000;
     if (costyx==4)   PORTD=0B011000;
     if (costyx==5)  PORTD=0B001000;
     if (costyx==6)  PORTD=0B001100;
     if (costyx==7)  PORTD=0B000100;
     if (costyx==8) PORTD=0B100100;

}

    }

    st.counter_y += current_block->steps_y;
    if (st.counter_y > 0) {
      out_bits |= (1<<Y_STEP_BIT);
      st.counter_y -= st.event_count;
      if (out_bits & (1<<Y_DIRECTION_BIT)) { sys.position[Y_AXIS]--;
      //DDRB=255;
      costyy=costyy-1;
      if (costyy < 1) costyy=8;
      if (costyy==1)   PORTC=0B1000;
      if (costyy==2)   PORTC=0B1100;
      if (costyy==3)   PORTC=0B0100;
      if (costyy==4)   PORTC=0B0110;
      if (costyy==5)  PORTC=0B0010;
      if (costyy==6)  PORTC=0B0011;
      if (costyy==7)  PORTC=0B0001;
      if (costyy==8) PORTC=0B1001;
      }
      else { sys.position[Y_AXIS]++;
      //DDRB=255;
      costyy=costyy+1;
     if (costyy > 8) costyy=1;
     if (costyy==1)   PORTC=0B1000;
     if (costyy==2)   PORTC=0B1100;
     if (costyy==3)   PORTC=0B0100;
     if (costyy==4)   PORTC=0B0110;
     if (costyy==5)  PORTC=0B0010;
     if (costyy==6)  PORTC=0B0011;
     if (costyy==7)  PORTC=0B0001;
     if (costyy==8) PORTC=0B1001;
      }

    }
    st.counter_z += current_block->steps_z;
    if (st.counter_z > 0) {
      out_bits |= (1<<Z_STEP_BIT);
      st.counter_z -= st.event_count;
      if (out_bits & (1<<Z_DIRECTION_BIT)) { sys.position[Z_AXIS]--; }
      else { sys.position[Z_AXIS]++; }
    }
    
    st.step_events_completed++; // Iterate step events

    // While in block steps, check for de/ac-celeration events and execute them accordingly.
    if (st.step_events_completed < current_block->step_event_count) {
      if (sys.state == STATE_HOLD) {

firmware.zip (307 KB)

I like your smileys. Use code tags - the </> button - not quotes.

And you may just a tad late for the party.

...R

I like your smileys. Use code tags - the </> button - not quotes.

fatto! :slight_smile:

And you may just a tad late for the party.

Maybe ... but if you try on google "grbl unipolar" ... this topic is first result...