Start building BOM of project with a rough price estimate

This commit is contained in:
Matt McWilliams 2024-11-06 13:51:17 -05:00
parent c3711dfeda
commit 2cc0503aa8
40 changed files with 741695 additions and 629445 deletions

View File

@ -2,6 +2,8 @@
A desktop 16mm contact printer and film transport platform made using 3D printing and aluminum extrusion. A desktop 16mm contact printer and film transport platform made using 3D printing and aluminum extrusion.
## [Project Home: git.sixteenmillimeter.com/16mm/contact_printer](https://git.sixteenmillimeter.com/16mm/contact_printer)
## Acknowledgements ## Acknowledgements
Developed with support from [Filmwerkplaats at WORM](https://worm.org/spaces/filmwerkplaats/) and [SPECTRAL](http://www.spectral-cinematics.eu/). Developed with support from [Filmwerkplaats at WORM](https://worm.org/spaces/filmwerkplaats/) and [SPECTRAL](http://www.spectral-cinematics.eu/).
@ -12,7 +14,21 @@ Magnetic clutch design inspired by Clyde Shaffer's [Shaffer Linear Processor](ht
--- ---
## [Project Home: git.sixteenmillimeter.com/16mm/contact_printer](https://git.sixteenmillimeter.com/16mm/contact_printer) # Bill of Materials
<!-- bom -->
| Part | Qty | Cost (USD) |
|-------------------------------------|-----|------------|
| M3 sliding t slot nut | 6 | 0.36 |
| M3 hex cap bolt 8mm | 6 | 0.54 |
| M3 hex cap bolt 6mm | 4 | 0.28 |
| ESP32 Dev board | 2 | 13.32 |
| 2020 Aluminum extrusion 420mm | 2 | 5.22 |
| 2020 Aluminum extrusion 260mm | 4 | 6.44 |
| 100RPM DC geared motor with encoder | 1 | 17.02 |
<!-- /bom -->
### Mirrors ### Mirrors

35
models.txt Normal file
View File

@ -0,0 +1,35 @@
2020_tslot_insert
bearing_post_nut
corner_foot
daylight_spool_insert_reinforced
daylight_spool_insert_reinforced_nut
electronics_panel
feed_panel_motor_mount
feed_panel_picture
feed_panel_stock
filter_carrier
full_gate
gate_carrier
gate_holder
idle_roller_half_a
idle_roller_half_b
lamp_cover
lamp_dual
lamp_LEDs
lamp_single
magnetic_coupling
motor_controller_panel
panel
picture_gate
slip_coupling
sound_gate
sprocketed_roller
sprocketed_roller_invert
sprocketed_roller_invert_solid
sprocketed_roller_solid
sprocketed_wheel
super_gate
takeup_panel_picture
takeup_panel_picture_motor_mount
takeup_panel_stock
takeup_panel_stock_motor_mount

View File

@ -152,9 +152,6 @@ L298NModulePostsX = 36.5;
L298NModulePostsY = 36.5; L298NModulePostsY = 36.5;
L298NModulePostsD = 2.8; L298NModulePostsD = 2.8;
echo("BOM: [Frame] 2020 Extrusion X (x2)", FrameX + 20);
echo("BOM: [Frame] 2020 Extrusion Y (x4)", FrameY);
/** /**
* DEBUG MODULES * DEBUG MODULES
**/ **/
@ -428,11 +425,11 @@ module gate_blank () {
SidesY = 2.7; SidesY = 2.7;
RollerVoidY = -2; RollerVoidY = -2;
SprocketShelfZ = 1.75; SprocketShelfZ = 1.75;
SprocketShelfOffsetZ = -7.2; SprocketShelfOffsetZ = -7;
SprocketShelfD = 44.75; SprocketShelfD = 44.75;
RollerShelfZ = 2.9; RollerShelfZ = 2.9;
RollerShelfD = 44.75; RollerShelfD = 44.75;
PictureShelfZ = 11; PictureShelfZ = 10.5;
PictureShelfOffsetZ = -0.5; PictureShelfOffsetZ = -0.5;
PictureShelfD = 44.75; PictureShelfD = 44.75;
@ -683,6 +680,10 @@ module panel_bearing_void (pos = [0, 0, 0]) {
} }
} }
//BOM: 4,M3 hex cap bolt 6mm,N/A,Attach encoder motor to panel
//BOM: 6,M3 hex cap bolt 8mm,N/A,Attach panel to aluminum extrusions
//BOM: 6,M3 sliding t slot nut,N/A,Attach aluminum extrusions to panel
//BOM: 1,100RPM DC geared motor with encoder,N/A,Drive the sprocketed_roller
module panel (pos = [0, 0, 0]) { module panel (pos = [0, 0, 0]) {
BoltX = (PanelX-20)/2; BoltX = (PanelX-20)/2;
BoltY2 = (PanelY)/2; BoltY2 = (PanelY)/2;
@ -1376,6 +1377,8 @@ module button_void (pos = [0, 0, 0], rot = [0, 0, 0]) {
} }
} }
//BOM: 1, ESP32 Dev board,N/A,Control the contact_printer
//BOM: 1, ESP32 Dev board,N/A,Control the contact_printer
module electronics_panel (pos = [0, 0, 0], rot = [0, 0, 0]) { module electronics_panel (pos = [0, 0, 0], rot = [0, 0, 0]) {
X = PanelX - 40; X = PanelX - 40;
Y = 100; Y = 100;
@ -1573,7 +1576,13 @@ module debug_lamp () {
gate_carrier([0, -2.5, 11]); gate_carrier([0, -2.5, 11]);
} }
PART = "gate_carrier"; //BOM: 2, 2020 Aluminum extrusion 420mm,N/A,Top and bottom frame
//BOM: 4, 2020 Aluminum extrusion 260mm,N/A,Sides and central frame
module contact_printer () {
//debug module for BOM
}
PART = "gate_carrierx";
LIBRARY = true; LIBRARY = true;
if (PART == "panel") { if (PART == "panel") {

58
scripts/bom.sh Normal file
View File

@ -0,0 +1,58 @@
#!/bin/bash
if [[ "${1}" == "" ]]; then
echo "Please use a .scad file as first argument"
exit 1
fi
FILENAME=$(basename "${1}" | tr '[:upper:]' '[:lower:]')
EXTENSION="${FILENAME##*.}"
if [[ "${EXTENSION}" != "scad" ]]; then
echo "Please use a .scad file as first argument, not .${EXTENSION}"
exit 2
fi
if [[ ! -f "${1}" ]]; then
echo "File ${1} does not exist"
exit 3
fi
mkdir -p hardware
NAME="${FILENAME%.*}"
DESTINATION="./hardware/${NAME}_BOM.csv"
TOTAL="./hardware/${NAME}_BOM_total.csv"
touch "${DESTINATION}"
touch "${TOTAL}"
DESTINATION=$(realpath "${DESTINATION}")
TOTAL=$(realpath "${TOTAL}")
PRICES=$(realpath "./hardware/prices.csv")
MODULE=""
echo "module,quantity,part,part_id,description" > "${DESTINATION}"
tac "${1}" | while read line; do
module=$(echo "${line}" | grep 'module')
if [[ "${module}" != "" ]]; then
MODULE=$(echo "${module}" | xargs | awk '{print $2}' | awk -F'{' '{print $1}')
fi
bom=$(echo "${line}" | grep '//' | grep 'BOM' | awk -F'BOM:' '{print $2}'| xargs)
if [[ "${bom}" != "" ]]; then
QUANTITY=$(echo "${bom}" | awk -F',' '{print $1}' | xargs)
PART=$(echo "${bom}" | awk -F',' '{print $2}' | xargs)
ID=$(echo "${bom}" | awk -F',' '{print $3}' | xargs)
DESCRIPTION=$(echo "${bom}" | awk -F',' '{print $4}' | xargs)
echo "[${MODULE}] ${QUANTITY}x ${PART} (${ID})"
echo "${MODULE},${QUANTITY},${PART},${ID},${DESCRIPTION}" >> "${DESTINATION}"
fi
done
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}"
sqlite3 :memory: -cmd '.mode csv' -cmd ".import ${TOTAL} bom" -cmd '.mode markdown' \
'SELECT part as Part, quantity as Qty, CAST(price / 100.00 as MONEY) as "Cost (USD)" FROM bom ORDER BY part DESC;'

View File

@ -12,8 +12,10 @@ cat scad/contact_printer.scad | grep "PART ==" | awk -F'==' '{print $2}' | awk -
while read m; do while read m; do
echo "Rendering $m..." echo "Rendering $m..."
openscad -o "stl/contact_printer_$m.stl" -D "PART=\"$m\"" scad/contact_printer.scad openscad --export-format=asciistl --enable manifold -o "stl/contact_printer_$m.stl" -D "PART=\"$m\"" scad/contact_printer.scad
python scad/common/c14n_stl.py "stl/contact_printer_$m.stl" python scad/common/c14n_stl.py "stl/contact_printer_$m.stl"
done < models.txt done < models.txt
bash scripts/bom.sh "./scad/contact_printer.scad"
#run client tests? #run client tests?

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff