uilleann

3d printable Uilleann bagpipes
git clone https://git.woozle.org/neale/uilleann.git

uilleann / daye / chanter
Neale Pickett  ·  2025-11-28

complete.scad

  1include <../common.scad>
  2
  3height = 360.0;
  4od = 16.0;
  5od_derlin = od + 0.5;
  6id_bot = 13.2;
  7id_top = 5.51;
  8cut_height = 155; // Where to cut it in half
  9axianov = false; // Axianov tone holes?
 10
 11module tonehole_axianov(h=10, d=10, undercut=0) {
 12  r = d/2;
 13  area = PI*r*r;
 14
 15  rounding_r = 2;
 16  rounding_area = (1 - PI/4) * (rounding_r^2); // area lost to rounding
 17  goal_area = area + rounding_area;
 18
 19  w = 6.25; // Marat uses 6.25mm on every hole, so we will too
 20  l = goal_area / w;
 21  
 22  rotate([0, 0, -90]) {
 23    translate([od/2, 0, h]) {
 24      rotate([0, -90+undercut, 0]) {
 25        // Scoot it down a hair so it will penetrate the entire tube when rotated
 26        translate([0, 0, -od/2]) {
 27          render(convexity=2)
 28          intersection() {
 29            cube([l, w, 20]);
 30            union() {
 31              translate([r, r, 0]) cylinder(r=r, h=20, center=true);
 32              translate([r, 0, 0]) cube(20, center=true);
 33              translate([0, r, 0]) cube(20, center=true);
 34            }
 35          }
 36        }
 37      }
 38    }
 39  }
 40}
 41
 42module tonehole(h=10, d=10, undercut=0) {
 43  if (axianov) {
 44    tonehole_axianov(h, d, undercut);
 45  } else {
 46    rotate([0, 0, -90]) {
 47      translate([od/2, 0, h]) {
 48        rotate([0, -90+undercut, 0]) {
 49	  translate([0, 0, -od/2]) {
 50	    cylinder(d=d, h=20);
 51	  }
 52	}
 53      }
 54    }
 55  }
 56  translate([0, -od/2 - 8, h]) rotate([0, 90, 0]) cylinder(r=10, h=50, center=true);
 57}
 58
 59
 60// Something like David Daye's Penny Chanter,
 61// based on my measurements and undercut hints on David's web site.
 62// This is symmetrical, so both pieces can be printed at the same time,
 63// with color changes
 64module chanter() {
 65  difference () {
 66    union() {
 67      // The core part of the instrument is this brass tube
 68      difference() {
 69        brass() cylinder(h=height, d=od);
 70
 71        // Seam guides
 72        translate([0, od/2, 0]) cylinder(d=1, h=400);
 73      }
 74
 75      // David adds this outer Derlin tube as an upgrade option
 76      difference() {
 77        derlin() translate([0, 0, 40.0]) cylinder(h=290, d=od_derlin);
 78
 79        // The slits up the sides serve three purposes:
 80        // 1. directs the slicer to place seams in it (and not on the face)
 81        // 2. provides alignment guides for attaching the two pieces
 82        // 3. looks like an intentional stylistic thing
 83        rotate([0, 0, 85]) translate([0, od_derlin/2, 0]) cylinder(d=1, h=cut_height+20); // overlap
 84        rotate([0, 0, -85]) translate([0, od_derlin/2, cut_height-20]) cylinder(d=1, h=400);
 85      }
 86
 87      // These little doodads are probably just to hide the Derlin seam
 88      ivory() translate([0, 0, 30.0]) {
 89        cylinder(h=3, d1=od, d2=22.0);
 90        translate([0, 0, 3]) cylinder(h=9, d=22.0);
 91      }
 92      ivory() translate([0, 0, height - 30.0 - 12]) {
 93        cylinder(h=12, d=22.0);
 94        translate([0, 0, 12]) cylinder(h=3, d1=22.0, d2=od);
 95      }
 96    }
 97
 98    // Seam guides
 99    translate([0, 11, 0]) cylinder(d=1, h=400);
100
101    // Inner bore, which runs up to the place where the reed drops in
102    translate([0, 0,   0]) cylinder(h=337.01, d1=id_bot, d2=id_top);
103    translate([0, 0, 337]) cylinder(h=23.1, d1=id_top, d2=7.1);
104
105    // I totally dig David's minimalist aesthetic
106    translate([0, 0, 3]) rings(d=16.0);
107
108    // Stamp my name on it
109    difference() {
110      translate([0, 0, 307]) {
111        rotate([90, 0, 180]) {
112          linear_extrude(50) {
113            translate([0, 5]) text("neale", font="Fontdiner Swanky", valign="bottom", size=3, halign="center");
114            translate([0, 0]) text("2024-2", font="Fontdiner Swanky", valign="bottom", size=3, halign="center");
115          }
116        }
117      }
118      cylinder(h=360, d=od-0.5);
119    }
120
121
122    // Tone Holes!
123    // XXX: Undercut angle should be taken into account here
124    tonehole(h=57.1, d=6.68); // E-
125    tonehole(h=87.0, d=4.25); // E
126    tonehole(h=118.0, d=8.33); // F#
127    tonehole(h=149.0, d=5.51, undercut=-15); // G
128    tonehole(h=184.5, d=7.75, undercut=15); // A
129    tonehole(h=184.5, d=7.75, undercut=-15); // A (wide undercut)
130    tonehole(h=219.0, d=6.72, undercut=15); // B
131    tonehole(h=250.0, d=5.50, undercut=30); // C
132    rotate([0, 0, 180]) tonehole(h=270.0, d=7.11, undercut=30); // D
133  }
134}
135
136module tenon(top=false, h=cut_height, od=od, depth=20, thickness=2) {
137  module cut() {
138        cylinder(h=cut_height+depth, d=od-thickness-clearance);
139        cylinder(h=cut_height, d=50);
140  }
141
142  if (top) {
143    difference() {
144      children();
145      cut();
146    }
147  } else {
148    intersection() {
149      children();
150      cut();
151    }
152  }
153}
154
155chanter();
156//translate([0, 50, 360]) rotate([180, 0, 0]) chanter();
157