Archive for March 21st, 2014

Laser-photodiode Beam-Break Sensor Fixture

The game plan: drop a small object through a laser beam that shines on a photodiode, thus causing an electrical signal that triggers various flashes and cameras and so forth and so on. This fixture holds the laser and photodiode in the proper orientation, with enough stability that you (well, I) can worry about other things:

Laser-photodiode fixture - on blade

Laser-photodiode fixture – on blade

It’s mounted on the blade of a dirt-cheap 2 foot machinist’s square¬†clamped to the bench which will probably get a few holes drilled in its baseplate for more permanent mounting.

The solid model looks about like you’d expect:

Laser-photodiode fixture - solid model

Laser-photodiode fixture – solid model

There’s a small hole in the back for an 8-32 setscrew that locks it to the blade; the fit turned out snug enough to render the screw superfluous. I added those two square blocks with the holes after I taped the wires to the one in the picture.

The two semicircular (well, half-octagonal) trenches have slightly different diameters to suit the heatshrink tubing around the photodiode (a.k.a., IR LED) and brass laser housing. A dab of fabric adhesive holds the tubes in place, in addition to the Gorilla Tape on the ends.

The laser came focused at infinity, of course. Unscrewing the lens almost all the way put the focus about 3/4 of the way across the ring; call it 40 mm. The beam is rectangular, about 1√ó2 mm, at the center of the ring, and I rotated the body to make the short axis vertical; that’s good enough for my purposes.

The cable came from a pair of cheap earbuds with separate Left/Right pairs all the way from the plug.

The model builds in one piece, of course, and pops off the platform ready to use:

Laser-photodiode fixture - on platform

Laser-photodiode fixture – on platform

If you were doing this for an analytic project, you’d want a marker for the beam centerline on the vertical scale, but that’s in the nature of fine tuning. As it stands, the beam sits 8 mm above the base and flush with the top surface of the ring; if that were 10 mm, it’d be easier to remember.

The OpenSCAD source code has a few tweaks and improvements:

// Laser and LED-photodiode break-beam sensor
// Ed Nisley - KE4ZNU - March 2014

Layout = "Show";			// Build Show Ring Mount Guide

//- Extrusion parameters must match reality!
//  Print with 2 shells and 3 solid layers

ThreadThick = 0.20;
ThreadWidth = 0.40;

HoleWindage = 0.2;			// extra clearance

Protrusion = 0.1;			// make holes end cleanly

AlignPinOD = 1.70;			// assembly alignment pins: filament dia

inch = 25.4;

function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);

//----------------------
// Dimensions

LaserOD = 6.0;				// brass focus tube
LaserLength = 20.0;			//  ... wire clearance

SensorOD = 6.5;				// including light shield
SensorLength = 20.0;		//  ... wire clearance

RingSize = [50.0,70.0,8.0,8*4];	// support ring dimensions
RING_ID = 0;
RING_OD = 1;
RING_THICK = 2;
RING_SIDES = 3;

StrutWidth = 2.5;					// strut supporting this thing
StrutLength = 26.5;

StrutBlock = [10.0,35.0,20.0];		// block around the clearance slot
BLOCK_WIDTH = 0;
BLOCK_LENGTH = 1;
BLOCK_HEIGHT = 2;

StrutScrewTap = 2.7;				// 6-32 SHCS

GuideID = 4.0;						// guide for cables
GuideOD = 3*GuideID;

BuildSpace = 3.0;					// spacing between objects on platform

//----------------------
// Useful routines

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=(FixDia + HoleWindage)/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);

}

module Ring() {

	difference() {
		union() {
			rotate(180/RingSize[RING_SIDES])
				cylinder(d=RingSize[RING_OD],h=RingSize[RING_THICK],
						$fn=RingSize[RING_SIDES]);
			translate([-LaserOD,(-LaserLength - RingSize[RING_ID]/2),0])
				cube([2*LaserOD,LaserLength,RingSize[RING_THICK]],center=false);
			translate([-SensorOD,(-0*SensorLength + RingSize[RING_ID]/2),0])
				cube([2*SensorOD,SensorLength,RingSize[RING_THICK]],center=false);
		}
		rotate(180/RingSize[RING_SIDES])
			translate([0,0,-Protrusion])
				cylinder(d=RingSize[RING_ID],h=(RingSize[RING_THICK] + 2*Protrusion),
						$fn=RingSize[RING_SIDES]);
		translate([0,0,RingSize[RING_THICK]])
			rotate([90,0,0]) rotate(180/8)
				PolyCyl(LaserOD,3*LaserLength,8);
		translate([0,0,RingSize[RING_THICK]])
			rotate([-90,0,0]) rotate(180/8)
				PolyCyl(SensorOD,3*SensorLength,8);
	}
}

module Mount() {
	translate([0,0,StrutBlock[2]/2])
		difference() {
			cube(StrutBlock,center=true);
			cube([StrutWidth,StrutLength,2*StrutBlock[2]],center=true);
			translate([0,-StrutLength/3,0])
				rotate([90,0,0])
					PolyCyl(StrutScrewTap,StrutLength/2,6);
		}
}

module Guide() {

	difference() {
		translate([0,0,RingSize[RING_THICK]/2])
			cube([GuideOD,GuideOD,RingSize[RING_THICK]],center=true);
		translate([0,0,-Protrusion]) rotate(180/8)
			PolyCyl(GuideID,(RingSize[RING_THICK] + 2*Protrusion),8);
	}
}

module Assembly() {
	Ring();
	translate([(RingSize[RING_OD]/2 + StrutBlock[BLOCK_LENGTH]/2
				- (StrutBlock[BLOCK_LENGTH] - StrutLength)/2) + Protrusion,0,0])
		rotate(90)
			Mount();
	for (i=[-1,1])
		translate([(RingSize[RING_OD]/2 + GuideID/2),
				  i*(StrutBlock[BLOCK_WIDTH]/2 + GuideID),
				  0])
			Guide();
}

//- Build it

ShowPegGrid();

if (Layout == "Ring") {
	Ring();
}

if (Layout == "Mount") {
	Mount();
}

if (Layout == "Guide") {
	Guide();
}

if (Layout == "Show") {
	Assembly();
}

if (Layout == "Build") {

	translate([-5/2,-5/2,0])
		cube(5);
}

,

7 Comments