//whistle
//Holland Hopson
//2021
//This design is adapted from a film can whistle I first encountered from a description by Bart Hopkins of Experimental Musical Instruments.
//The design Hopkins described was made by cutting a slit in the side of a canister used to hold 35mm film.
//requires hopson_attachment_bar.scad
//Adjust Hz to tune whistle
include ;
//global variables
$fn = 100; //make high resolution
//customize these variables
Hz = 1281; //frequency is also priinted on attachment bar
diameter = 40; //needed for attachment bar
//for attachment bar
//these override the variables in hopson_attachment_bar.scad
bar_radius = 2.5; //this was 1.5, but it was too small and brittle
cavity_diameter = 20; //At least 10mm, but less than 40mm (or diameter of whistle set above)
cavity_depth = 2*(bar_radius + 5); //2mm to provide clearance for smaller swivel. 5mm for larger swivel. May need to be closer to 10mm deep. Multiply by 2 because we're using a sphere, so this number is the diameter
module whistle(diameter, Hz, slit_width=5.5, wall_thickness=2, top_bottom_thickness=1, angle=50)
//top_bottom_thickness is important to create a ceiling/floor for whistle. Otherwise, attachment bar has a hole in it
{
//constants and calculations
speed_of_sound = 343.; //343 meters / second
height = ((speed_of_sound / (Hz * 8.))*1000.); //multiply by 1000 to get mm
echo(height, " mm");
echo(height * 0.1, " cm"); //print height in cm
slit_length = height/3;
//begin constructing whistle here
translate([0,0,height/2]){ //position bottom of object on origin
{
difference()
{
union() { //objects to be added to the design
//attachment bar top
translate([0,0,(height/2)+(cavity_depth/2)+top_bottom_thickness]){ //move to top of cylinder + offset to account for top_bottom_thickness
attachmentCavity();
attachmentBar();
}
//attachment bar bottom
translate([0,0,-1*(height/2)-(cavity_depth/2)-top_bottom_thickness]){ //move to bottom of cylinder + offset to account for top_bottom_thickness
rotate([180,0,0]){
attachmentCavity();
attachmentBar();
}
}
//outer shell
cylinder(h = height+(2*top_bottom_thickness), r = diameter/2, center=true);
//height has 2 top_bottom_thickness added to make sure that there's a ceiling/floor on the object and that inner height is calculated size so whislte is in tune
}
union() { //objects to be subtracted from the design
//inner space
cylinder(h = height, r = (diameter/2)-wall_thickness, center=true);
//inner height is calculated amount
//slit
translate([0, -diameter*0.5, 0]) { //move slit so it pokes out the front side
rotate([0, 0, angle]) { //rotating too far eats into the inside wall
cube([slit_width,diameter*0.65,slit_length], center=true);
}
}
//channel to direct air to edge
translate([0, -diameter*0.5-(slit_length/2)+(wall_thickness*0.25), 0]) {
rotate([90, 90, angle*2]) { //rotate cylinder so rounded edge is approx. perpendicular to slit
scale([2,1,1]) //squash cylinder so it contacts the surface more broadly
cylinder(r = slit_length/2, h = slit_length);
}
}
}
}
}
}
}
whistle(diameter, Hz);