imrishabh18/pedometer
This code defines and assembles a simple radio receiver hardware circuit using specific imported capacitors, inductors, RF connectors, and oscillator components with precise footprints and schematic attributes.
- Version
- 1.1.3
- License
- unset
- Stars
- 0
models/rf-bm-2340c2.ts
/** RF-star RF-BM-2340C2: dimensioned local assembly model.
* Source: hardware datasheet V1.0, pp. 8 and 15 (8 x 8 x 1.7 mm,
* 1 mm contact pitch, seven left contacts, eight right contacts, top ANT).
* Body envelope and contacts are dimensioned; internal components are
* illustrative envelopes from the module photograph, not production MCAD.
* Coordinates are millimetres, centered on the module body; z=0 is its base.
*/
import type { CadModelJscad } from "@tscircuit/props";
export const rfModuleContacts = [
...Array.from({ length: 7 }, (_, i) => ({ pin: i + 1, x: -4, y: 2.5 - i })),
...Array.from({ length: 8 }, (_, i) => ({ pin: i + 8, x: 4, y: -3.5 + i })),
{ pin: 16, x: -1.6, y: 4 },
];
type Op = Record<string, any>;
type Color = [number, number, number];
const gold: Color = [0.86, 0.69, 0.32];
const silver: Color = [0.72, 0.74, 0.77];
const ceramic: Color = [0.83, 0.78, 0.62];
const box = (size: number[], at: number[]): Op => ({
type: "translate", vector: at, shape: { type: "cuboid", size },
});
const color = (rgb: Color, shape: Op): Op => ({ type: "colorize", color: rgb, shape });
const union = (...shapes: Op[]): Op => ({ type: "union", shapes });
const subtract = (...shapes: Op[]): Op => ({ type: "subtract", shapes });
const hole = (x: number, y: number, radius: number): Op => ({
type: "cylinder", radius, height: 0.9, center: [x, y, 0.3], resolution: 24,
});
// Plated half-holes sit at the package edge. The host's SMT land extends
// outside this edge to form a solder fillet; its center need not equal the
// center of the narrower metal contact on the module itself.
const contactMetal = rfModuleContacts.map(p => {
const top = p.pin === 16;
const cx = top ? p.x : Math.sign(p.x) * 3.625;
const cy = top ? 3.625 : p.y;
const size = top ? [0.6, 0.75, 0.64] : [0.75, 0.6, 0.64];
const window = box(size, [cx, cy, 0.32]);
const plates = union(
box([size[0], size[1], 0.02], [cx, cy, 0.01]),
box([size[0], size[1], 0.02], [cx, cy, 0.61]),
{ type: "intersect", shapes: [window, hole(p.x, p.y, 0.32)] },
);
return color(gold, subtract(plates, hole(p.x, p.y, 0.3)));
});
const substrate = color([0.035, 0.29, 0.40], subtract(
box([8, 8, 0.6], [0, 0, 0.3]),
...rfModuleContacts.map(p => hole(p.x, p.y, 0.32)),
));
// Photo-based component envelopes leave the ceramic antenna visibly exposed.
const mcu = color([0.08, 0.09, 0.10], box([4, 4, 0.85], [-0.65, -0.8, 1.025]));
const crystal = color(silver, box([1.7, 2.2, 1.1], [2.65, -0.15, 1.15]));
const antenna = color(ceramic, box([1.8, 0.65, 0.6], [-2.55, 3.27, 0.9]));
const antennaEnds = [-3.35, -1.75].map(x => color(silver, box([0.22, 0.69, 0.63], [x, 3.27, 0.915])));
const passives = [
[-2.4, -3.35], [-1.15, -3.35], [0.1, -3.35], [1.4, -3.35], [2.75, -2.6],
[-0.5, 3.25], [0.6, 3.25], [1.75, 3.25], [2.9, 3.25],
[-0.35, 2.25], [1.0, 2.25], [2.7, 1.75],
].flatMap(([x, y]) => [
color(ceramic, box([0.75, 0.42, 0.32], [x, y, 0.76])),
...[-0.34, 0.34].map(dx => color(silver, box([0.17, 0.45, 0.34], [x + dx, y, 0.77]))),
]);
const pin1Mark = color([0.9, 0.91, 0.9], {
type: "cylinder", radius: 0.12, height: 0.025, center: [-2.15, 0.55, 1.46], resolution: 20,
});
export const rfModuleCadModel: CadModelJscad = {
jscad: union(substrate, ...contactMetal, mcu, crystal, antenna, ...antennaEnds, ...passives, pin1Mark),
modelOriginPosition: { x: 0, y: 0, z: 0 },
size: { x: 8, y: 8, z: 1.7 },
modelBounds: { min: { x: -4, y: -4, z: 0 }, max: { x: 4, y: 4, z: 1.7 } },
pcbRotationOffset: 0,
};