muse/book-reading-clip-lamp
A 60‑mm ESP32‑S3 lamp-head PCB combining USB‑C battery charging/power regulation, OV5640 autofocus camera interfacing, I²S microphone and differential speaker audio, six‑LED boost-driven reading light, buttons, status indicators, and battery monitoring.
- Version
- 0.2.5
- License
- unset
- Stars
- 0
camera-audio-parts.tsx
Schematic
import React, { type ReactElement } from "react"
import { INMP441ACEZ_R7 as CatalogMic } from "./imports/INMP441ACEZ_R7"
import type { ChipProps } from "@tscircuit/props"
import { MAX98357AETE_T } from "./imports/MAX98357AETE_T"
export const micPinLabels = {
pin1: ["SCK"], pin2: ["SD"], pin3: ["WS"], pin4: ["LR"],
pin5: ["GND_RING"], pin6: ["GND1"], pin7: ["VDD"],
pin8: ["CHIPEN"], pin9: ["GND2"],
} as const
// Exact C22379536 microphone lands from JLCSearch. R7 and R0 use the
// same 9-terminal package; R7 is the catalog reel variant (obsolete prototype).
// Recenter imported polygon primitives WITHOUT changing their board copper,
// so core clusters the two annular halves correctly. Add the 0.5 mm
// acoustic aperture (absent from the import) and a masked ground escape tab.
// TDK DS-INMP441-00 p17 recommends 0.5–1.0 mm; 0.5 mm preserves drill clearance.
export const INMP441Microphone = (props: ChipProps<typeof micPinLabels>) => {
const imported = CatalogMic({ ...props, pinLabels: micPinLabels } as any)
const fp = imported.props.footprint as ReactElement<{children: React.ReactNode}>
const children = React.Children.map(fp.props.children, child => {
if (!React.isValidElement<Record<string,any>>(child) || child.type !== "smtpad" || child.props.shape !== "polygon") return child
const points = child.props.points.map((p:{x:string|number,y:string|number})=>({x:parseFloat(String(p.x)),y:parseFloat(String(p.y))}))
const x=(Math.min(...points.map((p:any)=>p.x))+Math.max(...points.map((p:any)=>p.x)))/2
const y=(Math.min(...points.map((p:any)=>p.y))+Math.max(...points.map((p:any)=>p.y)))/2
return React.cloneElement(child,{pcbX:x,pcbY:y,points:points.map((p:any)=>({x:p.x-x,y:p.y-y}))})
})
return React.cloneElement(imported, { footprint: <footprint>
{children}
<hole name="ACOUSTIC_PORT" diameter={0.5} pcbX={1.2685395} pcbY={0}/>
<smtpad shape="rect" pcbX={3} pcbY={0} width={2.3} height={0.3} portHints={["pin5"]}
coveredWithSolderMask solderPasteMargin={-0.16}/>
</footprint> })
}
export const ampPinLabels = {
pin1: ["DIN"], pin2: ["GAIN_SLOT"], pin3: ["GND1"], pin4: ["SD_MODE"],
pin5: ["NC5"], pin6: ["NC6"], pin7: ["VDD1"], pin8: ["VDD2"],
pin9: ["OUTP"], pin10: ["OUTN"], pin11: ["GND2"], pin12: ["NC12"],
pin13: ["NC13"], pin14: ["LRCLK"], pin15: ["GND3"], pin16: ["BCLK"],
pin17: ["EP"],
} as const
// Imported exact QFN footprint; pin names independently checked with ADI rev16.
// SD_MODE is not simply an active-low signal: low=mute, high=left channel.
export const MAX98357Amplifier = (props: ChipProps<typeof ampPinLabels>) => (
<MAX98357AETE_T
{...props as any}
pinLabels={ampPinLabels as any}
pinAttributes={{
pin3: { requiresGround: true }, pin11: { requiresGround: true },
pin15: { requiresGround: true }, pin17: { requiresGround: true },
pin7: { requiresPower: true }, pin8: { requiresPower: true },
}}
/>
)