uilleann

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

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

chanter.quiet.scad

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