Week 10: Machine Building & End Effectors
This week's assignment was to make a machine that includes at least one stepper motor and to demonstrate that the motor position is calibrated each time you turn it on. I collaborated with Felicia Liang, since we used this brief as an opportunity to research and prototype a component of our final project, which will be a suminagashi (Japanese ink panting) machine. We decided to prototype the "x-axis arm" of our machine, which will eventually hold another motor-powered arm that will act as the "y-axis".
Testing Stepper Motors
We started by playing with different stepper motors to understand how they work. Thinking it would be sufficient for our machine, we initially programmed the 28BYJ-48 stepper motor
to move back and forth.
However, we ended up finding a tutorial for building a CNC drawing machine that would become the inspirational framework for our project.
Having initially thought we'd build a large frame similar to Suvin's machine, we found this person's approach to be much more agile and appropriate
for our creative purposes. In this example, they use NEMA 17 bipolar stepper motors for more power.
Building the Arm
In order to get the x-axis arm working mechanically, we performed research and collected the requisite materials, including toothed pulleys, timing belt, linear railing, a NEMA 17 motor, an A4988 driver and heat shield, and a 12V port and power source. Initially, we laser cut and 3D-printed linear railing parts, but ended up getting the metal piece in the mail on time. We also 3D-printed two base ends - one idle and one that will house the motor - as well as a raft mount for the y-axis. Although we anticipate the raft mount dimensions changing, it was a helpful exercise in understanding how the mount will sit upon and be powered by the first stepper motor.
Bipolar Stepper Motor Setup
After constructing the arm and ensuring the system works without an outside power source, we set up the stepper motor circuit to validate it would continue working if we programmed the motor to oscillate between clockwise and counterclockwise movements. We also had to solder 12v power source plug to the power and ground wires that would plug into the breadboard.
Adding the Limit Switch
Once we knew the motor moved the mount properly, we adapted different Arduino code snippets online to program the mount to travel clockwise, trigger the limit switch, and then travel counterclockwise back to its origin. We soldered the limit switch to power and ground wires and affixed it to the right edge of the mount, where it would hit the base and trigger the direction change.
Arduino Code
#include
#include
// Define pin connections
const int dirPin = 2;
const int stepPin = 3;
// Define motor interface type
#define motorInterfaceType 1
#define DIRECTION_CCW 1
#define DIRECTION_CW -1
#define MAX_POSITION 0x7FFFFFFF // maximum of position we can set (long type)
ezButton limitSwitch(7); // create ezButton object that attach to pin A0;
AccelStepper stepper(motorInterfaceType, stepPin, dirPin);
int direction = DIRECTION_CW;
long targetPos = 0;
void setup() {
Serial.begin(9600);
limitSwitch.setDebounceTime(50); // set debounce time to 50 milliseconds
stepper.setMaxSpeed(1000); // set the maximum speed
stepper.setAcceleration(100); // set acceleration
stepper.setSpeed(300); // set initial speed
stepper.setCurrentPosition(0); // set position
targetPos = direction * MAX_POSITION;
stepper.moveTo(targetPos);
}
void loop() {
limitSwitch.loop(); // MUST call the loop() function first
if (limitSwitch.isPressed()) {
Serial.println(F("The limit switch: TOUCHED"));
direction *= -1; // change direction
Serial.print(F("The direction -> "));
if (direction == DIRECTION_CW)
Serial.println(F("CLOCKWISE"));
else
Serial.println(F("ANTI-CLOCKWISE"));
targetPos = direction * MAX_POSITION;
stepper.setCurrentPosition(0); // set position
stepper.moveTo(targetPos);
}
// without this part, the move will stop after reaching maximum position
if (stepper.distanceToGo() == 0) { // if motor moved to the maximum position
stepper.setCurrentPosition(0); // reset position to 0
stepper.moveTo(targetPos); // move the motor to maximum position again
}
stepper.run(); // MUST be called in loop() function
}