Skip to content

Commit

Permalink
Merge changes from GrAndAG for motor shield v1 support.
Browse files Browse the repository at this point in the history
  • Loading branch information
jinschoi committed Mar 22, 2016
2 parents c07ccc2 + a8c60bf commit eeb73fe
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 57 deletions.
101 changes: 101 additions & 0 deletions Configuration.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright 2016 by GrAndAG
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>
*/


#ifndef Configuration_h
#define Configuration_h

/*
* Version of Adafruit motor shield used
*/

//#define ADAFRUIT_MOTOR_SHIELD_VERSION 1
#define ADAFRUIT_MOTOR_SHIELD_VERSION 2


/*
* PINS definitions
* Pen arm motor terminals : M1 & M2
* Rotation motor terminals : M3 & M4
* Arm servo port : SER1 (located closer to PCB corner
*/

#define PEN_AXIS_PORT 1
#define ROTATION_AXIS_PORT 2

#define SERVO_PIN 10

/*
* Steppers Configuration
*/

/* Full steps per revolution. Well known NEMA17 1.8 degrees motors have 200 steps. */
#define STEPS_PER_REVOLUTION 200

/* Suitable for Eggbot template and 200 steps/rev steppers at 16x microstepping. */
#define DEFAULT_ZOOM_FACTOR 1.0

/*
* Pen Arm Configuration
*/

/* Pen servo gets clamped to these values. */
#define MIN_PEN_POSITION 100
#define MAX_PEN_POSITION 130

/* Default pen up position. */
#define PEN_UP_POSITION 107

/* How long to take for pen down moves in ms. */
#define PEN_DOWN_MOVE_TIME 200

/* X axis gets clamped to these values to prevent inadvertent damage. */
#define MIN_PEN_AXIS_STEP -480
#define MAX_PEN_AXIS_STEP 480



/* Version dependent stuff */
#if ADAFRUIT_MOTOR_SHIELD_VERSION == 1

#include <AFMotor.h>

#define ADAFRUIT_CLASS AF_Stepper
#define ONE_STEP_TIME 168
// steps/s. A no-delay loop takes 0.17 ms per step, so this is the fastest we can go.
#define MAX_FEEDRATE 2900.0

#else

#include <Adafruit_MotorShield.h>
//#include <utility/Adafruit_MS_PWMServoDriver.h>

#define ADAFRUIT_CLASS Adafruit_StepperMotor
#define ONE_STEP_TIME 1290
// steps/s. A no-delay loop takes 1.29 ms per step, so this is the fastest we can go.
#define MAX_FEEDRATE 775.0

#endif


