--- /dev/null
+eps = 0.01;
+infty = 100;
+
+wall = 1.5;
+
+cyl_r = 8 + 0.5;
+cyl_x = 27 / 2;
+cyl_h = 10; // above pcb, max 13.8;
+
+pcb_x = 45 + 0.5;
+pcb_y = 20 + 0.5;
+xtal_h = 4;
+pcb_supp = 3;
+pcb_h = 5; // 1.2 + space for connector etc
+
+cyl_base = pcb_x/2 + wall - cyl_x;
+
+conn_x = 12.5;
+conn_y = 10;
+
+cable_w = 5;
+cable_h = 2;
+
+mount_h = 3;
+screw_sp = 5;
+
+module sensor() {
+ hull() {
+ // pcb and the space above it
+ translate([-pcb_x/2, -pcb_y/2, -eps])
+ cube([pcb_x, pcb_y, pcb_h+eps]);
+ // connector
+ translate([-conn_x/2, pcb_y/2-eps, -eps])
+ cube([conn_x, conn_y+eps, pcb_h+eps]);
+ }
+ // cable protrusion
+ translate([-cable_w/2, pcb_y/2+conn_y-eps, -eps])
+ cube([cable_w, 2*wall + eps, cable_h]);
+
+ // cylinders
+ for (x = [-1, 1]) translate([cyl_x*x, 0, pcb_h - eps])
+ cylinder(r = cyl_r, h = cyl_h + 2+wall + eps);
+ // space below the pcb (xtal, etc)
+ translate([-pcb_x/2+pcb_supp, -pcb_y/2, pcb_h - eps])
+ cube([pcb_x - 2*pcb_supp, pcb_y, xtal_h+eps]);
+};
+module case_body() {
+ hull() {
+ // pcb
+ translate([-pcb_x/2-wall, -pcb_y/2-wall, 0])
+ cube([pcb_x+2*wall, pcb_y+2*wall, pcb_h+wall]);
+
+ // cylinders
+ for (x = [-1, 1]) translate([cyl_x*x, 0, pcb_h + cyl_h])
+ cylinder(r = cyl_base, h = wall);
+
+ translate([0, 7, pcb_h + cyl_h])
+ cylinder(r = cyl_base, h = wall);
+
+ // connector
+ translate([-conn_x/2-wall, pcb_y/2-wall, 0])
+ cube([conn_x+2*wall, conn_y+2*wall, pcb_h+wall]);
+ }
+ for (x = [0, 180]) rotate([0, 0, x]) hull() {
+ // eps-wide cube
+ translate([pcb_x/2-eps, -4/2-wall, pcb_h + cyl_h + wall -eps])
+ cube([eps, 4+2*wall, eps]);
+ // bottom plate
+ translate([pcb_x/2+wall, -screw_sp/2-wall, 0])
+ cube([screw_sp+wall, screw_sp+2*wall, wall]);
+ }
+}
+
+difference() {
+ case_body();
+ # sensor();
+ // mount holes
+ for (x = [0, 180]) rotate([0, 0, x]) {
+ translate([pcb_x/2+wall, -screw_sp/2, wall])
+ cube([screw_sp +wall+eps, screw_sp, pcb_h + cyl_h + eps]);
+ translate([pcb_x/2+1+wall, -3/2, -eps])
+ cube([3, 3, wall + 2*eps]);
+ }
+}
+