mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-07 12:24:58 +10:00
s3
This commit is contained in:
@@ -810,8 +810,10 @@ public abstract class AbstractMakerBoard extends AbstractTransparentComponent<Vo
|
||||
Path2D.Double antPath = new Path2D.Double();
|
||||
double antPadX = x + new Size(1.5d, SizeUnit.mm).convertToPixels();
|
||||
double antPadW = width - new Size(3.0d, SizeUnit.mm).convertToPixels();
|
||||
double antTopY = y + new Size(1.3d, SizeUnit.mm).convertToPixels();
|
||||
double antMidY = y + new Size(5.4d, SizeUnit.mm).convertToPixels();
|
||||
double traceH = new Size(4.1d, SizeUnit.mm).convertToPixels();
|
||||
double marginY = height > traceH ? (height - traceH) / 2.0 : height * 0.15;
|
||||
double antTopY = y + marginY;
|
||||
double antMidY = y + height - marginY;
|
||||
antPath.moveTo(antPadX, antMidY);
|
||||
antPath.lineTo(antPadX, antTopY);
|
||||
antPath.lineTo(antPadX + antPadW * 0.25, antTopY);
|
||||
|
||||
@@ -52,7 +52,7 @@ import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(name = "ESP32 DevKit", category = "Controllers",
|
||||
author = "Branislav Stojkovic", description = "ESP32 DevKit Wi-Fi and Bluetooth Development Board (30-Pin / 38-Pin)",
|
||||
author = "Branislav Stojkovic", description = "ESP32 DevKit Wi-Fi and Bluetooth Development Board (30-Pin / 38-Pin / 44-Pin S3)",
|
||||
instanceNamePrefix = "MCU", zOrder = IDIYComponent.COMPONENT,
|
||||
bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME,
|
||||
enableCache = true)
|
||||
@@ -62,7 +62,8 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
|
||||
public enum DevKitVersion {
|
||||
DevKit_V1_30Pin("30-Pin (DevKit V1 / DOIT)"),
|
||||
DevKitC_V4_38Pin("38-Pin (DevKitC V4)");
|
||||
DevKitC_V4_38Pin("38-Pin (DevKitC V4)"),
|
||||
ESP32_S3_DevKitC_44Pin("44-Pin (9-S3 DevKitC-1)");
|
||||
|
||||
private final String label;
|
||||
|
||||
@@ -103,6 +104,18 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
// Common Spacing
|
||||
public static Size ROW_SPACING = new Size(1.0d, SizeUnit.in);
|
||||
|
||||
// ESP32-S3 DevKitC-1 (44-Pin) Dimensions
|
||||
// BOARD_LENGTH_S3 is the main PCB body only; antenna extends above separately
|
||||
public static Size BOARD_WIDTH_S3 = new Size(25.40d, SizeUnit.mm);
|
||||
public static Size BOARD_LENGTH_S3 = new Size(62.74d, SizeUnit.mm);
|
||||
public static Size ROW_SPACING_S3 = new Size(22.86d, SizeUnit.mm);
|
||||
public static Size TOP_MARGIN_S3 = new Size(1.40d, SizeUnit.mm);
|
||||
public static Size BOTTOM_MARGIN_S3 = new Size(8.0d, SizeUnit.mm);
|
||||
public static Size ANTENNA_WIDTH_S3 = new Size(18.0d, SizeUnit.mm);
|
||||
public static Size ANTENNA_LENGTH_S3 = new Size(6.0d, SizeUnit.mm);
|
||||
public static Size SHIELD_WIDTH_S3 = new Size(16.0d, SizeUnit.mm);
|
||||
public static Size SHIELD_LENGTH_S3 = new Size(16.0d, SizeUnit.mm);
|
||||
|
||||
public static final String[] PIN_NAMES_30 = new String[] {
|
||||
// Left row (pins 0..14, top to bottom)
|
||||
"EN", "VP (GPIO36)", "VN (GPIO39)", "D34", "D35", "D32", "D33", "D25", "D26", "D27", "D14", "D12", "GND1", "D13", "3V3",
|
||||
@@ -121,6 +134,20 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
"GPIO15", "D1 (GPIO8)", "D0 (GPIO7)", "CLK (GPIO6)"
|
||||
};
|
||||
|
||||
public static final String[] PIN_NAMES_S3_44 = new String[] {
|
||||
// Left row (pins 0..21, top to bottom)
|
||||
"3V3_1", "3V3_2", "RST", "GPIO4", "GPIO5", "GPIO6", "GPIO7",
|
||||
"GPIO15", "GPIO16", "GPIO17", "GPIO18", "GPIO8", "GPIO3",
|
||||
"GPIO46", "GPIO9", "GPIO10", "GPIO11", "GPIO12", "GPIO13",
|
||||
"GPIO14", "5V0", "GND1",
|
||||
// Right row (pins 22..43, top to bottom)
|
||||
"GND2", "GPIO43 (U0TXD)", "GPIO44 (U0RXD)", "GPIO1", "GPIO2",
|
||||
"GPIO42", "GPIO41", "GPIO40", "GPIO39", "GPIO38",
|
||||
"GPIO37", "GPIO36", "GPIO35", "GPIO0 (BOOT)", "GPIO45",
|
||||
"GPIO48", "GPIO47", "GPIO21", "GPIO20 (USB D+)", "GPIO19 (USB D-)",
|
||||
"GND3", "GND4"
|
||||
};
|
||||
|
||||
private DevKitVersion version = DevKitVersion.DevKit_V1_30Pin;
|
||||
protected boolean headers = false;
|
||||
|
||||
@@ -157,10 +184,14 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
if (index >= 0 && index < PIN_NAMES_30.length) {
|
||||
return PIN_NAMES_30[index];
|
||||
}
|
||||
} else {
|
||||
} else if (version == DevKitVersion.DevKitC_V4_38Pin) {
|
||||
if (index >= 0 && index < PIN_NAMES_38.length) {
|
||||
return PIN_NAMES_38[index];
|
||||
}
|
||||
} else if (version == DevKitVersion.ESP32_S3_DevKitC_44Pin) {
|
||||
if (index >= 0 && index < PIN_NAMES_S3_44.length) {
|
||||
return PIN_NAMES_S3_44[index];
|
||||
}
|
||||
}
|
||||
return "Pin " + (index + 1);
|
||||
}
|
||||
@@ -169,9 +200,9 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
protected void updateControlPoints() {
|
||||
Point2D firstPoint = controlPoints[0];
|
||||
double spacing = PIN_SPACING.convertToPixels();
|
||||
double rowSpacing = ROW_SPACING.convertToPixels(); // 200px (1.00")
|
||||
|
||||
if (version == DevKitVersion.DevKit_V1_30Pin) {
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
double[][] relativeOffsets = new double[30][2];
|
||||
for (int i = 0; i < 15; i++) {
|
||||
relativeOffsets[i][0] = 0;
|
||||
@@ -182,7 +213,8 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
relativeOffsets[15 + i][1] = (14 - i) * spacing;
|
||||
}
|
||||
rotatePoints(firstPoint, relativeOffsets);
|
||||
} else {
|
||||
} else if (version == DevKitVersion.DevKitC_V4_38Pin) {
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
double[][] relativeOffsets = new double[PIN_NAMES_38.length][2];
|
||||
for (int i = 0; i < 19; i++) {
|
||||
relativeOffsets[i][0] = 0;
|
||||
@@ -193,6 +225,18 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
relativeOffsets[19 + i][1] = i * spacing;
|
||||
}
|
||||
rotatePoints(firstPoint, relativeOffsets);
|
||||
} else if (version == DevKitVersion.ESP32_S3_DevKitC_44Pin) {
|
||||
double rowSpacingS3 = ROW_SPACING_S3.convertToPixels();
|
||||
double[][] relativeOffsets = new double[PIN_NAMES_S3_44.length][2];
|
||||
for (int i = 0; i < 22; i++) {
|
||||
relativeOffsets[i][0] = 0;
|
||||
relativeOffsets[i][1] = i * spacing;
|
||||
}
|
||||
for (int i = 0; i < 22; i++) {
|
||||
relativeOffsets[22 + i][0] = rowSpacingS3;
|
||||
relativeOffsets[22 + i][1] = i * spacing;
|
||||
}
|
||||
rotatePoints(firstPoint, relativeOffsets);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,16 +245,33 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
Point2D p0 = controlPoints[0];
|
||||
double x = p0.getX();
|
||||
double y = p0.getY();
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
|
||||
if (version == DevKitVersion.DevKit_V1_30Pin) {
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
double boardW = BOARD_WIDTH_30.convertToPixels();
|
||||
double boardH = BOARD_LENGTH_30.convertToPixels();
|
||||
double topMargin = TOP_MARGIN_30.convertToPixels();
|
||||
double boardX = (x + rowSpacing / 2.0) - boardW / 2.0;
|
||||
double boardY = y - topMargin;
|
||||
return new RoundRectangle2D.Double(boardX, boardY, boardW, boardH, 8, 8);
|
||||
} else if (version == DevKitVersion.ESP32_S3_DevKitC_44Pin) {
|
||||
double rowSpacingS3 = ROW_SPACING_S3.convertToPixels();
|
||||
double boardW = BOARD_WIDTH_S3.convertToPixels();
|
||||
double boardH = BOARD_LENGTH_S3.convertToPixels();
|
||||
double antennaW = ANTENNA_WIDTH_S3.convertToPixels();
|
||||
double antennaH = ANTENNA_LENGTH_S3.convertToPixels();
|
||||
double topMargin = TOP_MARGIN_S3.convertToPixels();
|
||||
|
||||
double mainX = (x + rowSpacingS3 / 2.0) - boardW / 2.0;
|
||||
double mainY = y - topMargin;
|
||||
double antennaX = (x + rowSpacingS3 / 2.0) - antennaW / 2.0;
|
||||
double antennaY = mainY - antennaH;
|
||||
|
||||
Area bodyArea = new Area(new Rectangle2D.Double(mainX, mainY, boardW, boardH));
|
||||
bodyArea.add(new Area(new Rectangle2D.Double(antennaX, antennaY, antennaW, antennaH + 1)));
|
||||
return bodyArea;
|
||||
} else {
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
double mainW = BOARD_WIDTH_38.convertToPixels();
|
||||
double mainH = MAIN_BODY_LENGTH_38.convertToPixels();
|
||||
double antennaW = ANTENNA_WIDTH.convertToPixels();
|
||||
@@ -243,10 +304,17 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
g2d.rotate(orientation.toRadians(), x, y);
|
||||
}
|
||||
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
Shape boardShape = getBodyShape();
|
||||
Composite oldComposite = applyAlpha(g2d, componentState);
|
||||
|
||||
// Determine the center X for the current version
|
||||
double centerX;
|
||||
if (version == DevKitVersion.ESP32_S3_DevKitC_44Pin) {
|
||||
centerX = x + ROW_SPACING_S3.convertToPixels() / 2.0;
|
||||
} else {
|
||||
centerX = x + ROW_SPACING.convertToPixels() / 2.0;
|
||||
}
|
||||
|
||||
drawingObserver.startTracking();
|
||||
if (outlineMode) {
|
||||
g2d.setColor(Constants.TRANSPARENT_COLOR);
|
||||
@@ -255,7 +323,27 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
if (version == DevKitVersion.DevKit_V1_30Pin) {
|
||||
g2d.setColor(bodyColor);
|
||||
g2d.fill(boardShape);
|
||||
} else if (version == DevKitVersion.ESP32_S3_DevKitC_44Pin) {
|
||||
double boardW = BOARD_WIDTH_S3.convertToPixels();
|
||||
double boardH = BOARD_LENGTH_S3.convertToPixels();
|
||||
double antennaW = ANTENNA_WIDTH_S3.convertToPixels();
|
||||
double antennaH = ANTENNA_LENGTH_S3.convertToPixels();
|
||||
double topMargin = TOP_MARGIN_S3.convertToPixels();
|
||||
|
||||
double mainX = centerX - boardW / 2.0;
|
||||
double mainY = y - topMargin;
|
||||
double antennaX = centerX - antennaW / 2.0;
|
||||
double antennaY = mainY - antennaH;
|
||||
|
||||
// Main board body (sharp rectangular edges)
|
||||
g2d.setColor(bodyColor);
|
||||
g2d.fill(new Rectangle2D.Double(mainX, mainY, boardW, boardH));
|
||||
|
||||
// Antenna tab in #1e1e1e
|
||||
g2d.setColor(ANTENNA_BG_COLOR);
|
||||
g2d.fill(new Rectangle2D.Double(antennaX, antennaY, antennaW, antennaH));
|
||||
} else {
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
double mainW = BOARD_WIDTH_38.convertToPixels();
|
||||
double mainH = MAIN_BODY_LENGTH_38.convertToPixels();
|
||||
double antennaW = ANTENNA_WIDTH.convertToPixels();
|
||||
@@ -281,32 +369,32 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
g2d.draw(boardShape);
|
||||
|
||||
if (!outlineMode) {
|
||||
double antennaW = ANTENNA_WIDTH.convertToPixels();
|
||||
double antennaH = (version == DevKitVersion.DevKit_V1_30Pin) ? ANTENNA_LENGTH.convertToPixels() : ANTENNA_LENGTH_38.convertToPixels();
|
||||
double antennaX = (x + rowSpacing / 2.0) - antennaW / 2.0;
|
||||
double antennaY;
|
||||
double shieldY;
|
||||
double shieldH = SHIELD_LENGTH.convertToPixels();
|
||||
double shieldW = SHIELD_WIDTH.convertToPixels();
|
||||
double shieldX = (x + rowSpacing / 2.0) - shieldW / 2.0;
|
||||
double usbY;
|
||||
double btnLeftX;
|
||||
double btnRightX;
|
||||
double btnY;
|
||||
double shift1mm = new Size(1.0d, SizeUnit.mm).convertToPixels();
|
||||
double btnW = 20;
|
||||
double btnH = 20;
|
||||
double shift1mm = new Size(1.0d, SizeUnit.mm).convertToPixels();
|
||||
|
||||
if (version == DevKitVersion.DevKit_V1_30Pin) {
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
double boardW = BOARD_WIDTH_30.convertToPixels();
|
||||
double boardH = BOARD_LENGTH_30.convertToPixels();
|
||||
double topMargin = TOP_MARGIN_30.convertToPixels();
|
||||
double boardX = (x + rowSpacing / 2.0) - boardW / 2.0;
|
||||
double boardX = centerX - boardW / 2.0;
|
||||
double boardY = y - topMargin;
|
||||
|
||||
antennaY = boardY;
|
||||
shieldY = boardY + antennaH;
|
||||
usbY = boardY + boardH - 22;
|
||||
double antennaW = ANTENNA_WIDTH.convertToPixels();
|
||||
double antennaH = ANTENNA_LENGTH.convertToPixels();
|
||||
double antennaX = centerX - antennaW / 2.0;
|
||||
double antennaY = boardY;
|
||||
|
||||
// Antenna (dark rectangle underneath + gold serpentine trace)
|
||||
drawPcbAntenna(g2d, antennaX, antennaY, antennaW, antennaH);
|
||||
|
||||
// ESP32-WROOM-32 metal shield module below antenna
|
||||
double shieldW = SHIELD_WIDTH.convertToPixels();
|
||||
double shieldH = SHIELD_LENGTH.convertToPixels();
|
||||
double shieldX = centerX - shieldW / 2.0;
|
||||
double shieldY = boardY + antennaH;
|
||||
drawMetalConnector(g2d, shieldX, shieldY, shieldW, shieldH, "ESP32-WROOM-32");
|
||||
|
||||
// 4 Corner Mounting Holes (diameter 2.8mm, 0.8mm away from edges in both directions)
|
||||
double holeDiameter = HOLE_DIAMETER_30.convertToPixels();
|
||||
@@ -322,58 +410,109 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
drawMountingHole(g2d, leftHoleX, bottomHoleY, holeDiameter);
|
||||
drawMountingHole(g2d, rightHoleX, bottomHoleY, holeDiameter);
|
||||
|
||||
btnY = boardY + boardH - 25 - shift1mm;
|
||||
btnLeftX = leftHoleX + 14 + shift1mm;
|
||||
btnRightX = rightHoleX - 14 - shift1mm - btnW;
|
||||
// Micro-USB Jack at bottom
|
||||
double usbW = 58;
|
||||
double usbH = 34;
|
||||
double usbX = centerX - usbW / 2.0;
|
||||
double usbY = boardY + boardH - 22;
|
||||
drawMetalConnector(g2d, usbX, usbY, usbW, usbH, "USB");
|
||||
|
||||
// EN & BOOT tactile buttons at bottom (flanking the Micro-USB port)
|
||||
double btnY = boardY + boardH - 25 - shift1mm;
|
||||
double btnLeftX = leftHoleX + 14 + shift1mm;
|
||||
double btnRightX = rightHoleX - 14 - shift1mm - btnW;
|
||||
drawButtons(g2d, btnLeftX, btnRightX, btnY, btnW, btnH, "EN", "BOOT");
|
||||
|
||||
// Silkscreen
|
||||
g2d.setColor(SILK_COLOR);
|
||||
g2d.setFont(SILK_FONT);
|
||||
StringUtils.drawCenteredText(g2d, "ESP32 DevKit V1", centerX, shieldY + shieldH + 45, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
|
||||
} else if (version == DevKitVersion.ESP32_S3_DevKitC_44Pin) {
|
||||
double boardW = BOARD_WIDTH_S3.convertToPixels();
|
||||
double boardH = BOARD_LENGTH_S3.convertToPixels();
|
||||
double topMargin = TOP_MARGIN_S3.convertToPixels();
|
||||
double antennaW = ANTENNA_WIDTH_S3.convertToPixels();
|
||||
double antennaH = ANTENNA_LENGTH_S3.convertToPixels();
|
||||
|
||||
double mainX = centerX - boardW / 2.0;
|
||||
double mainY = y - topMargin;
|
||||
double antennaX = centerX - antennaW / 2.0;
|
||||
double antennaY = mainY - antennaH;
|
||||
|
||||
// Antenna at top (dark rectangle + gold serpentine trace)
|
||||
drawPcbAntenna(g2d, antennaX, antennaY, antennaW, antennaH);
|
||||
|
||||
// ESP32-S3-WROOM-1 metal shield module below antenna
|
||||
double shieldW = SHIELD_WIDTH_S3.convertToPixels();
|
||||
double shieldH = SHIELD_LENGTH_S3.convertToPixels();
|
||||
double shieldX = centerX - shieldW / 2.0;
|
||||
double shieldY = mainY + 4;
|
||||
drawMetalConnector(g2d, shieldX, shieldY, shieldW, shieldH, "ESP32-S3-WROOM-1");
|
||||
|
||||
// BOOT & RESET tactile buttons (per DXF: BOOT on left near pin 13/14, RESET on right near pin 20/19)
|
||||
double btnY = y + 18.5 * PIN_SPACING.convertToPixels() - btnH / 2.0;
|
||||
double btnLeftX = mainX + 49;
|
||||
double btnRightX = mainX + boardW - 49 - btnW;
|
||||
drawButtons(g2d, btnLeftX, btnRightX, btnY, btnW, btnH, "BOOT", "RST");
|
||||
|
||||
// Two USB Type-C connectors at bottom edge (UART on left, USB on right)
|
||||
// Each is 7x7mm, centered 6mm from the board edge, protruding 0.5mm below
|
||||
double usbSize = new Size(7.0d, SizeUnit.mm).convertToPixels();
|
||||
double usbEdgeDist = new Size(6.0d, SizeUnit.mm).convertToPixels();
|
||||
double usbOverhang = new Size(0.5d, SizeUnit.mm).convertToPixels();
|
||||
double usbLeftX = mainX + usbEdgeDist - usbSize / 2.0;
|
||||
double usbRightX = mainX + boardW - usbEdgeDist - usbSize / 2.0;
|
||||
double usbY = mainY + boardH - usbSize + usbOverhang;
|
||||
drawMetalConnector(g2d, usbLeftX, usbY, usbSize, usbSize, "UART");
|
||||
drawMetalConnector(g2d, usbRightX, usbY, usbSize, usbSize, "USB");
|
||||
|
||||
// Silkscreen
|
||||
g2d.setColor(SILK_COLOR);
|
||||
g2d.setFont(SILK_FONT);
|
||||
StringUtils.drawCenteredText(g2d, "ESP32-S3 DevKitC-1", centerX, shieldY + shieldH + 45, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
|
||||
} else {
|
||||
// 38-Pin (DevKitC V4)
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
double mainW = BOARD_WIDTH_38.convertToPixels();
|
||||
double mainH = MAIN_BODY_LENGTH_38.convertToPixels();
|
||||
double mainX = (x + rowSpacing / 2.0) - mainW / 2.0;
|
||||
double mainX = centerX - mainW / 2.0;
|
||||
double mainY = (y + 18 * PIN_SPACING.convertToPixels() / 2.0) - mainH / 2.0;
|
||||
|
||||
antennaY = mainY - antennaH;
|
||||
shieldY = mainY + 8;
|
||||
usbY = mainY + mainH - 22;
|
||||
double antennaW = ANTENNA_WIDTH.convertToPixels();
|
||||
double antennaH = ANTENNA_LENGTH_38.convertToPixels();
|
||||
double antennaX = centerX - antennaW / 2.0;
|
||||
double antennaY = mainY - antennaH;
|
||||
|
||||
btnY = mainY + mainH - 25;
|
||||
btnLeftX = mainX + 38;
|
||||
btnRightX = mainX + mainW - 38 - btnW;
|
||||
// Antenna (dark rectangle underneath + gold serpentine trace)
|
||||
drawPcbAntenna(g2d, antennaX, antennaY, antennaW, antennaH);
|
||||
|
||||
// ESP32-WROOM-32 metal shield module below antenna
|
||||
double shieldW = SHIELD_WIDTH.convertToPixels();
|
||||
double shieldH = SHIELD_LENGTH.convertToPixels();
|
||||
double shieldX = centerX - shieldW / 2.0;
|
||||
double shieldY = mainY + 8;
|
||||
drawMetalConnector(g2d, shieldX, shieldY, shieldW, shieldH, "ESP32-WROOM-32");
|
||||
|
||||
// Micro-USB Jack at bottom
|
||||
double usbW = 58;
|
||||
double usbH = 34;
|
||||
double usbX = centerX - usbW / 2.0;
|
||||
double usbY = mainY + mainH - 22;
|
||||
drawMetalConnector(g2d, usbX, usbY, usbW, usbH, "USB");
|
||||
|
||||
// EN & BOOT tactile buttons at bottom
|
||||
double btnY = mainY + mainH - 25;
|
||||
double btnLeftX = mainX + 38;
|
||||
double btnRightX = mainX + mainW - 38 - btnW;
|
||||
drawButtons(g2d, btnLeftX, btnRightX, btnY, btnW, btnH, "EN", "BOOT");
|
||||
|
||||
// Silkscreen
|
||||
g2d.setColor(SILK_COLOR);
|
||||
g2d.setFont(SILK_FONT);
|
||||
StringUtils.drawCenteredText(g2d, "ESP32 DevKitC V4", centerX, shieldY + shieldH + 45, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
|
||||
// Antenna (dark rectangle underneath + gold serpentine trace)
|
||||
drawPcbAntenna(g2d, antennaX, antennaY, antennaW, antennaH);
|
||||
|
||||
// ESP32-WROOM-32 metal shield module below antenna
|
||||
drawMetalConnector(g2d, shieldX, shieldY, shieldW, shieldH, "ESP32-WROOM-32");
|
||||
|
||||
// Micro-USB Jack at bottom
|
||||
double usbW = 58;
|
||||
double usbH = 34;
|
||||
double usbX = (x + rowSpacing / 2.0) - usbW / 2.0;
|
||||
drawMetalConnector(g2d, usbX, usbY, usbW, usbH, "USB");
|
||||
|
||||
// EN & BOOT tactile buttons at bottom (flanking the Micro-USB port)
|
||||
g2d.setColor(BUTTON_BODY_COLOR);
|
||||
g2d.fill(new RoundRectangle2D.Double(btnLeftX, btnY, btnW, btnH, 3, 3));
|
||||
g2d.fill(new RoundRectangle2D.Double(btnRightX, btnY, btnW, btnH, 3, 3));
|
||||
g2d.setColor(BUTTON_BORDER_COLOR);
|
||||
g2d.draw(new RoundRectangle2D.Double(btnLeftX, btnY, btnW, btnH, 3, 3));
|
||||
g2d.draw(new RoundRectangle2D.Double(btnRightX, btnY, btnW, btnH, 3, 3));
|
||||
|
||||
// Button actuators
|
||||
g2d.setColor(BUTTON_ACTUATOR_COLOR);
|
||||
g2d.fillOval((int) (btnLeftX + btnW / 2.0 - 4), (int) (btnY + btnH / 2.0 - 4), 8, 8);
|
||||
g2d.fillOval((int) (btnRightX + btnW / 2.0 - 4), (int) (btnY + btnH / 2.0 - 4), 8, 8);
|
||||
|
||||
g2d.setColor(SILK_COLOR);
|
||||
g2d.setFont(SILK_FONT_SMALL);
|
||||
StringUtils.drawCenteredText(g2d, "EN", btnLeftX + btnW / 2.0, btnY - 8, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
StringUtils.drawCenteredText(g2d, "BOOT", btnRightX + btnW / 2.0, btnY - 8, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
|
||||
// Silkscreen
|
||||
g2d.setFont(SILK_FONT);
|
||||
String silkText = (version == DevKitVersion.DevKit_V1_30Pin) ? "ESP32 DevKit V1" : "ESP32 DevKitC V4";
|
||||
StringUtils.drawCenteredText(g2d, silkText, x + rowSpacing / 2.0, shieldY + shieldH + 45, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
|
||||
g2d.setTransform(oldTx);
|
||||
@@ -387,6 +526,29 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
g2d.setComposite(oldComposite);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to draw a pair of tactile buttons with labels.
|
||||
*/
|
||||
private void drawButtons(Graphics2D g2d, double btnLeftX, double btnRightX, double btnY, double btnW, double btnH,
|
||||
String leftLabel, String rightLabel) {
|
||||
g2d.setColor(BUTTON_BODY_COLOR);
|
||||
g2d.fill(new RoundRectangle2D.Double(btnLeftX, btnY, btnW, btnH, 3, 3));
|
||||
g2d.fill(new RoundRectangle2D.Double(btnRightX, btnY, btnW, btnH, 3, 3));
|
||||
g2d.setColor(BUTTON_BORDER_COLOR);
|
||||
g2d.draw(new RoundRectangle2D.Double(btnLeftX, btnY, btnW, btnH, 3, 3));
|
||||
g2d.draw(new RoundRectangle2D.Double(btnRightX, btnY, btnW, btnH, 3, 3));
|
||||
|
||||
// Button actuators
|
||||
g2d.setColor(BUTTON_ACTUATOR_COLOR);
|
||||
g2d.fillOval((int) (btnLeftX + btnW / 2.0 - 4), (int) (btnY + btnH / 2.0 - 4), 8, 8);
|
||||
g2d.fillOval((int) (btnRightX + btnW / 2.0 - 4), (int) (btnY + btnH / 2.0 - 4), 8, 8);
|
||||
|
||||
g2d.setColor(SILK_COLOR);
|
||||
g2d.setFont(SILK_FONT_SMALL);
|
||||
StringUtils.drawCenteredText(g2d, leftLabel, btnLeftX + btnW / 2.0, btnY - 8, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
StringUtils.drawCenteredText(g2d, rightLabel, btnRightX + btnW / 2.0, btnY - 8, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
g2d.setColor(ESP_BLACK);
|
||||
|
||||
@@ -204,6 +204,115 @@ public class ESP32DevKitTest {
|
||||
Assert.assertEquals(expectedTotalLength, bounds.getHeight(), 0.1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testControlPointCountAndNamesS3_44Pin() {
|
||||
ESP32DevKit devKit = new ESP32DevKit();
|
||||
devKit.setVersion(ESP32DevKit.DevKitVersion.ESP32_S3_DevKitC_44Pin);
|
||||
Assert.assertEquals(ESP32DevKit.DevKitVersion.ESP32_S3_DevKitC_44Pin, devKit.getVersion());
|
||||
Assert.assertEquals(44, devKit.getControlPointCount());
|
||||
|
||||
for (int i = 0; i < devKit.getControlPointCount(); i++) {
|
||||
String name = devKit.getControlPointNodeName(i);
|
||||
Assert.assertNotNull("Pin " + i + " name should not be null", name);
|
||||
Assert.assertFalse("Pin " + i + " name should not be empty", name.trim().isEmpty());
|
||||
}
|
||||
|
||||
// Left row (0..21, top to bottom)
|
||||
Assert.assertEquals("3V3_1", devKit.getControlPointNodeName(0));
|
||||
Assert.assertEquals("3V3_2", devKit.getControlPointNodeName(1));
|
||||
Assert.assertEquals("RST", devKit.getControlPointNodeName(2));
|
||||
Assert.assertEquals("GPIO4", devKit.getControlPointNodeName(3));
|
||||
Assert.assertEquals("GPIO5", devKit.getControlPointNodeName(4));
|
||||
Assert.assertEquals("GPIO6", devKit.getControlPointNodeName(5));
|
||||
Assert.assertEquals("GPIO7", devKit.getControlPointNodeName(6));
|
||||
Assert.assertEquals("GPIO15", devKit.getControlPointNodeName(7));
|
||||
Assert.assertEquals("GPIO16", devKit.getControlPointNodeName(8));
|
||||
Assert.assertEquals("GPIO17", devKit.getControlPointNodeName(9));
|
||||
Assert.assertEquals("GPIO18", devKit.getControlPointNodeName(10));
|
||||
Assert.assertEquals("GPIO8", devKit.getControlPointNodeName(11));
|
||||
Assert.assertEquals("GPIO3", devKit.getControlPointNodeName(12));
|
||||
Assert.assertEquals("GPIO46", devKit.getControlPointNodeName(13));
|
||||
Assert.assertEquals("GPIO9", devKit.getControlPointNodeName(14));
|
||||
Assert.assertEquals("GPIO10", devKit.getControlPointNodeName(15));
|
||||
Assert.assertEquals("GPIO11", devKit.getControlPointNodeName(16));
|
||||
Assert.assertEquals("GPIO12", devKit.getControlPointNodeName(17));
|
||||
Assert.assertEquals("GPIO13", devKit.getControlPointNodeName(18));
|
||||
Assert.assertEquals("GPIO14", devKit.getControlPointNodeName(19));
|
||||
Assert.assertEquals("5V0", devKit.getControlPointNodeName(20));
|
||||
Assert.assertEquals("GND1", devKit.getControlPointNodeName(21));
|
||||
|
||||
// Right row (22..43, top to bottom)
|
||||
Assert.assertEquals("GND2", devKit.getControlPointNodeName(22));
|
||||
Assert.assertEquals("GPIO43 (U0TXD)", devKit.getControlPointNodeName(23));
|
||||
Assert.assertEquals("GPIO44 (U0RXD)", devKit.getControlPointNodeName(24));
|
||||
Assert.assertEquals("GPIO1", devKit.getControlPointNodeName(25));
|
||||
Assert.assertEquals("GPIO2", devKit.getControlPointNodeName(26));
|
||||
Assert.assertEquals("GPIO42", devKit.getControlPointNodeName(27));
|
||||
Assert.assertEquals("GPIO41", devKit.getControlPointNodeName(28));
|
||||
Assert.assertEquals("GPIO40", devKit.getControlPointNodeName(29));
|
||||
Assert.assertEquals("GPIO39", devKit.getControlPointNodeName(30));
|
||||
Assert.assertEquals("GPIO38", devKit.getControlPointNodeName(31));
|
||||
Assert.assertEquals("GPIO37", devKit.getControlPointNodeName(32));
|
||||
Assert.assertEquals("GPIO36", devKit.getControlPointNodeName(33));
|
||||
Assert.assertEquals("GPIO35", devKit.getControlPointNodeName(34));
|
||||
Assert.assertEquals("GPIO0 (BOOT)", devKit.getControlPointNodeName(35));
|
||||
Assert.assertEquals("GPIO45", devKit.getControlPointNodeName(36));
|
||||
Assert.assertEquals("GPIO48", devKit.getControlPointNodeName(37));
|
||||
Assert.assertEquals("GPIO47", devKit.getControlPointNodeName(38));
|
||||
Assert.assertEquals("GPIO21", devKit.getControlPointNodeName(39));
|
||||
Assert.assertEquals("GPIO20 (USB D+)", devKit.getControlPointNodeName(40));
|
||||
Assert.assertEquals("GPIO19 (USB D-)", devKit.getControlPointNodeName(41));
|
||||
Assert.assertEquals("GND3", devKit.getControlPointNodeName(42));
|
||||
Assert.assertEquals("GND4", devKit.getControlPointNodeName(43));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPinGeometryAndSpacingS3_44Pin() {
|
||||
ESP32DevKit devKit = new ESP32DevKit();
|
||||
devKit.setVersion(ESP32DevKit.DevKitVersion.ESP32_S3_DevKitC_44Pin);
|
||||
|
||||
// Left row pitch (20px per pin = 0.10")
|
||||
for (int i = 0; i < 21; i++) {
|
||||
Point2D p1 = devKit.getControlPoint(i);
|
||||
Point2D p2 = devKit.getControlPoint(i + 1);
|
||||
Assert.assertEquals(20.0, p1.distance(p2), 0.01);
|
||||
Assert.assertEquals(p1.getX(), p2.getX(), 0.01);
|
||||
}
|
||||
|
||||
// Right row pitch (20px per pin = 0.10")
|
||||
for (int i = 22; i < 43; i++) {
|
||||
Point2D p1 = devKit.getControlPoint(i);
|
||||
Point2D p2 = devKit.getControlPoint(i + 1);
|
||||
Assert.assertEquals(20.0, p1.distance(p2), 0.01);
|
||||
Assert.assertEquals(p1.getX(), p2.getX(), 0.01);
|
||||
}
|
||||
|
||||
// Row spacing: 22.86mm (~0.9") between Left row and Right row
|
||||
double expectedRowSpacing = new Size(22.86d, SizeUnit.mm).convertToPixels();
|
||||
Point2D pLeftTop = devKit.getControlPoint(0);
|
||||
Point2D pRightTop = devKit.getControlPoint(22);
|
||||
Assert.assertEquals(expectedRowSpacing, pLeftTop.distance(pRightTop), 0.01);
|
||||
Assert.assertEquals(pLeftTop.getY(), pRightTop.getY(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBodyShapeDimensionsS3_44Pin() {
|
||||
ESP32DevKit devKit = new ESP32DevKit();
|
||||
devKit.setVersion(ESP32DevKit.DevKitVersion.ESP32_S3_DevKitC_44Pin);
|
||||
|
||||
Shape body = devKit.getBodyShape();
|
||||
Assert.assertNotNull(body);
|
||||
Rectangle2D bounds = body.getBounds2D();
|
||||
|
||||
double expectedWidth = new Size(25.40d, SizeUnit.mm).convertToPixels();
|
||||
// Total height = main body (62.74mm) + antenna (6.0mm)
|
||||
double expectedTotalLength = new Size(62.74d + 6.0d, SizeUnit.mm).convertToPixels();
|
||||
|
||||
// Width is the board width (antenna is 18mm, narrower than 25.4mm)
|
||||
Assert.assertEquals(expectedWidth, bounds.getWidth(), 0.1);
|
||||
Assert.assertEquals(expectedTotalLength, bounds.getHeight(), 1.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVersionSwitching() {
|
||||
ESP32DevKit devKit = new ESP32DevKit();
|
||||
@@ -214,6 +323,11 @@ public class ESP32DevKitTest {
|
||||
Assert.assertEquals("5V", devKit.getControlPointNodeName(18));
|
||||
Assert.assertEquals("CLK (GPIO6)", devKit.getControlPointNodeName(37));
|
||||
|
||||
devKit.setVersion(ESP32DevKit.DevKitVersion.ESP32_S3_DevKitC_44Pin);
|
||||
Assert.assertEquals(44, devKit.getControlPointCount());
|
||||
Assert.assertEquals("3V3_1", devKit.getControlPointNodeName(0));
|
||||
Assert.assertEquals("GND4", devKit.getControlPointNodeName(43));
|
||||
|
||||
devKit.setVersion(ESP32DevKit.DevKitVersion.DevKit_V1_30Pin);
|
||||
Assert.assertEquals(30, devKit.getControlPointCount());
|
||||
Assert.assertEquals("3V3", devKit.getControlPointNodeName(14));
|
||||
@@ -231,4 +345,81 @@ public class ESP32DevKitTest {
|
||||
devKit.setHeaders(false);
|
||||
Assert.assertFalse("Headers should be false after setter", devKit.getHeaders());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testS3RowSpacingDiffersFromOriginal() {
|
||||
ESP32DevKit devKit = new ESP32DevKit();
|
||||
|
||||
// Original uses 1.0" (25.4mm) row spacing
|
||||
Point2D p30_left = devKit.getControlPoint(0);
|
||||
Point2D p30_right = devKit.getControlPoint(29);
|
||||
double spacing30 = Math.abs(p30_right.getX() - p30_left.getX());
|
||||
|
||||
// S3 uses 22.86mm (~0.9") row spacing
|
||||
devKit.setVersion(ESP32DevKit.DevKitVersion.ESP32_S3_DevKitC_44Pin);
|
||||
Point2D pS3_left = devKit.getControlPoint(0);
|
||||
Point2D pS3_right = devKit.getControlPoint(22);
|
||||
double spacingS3 = Math.abs(pS3_right.getX() - pS3_left.getX());
|
||||
|
||||
// S3 row spacing should be narrower than original
|
||||
Assert.assertTrue("S3 row spacing should be narrower than original", spacingS3 < spacing30);
|
||||
|
||||
double expectedS3Spacing = new Size(22.86d, SizeUnit.mm).convertToPixels();
|
||||
Assert.assertEquals(expectedS3Spacing, spacingS3, 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testS3BottomMargin() {
|
||||
ESP32DevKit devKit = new ESP32DevKit();
|
||||
devKit.setVersion(ESP32DevKit.DevKitVersion.ESP32_S3_DevKitC_44Pin);
|
||||
|
||||
Point2D p0 = devKit.getControlPoint(0);
|
||||
Point2D p21 = devKit.getControlPoint(21);
|
||||
Point2D p43 = devKit.getControlPoint(43);
|
||||
|
||||
double mainY = p0.getY() - ESP32DevKit.TOP_MARGIN_S3.convertToPixels();
|
||||
double boardBottom = mainY + ESP32DevKit.BOARD_LENGTH_S3.convertToPixels();
|
||||
|
||||
double expectedBottomMargin = ESP32DevKit.BOTTOM_MARGIN_S3.convertToPixels();
|
||||
Assert.assertEquals(expectedBottomMargin, boardBottom - p21.getY(), 0.01);
|
||||
Assert.assertEquals(expectedBottomMargin, boardBottom - p43.getY(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testS3Drawing() {
|
||||
java.awt.image.BufferedImage img = new java.awt.image.BufferedImage(400, 400, java.awt.image.BufferedImage.TYPE_INT_ARGB);
|
||||
java.awt.Graphics2D g2d = img.createGraphics();
|
||||
org.diylc.core.Project project = new org.diylc.core.Project();
|
||||
org.diylc.core.IDrawingObserver observer = new org.diylc.core.IDrawingObserver() {
|
||||
@Override public void startTracking() {}
|
||||
@Override public void stopTracking() {}
|
||||
@Override public void startTrackingContinuityArea(boolean positive) {}
|
||||
@Override public void stopTrackingContinuityArea() {}
|
||||
@Override public boolean isTrackingContinuityArea() { return false; }
|
||||
@Override public void setContinuityMarker(String marker) {}
|
||||
};
|
||||
|
||||
ESP32DevKit devKit = new ESP32DevKit();
|
||||
devKit.setVersion(ESP32DevKit.DevKitVersion.ESP32_S3_DevKitC_44Pin);
|
||||
devKit.setControlPoint(new Point2D.Double(100, 100), 0);
|
||||
|
||||
// Normal mode with solder pads
|
||||
devKit.setHeaders(false);
|
||||
devKit.draw(g2d, org.diylc.core.ComponentState.NORMAL, false, project, observer);
|
||||
|
||||
// Normal mode with pin headers
|
||||
devKit.setHeaders(true);
|
||||
devKit.draw(g2d, org.diylc.core.ComponentState.NORMAL, false, project, observer);
|
||||
|
||||
// Selected mode
|
||||
devKit.draw(g2d, org.diylc.core.ComponentState.SELECTED, false, project, observer);
|
||||
|
||||
// Outline mode
|
||||
devKit.draw(g2d, org.diylc.core.ComponentState.NORMAL, true, project, observer);
|
||||
|
||||
// Icon drawing
|
||||
devKit.drawIcon(g2d, 32, 32);
|
||||
|
||||
g2d.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user