#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#endif /* Configuration_h */
24 changes: 15 additions & 9 deletions DualStepper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,18 @@ DualStepper::moveTo(int ax, int ay, float speed)
void
DualStepper::plotLine(SingleStepper *xAxis, SingleStepper *yAxis, uint8_t xdir, uint8_t ydir, unsigned int dx, unsigned int dy)
{
unsigned long usPerStep = 1000000L / majorAxisSpeed;
// usDelay is the nominal number of microseconds each step should take.
unsigned long usDelay = 1000000L / majorAxisSpeed;
// usPerStep is the actual number of microseconds to wait accounting for the time it takes to make the steps.
unsigned long usPerStep;

// Serial.print("delay: ");
// Serial.println(usPerStep);

if (usPerStep >= 1290)
usPerStep = usPerStep - 1290; // loop takes 1.29 ms without any delay.
if (usDelay >= ONE_STEP_TIME)
usDelay -= ONE_STEP_TIME; // bake in a single x-axis step time
else
usPerStep = 0;
usDelay = 0; // clamp to zero so we don't get underflow

// Serial.print("delay: ");
// Serial.println(usDelay);

int error = 2 * dy - dx;

Expand All @@ -134,12 +137,15 @@ DualStepper::plotLine(SingleStepper *xAxis, SingleStepper *yAxis, uint8_t xdir,
xAxis->step(xdir);
if (error > 0) {
yAxis->step(ydir);
// Take off another step delay from the wait time.
usPerStep = (usDelay >= ONE_STEP_TIME) ? usDelay - ONE_STEP_TIME : 0;
error += 2 * dy - 2 * dx;
} else {
usPerStep = usDelay;
error += 2 * dy;
}
if (usPerStep > 0)
delayMicroseconds(usPerStep);

delayMicroseconds(usPerStep);
}

// unsigned long endTime = millis();
Expand Down
1 change: 1 addition & 0 deletions DualStepper.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifndef DualStepper_h
#define DualStepper_h

#include "Configuration.h"
#include "SingleStepper.h"

class DualStepper
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ This is a fork of Eberhard Rensch's SphereBot firmware. This version has been mo

**IMPORTANT**: This sketch needs the following non-standard library (install them in the Arduino library directory):

* Adafruit Motor Shield v1: https://github.com/adafruit/Adafruit-Motor-Shield-library
OR
* Adafruit Motor Shield v2: https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library

To use:
Expand Down
2 changes: 1 addition & 1 deletion SingleStepper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

#include "SingleStepper.h"

SingleStepper::SingleStepper(Adafruit_StepperMotor *sm)
SingleStepper::SingleStepper(ADAFRUIT_CLASS *sm)
{
stepper = sm;
pos = 0;
Expand Down
9 changes: 5 additions & 4 deletions SingleStepper.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,20 @@
#ifndef SingleStepper_h
#define SingleStepper_h

#include <Adafruit_MotorShield.h>
#include "Configuration.h"

class SingleStepper {
public:
SingleStepper(Adafruit_StepperMotor *sm);
SingleStepper(ADAFRUIT_CLASS *sm);

void step(uint8_t dir);
void release() { stepper->release(); }

volatile int pos;
int targetPos;

protected:
Adafruit_StepperMotor *stepper;
ADAFRUIT_CLASS *stepper;
};

#endif
#endif
71 changes: 28 additions & 43 deletions SphereBot.ino
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,22 @@
* by Martin Price <http://www.HeliumFrog.com>
*
* Updated to run on Adafruit motor shield by Jin Choi <[email protected]>.
* Utated to support both versions of Adafruit motor shield by GrAndAG
*
* !!!!!!!!
* This sketch needs the following non-standard library (install it in the Arduino library directory):
* Adafruit Motor Shield: https://github.com/adafruit/Adafruit-Motor-Shield-library
* Adafruit Motor Shield:
* v1: https://github.com/adafruit/Adafruit-Motor-Shield-library
* v2: https://github.com/adafruit/Adafruit_Motor_Shield_V2_Library
*
* Also tune your configuration in "Configuration.h" file.
*
* !!!!!!!!
*/

/* Adafruit Motor Shield libraries */
#include "Configuration.h"
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"

/* DualStepper */
#include "DualStepper.h"
Expand All @@ -39,38 +43,6 @@

#include <EEPROM.h>


/*
* PINS
*/

#define PEN_AXIS_PORT 1
#define ROTATION_AXIS_PORT 2

#define SERVO_PIN 9

/*
* Other Configuration
*/

/* Pen servo gets clamped to these values. */
#define MIN_PEN_POSITION 100
#define MAX_PEN_POSITION 130

/* Default pen up position. */
#define PEN_UP_POSITION 107

/* How long to take for pen down moves in ms. */
#define PEN_DOWN_MOVE_TIME 200


/* X axis gets clamped to these values to prevent inadvertent damage. */
#define MIN_PEN_AXIS_STEP -480
#define MAX_PEN_AXIS_STEP 480

/* Suitable for Eggbot template and 200 steps/rev steppers at 16x microstepping. */
#define DEFAULT_ZOOM_FACTOR 1.0

enum {
VALUES_SAVED_EEPROM_LOCATION, MIN_PEN_EEPROM_LOCATION, MAX_PEN_EEPROM_LOCATION, PEN_UP_EEPROM_LOCATION
};
Expand All @@ -85,10 +57,15 @@ byte current_pen_position;
/* --------- */

/* Set up steppers */
#if ADAFRUIT_MOTOR_SHIELD_VERSION == 1
SingleStepper *xStepper = new SingleStepper(new AF_Stepper(STEPS_PER_REVOLUTION, ROTATION_AXIS_PORT));
SingleStepper *yStepper = new SingleStepper(new AF_Stepper(STEPS_PER_REVOLUTION, PEN_AXIS_PORT));
#else
Adafruit_MotorShield MS = Adafruit_MotorShield();
SingleStepper *xStepper = new SingleStepper(MS.getStepper(200, ROTATION_AXIS_PORT));
SingleStepper *yStepper = new SingleStepper(MS.getStepper(200, PEN_AXIS_PORT));
DualStepper *steppers = new DualStepper(xStepper, yStepper, 200 * MICROSTEPS);
SingleStepper *xStepper = new SingleStepper(MS.getStepper(STEPS_PER_REVOLUTION, ROTATION_AXIS_PORT));
SingleStepper *yStepper = new SingleStepper(MS.getStepper(STEPS_PER_REVOLUTION, PEN_AXIS_PORT));
#endif
DualStepper *steppers = new DualStepper(xStepper, yStepper, STEPS_PER_REVOLUTION * MICROSTEPS);

Servo servo;

Expand All @@ -106,9 +83,6 @@ boolean absoluteMode = true;
double feedrate = 160.0; // steps/s
double zoom = DEFAULT_ZOOM_FACTOR;

// steps/s. A no-delay loop takes 1.29 ms per step, so this is the fastest we can go.
#define MAX_FEEDRATE 775.0

// ------

void load_pen_configuration()
Expand Down Expand Up @@ -164,8 +138,10 @@ void setup()
Serial.begin(115200);
clear_buffer();

#if ADAFRUIT_MOTOR_SHIELD_VERSION == 2
MS.begin();
TWBR = ((F_CPU / 400000L) - 16) / 2; // Change the i2c clock to 400KHz for faster stepping.
#endif
Serial.println("Ready");

steppers->setMaxSpeed(MAX_FEEDRATE);
Expand Down Expand Up @@ -381,7 +357,16 @@ void process_commands(char command[], int command_length) // deals with standard
break;
}
}

else if (command_length>0 && command[0] == 'N') // N code
{
// skip line number
int i = 1;
while (i<command_length && command[i]!=' ') ++i;
if (i<command_length-1) {
process_commands(command+i+1, command_length-i-1);
return;
}
}
// done processing commands
if (Serial.available() <= 0) {
Serial.print("ok:");
Expand Down

0 comments on commit eeb73fe

Please sign in to comment.