Mary suggested converting wild bamboo up the hill into tunnel nests (per a xerces.org paper) for native bees buzzing around flowers in the yard, so:

I hung bundles of larger tubes in trees out back, in hopes of attracting huge carpenter bees.
3D printed mounts hold smaller bundles on the windows to let us keep an eye on the proceedings:
![Bee Tunnel Nest Mount - installed-]](https://softsolder.com/wp-content/uploads/2026/04/pxl_20260427_183308319-bee-tunnel-nest-mount-installed.jpg?w=1499)
Which look better when not seen though two layers of glass in desperate need of Spring Cleaning:

The tabs provide a bit of pressure to hold the mounts in place, although I don’t know if they have enough springiness or will survive contact with the elements:

The key advantage of not building bigger bee motels: these little bundles don’t need annual cleaning / maintenance and will eventually fall apart.
If the bees find them suitable, more power to ’em!
And I realized the cut-off ends fit in the rotary. Witticisms engraved on bamboo could become the New Hotness:

Stipulated: I’m barely half-right about being a wit …
The OpenSCAD source code as a GitHub Gist:
| // Bee Tunnel Nest Mount | |
| // Ed Nisley – KE4ZNU | |
| // 2026-04-26 | |
| include <BOSL2/std.scad> | |
| Layout = "Show"; // [Build,Show,Window,Bundle,Tabs] | |
| BundleOD = 35.0; | |
| BundleOffset = 0.0; | |
| SlotDepth = 18.0; | |
| SlotGap = 1.2; | |
| /* [Hidden] */ | |
| HoleWindage = 0.2; | |
| Protrusion = 0.01; | |
| NumSides = 3*2*4; | |
| Clearance = 0.3; | |
| //$fn=NumSides; | |
| WallThick = 2.0; | |
| MountHeight = 1.5*BundleOD; | |
| MountWidth = 1.5*BundleOD + BundleOffset; | |
| ClipOA = [SlotDepth + WallThick,SlotGap + 2*WallThick,MountHeight]; | |
| BundleCtr = [-WallThick/2,ClipOA.y + MountWidth/2 + BundleOffset/2,MountHeight/2]; | |
| TabOA = [0.7*SlotDepth,5.0,0.7*WallThick]; | |
| TabOffset = 0.2*SlotDepth; | |
| TabOC = MountHeight/2; | |
| TabClearance = [4*Clearance,0,Clearance]; | |
| //—– | |
| // Define things | |
| module BundleMount() { | |
| difference() { | |
| cuboid([WallThick,MountWidth + ClipOA.y,MountHeight], | |
| rounding=3.0,edges=[TOP+BACK,BOTTOM+BACK],anchor=FRONT+RIGHT); | |
| back(BundleCtr.y) | |
| xcyl(3*WallThick,d=BundleOD); | |
| for (j=[-1,1],k=[-1,1]) | |
| translate([BundleCtr.x,j*BundleOD/2 + BundleCtr.y,k*BundleOD/2]) | |
| xcyl(3*WallThick,d=3.0,$fn=6); | |
| } | |
| } | |
| module WindowMount() { | |
| difference() { | |
| cuboid(ClipOA,rounding=3.0,edges=[TOP+LEFT,BOTTOM+LEFT], | |
| anchor=FRONT+RIGHT); | |
| left(WallThick) back(WallThick) | |
| cuboid([2*SlotDepth,SlotGap,2*MountHeight],anchor=FRONT+RIGHT); | |
| for (k=[-1,1]) | |
| translate([-(ClipOA.x – TabOffset),-Protrusion,k*TabOC/2]) | |
| cuboid([TabOA.x + TabClearance.x,WallThick + 2*Protrusion,TabOA.y + 2*TabClearance.z],anchor=FRONT+LEFT); | |
| } | |
| } | |
| module Tabs() { | |
| for (j=[-1,1]) | |
| fwd(j*TabOC/2) | |
| cuboid(TabOA,anchor=BOTTOM+LEFT) position(LEFT+TOP) | |
| prismoid(size1=[3*SlotGap,TabOA.y],size2=[0,TabOA.y/2], | |
| h=(WallThick – TabOA.z) + SlotGap/3,anchor=BOTTOM+LEFT); | |
| } | |
| module Assembly() { | |
| union() { | |
| BundleMount(); | |
| WindowMount(); | |
| left(ClipOA.x – TabOffset – TabClearance.x) | |
| xrot(-90) | |
| Tabs(); | |
| } | |
| } | |
| //—– | |
| // Build things | |
| if (Layout == "Bundle") { | |
| BundleMount(); | |
| } | |
| if (Layout == "Window") { | |
| WindowMount(); | |
| } | |
| if (Layout == "Tabs") { | |
| Tabs(); | |
| } | |
| if (Layout == "Show") { | |
| Assembly(); | |
| } | |
| if (Layout == "Build") { | |
| yrot(90) | |
| Assembly(); | |
| } | |
Spam comments get trashed, so don’t bother. Comment moderation may cause a delay.