// Mark 6 Gerotor Pump (C) Tyler Montbriand 2014 // // THIS REQUIRES OPENSCAD 2014.05.30 OR NEWER! It uses a new for() feature which allows you to // build arrays of points from a loop. This is revolutionary. Things which took minutes to // do before are now fast enough to *ANIMATE*. So yes, it is worth it. // // This is a 3d-printable displacement pump which uses the gerotor, a specially-shaped // inner and outer gear whose teeth mesh perfectly at all points to form a chamber which // changes size during rotation. There are five parts: inner rotor, outer rotor, // valve sleeve, case, and lid. // // The only "Vitamins" this pump requires are two pieces of plexiglass as the top and bottom // of the casing, ordinary silicone sealant to glue it shut, four long thin 6-32 screws // and nuts, and some sort of 1/4" screwdriver bit to turn the rotor with. The case screws // are arranged in the same layout as an 80mm case fan, so hopefully not that difficult to drill. // Remember the inner rotor is 3.2mm away from the center of the four screws! // // Does it work? Yes! Much better than the mk5... By using plexiglass as part of the case, // I could make some important bits much smoother, not to mention, SEE WHERE ITS LEAKING. // Greased up, this one can actually generate PRESSURE enough to squirt through some feet of // aquarium tubing. It still doesn't do suction as well as I'd like, but even the best hydraulic // pumps will grind dry when an air bubble gets stuck in the inlet, so I guess my hopes were a // bit unrealistic. // // The inner and outer rotor are printed extra-tall so you can sand their rough top surfaces // smooth to fit the case. I did not acetone-polish mine, but it couldn't hurt. // // Many, many thanks to whoever created this file and put it on the net, I couldn't // have done this without you! // http://www.bconnex.net/elen/public_html/resources/Gerotor_Modeling_with_NX3.pdf // for radial() and torus() and pie() include ; // Precision-related values slop=0.5; // extra thickness to expect on parts HEX=((1/4)*25.4)+(slop/2); // Size of the hex key // These define the dimensions of the housing mount_w=71.5; // Distance between mounting screws, same as an 80mm fan :) ch=25; // Height of chamber, similar to 80mm fan cd=60; // Width of chamber screw=4.5+slop; // Diameter of mounting screw holes wall=3; // Minimum thickness of walls peak=35; // size of "house" shaped area pipe=5.25; // Diameter of inlet/outlet pipes inlet_w=25; // Distance between inlet and outlet pipes nub=3; // Key on sleeve to stop rotation // These values define the gerotor. ZO=7; // Number of lobes on the pump ring T=2; // Thickness of the pump ring E=3.2; // Difference in axes of rotation DOMAJ=52.36; // Major diameter of the pump ring DL=15.5; // Lobe diameter of the pump ring // Display two lines and a label for measurement module mark(p1, p2, c, d, text="CHANGEME", r=0.5, h=10, color="red", a=1) { color(color,a) { if(c && d) mark(c-(d/2), c+(d/2), r=r, h=h, color=color, a=a, text=text); else { translate(p1) cylinder(r=r, h=h, center=true); translate(p2) cylinder(r=r, h=h, center=true); hull() { translate(p1) sphere(r); translate(p2) sphere(r); } if(text) translate(p1+[0,0,h]/4) rotate([90,0,0]) linear_extrude(1) scale(.5) text(text); } } } // This is the bit of magic which does the real work. // It generates a 2D shape which must be extruded. // Note that ZO is the *OUTER* rotor. ZO=10 will // generate an innor rotor with 9 teeth. // // REQUIRES Openscad 2014.05.30 or newer. module gerotor_2d(ZO=10, E=3.2, DL=15.5, DOMAJ=74.8) { ZI=ZO-1; // Inner number of teeth DOMIN=DOMAJ-(4.0*E); // Outer rotor minimum diameter DIMIN=DOMAJ-(6.0*E); // Inner rotor minimum diameter DIMAJ=DOMAJ-(2.0*E); // Inner rotor maximum diameter DLC=DOMAJ+DL-(4.0*E); // Center of lobes on outer rotor r=DLC/2; s=DL/2; a=(ZO*ZO)*(E*E)+(r*r); b=2*ZO*E*r; mstep=fragments(DIMAJ*2, $fn, $fs, $fa); echo("DOMAJ",DOMAJ); function g(t)=sqrt(a+b*cos(ZI*t)); // Defines the X coordinate of the gerotor for 0 <= t <= 360. function x(t)=E*cos(ZO*t)+r*cos(t) - s*(ZO*E*cos(ZO*t)+r*cos(t))/g(t); function y(t)=E*sin(ZO*t)+r*sin(t) - s*(ZO*E*sin(ZO*t)+r*sin(t))/g(t); // These just step it to distribute points better. // If you just do x(t), the crests will have 85 points and the // valleys will have 5 function w(x,n,q) = pow(((x%q)-(q/2))/(q/2),(2*n)+1); function f(x,h=360/ZI,q=360/ZI)=(h/2)*( 1+( w(x,1,q))+2*floor(x/q) ); polygon([ for(t=[0:mstep-1]) [ x(f(t*(360/mstep))), y(f(t*(360/mstep))) ] ]); } // Given identical parameters to gerotor_2d(), generates a matching outer rotor. module gerotor_outer_2d(ZO=10, DOMAJ=74.8, DL=15.5, E=3.2, T=2) { DLC=(DOMAJ+DL)-(4.0*E); AO=(180/ZO)*(ZO%2); union() { difference() { circle(d=DOMAJ+(T*2)); circle(d=DOMAJ); } intersection() { radial(ZO, -[DLC,0]/2, ao=AO) circle(d=DL); circle(d=DOMAJ+T); } } } // Outline of the housing without the chamber module outline() { difference() { hull() { radial(4, [mount_w, mount_w]/2) circle((screw/2)+wall); translate([(cd/2)+peak,0]) circle((screw/2)+wall); } // Mounting screw holes radial(4, [mount_w, mount_w]/2) circle(d=screw); } } // The main housing module housing() difference() { linear_extrude(ch, convexity=3) difference() { outline(); circle(d=cd+(slop/2)); // The center cylinder // Keying slot for the sleeve to fit into translate([cd,0,0]/2) circle(d=nub+slop); } // Inlet and outlet holes translate([0,0,ch/2]) { mirrordup([0,1,0]) translate([0,inlet_w/2,0]) rotate([0,90,0]) cylinder(d=pipe+(slop/2), h=mount_w*2); } // Channels oring(cd+(wall*2), cd+(wall*4)); translate([0,0,ch]) oring(cd+(wall*2), cd+(wall*4)); } // inner gerotor module inner() difference() { linear_extrude(ch+slop, convexity=3) gerotor_2d(ZO=ZO, DOMAJ=DOMAJ, DL=DL, $fn=360); translate([0,0,ch+1]) rotate([180,0,0]) hex(HEX, (ch/3)+1); translate([0,0,-1]) hex(HEX, (ch/3)+1); } // outer gerotor module outer() { difference() { linear_extrude(ch+slop, convexity=4) gerotor_outer_2d(DOMAJ=DOMAJ, ZO=ZO, DL=DL, T=T); radial(ZO, [cd,0,ch]/2, ao=180) rotate([0,90,0]) cylinder(d=pipe, h=20, center=true); } } // A sleeve fitting into the housing, which extends the valve inlets. // Why's it not built in? You can make slight adjustments by // printing different sleeves instead of replacing the entire housing. module sleeve() { difference() { linear_extrude(ch, convexity=2) difference() { union() { circle(d=cd+(1.5*slop)); translate([cd,0,0]/2) circle(d=nub); } circle(d=(slop/2)+(DOMAJ+(T*2))); } mirrordup([0,1,0]) translate([0,0,ch]/2) linear_extrude(pipe, center=true) pie((cd/2)+1, 20, 120); } } module diagram() { $fs=1; $fa=3; housing(); rotate([0,0,90]) { mark(c=[0,mount_w/2,ch+3], d=[mount_w,0,0], text="mount_w"); mark(c=[0,0,ch+3], d=[cd,0,0], text="cd"); translate(-[0,peak+cd/2,0]) mark(c=[0,0,ch+3], d=[inlet_w,0,0], text="inlet_w"); } translate(-[0,cd,0]*1.25) sleeve(); translate([0,cd,0]*1.25) rotate([0,0,90]) { outer(); translate(-[E,0,0]) inner(); mark(c=[0,0,ch+slop], d=[DOMAJ,0,0], text="DOMAJ"); color("red") translate([0,0,ch+slop]) torus(DOMAJ/2, 0.5); color("red") rotate([0,0,-0360/ZO]) translate([(DOMAJ+E)/2,0,ch+slop]) { torus(DL/2, 0.5); rotate([90,0,360/ZO]) scale(0.5) text("DL"); } } } function tween(a, b, t, t0=0, t1=1)=a+( (b-a)*((t-t0)/(t1-t0)) ); module animation() { function traj(a,r=1)=r*[sin(a),cos(a),0]; function anim(t) = (t<0.25)?tween([peak+mount_w/2, inlet_w/2, 0], [E,0,0]+[cd/2,inlet_w,0]/2,t, 0, 0.25): (t<0.78)?[E,0,0]+traj(tween(50,-300+70,t,0.25,0.78),-E+(DOMAJ)/2): tween([E,0,0]+[cd/2,-inlet_w,0]/2,[peak+mount_w/2, -inlet_w/2, 0],t, 0.78, 1) ; housing(); sleeve(); color("green") rotate(($t*[0,0,360])+[0,0,180/ZO]) outer(); color("red") translate([E,0,0]) rotate($t*[0,0,360]*(ZO/(ZO-1))) inner(); color("blue") translate([0,0,ch+1]) linear_extrude(1) difference() { union() { circle(d=DOMAJ); translate([0,inlet_w-pipe,0]/2) square([70, pipe]); translate(-[0,inlet_w+pipe,0]/2) square([70, pipe]); } rotate(($t*[0,0,360])+[0,0,180/ZO]) gerotor_outer_2d(DOMAJ=DOMAJ, ZO=ZO, DL=DL, T=T); translate([E,0,0]) rotate($t*[0,0,360]*(ZO/(ZO-1))) gerotor_2d(ZO=ZO, DOMAJ=DOMAJ, DL=DL, $fn=180); for(n=[0:39]) translate(traj((n/4)*360, 1)) translate(anim( (.11+$t+(n/40))%1 )) circle(1); } } module assembly() { $fs=1; $fa=3; housing(); translate([0,0,20]) sleeve(); color("green") translate([0,0,40]) rotate([0,0,180]/ZO) outer(); color("red") translate([E,0,60]) inner(); color("blue", 0.5) translate([0,0,90]) outline(); color("blue", 0.5) translate([0,0,-20]) outline(); color("grey") radial(4, [mount_w, mount_w, -20]/2) cylinder(d=screw/2, h=ch+20); } /* Various pretty diagrams */ assembly(); //animation(); //diagram(); /* Individual parts in high quality */ //housing($fs=1, $fa=1); //sleeve($fs=1, $fa=1); //outer($fs=1, $fa=1); //translate([-E,0,0]) inner($fs=1, $fa=1);