Ed Nisley's Blog: Shop notes, electronics, firmware, machinery, 3D printing, laser cuttery, and curiosities. Contents: 100% human thinking, 0% AI slop.
A brace of “Fashion” USB video cameras arrived from halfway around the planet. According to the eBay description and the legend around the lens, they’re “5.0 Megapixel”:
Fashion USB camera – case front
The reality, of course, is that for five bucks delivered you get 640×480 VGA resolution at the hardware level and their Windows driver interpolates the other 4.7 megapixels. VGA resolution will be good enough for my simple needs, particularly because the lens has a mechanical focus adjustment; the double-headed arrow symbolizes the focus action.
But the case seemed entirely too bulky and awkward. A few minutes with a #0 Philips screwdriver extracted the actual camera hardware, which turns out to be a double-sided PCB with a lens assembly on the front:
Fashion USB video – case vs camera
The PCB has asymmetric tabs that ensure correct orientation in the case:
Fashion USB camera – wired PCB rear
In order to build an OpenSCAD model for a more compact case, we need the dimensions of that PCB and those tabs…
Start with a picture of the back of the PCB against white paper, taken from a few feet to flatten the perspective:
img_3300 – Camera PCB on white paper
Load it into The GIMP, zoom in, and pull a horizontal guide line down to about the middle of the image:
Camera PCB – horizontal guide – scaled
Rotate to align the two screws horizontally (they need not be centered on the guide, just lined up horizontally):
Camera PCB – rotated to match horizontal guide – scaled
Use the Magic Scissors to select the PCB border (it’s the nearly invisible ragged dotted outline):
Camera PCB – scissors selection – scaled
Flip to Quick Mask mode and clean up the selection as needed:
Camera PCB – quick mask cleanup – scaled
Flip back to normal view, invert the selection (to select the background, not the PCB), and delete the background to isolate the PCB:
Camera PCB – isolated – scaled
Tight-crop the PCB and flatten the image to get a white background:
Camera PCB – isolated – scaled
Fetch some digital graph paper from your favorite online source. The Multi-color (Light Blue / Light Blue / Light Grey) Multi-weight (1.0×0.6×0.3 pt) grid (1 / 2 / 10) works best for me, but do what you like. Get a full Letter / A4 size sheet, because it’ll come in handy for other projects.
Open it up (converting at 300 dpi), turn it into a layer atop the PCB image, use the color-select tool to select the white background between the grid lines, then delete the selection to leave just the grid with transparency:
Camera PCB with grid overlay – unscaled
We want one minor grid square to be 1×1 mm on the PCB image, sooo…
Accurately measure a large feature on the real physical object: 27.2 mm across the tabs
Drag the grid to align a major line with one edge of the PCB
Count the number of minor square across to the other side of the image: 29.5
Scale the grid overlay layer by image/physical size: 1.085 = 29.5/27.2
Drag the grid so it’s neatly centered on the object (or has a major grid intersection somewhere useful)
That produces a calibrated overlay:
Camera PCB with grid overlay
Then it’s just a matter of reading off the coordinates, with each minor grid square representing 1.0 mm in the real world, and writing some OpenSCAD code…
Sometimes crickets make their way into the basement. This one, a model that I’ve always known as a Jerusalem Cricket(*) evidently lost a pitched battle with one of the Dust Bunnies guarding the Basement Laboratory:
Jerusalem Cricket vs Dust Bunny – top view
A rear view:
Jerusalem Cricket vs Dust Bunny – rear view
From the front:
Jerusalem Cricket vs Dust Bunny – front view
I deported it to the flower garden outside the basement door, where I hope it can brush off the Bunny’s entrapments…
It may not be a Jerusalem Cricket, because they’re more common out west, but that’s the best match in our bug books and that’s what we’ve always called them.
[Update: (*) It’s most likely a Cave Cricket. See the comments for details.]
Then generate the sphere (well, two spheres, one for each dent) and offset it to scoop out the dent:
for (i=[-1,1]) {
translate([i*(DentSphereRadius + HandleThick/2 - DentDepth),0,StringHeight])
sphere(r=DentSphereRadius);
HandleThick controls exactly what you’d expect. StringHeight sets the location of the hole punched through the handle for a string, which is also the center of the dents.
The spheres have many facets, but only a few show up in the dent. I like the way the model looks, even if the facets don’t come through clearly in the plastic:
Quilting circle template – handle dent closeup – solid model
It Just Works and the exact math produces a better result than by-guess-and-by-gosh positioning.
The sphere radius will come out crazy large for very shallow dents. Here’s the helmet plate for my Bicycle Helmet Mirror Mount, which has an indentation (roughly) matching the curve on the side of my bike helmet:
Helmet mirror mount – plate
Here’s the sphere that makes the dent, at a somewhat different zoom scale:
Helmet mirror mount – plate with sphere
Don’t worry: trust the math, because It Just Works.
You find equations like that in Thomas Glover’s invaluable Pocket Ref. If you don’t have a copy, fix that problem right now; I don’t get a cut from the purchase, but you’ll decide you owe me anyway. Small, unmarked bills. Lots and lots of small unmarked bills…
The humidity in the basement safe started rising this month:
Basement Safe – 2013-07-28
The bag of new silica gel weighed 575 g, so it adsorbed about 67 g of water as the humidity rose from bone dry to 24%. Last month it had soaked up 31 g, so the safe admits nearly an ounce of water each month with 50% RH in the basement. It takes five months to accumulate 60-ish g of water during the winter.
According to the Sorbent Systems charts, silica gel’s equilibrium capacity at 24% is about 12% of the gel’s weight, which would work out to 60 g. That’s close enough, methinks, given the graph resolution; the humidity changes slowly enough that it’s sorta-kinda equilibrated in there… 67 g works out to 13.4% of the dry weight, which is in the same ballpark.
I made up three more bags of dry gel (500 g + 7 or 8 g tare), tossed one in the safe, one in the 6 gallon plastic bucket of 3D printer filament, and one in an empty 6 gallon bucket for comparison. Some 6 dot (10-through-60%) humidity indicator cards are on their way, seeing as how I don’t have nearly enough dataloggers to keep up with the demand…
Decades ago, one jaw on my little 1/4 inch wrench that fits 4-40 nuts broke off. I brazed it back on, fully aware that one day it would break off again, because brazing isn’t really a suitable repair technique for a wrench, even one labeled as “Precision” in that time-honored manner of all low-cost tools.
Time passes, I’m tightening screws against 4-40 nuts, and the jaw gives way:
Precision wrench – broken jaw
So I sawed off a strip of bedframe steel that fit the nuts better than the original stamped steel, did a bit of hand filing, and came up with a reasonable replacement:
Precision wrench – detail
I rammed it into the handle, just as they’d done with the original stamped steel shape:
Mary just started an ambitious pieced quilt that requires 50-some-odd precisely sized 1-1/2 inch circles, with marks to locate a 1 inch circle in the middle. She started using a drafting template to mark the smaller circle on freezer paper (don’t ask, it’s complicated), but we couldn’t find the template I know I have with the larger circles.
So I says to my wife, I sez, “Hey, we have the technology. What would really simplify what you’re doing?” After a bit of doodling, we came up with a ring having the proper ID and OD, plus a flat handle of some sort.
Half an hour later, I had a solid model:
Quilting circle template – solid model
An hour after that I handed her a warm piece of plastic:
Quilting circle template
The bottom ring is exactly 1-1/2 inch OD, 1 inch ID, and thin enough to draw around. The handle keeps her fingers out of the way and even has grips and a hole for a string.
The print quality near the hole isn’t as good as I’d like, because the slicer turned that entire volume into a solid slab of plastic. I can fix that in the second version, but right now she has something to work with, evaluate, and figure out what would improve it.
3D printing isn’t for everybody, but it’s a vital part of my shop!
The OpenSCAD source code has parameters for everything, so we can crank out more templates without fuss:
// Quilting - Circle Template
// Ed Nisley KE4ZNU - July 2013
Layout = "Show"; // Show Build Circle Handle
//-------
//- Extrusion parameters must match reality!
// Print with 2 shells
ThreadThick = 0.25;
ThreadWidth = 0.40;
HoleFinagle = 0.2;
HoleFudge = 1.00;
function HoleAdjust(Diameter) = HoleFudge*Diameter + HoleFinagle;
Protrusion = 0.1; // make holes end cleanly
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
function IntegerMultipleMin(Size,Unit) = Unit * floor(Size / Unit);
inch = 25.4;
//-------
// Dimensions
CircleID = (1) * inch;
SeamAllowance = (1/4) * inch;
CircleOD = CircleID + 2*SeamAllowance;
CircleThick = 6*ThreadThick;
CircleSides = 12*4;
HandleHeight = (2) * inch;
HandleThick = IntegerMultiple(5.0,ThreadWidth);
HandleSides = 12*4;
StringDia = 4.0;
StringSides = 8;
StringHeight = 0.75*HandleHeight;
DentDepth = HandleThick/4;
DentDia = 15.0;
DentSphereRadius = (pow(DentDepth,2) + pow(DentDia,2)/4)/(2*DentDepth);
//-------
module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes
Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
FixDia = Dia / cos(180/Sides);
cylinder(r=HoleAdjust(FixDia)/2,h=Height,$fn=Sides);
}
module ShowPegGrid(Space = 10.0,Size = 1.0) {
RangeX = floor(100 / Space);
RangeY = floor(125 / Space);
for (x=[-RangeX:RangeX])
for (y=[-RangeY:RangeY])
translate([x*Space,y*Space,Size/2])
%cube(Size,center=true);
}
//-------
// Circle ring plate
module CircleRing() {
rotate(180/CircleSides)
difference() {
cylinder(r=CircleOD/2,h=CircleThick,$fn=CircleSides);
translate([0,0,-Protrusion])
cylinder(r=CircleID/2,h=(CircleThick + 2*Protrusion),$fn=CircleSides);
}
}
//-------
// Handle
module Handle() {
difference() {
rotate([0,90,0])
scale([HandleHeight/(CircleOD/2),0.9,1])
rotate(180/HandleSides)
cylinder(r=CircleOD/2,h=HandleThick,center=true,$fn=HandleSides);
translate([0,0,-HandleHeight])
cube([2*CircleOD,2*CircleOD,2*HandleHeight],center=true);
translate([-HandleThick,0,StringHeight])
rotate([0,90,0])
rotate(180/StringSides)
PolyCyl(StringDia,2*HandleThick,StringSides);
# for (i=[-1,1]) {
translate([i*(DentSphereRadius + HandleThick/2 - DentDepth),0,StringHeight])
sphere(r=DentSphereRadius);
}
}
}
module Template() {
CircleRing();
Handle();
}
//-------
// Build it!
ShowPegGrid();
if (Layout == "Circle")
CircleRing();
if (Layout == "Handle")
Handle();
if (Layout == "Show")
Template();