Week 10: Mechanical and Machine Design¶
Assignment¶
Mechanical Design
- design a machine that includes mechanism+actuation+automation+application
- build the mechanical parts and operate it manually
Machine Design
- actuate and automate your machine
Cut-Craft: Semat (Bamboo Lid) Cutting Machine¶
Concept¶
Context¶
At Fab Lab Bali, one of the ongoing projects are the Canang Shooter: Semat (Bamboo Lid) Stapler for Canang (balinese offerings), aimed to create innovative aiding tools for crafting Canang and other balinese traditional and artisan craftsworks. These tools aim to simplify the process of utilizing natural semat stick without resorting to metal staplers that could harm the environment.
A key aspect of this project is providing pre-cut ‘semat’ (bamboo lid) to serve as ammunition for the stapler. Therefore, for this assignment, we’re going to use the opportunity to design and build a machine geared towards this purpose, while also being versatile for other tasks beyond cutting semat.
Application¶
Introducing, Cut-Craft: Your Versatile Semat Cutting Companion..
Cut-Craft is a multi-purpose automated cutting machine, aimed for cutting ‘Semat’ (bamboo lid) for Balinese traditional and artisan craftsworks. This machine enables you to automatically cut semat, wire, or similar materials to your desired length and quantity.
Powered by an Arduino Uno, CutCraft features essential components such as a Stepper Motor for wire advancement, a Servo Motor for cutting, a Rotary Encoder for inputting cutting parameters, and an OLED Display for user-friendly parameter selection. We designed and 3D printed a mechanical system to linearly feeds and advance wire, and holds and actuates the cutting pliers. With CutCraft, precision cutting becomes a straightforward task, tailored to your specific requirements.
Inspiration: Wire Cutting Machine¶
To do this, we’re drawing inspiration from wire-cutting machines. Here are some of our main references:
- DIY Wire Cutting & Stripper with Arduino
- B-strip: Open-source high-speed wire cutter and stripper
- Wire Cut & Strip with lasercut design
- Wire-cutter & stripper - compact integrated
System Overview¶
Based on our research, this is essentially how the overview system looks:
As you see, there are 2 main systems that needs to be mechanically designed and actuate, which are to advance the inserted wire/semat and to cut it. We plan to use a stepper motor and ball baearingto advance the wire and high-torque servo motor to move the pliers arm.
Overall, this is the skeleton of our machine:
Machine Parts & Components¶
- Semat/wire spool
- Advancer System
- Stepper Motor
- Ball bearing
- Cutting System
- Wire cutter (plier) holder
- Cam mechanism for the lever that controls the cutting plier arm
- Control Panel
- Rotary Encoder
- OLED Display
- Electronics
Mechanism Design¶
Advancement Mechanism¶
Components:
- Stepper Motor
- Gear
- Ball Bearing
Design Developments
Version 1 & 2:
Version 1 design results in not enough clearance
Final Version:
CAM Lever Mechanism for Controlling Cutting Plier Arm¶
Components:
- Servo Motor
- Cam Lobe
- Vertical board for the lever system
Development v1
Development v2
Development v3
Plier Holder¶
Electronic System¶
CNC Shield Setup¶
To control the stepper and servo motor we decided to use an Arduino Uno with a CNC Shield. The motors were wired together and connected to the CNC shield.
wip: physical circuit setup
Once we figure how to set the circuit. We figured out ways to wire so that the machine can working standalone, the CNC shield is powered by 12v power supply, and the Arduino by DC buck converter.
Automation¶
Programming 1: Controlling Stepper and Servo Motor¶
Here’ we’ve set up a program to control both a stepper motor and a servo motor. We use NEMA17 Steppar Motor and high-torque Servo MG996R. The stepper motor is used to advance a specific length of wire/semat, while the servo motor is responsible for cutting the wire/semat.
We first tried to assemble and simulate the code in Wokwi and then uploading it to Arduino to simultenaously test the code. Here’s the resulting wiring for our program
//rotate stepper motor... on button pressed
//precise number of steps
//as defined by potentiometer
#include <AccelStepper.h>
#include <Servo.h>
// Stepper motor pins
#define dirPin 5
#define stepPin 2
#define swPin 4
int buttonState = 0;
Servo cutServo; //create instance object of servo class - called cutServo
// Define the stepper motor and the pins that are connected to
AccelStepper stepper1(1, stepPin, dirPin); // (Typeof driver: with 2 pins, STEP, DIR)
unsigned int stepStart = 0; //value will increase for every woire length cut
int stepAdd = 0; //adjust value to get desired wire length
void setup() {
Serial.begin(9600);
// Stepper Motor Parameter
stepper1.setMaxSpeed(1000); // Set maximum speed value for the stepper
stepper1.setAcceleration(500); // Set acceleration value for the stepper
stepper1.setCurrentPosition(0); // Set the current position to 0 steps
cutServo.attach(9);
pinMode (swPin, INPUT);
}
void loop() {
//Grab value from potentiometer
stepAdd = 150;
//stepAdd = length*17; //length should be in cm... 1 cm = 17 steps
Serial.println(stepAdd);
//check if button is pressed
buttonState = digitalRead (swPin);
// Move stepper motor the required number of steps in clock-wise direction when button pushed
//for (int i=0; i==qty; i++) { //... comment out next line and use this line when quantity value is received
if (buttonState == HIGH) {
advanceWire();
}
}
//steppermotor function
void advanceWire () {
stepper1.moveTo(stepStart);
stepper1.runToPosition ();
stepStart = stepStart + stepAdd ;
delay (1000);
cutWire();
delay(3000);
}
void cutWire () {
cutServo.write(0);
delay(500);
cutServo.write(90);
delay(500);
cutServo.write(0);
}
Here, we try to control a stepper motor to rotate a specific number of steps when a button is pressed. When we press the button connected to the switch pin, it triggers the stepper motor to move a certain number of steps, which corresponds to the desired length of wire. This number of steps is determined by the stepAdd
variable.
Initially, we configure the stepper motor’s parameters such as maximum speed and acceleration in the setup function. Then, in the loop function, we continuously monitor the state of the button. When the button is pressed, indicating a HIGH state, the advanceWire()
function is called. Inside this function, the stepper motor moves to the specified position, increments the position for the next wire cut, introduces a slight delay for stability, and then activates the cutWire()
function.
Next, the cutWire()
function operates the servo motor to cut the wire. It rotates the servo to perform the cutting action, with intervals between movements for accuracy. After cutting the wire, there’s another delay to allow for the wire to be fully cut before the next iteration.
Testing Motor Actuation
Programming 2: Controlling OLED Display for Parameters Input¶
In order for the users to input the length and quantity parameters, we’re going to use OLED 0.96” display as the interface.
1st Development: OLED Display Setup
2nd Development: Incorporate UI Design
3rd Development
Actuation¶
Test 1¶
Test 2¶
Putting it all together: Integrating Mechanism, Automation Program, and Actuation System¶
Wiring connection
#include "menu.h"
#include "debounce.h"
#include "actuation.h"
#include "rotary_encoder.h"
#define RE_CLK 13
#define RE_DT 12
#define RE_SW 9
RotaryEncoder rotary(RE_DT, RE_CLK);
Debounce btn;
void setup() {
Serial.begin(9600);
if(!displayBegin()) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
pinMode(RE_SW, INPUT_PULLUP);
setupActuation();
}
bool processing = false;
void loop() {
processing
? process()
: btn.debounce(&click, 50);
rotary.decode(&cw, &ccw);
}
bool clicked = false;
unsigned int length;
unsigned int qty;
void click() {
if (digitalRead(RE_SW) == LOW && !clicked) {
clicked = true;
if (cursor < parameter_length) {
selected = !selected;
} else {
processing = !processing;
length = values[0];
qty = values[1];
}
displayUpdate();
} else if (digitalRead(RE_SW) == HIGH && clicked) {
clicked = false;
}
}
void cw() {
if (!selected && cursor == parameter_length)
return;
if (selected) {
if (cursor == 1 && values[1] < 100) {
values[1]++;
} else if (cursor == 0 && values[0] < 250) {
values[0]++;
}
} else {
cursor++;
}
displayUpdate();
}
void ccw() {
if (!selected && cursor == 0)
// if (!selected && cursor == 1)
return;
if (selected) {
if (cursor == 1 && values[1] > 1) {
values[1]--;
} else if (cursor == 0 && values[0] > 10) {
values[0]--;
}
} else {
cursor--;
}
displayUpdate();
}