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