Bill of Materials
Part Name | Quantity | Total Price |
300mm linear rail shaft | 2 | 11 |
100mm linear rail shaft | 2 | 9 |
0.25” plywood sheet (30”x48”) | 2 | 35 |
0.125” plywood sheet (12”x12”) | 1 | 10 |
0.25” acrylic sheet (12”x12”) | 1 | 10 |
NEMA 17 stepper motor | 1 | 14 |
Stepper motor driver | 1 | 10 |
12V DC power supply | 1 | 6 |
Assorted M4 nuts and bolts | 1 | 15 |
Assorted M5 nuts and bolts | 1 | 10 |
Lazy susan rotational bearing | 2 | 12 |
8mm bearing | 1 | 9 |
5mm bearing | 1 | 7.5 |
Linear shaft mount | 4 | 11.5 |
Linear bearing block | 4 | 15 |
TOTAL | $185 |
MATLAB Code
...
Code Block |
---|
FILLER |
...
for Producing Animation
Code Block |
---|
clear all;
close all;
% program settings
plot_container_path = false;
plot_distribution_points = false;
plot_distribution_circles = true;
show_labels = false;
show_linkages_and_container = false;
write_to_video = true;
% physical params
D = 190; % [mm]
d = 45.51; % [mm]
dist_slider_pt_to_container_ctr = 101.43; % [mm]
dist_crank_ctr_to_dish_ctr = 225; % [mm]
length_crank = 27.5; % [mm]
length_connecting_link = 167.5; % [mm]
% animated curve of path (stored in polar coordinates, with r referring to
% y position of the topping container and theta referring to
% theta_turntable)
path_points = struct('r', [], 'theta', []);
figure;
set(gcf,'Color','w');
for theta_crank = linspace(0, 2*pi, 200)
clf;
axis equal;
hold on;
set(gca,'Visible','off');
% set size of plot
center = struct('x', 0, 'y', -80);
span = struct('x', 400, 'y', 400);
xlim([(center.x - span.x/2) (center.x + span.x/2)]);
ylim([(center.y - span.y/2) (center.y + span.y/2)]);
% draw a circle for the dish
theta_turntable = theta_crank*6;
circleWithTicks(0, 0, D, theta_turntable, 'b', 'EdgeColor', 'b', 'LineStyle', '-', 'LineWidth',2);
% plot(0, 0, 'b.');
if show_labels
text(75, 75, 'D', 'FontSize', 14, 'Color', 'b');
end
% draw the crank
crank_start_pt = struct('x', 0, 'y', -dist_crank_ctr_to_dish_ctr);
crank_end_pt = struct('x', crank_start_pt.x+length_crank*cos(theta_crank), 'y', crank_start_pt.y+length_crank*sin(theta_crank));
if show_linkages_and_container
plot([crank_start_pt.x crank_end_pt.x], [crank_start_pt.y, crank_end_pt.y], 'm-', 'LineWidth',2);
end
% draw the connecting link
connecting_link_start_pt = crank_end_pt;
connecting_link_end_pt = struct( ...
'x', crank_start_pt.x, ...
'y', connecting_link_start_pt.y+length_connecting_link*sin(acos(-crank_start_pt.x/length_connecting_link)) ...
);
if show_linkages_and_container
plot([connecting_link_start_pt.x connecting_link_end_pt.x], [connecting_link_start_pt.y, connecting_link_end_pt.y], 'g-', 'LineWidth',2);
end
% draw the distance from the topping container to the end of the long
% arm of the crank slider
if show_linkages_and_container
plot([0 0], [connecting_link_end_pt.y, connecting_link_end_pt.y-d/2+dist_slider_pt_to_container_ctr],'Color','#4DBEEE','LineStyle',':','LineWidth',2);
end
% draw joints
if show_linkages_and_container
plot(crank_start_pt.x, crank_start_pt.y, 'k.', 'MarkerSize', 10);
plot(crank_end_pt.x, crank_end_pt.y, 'k.', 'MarkerSize', 10);
plot(connecting_link_end_pt.x, connecting_link_end_pt.y, 'k.', 'MarkerSize', 10);
end
% calculate the position of the container
container_y = connecting_link_end_pt.y+dist_slider_pt_to_container_ctr;
% add a point to the path_points of the current
path_points.r = [path_points.r container_y];
path_points.theta = [path_points.theta theta_turntable+pi/2];
% convert from polar to cartesian and plot
[path_points_x, path_points_y] = pol2cart(-path_points.theta+pi+theta_turntable, path_points.r);
if plot_container_path
plot(path_points_x, path_points_y, "k-.");
end
% draw in topping coverage as it dispenses
% build up array of dispensing coordinates
distribution_spots = struct('r', [], 'theta', []);
prev_rem = -1;
for i = 1:length(path_points.theta)
rem = mod(path_points.theta(i), pi/3);
if rem < prev_rem
distribution_spots.theta = [distribution_spots.theta path_points.theta(i)];
distribution_spots.r = [distribution_spots.r path_points.r(i)];
end
prev_rem = rem;
end
% plot distribution spots
[distribution_spots_x, distribution_spots_y] = pol2cart(-distribution_spots.theta+pi+theta_turntable, distribution_spots.r);
if plot_distribution_points
plot(distribution_spots_x, distribution_spots_y, "k*");
end
if plot_distribution_circles
for p = 1:length(distribution_spots_x)
circle(distribution_spots_x(p), distribution_spots_y(p), d, 'EdgeColor', 'none', 'FaceColor', [[1 1 0], .3])
end
end
% draw the circle for the container (has to be on top of other plots)
if show_linkages_and_container
circle(0, container_y, d, 'EdgeColor', 'r', 'FaceColor', [[1 0 0], .3], 'LineWidth',2);
end
if show_labels
text(d*.5, container_y+d*.5, 'd', 'FontSize', 14, 'Color', 'r');
end
pause(.03);
frames(i) = getframe(gcf); % capture the current frame
end
% write to video
if write_to_video
writerObj = VideoWriter('animation1.mp4', 'MPEG-4');
writerObj.FrameRate = 30;
open(writerObj);
for i = 1:length(frames)
writeVideo(writerObj, frames(i));
end
close(writerObj);
end
function circle(x, y, diam, varargin)
rectangle('Position',[(x-diam/2) (y-diam/2) diam diam],'Curvature',[1 1], varargin{:});
end
function circleWithTicks(x, y, diameter, rotation, tick_color, varargin)
radius = diameter/2;
rectangle('Position',[(x-radius) (y-radius) diameter diameter],'Curvature',[1 1], varargin{:});
for theta = linspace(0, 2*pi, 6)+rotation
plot([x+(radius-5)*cos(theta), x+radius*cos(theta)], [y+(radius-5)*sin(theta), y+radius*sin(theta)], "-", 'Color', tick_color, 'LineWidth',2);
end
end
|
Download Code: visualizer_3.m
MATLAB Code for Graphing Relationships
Code Block |
---|
close all;
% set omega_a to arbitrary value (in reality this is controlled by the motor)
omega_a = 10; % [rad/s]
% create linspace for theta_a
theta_a = linspace(0, 2*pi, 200);
% physical attributes
a = 27.5; % [mm]
b = 167.5; % [mm]
dist_slider_pt_to_container_ctr = 101.43; % [mm]
dist_crank_ctr_to_dish_ctr = 225; % [mm]
% equations to find desired quantities
omega_b = (-a*omega_a*sin(theta_a))./(b*sin(acos(-a*cos(theta_a)/b)));
c_dot = -a*omega_a*cos(theta_a) - (a^2*omega_a*sin(omega_a).*cos(omega_a))./(b*sin(acos(-a*cos(theta_a)/b)));
c = (a*sin(theta_a) + b*sin(acos(-a*cos(theta_a)/b)))-dist_crank_ctr_to_dish_ctr+dist_slider_pt_to_container_ctr;
% create a nondimensional time variable that is a percentage of a full cycle
% of the crank
t = theta_a/(2*pi)*100;
% plot omega_b
figure;
plot(t, omega_b, "r-");
xlabel("% of full crank rotation cycle");
ylabel("$\omega_b$ (rad/s)", 'interpreter','latex');
title("Angular Velocity of Connecting Link");
subtitle("For \omega_a = 10 rad/s");
% plot c_dot
figure;
plot(t, c_dot, "b-");
xlabel("% of full crank rotation cycle");
ylabel("$\dot c$ (mm/s)", 'interpreter','latex');
title("Velocity of Container");
subtitle("For \omega_a = 10 rad/s");
% plot y
figure;
plot(t, c, "-");
xlabel("% of full crank rotation cycle");
ylabel("$r$ (mm)", 'interpreter','latex');
title("Radial Position of Container (Distance From Center)"); |
Download Code: grapher_1.m