Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions ArduinoShield.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import React from "react";

// 2.54mm pin spacing
const PITCH = 2.54;
// Header Y offset between digital and analog (center-to-center)
const DIGITAL_ANALOG_Y_DIST = 15.24;

/**
* Props for ArduinoShield
* @param name - Name of the shield/group
* @param children - Any child components to render inside the shield group
* @param showResetButton - Show reset button (bonus)
* @param showLed - Show LED (bonus)
*/
export const ArduinoShield = ({
name = "ArduinoShield",
children,
showResetButton = false,
showLed = true,
}: {
name?: string;
children?: React.ReactNode;
showResetButton?: boolean;
showLed?: boolean;
}) => {
// Pin label arrays
const digitalPins = ["D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7"];
const analogPins = ["A0", "A1", "A2", "A3", "A4", "A5"];
const powerPins = ["RESET", "3.3V", "5V", "GND", "GND", "VIN"];
const icspPins = ["MISO", "VCC", "SCK", "MOSI", "RESET", "GND"];

const digitalHeader = {
pcbX: 0,
pcbY: 0,
pcbRotation: 0,
};
const analogHeader = {
pcbX: 15.24,
pcbY: 0,
pcbRotation: 0,
};
// Power header: top, horizontal
const powerHeader = {
pcbX: 2.54 * 2, // Centered above digital
pcbY: -2.54 * 2,
pcbRotation: 90,
};
// ICSP header: bottom, horizontal (6-pin, 2x3)
const icspHeader = {
pcbX: 7.62, // Centered between digital/analog
pcbY: 13.5, // Below headers
pcbRotation: 0,
};

// Bonus: Reset button and LED positions
const resetButton = {
pcbX: 1,
pcbY: -5,
};
const led = {
pcbX: 13,
pcbY: -5,
};

// Placeholder module group positions
const modulePlaceholders = [
{ name: "OLED", pcbX: 2, pcbY: 8 },
{ name: "RTC", pcbX: 8, pcbY: 8 },
{ name: "RF", pcbX: 13, pcbY: 8 },
];

return (
<group name={name}>
<board>
{/* Digital header (female) */}
<pinheader
name="Digital"
pinCount={8}
pitch={PITCH}
gender="female"
pcbX={digitalHeader.pcbX}
pcbY={digitalHeader.pcbY}
pcbRotation={digitalHeader.pcbRotation}
showSilkscreenPinLabels={true}
pcbPinLabels={digitalPins.reduce((acc, pin, i) => ({ ...acc, [i + 1]: pin }), {} as Record<string, string>)}
/>
{/* Analog header (female) */}
<pinheader
name="Analog"
pinCount={6}
pitch={PITCH}
gender="female"
pcbX={analogHeader.pcbX}
pcbY={analogHeader.pcbY}
pcbRotation={analogHeader.pcbRotation}
showSilkscreenPinLabels={true}
pcbPinLabels={analogPins.reduce((acc, pin, i) => ({ ...acc, [i + 1]: pin }), {} as Record<string, string>)}
/>
{/* Power header (female) */}
<pinheader
name="Power"
pinCount={6}
pitch={PITCH}
gender="female"
pcbX={powerHeader.pcbX}
pcbY={powerHeader.pcbY}
pcbRotation={powerHeader.pcbRotation}
showSilkscreenPinLabels={true}
pcbPinLabels={powerPins.reduce((acc, pin, i) => ({ ...acc, [i + 1]: pin }), {} as Record<string, string>)}
/>
{/* ICSP header (male, 2x3) */}
<pinheader
name="ICSP"
pinCount={6}
pitch={PITCH}
gender="male"
doubleRow={true}
pcbX={icspHeader.pcbX}
pcbY={icspHeader.pcbY}
pcbRotation={icspHeader.pcbRotation}
showSilkscreenPinLabels={true}
pcbPinLabels={icspPins.reduce((acc, pin, i) => ({ ...acc, [i + 1]: pin }), {} as Record<string, string>)}
/>
{/* Optional reset button */}
{showResetButton && (
<switch
name="RESET_BTN"
pcbX={resetButton.pcbX}
pcbY={resetButton.pcbY}
type="spst"
footprint="SW_SPST_6x6x5mm"
/>
)}
{/* Optional LED */}
{showLed && (
<led name="SHIELD_LED" pcbX={led.pcbX} pcbY={led.pcbY} footprint="0805" />
)}
{/* Placeholder module groups */}
{modulePlaceholders.map((mod) => (
<group name={mod.name} key={mod.name} pcbX={mod.pcbX} pcbY={mod.pcbY}>
{/* Placeholder for {mod.name} module */}
</group>
))}
{/* Render children */}
{children}
</board>
</group>
);
};
14 changes: 9 additions & 5 deletions index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { ArduinoShield } from "./ArduinoShield";

export default () => (
<board>
<resistor resistance="1k" footprint="0402" name="R1" schX={3} pcbX={3} />
<capacitor capacitance="1000pF" footprint="0402" name="C1" schX={-3} pcbX={-3} />
<trace from=".R1 > .pin1" to=".C1 > .pin1" />
<board width="50mm" height="60mm">
<ArduinoShield name="MyArduinoShield">
<resistor resistance="1k" footprint="0402" name="R1" pcbX={5} pcbY={5} />
<capacitor capacitance="1000pF" footprint="0402" name="C1" pcbX={10} pcbY={5} />
<trace from=".R1 > .pin1" to=".C1 > .pin1" />
</ArduinoShield>
</board>
)
)
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"moduleResolution": "node",
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"ignoreDeprecations": "6.0",
"resolveJsonModule": true,
"sourceMap": true,
"allowSyntheticDefaultImports": true,
Expand Down