krishnax12/usb-c-control-dial

USB-C control dial PCB with an EC11 push encoder and a 16-LED ring for volume and brightness controls. Work in progress; firmware not included and not fabrication-ready.

Version
0.0.3
License
unset
Stars
1

components/led-ring.tsx

import { Fragment } from "react"
import { applyToPoint, rotateDEG } from "transformation-matrix"
import { SK6812MINI_E } from "../imports/SK6812MINI_E/SK6812MINI_E"

export const ledCount = 16
export const ledRadius = 30
export const ledWindow = { width: 3.4, height: 3 }

export const ledPositions = Array.from({ length: ledCount }, (_, index) => {
  const ccwRotationDegrees = -150 + (300 * index) / (ledCount - 1)
  const ledToBoardTransform = rotateDEG(ccwRotationDegrees)
  return {
    index,
    ccwRotationDegrees,
    center: applyToPoint(ledToBoardTransform, { x: 0, y: ledRadius }),
    capacitorCenter: applyToPoint(ledToBoardTransform, {
      x: 0,
      y: ledRadius - 8,
    }),
    points: [
      { x: -ledWindow.width / 2, y: ledRadius - ledWindow.height / 2 },
      { x: ledWindow.width / 2, y: ledRadius - ledWindow.height / 2 },
      { x: ledWindow.width / 2, y: ledRadius + ledWindow.height / 2 },
      { x: -ledWindow.width / 2, y: ledRadius + ledWindow.height / 2 },
    ].map((corner) => applyToPoint(ledToBoardTransform, corner)),
  }
})

export function LedRing({
  openingShape = "polygon",
}: {
  openingShape?: "polygon" | "rect"
}) {
  return (
    <>
      {Array.from({ length: 4 }, (_, quadrant) => (
        <Fragment key={quadrant}>
          <schematicsheet name={`LED_RING_${quadrant + 1}`}>
            {ledPositions.slice(quadrant * 4, quadrant * 4 + 4).map((led) => (
              <group key={led.index} name={`PIXEL_${led.index + 1}`}>
                <SK6812MINI_E
                  openingShape={openingShape}
                  name={`D${led.index + 1}`}
                  layer="bottom"
                  pcbX={led.center.x}
                  pcbY={led.center.y}
                  pcbRotation={led.ccwRotationDegrees}
                  schWidth={1.8}
                  schHeight={2}
                  schPinArrangement={{
                    leftSide: { pins: ["pin2"], direction: "top-to-bottom" },
                    rightSide: { pins: ["pin4"], direction: "top-to-bottom" },
                    topSide: { pins: ["pin3"], direction: "left-to-right" },
                    bottomSide: { pins: ["pin1"], direction: "left-to-right" },
                  }}
                  connections={{
                    GND: "net.GND",
                    VDD: "net.V5",
                    DIN:
                      led.index === 0
                        ? "net.LED_DATA"
                        : `net.PIXEL_${led.index}`,
                    ...(led.index < ledCount - 1 && {
                      DOUT: `net.PIXEL_${led.index + 1}`,
                    }),
                  }}
                  noConnect={led.index === ledCount - 1 ? ["DOUT"] : []}
                />
                <capacitor
                  name={`C${led.index + 10}`}
                  capacitance="100nF"
                  supplierPartNumbers={{ jlcpcb: ["C14663"] }}
                  maxVoltageRating="16V"
                  footprint="0603"
                  layer="bottom"
                  pcbX={led.capacitorCenter.x}
                  pcbY={led.capacitorCenter.y}
                  pcbRotation={led.ccwRotationDegrees}
                  connections={{ pin1: "net.V5", pin2: "net.GND" }}
                />
              </group>
            ))}
          </schematicsheet>
        </Fragment>
      ))}
    </>
  )
}