オシロスコープのプローブを引っ掛けておけるホルダーがあると便利ですが、意外と市販されていないので、作ってみました。
OpenSCADで記述したので、パラメーターを変えるだけで、プローブを引っ掛ける穴の大きさ・数・位置や、壁の肉厚などを変更できて便利です。
Tektronixのプローブは細めなので穴径φ12、Keyshightや横河はφ13くらいにすると丁度いい感じです。
JLCPCBの3Dプリンティングサービスで、2種類の材料(LEDO 6060 Resin(白), 3201PA-F Nylon(黒))、いくつかの形状で出力してみました。
最も安いLEDO 6060 Resin(白)で4穴タイプのものが$1でできるように肉厚を調整しています。
価格は体積に比例するようですが、1個あたりの最低価格が$1になっているようで、これ以上体積を減らしても安くはなりませんでした。
ちなみに4穴(φ13)タイプの3201PA-F Nylon(黒)は$2.37でした。
実物を手にとった感想は、いずれも強度は十分だと思いますが3201PA-F Nylon(黒)のほうがしなりがあって柔らかめです。
コードを以下に示します。
本番出力では$fsを0.2にしていますが、表示に時間がかかるので、試行錯誤する段階では0.5以上にしておくといいでしょう。
// Probe Holder
$fa = 0.2;
$fs = 0.2;
//$fs = 0.5;
wt = 1.35; // wall thickness
iRd = 1; // inner R
oRd = 1; // outer R
oRd2 = 0.5;
dftS = 0.99; // draft scale
sizeX = 90;
sizeY = 25;
sizeZ = 25;
hPosX = [12, 34, 56, 78]; // probe holes positions(x)
hPosY = 16; // probe holes position(y)
hDia = 13; // probe holes diameter
hSlit = 5; // probe holes slit width
hst = 5; // hole slit thickness
hDepth = 7; // probe holes depth
RibShaveCmp = (wt/2+iRd) * (wt/2+iRd)/(hDia/2+wt);
difference(){
union(){
difference(){
linear_extrude(height=sizeZ){
translate([oRd, oRd, 0]){
offset(oRd){
square([sizeX-(iRd*2), sizeY-(iRd*2)]);
}
}
}
translate([wt+iRd, wt+iRd, wt+iRd]){
RoundEdgeCube(iRd, sizeX -(wt+iRd)*2, sizeY -(wt+iRd)*2, sizeZ, 1/dftS, 1);
}
}
for (hx = hPosX){
translate([hx, hPosY, 0]){
difference(){
r = hDia/2 + wt + iRd;
cylinder(h=sizeZ, r1=r, r2=r*dftS);
translate([0, 0, wt+iRd]){
RoundEdgeTube(sizeZ, iRd, (hDia/2)+wt+iRd, scale=dftS);
}
}
linear_extrude(height=sizeZ, scale=dftS){
translate([-hSlit/2 -(wt+iRd), 0, 0]){
square([hSlit+(wt+iRd)*2, sizeY-hPosY]);
}
}
}
translate([hx - wt/2 - iRd, 0, 0]){ //rib(Y)
cube([wt+(iRd*2), hPosY, sizeZ]);
}
}
translate([0, hPosY-wt/2-iRd, 0]){ //rib(X)
cube([sizeX, wt+iRd*2, sizeZ]);
}
}
for (hx = hPosX){
translate([hx, hPosY, 0]){
r = hDia/2;
cylinder(h=sizeZ, r1=r, r2=r*dftS);
linear_extrude(height=sizeZ, scale=1/dftS){
translate([-hSlit/2,0,0]){
square([hSlit, sizeY]);
}
}
}
for (dx = [wt/2 + iRd, -(wt/2 + iRd)]){
translate([hx + dx, wt+iRd, wt+iRd]){ //rib(Y)
y = hPosY - hDia/2 - (wt+iRd)*2 +
RibShaveCmp *0.5;
RoundEdgeCube(iRd, 0, y, sizeZ, 1/dftS, 1);
}
}
}
for (i =[0: len(hPosX)-2]){ //rib(X)
for (dy = [wt/2+iRd, -(wt/2+iRd)]){
translate([hPosX[i] + hDia/2 + wt + iRd - RibShaveCmp/2, hPosY + dy, wt+iRd]){
x = hPosX[i+1] - hPosX[i] - hDia - (wt+iRd)*2 + RibShaveCmp;
RoundEdgeCube(iRd, x, 0, sizeZ, 1/dftS, 1);
}
}
}
for (p = [[0, hPosX[0] - hDia/2, 0],
[hPosX[len(hPosX)-1] + hDia/2, sizeX, -RibShaveCmp * 0.5]]){
for (dy = [wt/2+iRd, -(wt/2+iRd)]){ //rib(X)
translate([p[0] + p[2] + wt + iRd, hPosY + dy, wt+iRd]){
RoundEdgeCube(iRd, p[1] - p[0] - (wt+iRd)*2 + RibShaveCmp * 0.5, 0, sizeZ, 1/dftS, 1);
}
}
}
translate([wt+iRd, wt+iRd, hDepth+iRd]){
RoundEdgeCube(iRd, sizeX - (wt+iRd)*2, sizeY, sizeZ, 1/dftS, 1);
}
translate([0, sizeY, sizeZ]){
rotate([0, 90, 0]){
scale([(sizeZ-hst)/(sizeZ-wt), 1, 1]){
cylinder(h=sizeX, r=sizeY-wt);
}
}
}
for (x = hPosX){
echo(x, sizeY);
for (d = [[hSlit/2, -90], [-hSlit/2, 180]]){
translate([x + d[0], sizeY, 0]){
rotate([0, 0, d[1]]){
EdgeRounder(iRd, sizeZ);
}
}
}
}
translate([0, sizeY, hst]){
rotate([-90, -3, -90]){
#EdgeRounder(oRd2, sizeX, 95);
}
}
}
module RoundEdgeCube(r, x, y, z, xscale=1, yscale=1){
xd = x*(1-xscale)/2;
yd = y*(1-yscale)/2;
points = [[0, 0, 0], [x, 0, 0], [x, y, 0], [0, y, 0],
[0+xd, 0+yd, z], [x-xd, 0+yd, z], [x-xd, y-yd, z], [0+xd, y-yd, z]];
faces = [ [0,1,2,3], [4,5,1,0], [7,6,5,4],
[5,6,2,1], [6,7,3,2], [7,4,0,3]];
minkowski(){
polyhedron(points, faces);
sphere(r);
}
}
module RoundEdgeTube(h, r1, r2, scale=1){
rotate_extrude(){
hull(){
for(p = [[r2, 0, 0], [r2*scale, h, 0]]){
translate(p){
circle(r1);
}
}
}
}
}
module EdgeRounder(r, h, angle=90, thickness=0.1){
difference(){
ox = r / tan(angle/2);
y = ox * sin(angle);
lx = ox * cos(angle);
linear_extrude(h){
polygon([[-thickness, -thickness], [ox, -thickness], [ox -thickness, y], [lx, y]]);
}
translate([ox, r, 0]){
cylinder(h, r, r);
}
}
}