display-frame

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

display-frame.scad (8465B)


      1 // Adafruit display and Raspberry Pi Zero wall frame
      2 // This consists of 2 parts, the back which mounts to the wall with screws,
      3 // holds the Raspberry Pi Zero, and the Adafruit 7" touchscreen display. And
      4 // the front bezel/frame which clips into the back.
      5 //
      6 // Copyright 2023 by Brian C. Lane <bcl@brianlane.com>
      7 // All Rights Reserved
      8 //
      9 // Redistribution and use in source and binary forms, with or without
     10 // modification, are permitted provided that the following conditions are met:
     11 //
     12 //     * Redistributions of source code must retain the above copyright notice,
     13 //       this list of conditions and the following disclaimer.
     14 //
     15 //     * Redistributions in binary form must reproduce the above copyright notice,
     16 //       this list of conditions and the following disclaimer in the documentation
     17 //       and/or other materials provided with the distribution.
     18 //
     19 //     * Neither the name of the <ORGANIZATION> nor the names of its contributors
     20 //       may be used to endorse or promote products derived from this software
     21 //       without specific prior written permission.
     22 //
     23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     24 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     25 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     26 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
     27 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     29 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     30 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     31 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     32 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     33 //
     34 // If you have any questions about this license please email bcl@brianlane.com
     35 $fn = 30;
     36 
     37 // Adafruit 7" touchscreen display with HDMI and USB connectors
     38 displayWidth = 85.5;
     39 displayHeight = 154;
     40 mountRadius = 2.8/2;
     41 corner = [19, 5*mountRadius, 0];
     42 
     43 
     44 module display(h=2) {
     45     cube([displayWidth, displayHeight, h]);
     46 }
     47 
     48 // A latch, place it so the tip slightly overlaps the board to hold it in place
     49 // Note that if it is too short and wide it will not flex
     50 module latch(r=[0,0,0], h=11) {
     51     rotate(r) difference() {
     52         union() {
     53             cube([4, 2, h]);
     54             translate([2, 1, h-4.5]) cylinder(h = 4, r1=1, r2=4);
     55             translate([2, 1, h-0.5]) cylinder(h = 1, r1=4, r2=3);
     56         }
     57         translate([-2, -4, 0]) cube([8, 4, h+4]);
     58         translate([-2, -1, 0]) cube([2, 6, h+4]);
     59         translate([4, -1, 0]) cube([2, 6, h+4]);
     60     }
     61 }
     62 
     63 // A smaller latch for the rPi zero
     64 module pi_latch_pin(r=[0, 0, 0]) {
     65     pin_r = 2.8/2;
     66     cylinder(r=pin_r, h=5);
     67     cylinder(r=pin_r*1.5, h=3);
     68     translate([1, 5.5, 0]) scale([0.5, 0.5, 1]) latch(r=[0, 0, 180], h=7);
     69 }
     70 
     71 // rPi zero board with mounting holes
     72 module pi_zero() {
     73     holes = [[3.5, 3.5], [61.5, 3.5], [3.5, 26.5], [61.5, 26.5]];
     74     r = 2.8/2;
     75     difference() {
     76         cube([65, 30, 2]);
     77         for(pos = holes) {
     78             translate([pos[0], pos[1], 0]) cylinder(r=r, h=2);
     79         }
     80     }
     81 }
     82 
     83 // Mounting plate for rPi zero
     84 module pi_mount() {
     85     mounts = [[3.5, 3.5, 90], [61.5, 3.5, -90], [3.5, 26.5, 90], [61.5, 26.5, -90]];
     86     r = 2.8/2;
     87     cube([65+11+11, 30+4+4, 2]);
     88 
     89     for(pos=mounts) {
     90         translate([11+pos[0], 4+pos[1], 2]) rotate([0, 0, pos[2]]) pi_latch_pin();
     91     }
     92 }
     93 
     94 // Hanger
     95 module hanger_hole(depth=2) {
     96     cylinder(r=9/2, h=depth);
     97     translate([0, 4+5, 0]) cylinder(r=4.5/2, h=depth);
     98     translate([-4.5/2, 4, 0]) cube([4.5, 5, depth]);
     99 }
    100 
    101 // Single hanger slot on a plate
    102 module hanger(width=15, height=20, depth=2) {
    103     difference() {
    104         cube([width, height, depth]);
    105         translate([width/2, (height-15.75+9)/2, 0]) hanger_hole();
    106     }
    107 }
    108 
    109 // 2 hanger slots, 90 degrees opposed, common center hole
    110 module dual_hanger(base=[20, 20, 2], center=[0, 0, 0], r=[0, 0, 90]) {
    111     difference() {
    112         cube(base);
    113         translate(center+[0, -15.75+9, 0]) {
    114             hanger_hole();
    115             rotate(r) hanger_hole();
    116         }
    117     }
    118 }
    119 
    120 // Diagnostic to help measure between two points and check alignment
    121 module measure(p1=[0, 0, 0], p2=[10, 0, 0], r=1, h=1) {
    122     #hull() {
    123         translate(p1) cylinder(r=r, h=h);
    124         translate(p2) cylinder(r=r, h=h);
    125     }
    126 }
    127 
    128 // A plate with a slot for the front to clip into
    129 module latch_plate() {
    130     difference() {
    131         cube([2, 20, 7]);
    132         translate([0, 7, 5]) rotate([-90, 0, 0]) cylinder(r=1, h=6);
    133     }
    134 }
    135 
    136 module front_latch() {
    137     cube([2, 20, 30]);
    138     translate([0, 7, 3]) rotate([-90, 0, 0]) cylinder(r=1, h=6);
    139 }
    140 
    141 module back_frame1() {
    142 
    143         // Corner pads
    144         cube([20, 20, 2]);
    145         translate([124-20, 0, 0]) cube([20, 20, 2]);
    146         translate([0, 185-35, 0]) cube([20, 20, 2]);
    147         translate([124-20, 185-35, 0]) cube([20, 20, 2]);
    148 
    149         // Mounting posts and latches
    150         translate(corner+[-9, 0, 0]) cylinder(r=mountRadius, h=26);
    151         translate(corner+[-9, 0, 0]) cylinder(r=mountRadius*1.5, h=24);
    152         translate(corner+[-10, 0, 2]) cube([2, 6, 8]);
    153         translate(corner+[-7, 7, 0]) latch(r=[0, 0, 180], h=28);
    154 
    155         translate(corner+[displayWidth+14, 0, 0]) cylinder(r=mountRadius, h=26);
    156         translate(corner+[displayWidth+14, 0, 0]) cylinder(r=mountRadius*1.5, h=24);
    157         translate(corner+[displayWidth+14-1, 0, 2]) cube([2, 6, 8]);
    158         translate(corner+[displayWidth+16, 7, 0]) latch(r=[0, 0, 180], h=28);
    159 
    160         translate(corner+[-9, 155+1.4, 0]) cylinder(r=mountRadius, h=26);
    161         translate(corner+[-9, 155+1.4, 0]) cylinder(r=mountRadius*1.5, h=24);
    162         translate(corner+[-10, 155+1.4-6, 2]) cube([2, 6, 8]);
    163         translate(corner+[-11, 155+1.4-7, 0]) latch(r=[0, 0, 0], h=28);
    164 
    165         translate(corner+[displayWidth+14, 155+1.4, 0]) cylinder(r=mountRadius, h=26);
    166         translate(corner+[displayWidth+14, 155+1.4, 0]) cylinder(r=mountRadius*1.5, h=24);
    167         translate(corner+[displayWidth+12+1, 155+1.4-6, 2]) cube([2, 6, 8]);
    168         translate(corner+[displayWidth+12, 155+1.4-7, 0]) latch(r=[0, 0, 0], h=28);
    169 
    170 // Diagnostic of the rPi Zero board and mounting holes
    171 //        translate(corner+[20, 58, 5]) #pi_zero();
    172 
    173         // rPi Zero mount with holes punched in it
    174         difference() {
    175             union() {
    176                 translate(corner+[9, 54, 0]) pi_mount();
    177                 translate([10, corner[1]+54, 0]) cube([18, 38, 2]);
    178             }
    179             translate([20, 80, -0.5]) cylinder(r=15, h=3);
    180             translate([60, 80, -0.5]) cylinder(r=15, h=3);
    181             translate([85, 80, -0.5]) cylinder(r=15, h=3);
    182         }
    183 
    184         // Join the pieces with a frame
    185         translate([0, 15, 0]) cube([10, 140, 2]);
    186         translate([124-10, 15, 0]) cube([10, 140, 2]);
    187         translate([114, 0, 0]) rotate([0, 0, 90]) cube([10, 100, 2]);
    188         translate([114, 160, 0]) rotate([0, 0, 90]) cube([10, 100, 2]);
    189 
    190         // Latch plate for front to clip into
    191         translate([6, 70, 2]) latch_plate();
    192         translate([3, 70, 2]) cube([1, 20, 10]);
    193         translate([124-6, 70, 2]) mirror([1, 0, 0]) latch_plate();
    194         translate([124-4, 70, 2]) cube([1, 20, 10]);
    195 
    196         // Hangers
    197         translate([16, 140, 0]) hanger();
    198         translate([92, 140, 0]) dual_hanger(base=[23, 25, 2], center=[8, 14.5, 0], r=[0, 0, -90]);
    199         translate([93, 32, 0]) rotate([0, 0, -90]) hanger(height=21);
    200 }
    201 
    202 module ell() {
    203     cube([10, 1.0, 12]);
    204     cube([1.0, 10, 12]);
    205 }
    206 
    207 module front_frame() {
    208     union() {
    209         difference() {
    210             translate([0, corner[1]-20, 0]) cube([124, displayHeight+40, 2]);
    211             translate(corner-[0, 0, 1]) display(4);
    212         }
    213 
    214         translate([6, 70, -29]) mirror([1, 0, 0]) front_latch();
    215         translate([124-6, 70, -29]) front_latch();
    216 
    217         // Corner registration on display mounting tabs
    218         translate(corner+[-9-5.5, -5.5, -12]) ell();
    219         translate(corner+[displayWidth+14-6.5+12, -5.5, -12]) mirror([1, 0, 0]) ell();
    220         translate(corner+[-9-5.5, 155+1.4+5.5, -12]) mirror([0, 1, 0]) ell();
    221         translate(corner+[displayWidth+14-6.5+12, 155+1.4+5.5, -12]) mirror([1, 1, 0]) ell();
    222     }
    223 }
    224 
    225 
    226 // Comment out one or the other before exporting to STL
    227 translate([0, 0, -33.5]) #back_frame1();
    228 front_frame();