73 lines
2.3 KiB
Python
73 lines
2.3 KiB
Python
|
from dataclasses import dataclass, field
|
||
|
from typing import Tuple
|
||
|
import cadquery as Cq
|
||
|
from nhf import Item, Role
|
||
|
from nhf.parts.box import Hole, MountingBox
|
||
|
import nhf.utils
|
||
|
|
||
|
@dataclass(frozen=True)
|
||
|
class ArduinoUnoR3(Item):
|
||
|
# From datasheet
|
||
|
mass: float = 25.0
|
||
|
length: float = 68.6
|
||
|
width: float = 53.4
|
||
|
|
||
|
# with clearance
|
||
|
base_height: float = 5.0
|
||
|
# aesthetic only for illustrating clearance
|
||
|
total_height: float = 50.0
|
||
|
roof_height: float = 20.0
|
||
|
|
||
|
# This is labeled in mirrored coordinates from top down (i.e. unmirrored from bottom up)
|
||
|
holes: list[Tuple[float, float]] = field(default_factory=lambda: [
|
||
|
(15.24, 2.54),
|
||
|
(13.74, 50.80), # x coordinate not labeled on schematic
|
||
|
(66.04, 17.78),
|
||
|
(66.04, 45.72),
|
||
|
])
|
||
|
hole_diam: float = 3.0
|
||
|
|
||
|
@property
|
||
|
def name(self) -> str:
|
||
|
return "Arduino Uno R3"
|
||
|
|
||
|
@property
|
||
|
def role(self) -> Role:
|
||
|
return Role.ELECTRONIC
|
||
|
|
||
|
def generate(self) -> Cq.Assembly:
|
||
|
sketch = (
|
||
|
Cq.Sketch()
|
||
|
.polygon([
|
||
|
(0,0),
|
||
|
(self.length, 0),
|
||
|
(self.length, self.width),
|
||
|
(0,self.width)
|
||
|
])
|
||
|
.push([(x, self.width - y) for x,y in self.holes])
|
||
|
.circle(self.hole_diam / 2, mode='s')
|
||
|
)
|
||
|
# pillar thickness
|
||
|
t = 3.0
|
||
|
pillar_height = self.total_height - self.base_height
|
||
|
pillar = Cq.Solid.makeBox(
|
||
|
t, t, pillar_height
|
||
|
)
|
||
|
roof = Cq.Solid.makeBox(
|
||
|
self.length, self.width, t
|
||
|
)
|
||
|
result = (
|
||
|
Cq.Workplane('XY')
|
||
|
.placeSketch(sketch)
|
||
|
.extrude(self.base_height)
|
||
|
.union(pillar.located(Cq.Location((0, 0, self.base_height))))
|
||
|
.union(pillar.located(Cq.Location((self.length - t, 0, self.base_height))))
|
||
|
.union(pillar.located(Cq.Location((self.length - t, self.width - t, self.base_height))))
|
||
|
.union(pillar.located(Cq.Location((0, self.width - t, self.base_height))))
|
||
|
.union(roof.located(Cq.Location((0, 0, self.total_height - t))))
|
||
|
)
|
||
|
plane = result.copyWorkplane(Cq.Workplane('XY'))
|
||
|
for i, (x, y) in enumerate(self.holes):
|
||
|
plane.moveTo(x, self.width - y).tagPlane(f"conn{i}", direction='-Z')
|
||
|
return result
|