Loading openscad/libs/cameras/arducam_b0196.scad +15 −3 Original line number Diff line number Diff line Loading @@ -152,10 +152,15 @@ module arducam_rounded_block(b=33, w=33, h=6, roc = 2){ } } /* A mount for the Arducam B0196 USB camera This has the top at z=0+tiny(), with a surface that can be hull-ed onto the lens assembly. :param screwhole: Boolean for adding tri-linder holes for self-tapping screws */ module arducam_b0196_camera_mount(screwhole=true){ // A mount for the Arducam B0196 USB camera // This should finish at z=0+tiny(), with a surface that can be // hull-ed onto the lens assembly. w = 33; b = 33; Loading Loading @@ -239,6 +244,13 @@ module b0196_camera_bottom_mounting_posts(optics_config, outers=true, cutouts=tr } } /* Replicate and place geometry at the mounting positions for the Arducam B0196 USB camera A transformation that replicates the geometry, and postions the replicas at the mounting hole positions for the Arducam B0196 USB camera. */ module at_b0196_hole_pattern(){ screw_xy = arducam_b0196_corner_hole_spacing(); Loading openscad/libs/cameras/logitech_c270.scad +31 −4 Original line number Diff line number Diff line Loading @@ -94,10 +94,15 @@ function c270_backshell_screw_positions(flip_x=false) = let( sign = flip_x ? 1 : -1 ) [[sign*(-w/2+4), y_pos, 3], [sign*(w/2-4), y_pos, 3]]; /* A mount for the Logitech C270 USB webcam This has the top at z=0+tiny(), with a surface that can be hull-ed onto the lens assembly. :param screwhole: Boolean for adding tri-linder holes for self-tapping screws */ module c270_camera_mount(screwhole=true){ // A mount for the Logitech C270 webcam // This should finish at z=0+tiny(), with a surface that can be // hull-ed onto the lens assembly. // camera dims h = c270_dims().y; Loading Loading @@ -170,8 +175,24 @@ module c270_backshell_self_tap_screwholes(){ } } /* Height of the backshell for the C270 camera The height of the backshell part of the C270 camera cover. It is a function so that the backshell can be translated easily from its to to its base. :return: 6 */ function c270_backshell_height() = 6; /* Generate a cover for the back of the C270 camera board The cover does not reach over the entire board. It is designed to reach up to the camera platform when used with a lens spacer */ module c270_backshell(){ height = c270_backshell_height(); Loading Loading @@ -297,8 +318,14 @@ module c270_camera_bottom_mounting_posts(optics_config, outers=true, cutouts=tru } } /* Replicate and place geometry at the mounting positions for the Logitech C270 USB webcam A transformation that replicates the geometry, and postions the replicas at the mounting hole positions for the Logitech C270 USB webcam. */ module at_c270_hole_pattern(){ // posts to mount to Logitech C270 camera from below screw_x = c270_camera_hole_spacing(); // Third hole position at the far end of the board [-6,42.3,0] is too far away and makes Loading openscad/libs/cameras/picamera_2.scad +17 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,15 @@ module picam2_board(h=tiny()){ } } /* A mount for the Pi Camera v2 This has the top at z=0+tiny(), with a surface that can be hull-ed onto the lens assembly. :param screwhole: Boolean for adding tri-linder holes for self-tapping screws :param counterbore: Boolean for counterboring from the top for self-tapping screws */ module picamera_2_camera_mount(screwhole=true, counterbore=false){ // A mount for the pi camera v2 // This should finish at z=0+tiny(), with a surface that can be Loading Loading @@ -228,6 +237,14 @@ module picamera_2_bottom_mounting_posts(optics_config, outers=true, cutouts=true } } /* Replicate and place geometry at the mounting positions for the Pi camera v2 A transformation that replicates the geometry, and postions the replicas at the mounting hole positions for the Pi camera v2. The mounting positions are the same for the Pi Camera v1 and v3 */ module at_picamera_2_hole_pattern(){ // posts to mount to pi camera from below screw_x = picamera_2_hole_spacing()/2; Loading openscad/libs/lib_optics.scad +26 −4 Original line number Diff line number Diff line Loading @@ -23,13 +23,29 @@ function optics_wedge_bottom() = -2; //bottom of dovetail (<0 to allow some play // This is used for both the lens spacer and the tube lens gripper function lens_aperture(lens_r) = lens_r - 1.5; // This function is used for conditional modification of optics modules and platforms // to fit the Logitech C270 webcam /* Identify optics type as Logitech C270 lens spacer This function is used for conditional modification of optics modules and platforms to fit the Logitech C270 webcam :param optics_config: Optics configuration dictionary :return: Boolean identifying if the camera type is logitech C270 and the optics is a lens spacer */ function is_c270_spacer(optics_config) = (key_lookup("optics_type", optics_config) == "spacer") && (key_lookup("camera_type", optics_config) == "logitech_c270"); // This function is used because the Arducam B0196 camera needs a cut-out in the // camera platform for the USB cable /* Identify optics type as Arducam B0196 lens spacer This function is used because the Arducam B0196 USB camera needs a cut-out in the camera platform for the USB cable :param optics_config: Optics configuration dictionary :return: Boolean identifying if the camera type is Arducam B0196 and the optics is a lens spacer */ function is_b0196_spacer(optics_config) = (key_lookup("optics_type", optics_config) == "spacer") && (key_lookup("camera_type", optics_config) == "arducam_b0196") ; Loading Loading @@ -352,6 +368,12 @@ function lens_spacer_z(params, optics_config) = let( lens_spacing = key_lookup("lens_spacing", optics_config) ) sample_z - (parfocal_distance + camera_sensor_height(optics_config) + lens_spacing); /* Generate a configurable lens spacer for low-cost optics modules :param params: Microscope parameters dictionary :param optics_config: Optics configuration dictionary */ module lens_spacer(params, optics_config){ // Mount a lens some distance from the camera Loading openscad/libs/optics_configurations.scad +54 −8 Original line number Diff line number Diff line use <./libdict.scad> /* Return the rotation angle for a camera type used in rms optics :param camera_type: String defining the camera type :return: Angle to rotate the camera */ function rms_optics_camera_rotation(camera_type) = let( rotations_dict = [["picamera_2", 45], ["m12", 0], Loading @@ -7,15 +14,19 @@ function rms_optics_camera_rotation(camera_type) = let( ["arducam_b0196", 45]] ) key_lookup(camera_type, rotations_dict); // Notes on parameters: // // camera_rotation: The angle of the camera mount (for PiCamera v2 the ribbon cable exits at // 180 degrees from mount for '0' & 135 degrees from mount for '45') // // beamsplitter_rotation: The angle of the block to hold the fl cube (0 for the fl cube exiting // at 180 degree from the mount and -60 for the fl cube exiting at 120 // from the mount) /* Return a dictionary of parameters for defining a finite conjugates RMS optics module :param camera_type: String defining the camera type :param beamsplitter: Boolean for adding a beamsplitter module :param parfocal_distance: Parfocal distance for the microscope objective (mm) :param camera_rotation: The angle of the camera mount (for PiCamera v2 the ribbon cable exits at 180 degrees from mount for '0' & 135 degrees from mount for '45') :param beamsplitter_rotation: The angle of the block to hold the fl cube (0 for the fl cube exiting at 180 degree from the mount and -60 for the fl cube exiting at 120 from the mount) :return: optics configuration dictionary */ function rms_f50d13_config(camera_type = "picamera_2", beamsplitter=false, parfocal_distance=45, camera_rotation=undef, beamsplitter_rotation=0) = let( // if the parfocal distance is undefined, use the default. parfocal_distance_validated = (parfocal_distance == undef) ? 45 : parfocal_distance, Loading @@ -40,11 +51,32 @@ function rms_f50d13_config(camera_type = "picamera_2", beamsplitter=false, parfo ["beamsplitter_rotation", beamsplitter_rotation]] ) config_dict; /* Return a dictionary of parameters for defining an infinite conjugates RMS optics module :param camera_type: String defining the camera type :param beamsplitter: Boolean for adding a beamsplitter module :param parfocal_distance: Parfocal distance for the microscope objective (mm) :param camera_rotation: The angle of the camera mount (for PiCamera v2 the ribbon cable exits at 180 degrees from mount for '0' & 135 degrees from mount for '45') :param beamsplitter_rotation: The angle of the block to hold the fl cube (0 for the fl cube exiting at 180 degree from the mount and -60 for the fl cube exiting at 120 from the mount) :return: optics configuration dictionary */ function rms_infinity_f50d13_config(camera_type = "picamera_2", beamsplitter=false, parfocal_distance=undef, camera_rotation=0, beamsplitter_rotation=0) = let( finite_config = rms_f50d13_config(camera_type, beamsplitter, parfocal_distance, camera_rotation, beamsplitter_rotation), replacements = [["is_finite_conjugate", false]] ) replace_multiple_values(replacements, finite_config); /* Return a dictionary of parameters for defining a lens spacer module for a Pi Camera v2 :param camera_type: String defining the camera type :param upright: Boolean to select values for using on an upright microscope :return: optics configuration dictionary */ function pilens_config(camera_type = "picamera_2", upright=false) = let( rotation = upright ? 45+180 : 45, config_dict = [["optics_type", "spacer"], Loading @@ -58,6 +90,13 @@ function pilens_config(camera_type = "picamera_2", upright=false) = let( ["rotation", rotation]] // camera rotation about z ) config_dict; /* Return a dictionary of parameters for defining a lens spacer module for a Logitech C270 webcam :param camera_type: String defining the camera type :return: optics configuration dictionary */ function c270lens_config(camera_type = "logitech_c270") = let( config_dict = [["optics_type", "spacer"], ["camera_type", camera_type], Loading @@ -70,6 +109,13 @@ function c270lens_config(camera_type = "logitech_c270") = let( ["rotation", 180]] // camera rotation about z ) config_dict; /* Return a dictionary of parameters for defining a lens spacer module for an Arducam B0196 USB camera :param camera_type: String defining the camera type :return: optics configuration dictionary */ function b0196lens_config(camera_type = "arducam_b0196") = let( config_dict = [["optics_type", "spacer"], ["camera_type", camera_type], Loading Loading
openscad/libs/cameras/arducam_b0196.scad +15 −3 Original line number Diff line number Diff line Loading @@ -152,10 +152,15 @@ module arducam_rounded_block(b=33, w=33, h=6, roc = 2){ } } /* A mount for the Arducam B0196 USB camera This has the top at z=0+tiny(), with a surface that can be hull-ed onto the lens assembly. :param screwhole: Boolean for adding tri-linder holes for self-tapping screws */ module arducam_b0196_camera_mount(screwhole=true){ // A mount for the Arducam B0196 USB camera // This should finish at z=0+tiny(), with a surface that can be // hull-ed onto the lens assembly. w = 33; b = 33; Loading Loading @@ -239,6 +244,13 @@ module b0196_camera_bottom_mounting_posts(optics_config, outers=true, cutouts=tr } } /* Replicate and place geometry at the mounting positions for the Arducam B0196 USB camera A transformation that replicates the geometry, and postions the replicas at the mounting hole positions for the Arducam B0196 USB camera. */ module at_b0196_hole_pattern(){ screw_xy = arducam_b0196_corner_hole_spacing(); Loading
openscad/libs/cameras/logitech_c270.scad +31 −4 Original line number Diff line number Diff line Loading @@ -94,10 +94,15 @@ function c270_backshell_screw_positions(flip_x=false) = let( sign = flip_x ? 1 : -1 ) [[sign*(-w/2+4), y_pos, 3], [sign*(w/2-4), y_pos, 3]]; /* A mount for the Logitech C270 USB webcam This has the top at z=0+tiny(), with a surface that can be hull-ed onto the lens assembly. :param screwhole: Boolean for adding tri-linder holes for self-tapping screws */ module c270_camera_mount(screwhole=true){ // A mount for the Logitech C270 webcam // This should finish at z=0+tiny(), with a surface that can be // hull-ed onto the lens assembly. // camera dims h = c270_dims().y; Loading Loading @@ -170,8 +175,24 @@ module c270_backshell_self_tap_screwholes(){ } } /* Height of the backshell for the C270 camera The height of the backshell part of the C270 camera cover. It is a function so that the backshell can be translated easily from its to to its base. :return: 6 */ function c270_backshell_height() = 6; /* Generate a cover for the back of the C270 camera board The cover does not reach over the entire board. It is designed to reach up to the camera platform when used with a lens spacer */ module c270_backshell(){ height = c270_backshell_height(); Loading Loading @@ -297,8 +318,14 @@ module c270_camera_bottom_mounting_posts(optics_config, outers=true, cutouts=tru } } /* Replicate and place geometry at the mounting positions for the Logitech C270 USB webcam A transformation that replicates the geometry, and postions the replicas at the mounting hole positions for the Logitech C270 USB webcam. */ module at_c270_hole_pattern(){ // posts to mount to Logitech C270 camera from below screw_x = c270_camera_hole_spacing(); // Third hole position at the far end of the board [-6,42.3,0] is too far away and makes Loading
openscad/libs/cameras/picamera_2.scad +17 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,15 @@ module picam2_board(h=tiny()){ } } /* A mount for the Pi Camera v2 This has the top at z=0+tiny(), with a surface that can be hull-ed onto the lens assembly. :param screwhole: Boolean for adding tri-linder holes for self-tapping screws :param counterbore: Boolean for counterboring from the top for self-tapping screws */ module picamera_2_camera_mount(screwhole=true, counterbore=false){ // A mount for the pi camera v2 // This should finish at z=0+tiny(), with a surface that can be Loading Loading @@ -228,6 +237,14 @@ module picamera_2_bottom_mounting_posts(optics_config, outers=true, cutouts=true } } /* Replicate and place geometry at the mounting positions for the Pi camera v2 A transformation that replicates the geometry, and postions the replicas at the mounting hole positions for the Pi camera v2. The mounting positions are the same for the Pi Camera v1 and v3 */ module at_picamera_2_hole_pattern(){ // posts to mount to pi camera from below screw_x = picamera_2_hole_spacing()/2; Loading
openscad/libs/lib_optics.scad +26 −4 Original line number Diff line number Diff line Loading @@ -23,13 +23,29 @@ function optics_wedge_bottom() = -2; //bottom of dovetail (<0 to allow some play // This is used for both the lens spacer and the tube lens gripper function lens_aperture(lens_r) = lens_r - 1.5; // This function is used for conditional modification of optics modules and platforms // to fit the Logitech C270 webcam /* Identify optics type as Logitech C270 lens spacer This function is used for conditional modification of optics modules and platforms to fit the Logitech C270 webcam :param optics_config: Optics configuration dictionary :return: Boolean identifying if the camera type is logitech C270 and the optics is a lens spacer */ function is_c270_spacer(optics_config) = (key_lookup("optics_type", optics_config) == "spacer") && (key_lookup("camera_type", optics_config) == "logitech_c270"); // This function is used because the Arducam B0196 camera needs a cut-out in the // camera platform for the USB cable /* Identify optics type as Arducam B0196 lens spacer This function is used because the Arducam B0196 USB camera needs a cut-out in the camera platform for the USB cable :param optics_config: Optics configuration dictionary :return: Boolean identifying if the camera type is Arducam B0196 and the optics is a lens spacer */ function is_b0196_spacer(optics_config) = (key_lookup("optics_type", optics_config) == "spacer") && (key_lookup("camera_type", optics_config) == "arducam_b0196") ; Loading Loading @@ -352,6 +368,12 @@ function lens_spacer_z(params, optics_config) = let( lens_spacing = key_lookup("lens_spacing", optics_config) ) sample_z - (parfocal_distance + camera_sensor_height(optics_config) + lens_spacing); /* Generate a configurable lens spacer for low-cost optics modules :param params: Microscope parameters dictionary :param optics_config: Optics configuration dictionary */ module lens_spacer(params, optics_config){ // Mount a lens some distance from the camera Loading
openscad/libs/optics_configurations.scad +54 −8 Original line number Diff line number Diff line use <./libdict.scad> /* Return the rotation angle for a camera type used in rms optics :param camera_type: String defining the camera type :return: Angle to rotate the camera */ function rms_optics_camera_rotation(camera_type) = let( rotations_dict = [["picamera_2", 45], ["m12", 0], Loading @@ -7,15 +14,19 @@ function rms_optics_camera_rotation(camera_type) = let( ["arducam_b0196", 45]] ) key_lookup(camera_type, rotations_dict); // Notes on parameters: // // camera_rotation: The angle of the camera mount (for PiCamera v2 the ribbon cable exits at // 180 degrees from mount for '0' & 135 degrees from mount for '45') // // beamsplitter_rotation: The angle of the block to hold the fl cube (0 for the fl cube exiting // at 180 degree from the mount and -60 for the fl cube exiting at 120 // from the mount) /* Return a dictionary of parameters for defining a finite conjugates RMS optics module :param camera_type: String defining the camera type :param beamsplitter: Boolean for adding a beamsplitter module :param parfocal_distance: Parfocal distance for the microscope objective (mm) :param camera_rotation: The angle of the camera mount (for PiCamera v2 the ribbon cable exits at 180 degrees from mount for '0' & 135 degrees from mount for '45') :param beamsplitter_rotation: The angle of the block to hold the fl cube (0 for the fl cube exiting at 180 degree from the mount and -60 for the fl cube exiting at 120 from the mount) :return: optics configuration dictionary */ function rms_f50d13_config(camera_type = "picamera_2", beamsplitter=false, parfocal_distance=45, camera_rotation=undef, beamsplitter_rotation=0) = let( // if the parfocal distance is undefined, use the default. parfocal_distance_validated = (parfocal_distance == undef) ? 45 : parfocal_distance, Loading @@ -40,11 +51,32 @@ function rms_f50d13_config(camera_type = "picamera_2", beamsplitter=false, parfo ["beamsplitter_rotation", beamsplitter_rotation]] ) config_dict; /* Return a dictionary of parameters for defining an infinite conjugates RMS optics module :param camera_type: String defining the camera type :param beamsplitter: Boolean for adding a beamsplitter module :param parfocal_distance: Parfocal distance for the microscope objective (mm) :param camera_rotation: The angle of the camera mount (for PiCamera v2 the ribbon cable exits at 180 degrees from mount for '0' & 135 degrees from mount for '45') :param beamsplitter_rotation: The angle of the block to hold the fl cube (0 for the fl cube exiting at 180 degree from the mount and -60 for the fl cube exiting at 120 from the mount) :return: optics configuration dictionary */ function rms_infinity_f50d13_config(camera_type = "picamera_2", beamsplitter=false, parfocal_distance=undef, camera_rotation=0, beamsplitter_rotation=0) = let( finite_config = rms_f50d13_config(camera_type, beamsplitter, parfocal_distance, camera_rotation, beamsplitter_rotation), replacements = [["is_finite_conjugate", false]] ) replace_multiple_values(replacements, finite_config); /* Return a dictionary of parameters for defining a lens spacer module for a Pi Camera v2 :param camera_type: String defining the camera type :param upright: Boolean to select values for using on an upright microscope :return: optics configuration dictionary */ function pilens_config(camera_type = "picamera_2", upright=false) = let( rotation = upright ? 45+180 : 45, config_dict = [["optics_type", "spacer"], Loading @@ -58,6 +90,13 @@ function pilens_config(camera_type = "picamera_2", upright=false) = let( ["rotation", rotation]] // camera rotation about z ) config_dict; /* Return a dictionary of parameters for defining a lens spacer module for a Logitech C270 webcam :param camera_type: String defining the camera type :return: optics configuration dictionary */ function c270lens_config(camera_type = "logitech_c270") = let( config_dict = [["optics_type", "spacer"], ["camera_type", camera_type], Loading @@ -70,6 +109,13 @@ function c270lens_config(camera_type = "logitech_c270") = let( ["rotation", 180]] // camera rotation about z ) config_dict; /* Return a dictionary of parameters for defining a lens spacer module for an Arducam B0196 USB camera :param camera_type: String defining the camera type :return: optics configuration dictionary */ function b0196lens_config(camera_type = "arducam_b0196") = let( config_dict = [["optics_type", "spacer"], ["camera_type", camera_type], Loading