display-frame

Wall frame for touchscreen display
git clone https://www.brianlane.com/git/display-frame
Log | Files | Refs | README

commit 9ece54e336a215cd8fc3f03afe0cc864f943c540
Author: Brian C. Lane <bcl@brianlane.com>
Date:   Mon, 26 Jun 2023 07:41:48 -0700

Initial commit of cleaned up frame source

Diffstat:
Adisplay-frame.scad | 228+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 228 insertions(+), 0 deletions(-)

diff --git a/display-frame.scad b/display-frame.scad @@ -0,0 +1,228 @@ +// Adafruit display and Raspberry Pi Zero wall frame +// This consists of 2 parts, the back which mounts to the wall with screws, +// holds the Raspberry Pi Zero, and the Adafruit 7" touchscreen display. And +// the front bezel/frame which clips into the back. +// +// Copyright 2023 by Brian C. Lane <bcl@brianlane.com> +// All Rights Reserved +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of the <ORGANIZATION> nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// If you have any questions about this license please email bcl@brianlane.com +$fn = 30; + +// Adafruit 7" touchscreen display with HDMI and USB connectors +displayWidth = 85.5; +displayHeight = 154; +mountRadius = 2.8/2; +corner = [19, 5*mountRadius, 0]; + + +module display(h=2) { + cube([displayWidth, displayHeight, h]); +} + +// A latch, place it so the tip slightly overlaps the board to hold it in place +// Note that if it is too short and wide it will not flex +module latch(r=[0,0,0], h=11) { + rotate(r) difference() { + union() { + cube([4, 2, h]); + translate([2, 1, h-4.5]) cylinder(h = 4, r1=1, r2=4); + translate([2, 1, h-0.5]) cylinder(h = 1, r1=4, r2=3); + } + translate([-2, -4, 0]) cube([8, 4, h+4]); + translate([-2, -1, 0]) cube([2, 6, h+4]); + translate([4, -1, 0]) cube([2, 6, h+4]); + } +} + +// A smaller latch for the rPi zero +module pi_latch_pin(r=[0, 0, 0]) { + pin_r = 2.8/2; + cylinder(r=pin_r, h=5); + cylinder(r=pin_r*1.5, h=3); + translate([1, 5.5, 0]) scale([0.5, 0.5, 1]) latch(r=[0, 0, 180], h=7); +} + +// rPi zero board with mounting holes +module pi_zero() { + holes = [[3.5, 3.5], [61.5, 3.5], [3.5, 26.5], [61.5, 26.5]]; + r = 2.8/2; + difference() { + cube([65, 30, 2]); + for(pos = holes) { + translate([pos[0], pos[1], 0]) cylinder(r=r, h=2); + } + } +} + +// Mounting plate for rPi zero +module pi_mount() { + mounts = [[3.5, 3.5, 90], [61.5, 3.5, -90], [3.5, 26.5, 90], [61.5, 26.5, -90]]; + r = 2.8/2; + cube([65+11+11, 30+4+4, 2]); + + for(pos=mounts) { + translate([11+pos[0], 4+pos[1], 2]) rotate([0, 0, pos[2]]) pi_latch_pin(); + } +} + +// Hanger +module hanger_hole(depth=2) { + cylinder(r=9/2, h=depth); + translate([0, 4+5, 0]) cylinder(r=4.5/2, h=depth); + translate([-4.5/2, 4, 0]) cube([4.5, 5, depth]); +} + +// Single hanger slot on a plate +module hanger(width=15, height=20, depth=2) { + difference() { + cube([width, height, depth]); + translate([width/2, (height-15.75+9)/2, 0]) hanger_hole(); + } +} + +// 2 hanger slots, 90 degrees opposed, common center hole +module dual_hanger(base=[20, 20, 2], center=[0, 0, 0], r=[0, 0, 90]) { + difference() { + cube(base); + translate(center+[0, -15.75+9, 0]) { + hanger_hole(); + rotate(r) hanger_hole(); + } + } +} + +// Diagnostic to help measure between two points and check alignment +module measure(p1=[0, 0, 0], p2=[10, 0, 0], r=1, h=1) { + #hull() { + translate(p1) cylinder(r=r, h=h); + translate(p2) cylinder(r=r, h=h); + } +} + +// A plate with a slot for the front to clip into +module latch_plate() { + difference() { + cube([2, 20, 7]); + translate([0, 7, 5]) rotate([-90, 0, 0]) cylinder(r=1, h=6); + } +} + +module front_latch() { + cube([2, 20, 30]); + translate([0, 7, 3]) rotate([-90, 0, 0]) cylinder(r=1, h=6); +} + +module back_frame1() { + + // Corner pads + cube([20, 20, 2]); + translate([124-20, 0, 0]) cube([20, 20, 2]); + translate([0, 185-35, 0]) cube([20, 20, 2]); + translate([124-20, 185-35, 0]) cube([20, 20, 2]); + + // Mounting posts and latches + translate(corner+[-9, 0, 0]) cylinder(r=mountRadius, h=26); + translate(corner+[-9, 0, 0]) cylinder(r=mountRadius*1.5, h=24); + translate(corner+[-10, 0, 2]) cube([2, 6, 8]); + translate(corner+[-7, 7, 0]) latch(r=[0, 0, 180], h=28); + + translate(corner+[displayWidth+14, 0, 0]) cylinder(r=mountRadius, h=26); + translate(corner+[displayWidth+14, 0, 0]) cylinder(r=mountRadius*1.5, h=24); + translate(corner+[displayWidth+14-1, 0, 2]) cube([2, 6, 8]); + translate(corner+[displayWidth+16, 7, 0]) latch(r=[0, 0, 180], h=28); + + translate(corner+[-9, 155+1.4, 0]) cylinder(r=mountRadius, h=26); + translate(corner+[-9, 155+1.4, 0]) cylinder(r=mountRadius*1.5, h=24); + translate(corner+[-10, 155+1.4-6, 2]) cube([2, 6, 8]); + translate(corner+[-11, 155+1.4-7, 0]) latch(r=[0, 0, 0], h=28); + + translate(corner+[displayWidth+14, 155+1.4, 0]) cylinder(r=mountRadius, h=26); + translate(corner+[displayWidth+14, 155+1.4, 0]) cylinder(r=mountRadius*1.5, h=24); + translate(corner+[displayWidth+12+1, 155+1.4-6, 2]) cube([2, 6, 8]); + translate(corner+[displayWidth+12, 155+1.4-7, 0]) latch(r=[0, 0, 0], h=28); + +// Diagnostic of the rPi Zero board and mounting holes +// translate(corner+[20, 58, 5]) #pi_zero(); + + // rPi Zero mount with holes punched in it + difference() { + union() { + translate(corner+[9, 54, 0]) pi_mount(); + translate([10, corner[1]+54, 0]) cube([18, 38, 2]); + } + translate([20, 80, -0.5]) cylinder(r=15, h=3); + translate([60, 80, -0.5]) cylinder(r=15, h=3); + translate([85, 80, -0.5]) cylinder(r=15, h=3); + } + + // Join the pieces with a frame + translate([0, 15, 0]) cube([10, 140, 2]); + translate([124-10, 15, 0]) cube([10, 140, 2]); + translate([114, 0, 0]) rotate([0, 0, 90]) cube([10, 100, 2]); + translate([114, 160, 0]) rotate([0, 0, 90]) cube([10, 100, 2]); + + // Latch plate for front to clip into + translate([6, 70, 2]) latch_plate(); + translate([3, 70, 2]) cube([1, 20, 10]); + translate([124-6, 70, 2]) mirror([1, 0, 0]) latch_plate(); + translate([124-4, 70, 2]) cube([1, 20, 10]); + + // Hangers + translate([16, 140, 0]) hanger(); + translate([92, 140, 0]) dual_hanger(base=[23, 25, 2], center=[8, 14.5, 0], r=[0, 0, -90]); + translate([93, 32, 0]) rotate([0, 0, -90]) hanger(height=21); +} + +module ell() { + cube([10, 1.0, 12]); + cube([1.0, 10, 12]); +} + +module front_frame() { + union() { + difference() { + translate([0, corner[1]-20, 0]) cube([124, displayHeight+40, 2]); + translate(corner-[0, 0, 1]) display(4); + } + + translate([6, 70, -29]) mirror([1, 0, 0]) front_latch(); + translate([124-6, 70, -29]) front_latch(); + + // Corner registration on display mounting tabs + translate(corner+[-9-5.5, -5.5, -12]) ell(); + translate(corner+[displayWidth+14-6.5+12, -5.5, -12]) mirror([1, 0, 0]) ell(); + translate(corner+[-9-5.5, 155+1.4+5.5, -12]) mirror([0, 1, 0]) ell(); + translate(corner+[displayWidth+14-6.5+12, 155+1.4+5.5, -12]) mirror([1, 1, 0]) ell(); + } +} + + +// Comment out one or the other before exporting to STL +translate([0, 0, -33.5]) #back_frame1(); +front_frame();