Skip to content

Instantly share code, notes, and snippets.

@nathanic
Created April 16, 2018 14:40
Show Gist options
  • Save nathanic/1b71d0ec82496648b8658220aa71c38b to your computer and use it in GitHub Desktop.
Save nathanic/1b71d0ec82496648b8658220aa71c38b to your computer and use it in GitHub Desktop.
/* Stepper Motor Driver -> Servo Adapter
Interpret direction and step pulses from GRBL or other stepper-driving software
and instead translate it to a PWM signal appropriate for a nice cheap standard
servo. Ideally we wouldn't use a whole extra arduino for this but GRBL is not
really set up to do this natively and I don't feel like hacking it. Off-brand
Arduino Nanos are a couple bucks each these days. ¯\_(ツ)_/¯
*/
#include <Servo.h>
// CONSTANTS
const byte MAX_POS = 180;
const byte SERVO_PIN = 9;
const byte STEP_PIN = 2;
const byte DIR_PIN = 3;
const byte ENABLE_PIN = 4;
const byte NEG_LIMIT_PIN = 11;
const byte POS_LIMIT_PIN = 12;
// GRBL sends active low on this
const byte ENABLED = LOW;
const byte LIMIT_TRIGGERED = LOW;
const byte LIMIT_NOT_TRIGGERED = HIGH;
const byte DIR_CW = LOW;
const byte DIR_CCW = HIGH;
// GLOBAL VARIABLES >:-O
Servo g_servo;
volatile byte g_pos = 90; // count step pulses to update the servo
// Interrupt service routine - saturated inc/dec of position counter
void handle_step_pulse() {
// real steppers don't listen for pulses when they're not enabled
if(digitalRead(ENABLE_PIN) != ENABLED) {
return;
}
if (digitalRead(DIR_PIN) == DIR_CW) {
if (g_pos < MAX_POS) {
g_pos++;
}
} else {
if (g_pos > 0) {
g_pos--;
}
}
}
void setup() {
g_servo.attach(SERVO_PIN);
pinMode(STEP_PIN, INPUT);
pinMode(DIR_PIN, INPUT);
pinMode(NEG_LIMIT_PIN, OUTPUT);
pinMode(POS_LIMIT_PIN, OUTPUT);
attachInterrupt(digitalPinToInterrupt(STEP_PIN), handle_step_pulse, RISING);
}
void loop() {
if(digitalRead(ENABLE_PIN) == ENABLED) {
if(!g_servo.attached()) {
g_servo.attach(SERVO_PIN);
}
g_servo.write( g_pos );
} else {
if(g_servo.attached()) {
g_servo.detach();
}
}
// real limit switches don't care about enablement
digitalWrite(NEG_LIMIT_PIN, g_pos == 0 ? LIMIT_TRIGGERED : LIMIT_NOT_TRIGGERED);
digitalWrite(POS_LIMIT_PIN, g_pos == MAX_POS ? LIMIT_TRIGGERED : LIMIT_NOT_TRIGGERED);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment