Cut-Urumbu¶
Machine Week project¶
We are Nihal, Laxmi, Midhun, Kalyani and Thej. We are building a Cake portioner based on urumbu - machine building approach.
Concept¶
To design a Cake cutting machine which will split a cake into equal slices. Conceptualisation was done by Kalyani. For detailed documentation refer here Kalyani
Project management¶
Project management is done by Nihal and is documented detail here.
Project management is the discipline of planning, organising, and executing tasks and resources to achieve specific goals within a defined timeframe and budget. It involves overseeing the entire lifecycle of a project, from initiation to closure, to ensure successful completion.
Gantt chart
A Gantt chart is a type of bar chart that visually represents a project schedule. It illustrates the start and finish dates of various elements of a project, such as tasks, milestones, and deadlines. The chart consists of horizontal bars representing each task, with their lengths corresponding to the duration of the task. Gantt charts also show dependencies between tasks, allowing project managers to understand the sequence of activities and identify critical path items. They provide a clear overview of project timelines, resource allocation, and progress tracking, making them a valuable tool for project planning and management. We are using project management tools like gantt chart and Kanban board to manage our project.
kanban board for project mangement
Kanban is a visual project management framework used to manage work as it moves through a process. The Kanban board is a visualization tool that helps teams manage work by dividing it into columns representing different stages of the workflow. Tasks or cards representing work items are moved through these columns from left to right as they progress. Typically, these columns represent stages like “To Do,” “In Progress,” and “Done.” The primary goal of a Kanban board is to limit work in progress (WIP), optimise workflow, and identify bottlenecks to improve efficiency.
BOM¶
Here is the Consolidated Bill of Materials for cut urumbu
Electronics and Programming¶
We are using urumbu board modified by saheen and is documented here. URUMB BOARD
We need to replicate the board as we require 2 stepper motors.
Took the required components from our inventory
Milled the board using the schematics from the documentation.
soldered the components exactly same as the reference board.
replicated urumbu board
Testing the urumbu with serial communciation .
{
/
// serialstep.ino
//
// serial step-and-direction
//
// Neil Gershenfeld 4/11/21
// Quentin Bolsee 12/7/21 : add button
//
// This work may be reproduced, modified, distributed,
// performed, and displayed for any purpose, but must
// acknowledge this project. Copyright is retained and
// must be preserved. The work is provided as is; no
// warranty is provided, and users accept all liability.
//
#define LEDA 30
#define LEDC 14
#define EN 5
#define DIR 2
#define STEP 4
#define BUTTON 31
void setup() {
SerialUSB.begin(9600);
digitalWrite(LEDA, HIGH);
pinMode(LEDA, OUTPUT);
digitalWrite(LEDC, LOW);
pinMode(LEDC, OUTPUT);
digitalWrite(EN, LOW);
pinMode(EN, OUTPUT);
digitalWrite(STEP, LOW);
pinMode(STEP, OUTPUT);
digitalWrite(DIR, LOW);
pinMode(DIR, OUTPUT);
pinMode(BUTTON, INPUT_PULLUP);
/*
// 1 step
digitalWrite(M0,LOW);
digitalWrite(M1,LOW);
pinMode(M0,OUTPUT);
pinMode(M1,OUTPUT);
// 1/2 step
digitalWrite(M0,HIGH);
digitalWrite(M1,LOW);
pinMode(M0,OUTPUT);
pinMode(M1,OUTPUT);
*/
// 1/8 step
// digitalWrite(M0,HIGH);
// digitalWrite(M1,HIGH);
// pinMode(M0,OUTPUT);
// pinMode(M1,OUTPUT);
/*
// 1/16 step
digitalWrite(M1,HIGH);
pinMode(M0,INPUT);
pinMode(M1,OUTPUT);
// 1/32 step
digitalWrite(M0,LOW);
pinMode(M0,OUTPUT);
pinMode(M1,INPUT);
*/
}
void loop() {
if (SerialUSB.available()) {
char c = SerialUSB.read();
if (c == 'f') {
digitalWrite(DIR, HIGH);
digitalWrite(STEP, HIGH);
delayMicroseconds(100);
digitalWrite(STEP, LOW);
} else if (c == 'r') {
digitalWrite(DIR, LOW);
digitalWrite(STEP, HIGH);
delayMicroseconds(100);
digitalWrite(STEP, LOW);
} else if (c == '?') {
// reply with button value
int btn = digitalRead(BUTTON);
SerialUSB.write(btn ? '1' : '0');
} else if (c == '@') {
SerialUSB.write("0000");
}
}
}
}
code for serial communication
Running two stepper motor at same time with serial communication.
Interface¶
Interface is done by Thej and is documented here in detail Thej
Interface is done using Streamlit. Streamlit is a promising open-source Python library, which enables developers to build attractive user interfaces in no time.
This graphical representation allow us to visualise how many slices we get.It is done using matplot lib of python.
testing the motors using interface
Design and Mechanism¶
Design part is done by Laxmi, Midhun. It is documentented in detail here Laxmi and Midhun
We have gone through 3 design iterations to end up in a sleek final design
Our instructors hugely comtributed in iterating our designs to achieve end result which is very minimal and sleek.
We have routed wood plate for the base using zund cutter.
Turn table is milled in acrylic sheet and 3d printed gears are attached to it using custom mounts
M3 screws and M4 screws are used in the whole machine requirements.
*custom attachments designed to attach cutting mechanism to the base *
gears mounted with ball bearings
testing our turntable mechanism
Final Assembly
If the file is not visible, please download it here: Fusion File
System Integration¶
Testing on Machine¶
While testing on the machine there were a few things to be considered.
steps_per_mm_blade = 800
steps_per_deg_table = (7.067 * 6400)/360
cut_bottom_limit=254 # full length in mm
speed_delay=1 / (1000000*speed) #speed will be inputed
To start the machine, the blade has to be homed first i.e. at the highest position so for that we have a limiting switch connected to pin 31 and in the arduino code used, sending ‘?’ will be send the state of the button as ‘1’ or ‘0’. Here ‘0’ denotes that the button is pressed. Implementation of this in a function is this code.
def home():
try:
ser = ser_ports[:1][0]
global speed_delay
response = ''
while response != '0':
ser.write(b'?') # Send command to check if motor is in home position
response = ser.read().decode().strip()
if response == '0': # Motor is in home position
st.info("Motor is in home position.")
break
else: # Motor is not in home position, move towards home
ser.write(b'r') # Move motor towards home
time.sleep(speed_delay)
except serial.SerialException:
st.error("Error occurred while sending commands to Arduino.")
Since cake height will also be inputed, the blade to cut will come down to the cake height position to start with the cutting process.
def setCutHeight():
try:
steps_to_set_height=int((cut_bottom_limit-cake_height)*steps_per_mm_blade)
global speed_delay
ser = ser_ports[:1][0]
for _ in range(steps_to_set_height):
ser.write(b'f') # Signal to Arduino to move motor 1 backward
time.sleep(speed_delay)
except serial.SerialException:
st.error("Error occurred while sending commands to Arduino.")
For cutting ‘f’ will move the blade down and ‘r’ will move the blade upto the steps calculated based on cake height.
def cut():
try:
steps_per_slice_mm = int(steps_per_mm_blade*cake_height)
global speed_delay
# Motor 1
ser = ser_ports[:1][0]
print(ser)
# Move Motor 1 backward (r) in steps_per_slice3
for _ in range(steps_per_slice_mm):
ser.write(b'f') # Signal to Arduino to move motor 1 backward
time.sleep(speed_delay)
time.sleep(0.1) # Delay before changing motor direction
# Move Motor 1 backward (r) in steps_per_slice3
for _ in range(steps_per_slice_mm):
ser.write(b'r') # Signal to Arduino to move motor 1 backward
time.sleep(speed_delay)
except serial.SerialException:
st.error("Error occurred while sending commands to Arduino.")
For the turn table sending ‘f’ will rotate the table depending upon the slices.
def rotate():
ser = ser_ports[1:][0]
steps_per_slice = int(steps_per_deg_table*(360/num_slices))
global speed_delay
for _ in range(steps_per_slice):
ser.write(b'f') # Signal to Arduino to move motor 2 forward
time.sleep(speed_delay)
Here’s the full code:
import streamlit as st
import serial.tools.list_ports
import time
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
steps_per_mm_blade = 800
steps_per_deg_table = (7.067 * 6400)/360
cake_height=170
cut_bottom_limit=254
num_slices=2
speed= 1
speed_delay=1 / (1000000*speed)
ser_ports = []
# Importing the image
image = Image.open('cuturumbu.png')
# Setting up the Streamlit page configuration
st.set_page_config(page_title='Cut-Urumbu', page_icon='cuturumbu.png')
# Displaying the image in the sidebar
st.sidebar.image(image, width=275)
# Function to open serial ports
def open_ports(ports):
for port in ports:
try:
ser = serial.Serial(port, timeout=1)
st.sidebar.success(f"Port {port} opened successfully!")
ser_ports.append(ser)
except serial.SerialException:
st.sidebar.error(f"Failed to open port {port}. Make sure the port is available.")
# Function to generate the pie chart
def generate_pie_chart(num_slices):
labels = [f'Slice {i+1}' for i in range(num_slices)]
sizes = np.ones(num_slices)
explode = [0.05] * num_slices # Explode each slice slightly for better visualization
fig, ax = plt.subplots()
ax.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', startangle=140)
ax.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle
ax.set_title('See your Cake Slices')
st.pyplot(fig)
# Function to return the motor to home position
def home():
try:
ser = ser_ports[:1][0]
global speed_delay
response = ''
while response != '0':
ser.write(b'?') # Send command to check if motor is in home position
response = ser.read().decode().strip()
if response == '0': # Motor is in home position
st.info("Motor is in home position.")
break
else: # Motor is not in home position, move towards home
ser.write(b'r') # Move motor towards home
time.sleep(speed_delay)
except serial.SerialException:
st.error("Error occurred while sending commands to Arduino.")
def setCutHeight():
try:
steps_to_set_height=int((cut_bottom_limit-cake_height)*steps_per_mm_blade)
global speed_delay
ser = ser_ports[:1][0]
for _ in range(steps_to_set_height):
ser.write(b'f') # Signal to Arduino to move motor 1 backward
time.sleep(speed_delay)
except serial.SerialException:
st.error("Error occurred while sending commands to Arduino.")
def cut():
try:
steps_per_slice_mm = int(steps_per_mm_blade*cake_height)
global speed_delay
# Motor 1
ser = ser_ports[:1][0]
print(ser)
# Move Motor 1 backward (r) in steps_per_slice3
for _ in range(steps_per_slice_mm):
ser.write(b'f') # Signal to Arduino to move motor 1 backward
time.sleep(speed_delay)
time.sleep(0.1) # Delay before changing motor direction
# Move Motor 1 backward (r) in steps_per_slice3
for _ in range(steps_per_slice_mm):
ser.write(b'r') # Signal to Arduino to move motor 1 backward
time.sleep(speed_delay)
except serial.SerialException:
st.error("Error occurred while sending commands to Arduino.")
def rotate():
ser = ser_ports[1:][0]
steps_per_slice = int(steps_per_deg_table*(360/num_slices))
global speed_delay
for _ in range(steps_per_slice):
ser.write(b'f') # Signal to Arduino to move motor 2 forward
time.sleep(speed_delay)
# Streamlit app
def main():
st.title("Cut-Urumbu🐜🍰")
# Get available serial ports
available_ports = serial.tools.list_ports.comports()
port_names = [port.device for port in available_ports]
# Open port selection
selected_ports = st.sidebar.multiselect("Select Ports", port_names)
# Open selected ports
open_ports(selected_ports)
print(ser_ports)
# Input for number of slices
global num_slices
num_slices = st.number_input("Enter number of slices", min_value=2, value=2)
# Input for speed
global speed
speed = st.number_input("Enter speed", min_value=0.01, value=1.00, step=0.01)
global cake_height
cake_height = st.number_input("Enter height of the cake (in mm)",min_value=0, value=0, step=1)
global speed_delay
speed_delay=1 / (100000000000*speed)
# Display the pie chart
generate_pie_chart(num_slices)
if st.sidebar.button("Home"):# Return the motor to home position
home()
# Button to run the motors
if st.sidebar.button("Cut Cake"):
if cake_height == 0:
st.error("Warning: Cake height is 0. Set a non-zero height value.")
else:
home()
setCutHeight()
for _ in range(num_slices):
cut()
rotate()
st.balloons()
home()
# Close serial ports
for ser in ser_ports:
if ser.isOpen():
ser.close()
# Footer
st.sidebar.markdown("---")
st.sidebar.text("Made at Super FabLab Kerala")
st.markdown("---")
st.text("Made by Laxmi, Kalyani, Thej, Nihal & Midhun")
if __name__ == "__main__":
main()
Cut-Urumbu¶
Working¶
Problems Faced¶
Design Iterations: We went through several design iterations for both the turntable and cutting mechanism. The initial designs consumed more space and materials than anticipated, leading to inefficiencies.
Motor Issues: One of the motors exhibited abnormal behavior due to a problem with the board. After investigation, we found that the issue was caused by the enable pin not being properly connected. This was subsequently fixed.
Further Improvements:¶
Faster Cutting Speed: Enhance the speed of the cutting mechanism to improve overall efficiency and reduce processing time. Wireless Communication: Implement wireless communication for remote operation and monitoring, eliminating the need for physical connections.
Different Cutting Patterns: Develop the capability to execute various cutting patterns, allowing for more versatile and customized cake portions.