gokul/flex-led-wristband
A flexible, rechargeable touch wristband PCB with MCP73831 Li-ion charging, switched 3.0 V regulation, ATtiny402 control, TTP223 capacitive touch sensing, and six charlieplexed red LEDs plus power/charge indicators.
- Version
- 0.0.3
- License
- unset
- Stars
- 0
lib/board.tsx
import {
ChargerFootprint,
RegulatorFootprint,
TouchFootprint,
LedFootprint,
} from "./Footprints";
import { boardOutline } from "./outline";
import { PowerSwitch } from "./PowerSwitch";
import type { ChipProps } from "@tscircuit/props";
const padFootprint = (
<footprint insertionDirection="from_above">
<smtpad
noSolderPaste
portHints={["1"]}
pcbX={0}
pcbY={0}
width={2.5}
height={3.1}
solderMaskMargin={-0.35}
shape="rect"
/>
<courtyardrect width={2.9} height={3.5} />
</footprint>
);
function Pad(props: ChipProps) {
return (
<chip
doNotPlace
footprint={padFootprint}
{...props}
pinAttributes={props.pinAttributes ?? { pin1: { isPassive: true } }}
/>
);
}
export default function FlexLedWristband() {
return (
<board
partsEngine={{ findPart: () => ({}) }}
pcbStyle={{ silkscreenFontSize: 0.8 }}
schSheetName="Main"
title="Touch LED wristband"
material="flex"
thickness="0.12mm"
layers={2}
width={90}
height={32}
outline={boardOutline}
autorouter={{ local: true, traceClearance: 0.22 }}
minViaHoleDiameter={0.3}
minViaPadDiameter={0.6}
minViaEdgeToPadEdgeClearance={0.2}
minViaHoleEdgeToViaHoleEdgeClearance={0.25}
minTraceToPadEdgeClearance={0.2}
minPadEdgeToPadEdgeClearance={0.2}
minTraceToHoleEdgeClearance={0.25}
minTraceWidth="0.2mm"
minBoardEdgeClearance="0.5mm"
schLayout={{ grid: true, gridCols: 3, gridGap: 2 }}
>
<keepout
shape="rect"
pcbX={10}
pcbY={1}
width={7}
height={7}
layers={["bottom"]}
/>
{[-1, 1].flatMap((side) => [
<keepout
shape="rect"
pcbX={side * 16}
pcbY={0}
width={2}
height={10}
layers={["bottom"]}
/>,
...[25, 35, 44].map((x) => (
<keepout
shape="rect"
pcbX={side * x}
pcbY={0}
width={x === 44 ? 2 : 4}
height={10}
layers={["bottom"]}
/>
)),
])}
<keepout
shape="rect"
pcbX={2}
pcbY={-5}
width={1.2}
height={3.4}
layers={["bottom"]}
/>
<keepout
shape="rect"
pcbX={-10.4}
pcbY={-5}
width={1.3}
height={2.7}
layers={["bottom"]}
/>
<keepout
shape="rect"
pcbX={-7.6}
pcbY={-5}
width={1.3}
height={2.7}
layers={["bottom"]}
/>
<keepout
shape="rect"
pcbX={-9}
pcbY={-8}
width={2.6}
height={1.1}
layers={["bottom"]}
/>
<schematicsheet name="Main" sheetSize="ANSI_B" />
<schematicsection name="power" displayName="Power and 50 mA charging" />
<schematicsection
name="control"
displayName="ATtiny402 control / regulated 3.0 V"
/>
<schematicsection name="touch" displayName="Capacitive touch / 2–5.5 V" />
<schematicsection
name="lights"
displayName="Six charlieplexed red LEDs"
/>
<pcbstiffener
name="CENTER"
shape="rect"
width={30}
height={30}
layer="bottom"
material="fr4"
thickness={0.4}
adhesiveThickness={0.05}
/>
{[-40, -30, -20, 20, 30, 40].map((pcbX, i) => (
<pcbstiffener
key={i}
name={`LED_SUPPORT_${i + 1}`}
pcbX={pcbX}
pcbY={0}
shape="rect"
width={6}
height={8}
layer="bottom"
material="polyimide"
thickness={0.2}
adhesiveThickness={0.05}
/>
))}
<Pad
schSectionName="power"
pinAttributes={{ pin1: { providesPower: true } }}
name="J_BAT_P"
pcbX={-12}
pcbY={12}
connections={{ pin1: "net.BAT" }}
/>
<Pad
schSectionName="power"
pinAttributes={{ pin1: { providesGround: true } }}
name="J_BAT_N"
pcbX={-9}
pcbY={12}
connections={{ pin1: "net.GND" }}
/>
<Pad
schSectionName="power"
pinAttributes={{ pin1: { providesPower: true, providesVoltage: 5 } }}
name="J_5V"
pcbX={-12}
pcbY={-12}
connections={{ pin1: "net.VBUS" }}
/>
<Pad
schSectionName="power"
pinAttributes={{ pin1: { providesGround: true } }}
name="J_0V"
pcbX={-9}
pcbY={-12}
connections={{ pin1: "net.GND" }}
/>
<chip
schSectionName="power"
pinAttributes={{
VDD: { requiresPower: true },
GND: { requiresGround: true },
VBAT: { isPassive: true },
PROG: { isPassive: true },
STAT: {
isOutput: true,
canUseOpenDrain: true,
isUsingOpenDrain: true,
},
}}
pcbStyle={{ silkscreenTextVisibility: "hidden" }}
name="U2"
manufacturerPartNumber="MCP73831T-2ACI/OT"
footprint={<ChargerFootprint />}
pcbX={-9}
pcbY={-5}
pinLabels={{
pin1: "STAT",
pin2: "GND",
pin3: "VBAT",
pin4: "VDD",
pin5: "PROG",
}}
connections={{
STAT: "net.CHARGE",
GND: "net.GND",
VBAT: "net.BAT",
VDD: "net.VBUS",
PROG: "net.PROG",
}}
/>
<resistor
schSectionName="power"
name="RPROG"
manufacturerPartNumber="RC0603FR-0720KL"
resistance="20k"
footprint="0603"
pcbX={-9}
pcbY={-8}
connections={{ pin1: "net.PROG", pin2: "net.GND" }}
/>
<capacitor
schSectionName="power"
name="CIN"
manufacturerPartNumber="GRM188R61A475KE15D"
capacitance="4.7uF"
maxVoltageRating={10}
footprint="0603"
pcbX={-13}
pcbY={-5}
pcbRotation={90}
connections={{ pin1: "net.VBUS", pin2: "net.GND" }}
/>
<capacitor
schSectionName="power"
name="CBAT"
manufacturerPartNumber="GRM188R61A475KE15D"
capacitance="4.7uF"
maxVoltageRating={10}
footprint="0603"
pcbX={-5}
pcbY={-5}
pcbRotation={90}
connections={{ pin1: "net.BAT", pin2: "net.GND" }}
/>
<PowerSwitch
schSectionName="power"
pinAttributes={{
pin1: { isPassive: true },
pin2: { isPassive: true },
pin3: { isPassive: true, providesPower: true },
}}
name="SW1"
manufacturerPartNumber="JS102011SAQN"
pcbX={0}
pcbY={11}
pcbRotation={180}
connections={{ pin2: "net.BAT", pin3: "net.VSW" }}
/>
<chip
name="U4"
schSectionName="power"
manufacturerPartNumber="MCP1700T-3002E/TT"
footprint={<RegulatorFootprint />}
pcbX={-1}
pcbY={-6}
pinLabels={{ pin1: "GND", pin2: "VOUT", pin3: "VIN" }}
pinAttributes={{
GND: { requiresGround: true },
VIN: { requiresPower: true },
VOUT: { providesPower: true, providesVoltage: 3 },
}}
connections={{ GND: "net.GND", VIN: "net.VSW", VOUT: "net.VCC" }}
/>
<capacitor
name="C4"
schSectionName="power"
manufacturerPartNumber="GRM188R61A475KE15D"
capacitance="4.7uF"
maxVoltageRating={10}
footprint="0603"
pcbX={-4}
pcbY={-9}
connections={{ pin1: "net.VSW", pin2: "net.GND" }}
/>
<capacitor
pcbStyle={{ silkscreenTextVisibility: "hidden" }}
name="C5"
schSectionName="power"
manufacturerPartNumber="GRM188R61A475KE15D"
capacitance="4.7uF"
maxVoltageRating={10}
footprint="0603"
pcbX={-1}
pcbY={-9}
connections={{ pin1: "net.VCC", pin2: "net.GND" }}
/>
<resistor
schSectionName="power"
name="RPWR"
manufacturerPartNumber="RC0603FR-0710KL"
resistance="10k"
footprint="0603"
pcbX={8}
pcbY={7}
connections={{ pin1: "net.VCC", pin2: "net.PWR_LED" }}
/>
<led
schSectionName="power"
pcbStyle={{ silkscreenTextVisibility: "hidden" }}
name="DPWR"
color="green"
manufacturerPartNumber="LTST-C190KGKT"
footprint={<LedFootprint />}
pcbX={12}
pcbY={7}
connections={{ anode: "net.PWR_LED", cathode: "net.GND" }}
/>
<resistor
schSectionName="power"
name="RCHG"
manufacturerPartNumber="RC0603FR-073K3L"
resistance="3.3k"
footprint="0603"
pcbX={8}
pcbY={11}
connections={{ pin1: "net.VBUS", pin2: "net.CHG_LED" }}
/>
<led
schSectionName="power"
pcbStyle={{ silkscreenTextVisibility: "hidden" }}
name="DCHG"
color="red"
manufacturerPartNumber="LTST-C190KRKT"
footprint={<LedFootprint />}
pcbX={12}
pcbY={11}
connections={{ anode: "net.CHG_LED", cathode: "net.CHARGE" }}
/>
<chip
schSectionName="control"
pinAttributes={{
VDD: { requiresPower: true },
GND: { requiresGround: true },
PA6: {
isBidirectional: true,
canUseTriState: true,
isUsingTriState: true,
},
PA7: {
isBidirectional: true,
canUseTriState: true,
isUsingTriState: true,
},
PA1: {
isBidirectional: true,
canUseTriState: true,
isUsingTriState: true,
},
PA2: { isInput: true },
PA3: { isInput: true },
UPDI: { isBidirectional: true },
}}
pcbStyle={{ silkscreenTextVisibility: "hidden" }}
name="U1"
manufacturerPartNumber="ATTINY402-SSN"
footprint="soic8_w6.95mm_pl1.55mm_pw0.6mm"
pcbX={-3}
pcbY={2}
pinLabels={{
pin1: "VDD",
pin2: "PA6",
pin3: "PA7",
pin4: "PA1",
pin5: "PA2",
pin6: "UPDI",
pin7: "PA3",
pin8: "GND",
}}
connections={{
VDD: "net.VCC",
GND: "net.GND",
PA6: "net.GPIO_A",
PA7: "net.GPIO_B",
PA1: "net.GPIO_C",
PA2: "net.TOUCH",
UPDI: "net.UPDI",
}}
/>
<capacitor
schSectionName="control"
name="C1"
manufacturerPartNumber="GRM188R71C104KA01D"
maxVoltageRating={16}
capacitance="100nF"
footprint="0603"
pcbX={-8}
pcbY={4}
pcbRotation={90}
connections={{ pin1: "net.VCC", pin2: "net.GND" }}
/>
<resistor
schSectionName="control"
name="RA"
manufacturerPartNumber="RC0603FR-07330RL"
resistance="330"
footprint="0603"
pcbX={-13}
pcbY={4}
connections={{ pin1: "net.GPIO_A", pin2: "net.A" }}
/>
<resistor
schSectionName="control"
name="RB"
manufacturerPartNumber="RC0603FR-07330RL"
resistance="330"
footprint="0603"
pcbX={-13}
pcbY={1}
connections={{ pin1: "net.GPIO_B", pin2: "net.B" }}
/>
<resistor
schSectionName="control"
name="RC"
manufacturerPartNumber="RC0603FR-07330RL"
resistance="330"
footprint="0603"
pcbX={-9}
pcbY={-1}
connections={{ pin1: "net.GPIO_C", pin2: "net.C" }}
/>
<Pad
schSectionName="control"
name="J_UPDI"
pcbX={0}
pcbY={-12}
connections={{ pin1: "net.UPDI" }}
/>
<Pad
schSectionName="control"
name="J_VREF"
pcbX={3}
pcbY={-12}
connections={{ pin1: "net.VCC" }}
/>
<Pad
schSectionName="control"
name="J_GND"
pcbX={6}
pcbY={-12}
connections={{ pin1: "net.GND" }}
/>
<chip
schSectionName="touch"
pinAttributes={{
VDD: { requiresPower: true },
GND: { requiresGround: true },
Q: { isOutput: true },
I: { isPassive: true },
AHLB: { isInput: true },
TOG: { isInput: true },
}}
pcbStyle={{ silkscreenTextVisibility: "hidden" }}
name="U3"
manufacturerPartNumber="TTP223-BA6"
footprint={<TouchFootprint />}
pcbX={6}
pcbY={-5}
pinLabels={{
pin1: "Q",
pin2: "GND",
pin3: "I",
pin4: "AHLB",
pin5: "VDD",
pin6: "TOG",
}}
connections={{
Q: "net.TOUCH",
GND: "net.GND",
I: "net.SENSE",
AHLB: "net.GND",
VDD: "net.VCC",
TOG: "net.GND",
}}
/>
<capacitor
schSectionName="touch"
pcbStyle={{ silkscreenTextVisibility: "hidden" }}
name="C3"
manufacturerPartNumber="GRM188R71C104KA01D"
maxVoltageRating={16}
capacitance="100nF"
footprint="0603"
pcbX={2}
pcbY={-5}
pcbRotation={90}
connections={{ pin1: "net.VCC", pin2: "net.GND" }}
/>
<chip
schSectionName="touch"
doNotPlace
pinAttributes={{ pin1: { isPassive: true } }}
name="J_TOUCH"
pcbX={10}
pcbY={1}
connections={{ pin1: "net.SENSE" }}
footprint={
<footprint insertionDirection="from_above">
<smtpad
noSolderPaste
coveredWithSolderMask
shape="circle"
radius={2.5}
portHints={["1"]}
pcbX={0}
pcbY={0}
/>
<courtyardcircle radius={2.75} />
</footprint>
}
/>
{(
[
[-40, "A", "B"],
[-30, "B", "A"],
[-20, "A", "C"],
[20, "C", "A"],
[30, "B", "C"],
[40, "C", "B"],
] as const
).map(([pcbX, anode, cathode], i) => (
<led
schSectionName="lights"
key={i}
name={`D${i + 1}`}
manufacturerPartNumber="LTST-C190KRKT"
color="red"
footprint={<LedFootprint />}
pcbX={pcbX}
pcbY={0}
connections={{ anode: `net.${anode}`, cathode: `net.${cathode}` }}
/>
))}
<silkscreentext text="BAT+" pcbX={-12} pcbY={14.2} fontSize={0.8} />
<silkscreentext text="BAT-" pcbX={-9} pcbY={14.2} fontSize={0.8} />
<silkscreentext text="5V" pcbX={-12} pcbY={-14.2} fontSize={0.8} />
<silkscreentext text="GND" pcbX={-9} pcbY={-14.2} fontSize={0.8} />
<silkscreentext text="UPDI" pcbX={0} pcbY={-14.2} fontSize={0.8} />
<silkscreentext text="VCC" pcbX={3} pcbY={-14.2} fontSize={0.8} />
<silkscreentext text="GND" pcbX={6} pcbY={-14.2} fontSize={0.8} />
<silkscreentext text="PWR" pcbX={12} pcbY={8.5} fontSize={0.8} />
<silkscreentext text="CHG" pcbX={12} pcbY={12.5} fontSize={0.8} />
<silkscreentext text="TOUCH" pcbX={10} pcbY={4.4} fontSize={0.8} />
<silkscreentext text="ON" pcbX={4} pcbY={15} fontSize={0.8} />
<silkscreentext text="OFF" pcbX={-4} pcbY={15} fontSize={0.8} />
</board>
);
}