Copy and paste the following code into your OpenSCAD editor:
// No Touch Change Dispenser
// Version 0.61;
////////////////////////////////////////////////////////////////////////////////////
//
// Licence:
//
// Creative Commons - Attribution
//
// You may use this file in any way you wish save
// only that every instance must include a link to
// http://www.half-baked-idea.co.uk/
//
////////////////////////////////////////////////////////////////////////////////////
// START of user adjustable settings
explode=0; // set to 0 for built view, 1 for printable parts
// Uncomment just one set of coins
// Full Sterling - width on print bed 274mm
//coins=[["£2",28.4,2.5],["£1",23.43,2.8],["50p",27.3,1.78],["20p",21.4,1.7],["10p",24.5,1.85],["5p",18,1.7],["2p",25.9,2.03],["1p",20.3,1.65]];
// Short Sterling - width on print bed 235mm
coins=[["£1",23.43,2.8],["50p",27.3,1.78],["20p",21.4,1.7],["10p",24.5,1.85],["5p",18,1.7],["2p",25.9,2.03],["1p",20.3,1.65]];
// Full Euro - width on print bed - 256mm reduce 'sideallowance' to 1.5 to fit 250mm printbed
//coins=[["€2",25.75,2.2],["€1",23.25,2.33],["50c",24.25,2.38],["20c",22.25,2.14],["10c",19.75,1.93],["5c",21.25,1.67],["2c",18.75,1.67],["1c",16.25,1.67]];
// Short Euro - width on print bed 200mm reduce 'sideallowance' to 1.75 to fit 200mm printbed
//coins=[["€2",25.75,2.2],["€1",23.25,2.33],["50c",24.25,2.38],["20c",22.25,2.14],["10c",19.75,1.93],["5c",21.25,1.67]];
// Short USA - width on print bed 125mm
//coins=[["25¢",24.26,1.75],["10¢",17.91,1.35],["5¢",21.21,1.95],["1¢",19.05,1.52]];
// Add new coin sets at bottom, works with coins up to 5mm thick.
// Format is: [ "Printable_Label" , diameter_mm , thickness_mm ]
towerht=100; // Height of coin stack (range 50 - 150)
sideallowance=2; // Larger is stronger but wider
cointolerance=1; // allow coins to move freely
slidelen=80; // Increase for large diameter coins
pushplate=10; // Height of push plate
pushedgerad=3; // Edge softening
$fn=50; // Increase for higher curve precision
exp0=0; // Exploded spacings, ...
exp1=85; // ...may need...
exp2=170; // ...increasing if slidelen...
exp3=50; // ...is changed
// END of user adjustable settings
tbary=2.5;
tbarx=5;
pinholerad=2;
pintolerance=0.25;
sepwidth=pinholerad+0.5;
slidetolerance=0.25;
bandpostrad=pinholerad;
bandpostlen=8;
bandpathradius=4;
baseheight=50;
widths=[for (v=[0:len(coins)-1]) coins[v][1] ];
maxy=sum(widths,len(widths)-1)+len(coins)*((sepwidth*2)+(2*sideallowance)+cointolerance+(2*slidetolerance))-5.5+(2*slidetolerance);
totwidth=maxy+5.5;
maxwidth=max(widths);
maxslidewid=maxwidth+cointolerance+4;
echo();
echo(str(" ",state(explode)));
echo();
echo(str(" Width on build plate=",totwidth));
echo();
thicknesses=[for (v=[0:len(coins)-1]) coins[v][2] ];
maxthick=max(thicknesses);
// one slide per denomination
for (c=[0:len(coins)-1]){
space=sum(widths,c-1)+widths[c]/2+(((sepwidth*2)+(2*sideallowance)+cointolerance+slidetolerance*2)*c);
translate([exp1*explode,space,0]){
slide(coins[c]);
}
}
// Seperate loops to make integrated parts
difference(){
union(){
for (c=[0:len(coins)-1]){
space=sum(widths,c-1)+widths[c]/2+(((sepwidth*2)+(2*sideallowance)+cointolerance+slidetolerance*2)*c);
translate([exp0*explode,space,2.25*explode]){
slot(coins[c]);
}
}
}
// trim ends
translate([exp0*explode-maxslidewid/2,-5.5-5,-2.25]){
cube([slidelen,5,15]);
}
translate([exp0*explode-maxslidewid/2,maxy,-2.25]){
cube([slidelen,5,15]);
}
}
difference(){
union(){
for (c=[0:len(coins)-1]){
space=sum(widths,c-1)+widths[c]/2+(((sepwidth*2)+(2*sideallowance)+cointolerance+slidetolerance*2)*c);
translate([exp2*explode,space,(towerht+5)*explode]){
rotate([180*explode,0,180*explode]){
tower(coins[c]);
}
}
}
}
translate([(maxwidth/2+1.5)*(explode?1:-1)+exp2*explode,0,(towerht+5)*explode]){
rotate([0,270-180*explode,0]){
textpane();
}
}
// trim ends
translate([exp2*explode-maxwidth/2,-5.5-5,-10+(towerht-5)*explode]){
cube([maxwidth,5,30]);
}
translate([exp2*explode-maxwidth/2,maxy,-10+(towerht-5)*explode]){
cube([maxwidth,5,30]);
}
}
base();
module base(){
translate([-maxslidewid/2-exp3*explode,-5.5,-baseheight-2.25+(baseheight+2.25)*explode]){
difference(){
cube([maxslidewid*1.5,totwidth,baseheight]);
translate([maxslidewid*1.5-9,0,0]){
rotate([0,0,90]){
fixrecess(baseheight*9/10);
}
translate([0,totwidth,0]){
rotate([0,0,270]){
fixrecess(baseheight*9/10);
}
}
}
for (c=[0:len(coins)-1]){
slidewid=coins[c][1]+2*sideallowance+cointolerance;
space=sum(widths,c-1)+widths[c]/2+(((sepwidth*2)+(2*sideallowance)+cointolerance+slidetolerance*2)*c);
translate([0,space,0]){
translate([8,-slidewid/2-sepwidth-slidetolerance+5.5,baseheight-12]){
cylinder(r=pinholerad,h=100);
}
translate([8,slidewid/2+sepwidth+slidetolerance+5.5,baseheight-12]){
cylinder(r=pinholerad,h=100);
}
translate([maxslidewid-5,-slidewid/2-sepwidth-slidetolerance+5.5,baseheight-12]){
cylinder(r=pinholerad,h=100);
}
translate([maxslidewid-5,slidewid/2+sepwidth+slidetolerance+5.5,baseheight-12]){
cylinder(r=pinholerad,h=100);
}
}
}
}
translate([0,totwidth,0]){
rotate([90,0,0]){
// wide slope
linear_extrude(height=totwidth, scale=[1.0,1.0]){
polygon(points=[[0,0],[0,baseheight],[-maxslidewid/2,baseheight*7/8],[-maxslidewid/2,0]]);
}
}
}
frontrace=[[0,0],[0,baseheight*7/8],[totwidth/2-maxslidewid/2-2,baseheight*2/6],[totwidth/2-maxslidewid/2-2,0]];
difference(){
union(){
translate([-maxslidewid*1.5-1,0,5]){ // overlap to make single part
rotate([90,0,90]){
linear_extrude(height=2){
polygon(points=frontrace);
}
translate([0,-5,0]){
linear_extrude(height=maxslidewid+2){
polygon(points=frontrace);
}
}
}
}
translate([-maxslidewid*1.5-1,totwidth,5]){
mirror([0,1,0]){
rotate([90,0,90]){
linear_extrude(height=2){
polygon(points=frontrace);
}
translate([0,-5,0]){
linear_extrude(height=maxslidewid+2){
polygon(points=frontrace);
}
}
}
}
}
}
translate([-maxslidewid*1.5+7,0,0]){
rotate([0,0,90]){
fixrecess(baseheight*3/4);
}
translate([0,totwidth,0]){
rotate([0,0,270]){
fixrecess(baseheight*3/4);
}
}
}
}
translate([-maxslidewid*0.5,totwidth/2-maxslidewid/2-2,0]){
rotate([90,0,180]){
linear_extrude(height=maxslidewid+4){
polygon(points=[[0,0],[0,baseheight*2/6],[maxslidewid*3/2,2],[maxslidewid*3/2,0]]);
}
}
translate([-maxslidewid*3/2,-2,0]){
cube([maxslidewid*3/2,2,baseheight/6]);
translate([0,maxslidewid+6,0]){
cube([maxslidewid*3/2,2,baseheight/6]);
}
}
}
}
}
module slide(dims){
label=dims[0];
dia=dims[1]+cointolerance;
thick=dims[2];
slidewid=dia+(2*sideallowance);
difference(){
union(){
translate([-maxslidewid/2,-slidewid/2-tbary,0]){
cube([tbarx,slidewid+tbary*2,thick*1.2]);
}
// Basic Slide
translate([-maxslidewid/2,-slidewid/2,0]){
cube([slidelen,slidewid,thick*1.2]);
}
}
// cut out
cylinder(d=dia,h=thick*2);
hull(){ // long chamfer to seperate coins
translate([0,0,thick*2/3]){
cylinder(d=dia,h=thick*2);
translate([thick*3,0,thick/2]){
cylinder(d=dia,h=thick*2);
}
}
}
}
difference(){
// Push block
translate([maxslidewid*1.5,-slidewid/2,thick*1.2]){
cube([slidelen-maxslidewid*2,slidewid,pushplate-(thick*1.2)]);
}
// Soften edge
translate([slidelen-maxslidewid/2-pushedgerad,-slidewid/2,pushplate-pushedgerad]){
difference(){
cube([pushedgerad,slidewid,pushedgerad]);
rotate([270,0,0]){
cylinder(r=pushedgerad,h=slidewid);
}
}
}
// bandpath
translate([maxslidewid*1.5-pushplate/8,-slidewid/2,pushplate/2]){
rotate([270,0,0]){
cylinder(r=bandpathradius,h=slidewid);
}
}
// chamfer bandpath
translate([maxslidewid*1.5,-slidewid/2,pushplate/2]){
rotate([270,0,45]){
translate([0,0,-5]){
cylinder(r=bandpathradius,h=10);
}
}
}
translate([maxslidewid*1.5,slidewid/2,pushplate/2]){
rotate([270,0,135]){
translate([0,0,-5]){
cylinder(r=bandpathradius,h=10);
}
}
}
translate([maxslidewid*1.5-pushplate/8,-slidewid/2-pushplate/6,pushplate/2]){
rotate([0,90,0]){
cylinder(r=bandpathradius,h=20);
}
}
translate([maxslidewid*1.5-pushplate/8,slidewid/2+pushplate/6,pushplate/2]){
rotate([0,90,0]){
cylinder(r=bandpathradius,h=20);
}
}
}
translate([slidelen-maxslidewid/2-10,0,pushplate]){
rotate([0,0,90]){
linear_extrude(height=0.5){
text(label,size=5,halign="center",valign="center");
}
}
}
}
module slot(dims){
label=dims[0];
dia=dims[1]+cointolerance;
thick=dims[2];
slidewid=dia+(2*sideallowance);
difference(){
union(){
difference(){
union(){
translate([-maxslidewid/2,-slidewid/2-sepwidth-slidetolerance-1,-2.25]){
cube([slidelen,slidewid+(sepwidth+slidetolerance+1)*2,2]); // overwide to fuse all into single plate
}
translate([-maxslidewid/2+tbarx+0.25,-slidewid/2-sepwidth-slidetolerance,-0.25]){
cube([slidelen-3.25,sepwidth,thick*1.2+0.5]);
}
translate([-maxslidewid/2+tbarx+0.25,slidewid/2+slidetolerance,-0.25]){
cube([slidelen-3.25,sepwidth,thick*1.2+0.5]);
}
}
translate([-maxslidewid/2+8,-slidewid/2-sepwidth-slidetolerance,-2.5]){
cylinder(r=pinholerad,h=10);
}
translate([-maxslidewid/2+8,slidewid/2+sepwidth+slidetolerance,-2.5]){
cylinder(r=pinholerad,h=10);
}
translate([maxslidewid/2-5,-slidewid/2-sepwidth-slidetolerance,-2.5]){
cylinder(r=pinholerad,h=10);
}
translate([maxslidewid/2-5,slidewid/2+sepwidth+slidetolerance,-2.5]){
cylinder(r=pinholerad,h=10);
}
hull(){ // finger bay
translate([slidelen,0,-2.5]){
cylinder(d=dia+(2*sideallowance),h=10);
}
translate([slidelen-maxslidewid,0,-2.5]){
cylinder(d=dia,h=10);
}
}
}
translate([slidelen-maxslidewid/2-5-bandpostlen,-slidewid/2-sepwidth-slidetolerance,0]){
cube([bandpostlen+5,sepwidth,maxthick*1.2+0.5]);
}
translate([slidelen-maxslidewid/2-5-bandpostlen+bandpostrad,-slidewid/2-sepwidth-slidetolerance,maxthick*1.2+0.5]){
cylinder(r1=bandpostrad,r2=bandpostrad+0.5,h=4);
}
translate([slidelen-maxslidewid/2-5-bandpostlen+bandpostrad,-slidewid/2-slidetolerance-sepwidth,maxthick*1.2+0.5]){
cube([bandpostlen,bandpostrad,4]);
hull(){
cube([bandpostlen,bandpostrad,1]);
translate([2,0,3]){
cube([bandpostlen,bandpostrad,1]);
}
}
}
translate([slidelen-maxslidewid/2-5-bandpostlen,slidewid/2+slidetolerance,0]){
cube([bandpostlen+5,sepwidth,maxthick*1.2+0.5]);
}
translate([slidelen-maxslidewid/2-5-bandpostlen+bandpostrad,slidewid/2+sepwidth+slidetolerance,maxthick*1.2+0.5]){
cylinder(r1=bandpostrad,r2=bandpostrad+0.5,h=4);
}
translate([slidelen-maxslidewid/2-5-bandpostlen+bandpostrad,slidewid/2+slidetolerance+0.5,maxthick*1.2+0.5]){
cube([bandpostlen,bandpostrad,4]);
hull(){
cube([bandpostlen,bandpostrad,1]);
translate([2,0,3]){
cube([bandpostlen,bandpostrad,1]);
}
}
}
}
// soften edge
translate([slidelen-maxslidewid/2-sepwidth-sideallowance,slidewid/2+sepwidth+slidetolerance,-2.5]){
difference(){
translate([0,-(sepwidth+sideallowance)*2,0]){
cube([(sepwidth+sideallowance)*2,(sepwidth+sideallowance)*2,10]);
}
intersection(){
cylinder(r=sepwidth+sideallowance,h=10);
translate([0,-(sepwidth+sideallowance)*2,0]){
cube([(sepwidth+sideallowance)*2,(sepwidth+sideallowance)*2,10]);
}
}
}
}
translate([slidelen-maxslidewid/2-sepwidth-sideallowance,-slidewid/2-sepwidth-slidetolerance,-2.5]){
difference(){
translate([0,0,0]){
cube([(sepwidth+sideallowance)*2,(sepwidth+sideallowance)*2,10]);
}
intersection(){
cylinder(r=sepwidth+sideallowance,h=10);
translate([0,0,0]){
cube([(sepwidth+sideallowance)*2,(sepwidth+sideallowance)*2,10]);
}
}
}
}
}
}
module tower(dims){
label=dims[0];
dia=dims[1]+cointolerance;
thick=dims[2];
slidewid=dia+(2*sideallowance);
difference(){
union(){
translate([-maxslidewid/2,-slidewid/2-3+0.5,thick*1.2+0.25]){
cube([maxslidewid+1,slidewid+(sepwidth+slidetolerance)*2-0.5,5-thick*1.2]);
}
translate([-maxslidewid/2,-slidewid/2-3,5]){
cube([maxslidewid+1,slidewid+(sepwidth+slidetolerance)*2,towerht]);
}
}
cylinder(d=dia,h=towerht); // bore
translate([0,0,towerht]){
cylinder(r1=dia/2,r2=dia/2+1,h=5); // flare
}
translate([maxslidewid/2,0,towerht/2]){
rotate([90,0,90]){
linear_extrude(height=2){
text(label,size=5,halign="center",valign="center");
}
}
}
}
translate([-maxslidewid/2+8,-slidewid/2-sepwidth-slidetolerance,-7]){
cylinder(r=pinholerad-pintolerance,h=15);
}
translate([-maxslidewid/2+8,slidewid/2+sepwidth+slidetolerance,-7]){
cylinder(r=pinholerad-pintolerance,h=15);
}
translate([maxslidewid/2-5,-slidewid/2-sepwidth-slidetolerance,-7]){
cylinder(r=pinholerad-pintolerance,h=15);
}
translate([maxslidewid/2-5,slidewid/2+sepwidth+slidetolerance,-7]){
cylinder(r=pinholerad-pintolerance,h=15);
}
}
module textpane(){
translate([towerht*19/20,maxy-totwidth/20,0]){
rotate([0,0,270]){
linear_extrude(height=2){
text("No Touch Change Dispenser",size=6,align="left",valign="center");
}
}
}
translate([towerht*4/20,maxy-(totwidth*19/20),0]){
rotate([0,0,270]){
linear_extrude(height=2){
text("Free download",size=4,halign="right",valign="center");
}
}
}
translate([towerht*2/20,maxy-(totwidth*19/20),0]){
rotate([0,0,270]){
linear_extrude(height=2){
text("www.half-baked-idea.co.uk/3d/",size=4,halign="right",valign="center");
}
}
}
}
module fixrecess(ht){
translate([0,0,2]){
resize([28,14,ht]){
cylinder(r=7,h=ht/3);
translate([0,0,ht/3]){
cylinder(r1=7,r2=0,h=ht*2/3);
}
}
translate([7,0,-2]){
cylinder(r=2.5,h=3);
}
}
}
function sum( vec, pos) =( pos<0 ?0:vec[pos]+sum(vec,pos-1));
function state(s)=(s==1?"Exploded to printable parts" : "Built view: Set explode (on line 19) to 1 for printable parts");