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,
};