diff --git a/hardware/bom/mcopy_gate_BOM.csv b/hardware/bom/mcopy_gate_BOM.csv index fbecd6b..fedad45 100644 --- a/hardware/bom/mcopy_gate_BOM.csv +++ b/hardware/bom/mcopy_gate_BOM.csv @@ -1,13 +1,13 @@ module,quantity,part,part_id,description -front_block_pegs,2,M2.5 hex cap bolts 10mm,N/A,Fasctens front_block_pegs to front_block +front_block_pegs,2,M2.5 hex cap bolt 10mm,N/A,Fasctens front_block_pegs to front_block front_block,4,M2.5 hex nut,N/A,Attach the film path blocks front_block,2,M5 hex cap bolt 25mm,N/A,Attach the front_block to the body -body,2,Bearing,N/A,Center sprocketed_roller in gate voids and allow for smooth rotation +body,2,608-RS Ball Bearing,608-RS,Center sprocketed_roller in gate voids and allow for smooth rotation body,2,M3 hex nut,N/A,Attach slide_catch to gate body,12,M2.5 hex nut,ISO 4032,Attach idle_roller and filter_holder and slide_rail to gate body,4,M2.5 hex cap bolt 10mm,N/A,Attach slide_rail to gate body,2,M2.5 hex cap bolt 25mm,N/A,Attach filter_holder to gate -body,6,M2.5 hex cap bolt 15mm,N/A,Attach idle_roller to gate +body,6,M2.5 hex cap bolt 16mm,N/A,Attach idle_roller to gate body,2,M5 hex nut,N/A,Attach front_block to gate body,2,M5 hex cap bolt 20mm,N/A,Attach gate to projector sprocketed_roller_nut_16mm,2,M2.5 hex nut,ISO 4032,Attaches the bolt to the nut diff --git a/hardware/bom/mcopy_gate_BOM_total.csv b/hardware/bom/mcopy_gate_BOM_total.csv index 17267e3..887f8f8 100644 --- a/hardware/bom/mcopy_gate_BOM_total.csv +++ b/hardware/bom/mcopy_gate_BOM_total.csv @@ -1,13 +1,11 @@ -quantity,part_id,part,price -2,"M5 hex nut",N/A,0 -2,"M5 hex cap bolt 25mm",N/A,0 -2,"M5 hex cap bolt 20mm",N/A,0 -2,"M3 hex nut",N/A,6 -19,"M2.5 hex nut",N/A,171 -2,"M2.5 hex cap bolts 10mm",N/A,0 -2,"M2.5 hex cap bolt 25mm",N/A,0 -2,"M2.5 hex cap bolt 16mm","ISO 4762",0 -6,"M2.5 hex cap bolt 15mm",N/A,0 -5,"M2.5 hex cap bolt 10mm",N/A,0 -2,Bearing,N/A,0 -46,N/A,TOTALS,177 +quantity,part,part_id,price +2,"M5 hex nut",N/A,10 +2,"M5 hex cap bolt 25mm",N/A,54 +2,"M5 hex cap bolt 20mm",N/A,38 +2,"M3 hex nut",N/A,7 +19,"M2.5 hex nut",N/A,120 +2,"M2.5 hex cap bolt 25mm",N/A,12 +8,"M2.5 hex cap bolt 16mm",N/A,112 +7,"M2.5 hex cap bolt 10mm",N/A,98 +2,"608-RS Ball Bearing",608-RS,36 +46,TOTAL,N/A,487 diff --git a/hardware/bom/mcopy_rails_BOM.csv b/hardware/bom/mcopy_rails_BOM.csv index 3d9a59c..9ab3d4b 100644 --- a/hardware/bom/mcopy_rails_BOM.csv +++ b/hardware/bom/mcopy_rails_BOM.csv @@ -1,4 +1,4 @@ module,quantity,part,part_id,description -sled,8,Radial bearing,N/A,For something +sled,8,608-RS Ball Bearing,608-RS,To smooth sled moving along rails sled,2,Linear bearing,N/A,For center rails -sled,2,T8 Nut,N/A,For drive screw +sled,2,T8 Nut,Tr8x2,For drive screw diff --git a/hardware/bom/mcopy_rails_BOM_total.csv b/hardware/bom/mcopy_rails_BOM_total.csv index 37fe35d..0fc99a4 100644 --- a/hardware/bom/mcopy_rails_BOM_total.csv +++ b/hardware/bom/mcopy_rails_BOM_total.csv @@ -1,5 +1,5 @@ -quantity,part_id,part,price -2,"T8 Nut",N/A,0 -8,"Radial bearing",N/A,0 -2,"Linear bearing",N/A,0 -12,N/A,TOTALS,0 +quantity,part,part_id,price +2,"T8 Nut",Tr8x2,499 +2,"Linear bearing",N/A,200 +8,"608-RS Ball Bearing",608-RS,143 +12,TOTAL,N/A,842 diff --git a/hardware/parts/prices.csv b/hardware/parts/prices.csv index 716196f..b08f5ff 100644 --- a/hardware/parts/prices.csv +++ b/hardware/parts/prices.csv @@ -1,5 +1,23 @@ -part,part_id,price,url -M3 hex nut,N/A,3,https://amzn.to/4hAnwjc -M3 hex cap bolt 12mm,N/A,9,https://amzn.to/48CGa5Y -608-RS Ball Bearing,608-RS,8,https://amzn.to/4fKxDA7 -M2.5 hex nut, ISO 4032,9,https://www.metricscrewandtool.com/product-page/m2-5-hex-nuts \ No newline at end of file +part,part_id,price,quantity,url +M3 hex nut,N/A,999,300,https://amzn.to/4hAnwjc +M2.5 hex nut,ISO 4032,629,100,https://amzn.to/4i7qxrr +M2.5 hex cap bolt 10mm,N/A,699,50,https://amzn.to/49froT4 +M2.5 hex cap bolt 16mm,N/A,699,50,https://amzn.to/49cj6v2 +M2.5 hex cap bolt 25mm,N/A,598,100,https://amzn.to/41faYb0 +M3 hex cap bolt 6mm,N/A,726,100,https://amzn.to/3AwiZxo +M3 hex cap bolt 8mm,N/A,899,100,https://amzn.to/3YEvWNB +M3 hex cap bolt 12mm,N/A,836,100,https://amzn.to/48CGa5Y +M3 sliding t slot nut,N/A,599,105,https://amzn.to/48GRrSU +M5 hex cap bolt 20mm,N/A,949,50,https://amzn.to/4ePHCmW +M5 hex cap bolt 25mm,N/A,809,30,https://amzn.to/3VgdQAW +M5 hex nut,N/A,999,200,https://amzn.to/3ZdMNHs +2020 Aluminum extrusion mm,N/A,7399,12200,https://amzn.to/418OicC +100RPM DC geared motor with encoder,N/A,1619,1,https://amzn.to/3UF707G +250RPM DC geared motor,JSX40-370,1499,1,https://amzn.to/3NWkcRL +ESP32 Dev board,N/A,1999,3,https://amzn.to/3NXCvGj +L298N Motor driver module,N/A,1149,4,https://amzn.to/4ellssy +ESP32 GPIO breakout board,N/A,1199,2,https://amzn.to/3UFjpbO +M4 hex bolt 40mm,N/A,609,10,https://amzn.to/4ikpYL8 +608-RS Ball Bearing,608-RS,1779,100,https://amzn.to/4fKxDA7 +Linear bearing,LM8UU,1199,12,https://amzn.to/4i5XsMZ +T8 Nut,Tr8x2,499,2,https://amzn.to/3B4m4VW \ No newline at end of file diff --git a/scad/mcopy_gate.scad b/scad/mcopy_gate.scad index 89b5838..d9dfa96 100644 --- a/scad/mcopy_gate.scad +++ b/scad/mcopy_gate.scad @@ -368,7 +368,7 @@ module sprocketed_roller_text (pos = [0, 0, 0], rot = [0, 0, 0], font_size = 3, translate(pos) rotate(rot) { for (i = [0 : chars_len - 1]) { rotate(-i * step_angle) { - translate([0, radius + font_size / 2, 0]) { + translate([0, radius + font_size / 2, 0]) rotate([180, 0, 0]) { linear_extrude(height = h) { text(chars[i], font = "Liberation Sans:style=Bold", size = font_size, valign = "center", halign = "center"); } @@ -410,7 +410,7 @@ module sprocketed_roller_16mm (pos = [0, 0, 0], rot = [0, 0, 0], side = "TAKEUP" //m2.5 bolt translate([0, 0, -15.85]) rotate([0, 90, 0]) cylinder(r = R(2.75), h = 30, center = true, $fn = 30); // - sprocketed_roller_text([0, 0, 16], chars = side); + sprocketed_roller_text([0, 0, -1], chars = side); } } @@ -447,12 +447,12 @@ module sprocketed_roller_nut_16mm (pos = [0, 0, 0], rot = [0, 0, 0]) { //BOM: 2, M5 hex cap bolt 20mm, N/A, Attach gate to projector //BOM: 2, M5 hex nut, N/A, Attach front_block to gate -//BOM: 6, M2.5 hex cap bolt 15mm, N/A, Attach idle_roller to gate +//BOM: 6, M2.5 hex cap bolt 16mm, N/A, Attach idle_roller to gate //BOM: 2, M2.5 hex cap bolt 25mm, N/A, Attach filter_holder to gate //BOM: 4, M2.5 hex cap bolt 10mm, N/A, Attach slide_rail to gate //BOM: 12, M2.5 hex nut, ISO 4032, Attach idle_roller and filter_holder and slide_rail to gate //BOM: 2, M3 hex nut, N/A, Attach slide_catch to gate -//BOM: 2, Bearing, N/A, Center sprocketed_roller in gate voids and allow for smooth rotation +//BOM: 2, 608-RS Ball Bearing, 608-RS, Center sprocketed_roller in gate voids and allow for smooth rotation module body (pos = [0, 0, 0], gauge = "16mm") { SlideRailsOffsetZ = -5; translate(pos) { @@ -770,7 +770,7 @@ module front_block_peg (pos = [0, 0, 0], rot = [0, 0, 0], h = 10) { } } -//BOM: 2, M2.5 hex cap bolts 10mm, N/A, Fasctens front_block_pegs to front_block +//BOM: 2, M2.5 hex cap bolt 10mm, N/A, Fasctens front_block_pegs to front_block module front_block_pegs (pos = [0, 0, 0], rot = [0, 0, 0]) { PegSpacingY = 24.2; BoltSpacingY = 24; @@ -822,18 +822,29 @@ module filter_block (pos = [0, 0, 0], rot = [0, 0, 0], side = "A") { } } +module debug_film (pos = [0, 0, 0]) { + color("blue") translate(pos) { + difference () { + 16mm_film(18, true, true); + translate([0, -7.49 / 2, 0]) cube([10.26, 7.49, 1], center = true); + } + } +} + module debug () { + FilmRestingDistanceZ = -3.5; FilmRetractionDistanceZ = -7.2; difference () { - //color("blue") translate([8, 4.6, FilmZ]) 16mm_film(18, true, true); union () { - FilmZ = - 7.2; //retraction distance + FilmZ = FilmRestingDistanceZ; //retraction distance translate([(-BodyX / 2) - 1, 0, -BodyZ / 2]) body(gauge = "16mm"); - + + debug_film([8, 4.6, FilmZ]); + translate([0, 0, FilmZ + 1.4]) front_plate(); translate([0, 0, FilmZ - 1.4]) back_plate(); - //gate_mask_slide_standard16([(PlateX / 2) - (FrontPlateVoidX / 2) - 1.9, 0, FilmZ - .9]); - gate_mask_slide_super16([(PlateX / 2) - (FrontPlateVoidX / 2) - 1.9, 0, FilmZ - .9]); + gate_mask_slide_standard16([(PlateX / 2) - (FrontPlateVoidX / 2) - 1.9, 0, FilmZ - .9]); + //gate_mask_slide_super16([(PlateX / 2) - (FrontPlateVoidX / 2) - 1.9, 0, FilmZ - .9]); //front_plate_void([(PlateX / 2) - (FrontPlateVoidX / 2) - 2.41, 0, 0]); //film_clearance_void([0, 0, 15]); @@ -874,7 +885,7 @@ module debug () { } } -PART="front_block_16mmx"; +PART="sprocketed_roller_takeup_16mmx"; if (PART == "front_plate") { //1 diff --git a/scad/mcopy_lens_assembly.scad b/scad/mcopy_lens_assembly.scad index 50e58db..faa1ef3 100644 --- a/scad/mcopy_lens_assembly.scad +++ b/scad/mcopy_lens_assembly.scad @@ -93,15 +93,22 @@ module m3BoltNut (bolt = 20, nut = 3.5) { } } -module m4BoltNut (bolt = 10, nut = 3.5) { +module m4BoltNut (bolt = 10, nut = 3.5, drop = true) { m4Bolt(bolt); translate([0, 0, nut]) color("red") { - m4_nut(); - translate([-10, 0, 0]) cube([20, 6.9, 3.5], center = true); + m4_nut(3.5); + if (drop) { + translate([-10, 0, 0]) cube([20, 6.9, 3.5], center = true); + } } } +module m5Nut () { + cylinder(r = R(9), h = 4, center = true, $fn = 6); + cylinder(r = R(5), h = 20, center = true, $fn = 30); +} + module lensAssembyBellowBoardLinearBearingMount (X = 0) { difference () { translate([X, XOffset, FrontOffset]) rotate([0, 90, 0]) cylinder(r = R(25), h = 24, center = true, $fn = 80); @@ -385,7 +392,7 @@ module jkLensLinearRodTerminalBlock (pos = [0, 0, 0]) { translate(pos) difference() { cube([26.5, 20, 15], center = true); cylinder(r = 8.1 / 2, h = 15 + 1, center = true, $fn = 50); - translate([12, 0, 0]) rotate([0, 90, 180]) m4BoltNut(20); + translate([5, 0, 0]) rotate([0, -90, 180]) m4BoltNut(20); } } @@ -394,6 +401,7 @@ module jkLensMount () { BoltSpacingX = 78.5 + 5.3; BoltD = 4.25; RailsY = -32; + difference () { union() { cube([140, 15.5, 3], center = true); @@ -409,24 +417,62 @@ module jkLensMount () { translate([-130 / 2, -25, 4]) cube([26.5, 40, 5], center = true); //linear rod terminal block - jkLensLinearRodTerminalBlock([130 / 2, -32, 14]); + jkLensLinearRodTerminalBlock([130 / 2, -32, 14 - 20]); //threaded rod bearing block - translate([-130 / 2, -32, 12]) cylinder(r = 22.5 / 2, h = 20, center = true, $fn = 90); + translate([-130 / 2, -32, 12 - 20]) cylinder(r = 22.5 / 2, h = 22, center = true, $fn = 90); } + } + translate([73.25, -32, 14 - 5]) cylinder(r = 8.1 / 2, h = 20, center = true, $fn = 50); translate([BoltSpacingX / 2, 0, 0]) cylinder( r = BoltD / 2, h = 20, center = true, $fn = 30); translate([-BoltSpacingX / 2, 0, 0]) cylinder( r = BoltD / 2, h = 20, center = true, $fn = 30); translate([-BoltSpacingX / 2, 0, 14.5]) cylinder( r = 8/ 2, h = 20, center = true, $fn = 30); - translate([-(130 / 2) + 8.25, -32, 8]) { + translate([-(130 / 2) + 8.25, -32, 8 - 13]) { linear_bearing(padD = 0.2); cylinder(r = 9 / 2, h = 40, center = true, $fn = 40); } } + difference () { + translate([10, -25, 4]) cube([110, 30, 5], center = true); + translate([2 + 22, -27, 1.5]) rotate([0, 0, 30]) m4BoltNut(bolt = 30, drop = false); + translate([2 - 22, -27, 1.5]) rotate([0, 0, 30]) m4BoltNut(bolt = 30, drop = false); + } + //translate([(130 / 2) + 8.25, RailsY, XOffset]) rotate([0, 0, 0]) linearMotionRod(RodLength); //translate([(-130 / 2) + 8.25, RailsY, XOffset]) rotate([0, 0, 0]) linearMotionRod(RodLength); + + +} + +module jkLensBrace () { + difference () { + union () { + + translate([2, -20, -(75 / 2) + 1.5]) { + difference () { + cube([80, 20, 75], center = true); + difference () { + cube([60, 20 + 1, 55], center = true); + union () { + rotate([0, 45 ,0]) cube([200, 20 + 2, 15], center = true); + rotate([0, -45 ,0]) cube([200, 20 + 2, 15], center = true); + } + } + } + } + translate([2, -25, -75 + 4]) cube([90, 20, 5], center = true); + } + translate([2, -30, -(75 / 2) + 1 ]) cube([60, 20, 60], center = true); + //m5 + translate([2 + 23, -25, -75 + 3.4]) rotate([0, 0, 30]) m5Nut(); + translate([2 - 23, -25, -75 + 3.4]) rotate([0, 0, 30]) m5Nut(); + + translate([2 + 22, -27, 0]) cylinder(r = R(4.25), h = 30, center = true, $fn = 30); + translate([2 - 22, -27, 0]) cylinder(r = R(4.25), h = 30, center = true, $fn = 30); + } } module debug () { @@ -504,6 +550,8 @@ if (PART == "lens_assembly_camera_bellows_board") { lensAssemblyThreadedCollar(6, 0.2); } else if (PART == "lens_assembly_jk_mount") { jkLensMount(); +} else if (PART == "lens_assembly_jk_brace") { + rotate([-90, 0, 0]) jkLensBrace(); } else { debug(); } diff --git a/scad/mcopy_rails.scad b/scad/mcopy_rails.scad index 9fb57b0..68d390c 100644 --- a/scad/mcopy_rails.scad +++ b/scad/mcopy_rails.scad @@ -226,9 +226,9 @@ module rail_end (pos = [0, 0, 0], rot = [90, 0, 0], Motors = true, Projector = f } -//BOM: 2,T8 Nut, N/A, For drive screw +//BOM: 2, T8 Nut, Tr8x2, For drive screw //BOM: 2, Linear bearing, N/A, For center rails -//BOM: 8, Radial bearing, N/A, For something +//BOM: 8, 608-RS Ball Bearing, 608-RS, To smooth sled moving along rails module sled (pos = [0, 0, 0], rot = [90, 0, 0], Length = 60) { X = RailEndX; diff --git a/scad/projector_controller.scad b/scad/projector_controller.scad index a5e7341..7b61a9e 100644 --- a/scad/projector_controller.scad +++ b/scad/projector_controller.scad @@ -323,6 +323,40 @@ module usb_protector () { } } +module power_cable () { + OD = 14; + difference () { + union () { + cylinder(r = R(18), h = 2, center = true, $fn = 80); + translate([0, 0, 10 / 2]) cylinder(r = R(OD), h = 10, center = true, $fn = 80); + } + cylinder(r = R(6.75), h = 40, center = true, $fn = 80); + translate([0, 0, 7.75]) difference() { + cylinder(r = R(OD + 2), h = 5, center = true); + cylinder(r = R(8), h = 5 + 1, center = true, $fn = 80); + translate([0, 0, -0.1]) cylinder(r2 = R(9), r1 = R(OD + .5), h = 5, center = true, $fn = 80); + } + } +} + +module power_cable_halves () { + NotchSpacing = 10.5; + translate([-3, 0, 0]) difference () { + power_cable(); + translate([50 / 2, 0, 0]) cube([50, 50, 50], center = true); + translate([0, NotchSpacing / 2, 0]) rotate([0, 0, 45]) cube([1.5, 1.5, 50], center = true); + translate([0, -NotchSpacing / 2, 0]) rotate([0, 0, 45]) cube([1.5, 1.5, 50], center = true); + } + translate([3, 0, 0]) difference () { + power_cable(); + difference () { + translate([-50 / 2, 0, 0]) cube([50, 50, 50], center = true); + translate([0, NotchSpacing / 2, 0]) rotate([0, 0, 45]) cube([1.5, 1.5, 50], center = true); + translate([0, -NotchSpacing / 2, 0]) rotate([0, 0, 45]) cube([1.5, 1.5, 50], center = true); + } + } +} + module debug () { case_debug(); translate([0, 0, -CaseInnerZ/2+(CaseMountsH)]) electronics_mount(); @@ -332,14 +366,14 @@ module debug () { translate(ArduinoPosition) translate([-27.5, -8, -10]) electronics_attachment(); } -PART="electronics_attachment"; +PART="power_cable"; if (PART == "electronics_mount") { electronics_mount(); } else if (PART == "electronics_attachment") { electronics_attachment(); -} else if (PART == "case_mounts") { - case_mounts(); +} else if (PART == "power_cable") { + power_cable_halves(); } else if (PART == "usb_protector") { usb_protector(); } else { diff --git a/scripts/bom.sh b/scripts/bom.sh index ffa2aab..9d7a148 100644 --- a/scripts/bom.sh +++ b/scripts/bom.sh @@ -50,9 +50,30 @@ tac "${1}" | while read line; do fi done -echo "quantity,part_id,part,price" > "${TOTAL}" +echo "quantity,part,part_id,price" > "${TOTAL}" sqlite3 :memory: -cmd '.mode csv' -cmd ".import ${DESTINATION} bom" -cmd ".import ${PRICES} prices"\ - 'SELECT SUM(quantity),part,part_id, SUM(quantity) * (COALESCE((SELECT prices.price FROM prices WHERE prices.part = bom.part LIMIT 1), 0)) as price FROM bom GROUP BY part ORDER BY part DESC;' >> "${TOTAL}" + 'SELECT SUM(quantity),part,part_id, CAST( CEIL( CAST(SUM(quantity) AS FLOAT) * (SELECT CAST(prices.price AS FLOAT) / CAST(prices.quantity AS FLOAT) FROM prices WHERE prices.part = bom.part LIMIT 1) ) AS INTEGER) as price FROM bom GROUP BY part ORDER BY part DESC;' >> "${TOTAL}" + +sqlite3 :memory: -cmd '.mode csv' -cmd ".import ${TOTAL} bom" -cmd ".import ${PRICES} prices" -cmd '.mode markdown' \ + "SELECT part as Part, quantity as Qty, \ + printf('$%.2f', CAST(price AS FLOAT) / 100) as 'Cost (USD)', \ + printf( '[%s for $%.2f](%s)', (SELECT prices.quantity FROM prices WHERE prices.part = bom.part), (SELECT CAST(prices.price AS FLOAT) / 100 FROM prices WHERE prices.part = bom.part), (SELECT prices.url FROM prices WHERE prices.part = bom.part)) as 'Minumum' \ + FROM bom ORDER BY part DESC;" + +sqlite3 :memory: -cmd '.mode csv' -cmd ".import ${TOTAL} bom" -cmd ".import ${PRICES} prices" -cmd '.mode markdown' \ + "SELECT 'TOTAL', SUM(quantity) AS qty, \ + printf('$%.2f', CAST(SUM(price) AS FLOAT) / 100) as total, \ + printf('$%.2f', ( SELECT CAST( SUM(price) AS FLOAT) / 100 FROM prices WHERE prices.part IN ( SELECT bom.part FROM bom ) ) ) as min \ + FROM bom;" | grep -v 'qty' sqlite3 :memory: -cmd '.mode csv' -cmd ".import ${TOTAL} bom"\ - 'SELECT SUM(quantity),"N/A","TOTALS", SUM(price) FROM bom;' | tr -d '"' >> "${TOTAL}" \ No newline at end of file + "SELECT SUM(quantity), 'TOTAL', 'N/A', SUM(price) FROM bom;" | tr -d '"' >> "${TOTAL}" + +NONEFOUND=$(sqlite3 :memory: -cmd '.mode csv' -cmd ".import ${DESTINATION} bom" -cmd ".import ${PRICES} prices" -cmd '.mode column' -cmd '.headers off' \ + 'SELECT DISTINCT part FROM bom WHERE part NOT IN (SELECT part FROM prices) ORDER BY part;') + +if [[ "${NONEFOUND}" != "" ]]; then + echo "No price found for the following parts:" + echo "${NONEFOUND}" +fi +