mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-07 12:24:58 +10:00
consolidate esp32
This commit is contained in:
@@ -21,8 +21,17 @@
|
||||
*/
|
||||
package org.diylc.components.micro;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.*;
|
||||
import java.awt.Color;
|
||||
import java.awt.Composite;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
import org.diylc.awt.StringUtils;
|
||||
import org.diylc.common.HorizontalAlignment;
|
||||
@@ -36,13 +45,14 @@ import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.annotations.BomPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.annotations.KeywordPolicy;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
@ComponentDescriptor(name = "ESP32 DevKit", category = "Controllers",
|
||||
author = "Branislav Stojkovic", description = "ESP32 DevKit V1 DOIT Wi-Fi and Bluetooth Development Board",
|
||||
author = "Branislav Stojkovic", description = "ESP32 DevKit Wi-Fi and Bluetooth Development Board (30-Pin / 38-Pin)",
|
||||
instanceNamePrefix = "MCU", zOrder = IDIYComponent.COMPONENT,
|
||||
bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME,
|
||||
enableCache = true)
|
||||
@@ -50,38 +60,95 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public enum DevKitVersion {
|
||||
DevKit_V1_30Pin("30-Pin (DevKit V1 / DOIT)"),
|
||||
DevKitC_V4_38Pin("38-Pin (DevKitC V4)");
|
||||
|
||||
private final String label;
|
||||
|
||||
DevKitVersion(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
public static Color ESP_BLACK = Color.decode("#1E1E1E");
|
||||
public static Color ANTENNA_COLOR = Color.decode("#DAA520");
|
||||
public static Color BUTTON_BODY_COLOR = Color.decode("#383838");
|
||||
public static Color BUTTON_BORDER_COLOR = Color.decode("#666666");
|
||||
public static Color BUTTON_ACTUATOR_COLOR = Color.decode("#A0A0A0");
|
||||
public static Color SILK_COLOR = Color.WHITE;
|
||||
public static Size BOARD_WIDTH = new Size(28.2d, SizeUnit.mm);
|
||||
public static Size BOARD_LENGTH = new Size(51.8d, SizeUnit.mm);
|
||||
public static Size TOP_MARGIN = new Size(6.7d, SizeUnit.mm);
|
||||
public static Size ANTENNA_LENGTH = new Size(6.2d, SizeUnit.mm);
|
||||
public static Size ANTENNA_WIDTH = new Size(20.0d, SizeUnit.mm);
|
||||
public static Size ROW_SPACING = new Size(1.0d, SizeUnit.in);
|
||||
public static Size HOLE_DIAMETER = new Size(2.8d, SizeUnit.mm);
|
||||
public static Size HOLE_EDGE_MARGIN = new Size(0.8d, SizeUnit.mm);
|
||||
|
||||
public static final String[] PIN_NAMES = new String[] {
|
||||
// Left row (pins 0..14)
|
||||
// 30-Pin (DOIT V1) Dimensions
|
||||
public static Size BOARD_WIDTH_30 = new Size(28.2d, SizeUnit.mm);
|
||||
public static Size BOARD_LENGTH_30 = new Size(51.8d, SizeUnit.mm);
|
||||
public static Size TOP_MARGIN_30 = new Size(6.7d, SizeUnit.mm);
|
||||
public static Size ANTENNA_LENGTH_30 = new Size(6.2d, SizeUnit.mm);
|
||||
public static Size ANTENNA_WIDTH_30 = new Size(20.0d, SizeUnit.mm);
|
||||
public static Size HOLE_DIAMETER_30 = new Size(2.8d, SizeUnit.mm);
|
||||
public static Size HOLE_EDGE_MARGIN_30 = new Size(0.8d, SizeUnit.mm);
|
||||
|
||||
// 38-Pin (DevKitC V4) Dimensions
|
||||
public static Size BOARD_WIDTH_38 = new Size(27.9d, SizeUnit.mm);
|
||||
public static Size BOARD_LENGTH_38 = new Size(54.4d, SizeUnit.mm);
|
||||
public static Size MAIN_BODY_LENGTH_38 = new Size(48.2d, SizeUnit.mm);
|
||||
public static Size ANTENNA_LENGTH_38 = new Size(6.2d, SizeUnit.mm);
|
||||
public static Size ANTENNA_WIDTH_38 = new Size(19.0d, SizeUnit.mm);
|
||||
|
||||
// Common Spacing
|
||||
public static Size ROW_SPACING = new Size(1.0d, SizeUnit.in);
|
||||
|
||||
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",
|
||||
// Right row (pins 15..29)
|
||||
// Right row (pins 15..29, bottom to top)
|
||||
"VIN", "GND2", "D15", "D2", "D4", "D16 (RX2)", "D17 (TX2)", "D5", "D18", "D19", "D21", "RX0 (GPIO3)", "TX0 (GPIO1)", "D22", "D23"
|
||||
};
|
||||
|
||||
public static final String[] PIN_NAMES_38 = new String[] {
|
||||
// Left row (pins 0..18, top to bottom)
|
||||
"3V3", "EN", "VP (GPIO36)", "VN (GPIO39)", "GPIO34", "GPIO35", "GPIO32", "GPIO33",
|
||||
"GPIO25", "GPIO26", "GPIO27", "GPIO14", "GPIO12", "GND1", "GPIO13",
|
||||
"D2 (GPIO9)", "D3 (GPIO10)", "CMD (GPIO11)", "5V",
|
||||
// Right row (pins 19..37, top to bottom)
|
||||
"GND2", "GPIO23", "GPIO22", "TX0 (GPIO1)", "RX0 (GPIO3)", "GPIO21", "GND3",
|
||||
"GPIO19", "GPIO18", "GPIO5", "GPIO17", "GPIO16", "GPIO4", "GPIO0", "GPIO2",
|
||||
"GPIO15", "D1 (GPIO8)", "D0 (GPIO7)", "CLK (GPIO6)"
|
||||
};
|
||||
|
||||
private DevKitVersion version = DevKitVersion.DevKit_V1_30Pin;
|
||||
|
||||
public ESP32DevKit() {
|
||||
super();
|
||||
this.bodyColor = ESP_BLACK;
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
@EditableProperty(name = "Version")
|
||||
public DevKitVersion getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(DevKitVersion version) {
|
||||
this.version = version;
|
||||
updateControlPoints();
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getControlPointNodeName(int index) {
|
||||
if (index >= 0 && index < PIN_NAMES.length) {
|
||||
return PIN_NAMES[index];
|
||||
if (version == DevKitVersion.DevKit_V1_30Pin) {
|
||||
if (index >= 0 && index < PIN_NAMES_30.length) {
|
||||
return PIN_NAMES_30[index];
|
||||
}
|
||||
} else {
|
||||
if (index >= 0 && index < PIN_NAMES_38.length) {
|
||||
return PIN_NAMES_38[index];
|
||||
}
|
||||
}
|
||||
return "Pin " + (index + 1);
|
||||
}
|
||||
@@ -90,19 +157,31 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
protected void updateControlPoints() {
|
||||
Point2D firstPoint = controlPoints[0];
|
||||
double spacing = PIN_SPACING.convertToPixels();
|
||||
double rowSpacing = ROW_SPACING.convertToPixels(); // 200px
|
||||
double rowSpacing = ROW_SPACING.convertToPixels(); // 200px (1.00")
|
||||
|
||||
double[][] relativeOffsets = new double[30][2];
|
||||
for (int i = 0; i < 15; i++) {
|
||||
relativeOffsets[i][0] = 0;
|
||||
relativeOffsets[i][1] = i * spacing;
|
||||
if (version == DevKitVersion.DevKit_V1_30Pin) {
|
||||
double[][] relativeOffsets = new double[30][2];
|
||||
for (int i = 0; i < 15; i++) {
|
||||
relativeOffsets[i][0] = 0;
|
||||
relativeOffsets[i][1] = i * spacing;
|
||||
}
|
||||
for (int i = 0; i < 15; i++) {
|
||||
relativeOffsets[15 + i][0] = rowSpacing;
|
||||
relativeOffsets[15 + i][1] = (14 - i) * spacing;
|
||||
}
|
||||
rotatePoints(firstPoint, relativeOffsets);
|
||||
} else {
|
||||
double[][] relativeOffsets = new double[PIN_NAMES_38.length][2];
|
||||
for (int i = 0; i < 19; i++) {
|
||||
relativeOffsets[i][0] = 0;
|
||||
relativeOffsets[i][1] = i * spacing;
|
||||
}
|
||||
for (int i = 0; i < 19; i++) {
|
||||
relativeOffsets[19 + i][0] = rowSpacing;
|
||||
relativeOffsets[19 + i][1] = i * spacing;
|
||||
}
|
||||
rotatePoints(firstPoint, relativeOffsets);
|
||||
}
|
||||
for (int i = 0; i < 15; i++) {
|
||||
relativeOffsets[15 + i][0] = rowSpacing;
|
||||
relativeOffsets[15 + i][1] = (14 - i) * spacing;
|
||||
}
|
||||
|
||||
rotatePoints(firstPoint, relativeOffsets);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,12 +190,29 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
double x = p0.getX();
|
||||
double y = p0.getY();
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
double boardW = BOARD_WIDTH.convertToPixels();
|
||||
double boardH = BOARD_LENGTH.convertToPixels();
|
||||
double topMargin = TOP_MARGIN.convertToPixels();
|
||||
double boardX = (x + rowSpacing / 2.0) - boardW / 2.0;
|
||||
double boardY = y - topMargin;
|
||||
return new RoundRectangle2D.Double(boardX, boardY, boardW, boardH, 8, 8);
|
||||
|
||||
if (version == DevKitVersion.DevKit_V1_30Pin) {
|
||||
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 {
|
||||
double mainW = BOARD_WIDTH_38.convertToPixels();
|
||||
double mainH = MAIN_BODY_LENGTH_38.convertToPixels();
|
||||
double antennaW = ANTENNA_WIDTH_38.convertToPixels();
|
||||
double antennaH = ANTENNA_LENGTH_38.convertToPixels();
|
||||
|
||||
double mainX = (x + rowSpacing / 2.0) - mainW / 2.0;
|
||||
double mainY = (y + 18 * PIN_SPACING.convertToPixels() / 2.0) - mainH / 2.0;
|
||||
double antennaX = (x + rowSpacing / 2.0) - antennaW / 2.0;
|
||||
double antennaY = mainY - antennaH;
|
||||
|
||||
Area bodyArea = new Area(new RoundRectangle2D.Double(mainX, mainY, mainW, mainH, 8, 8));
|
||||
bodyArea.add(new Area(new Rectangle2D.Double(antennaX, antennaY, antennaW, antennaH + 1)));
|
||||
return bodyArea;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -136,24 +232,41 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
}
|
||||
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
double boardW = BOARD_WIDTH.convertToPixels();
|
||||
double boardH = BOARD_LENGTH.convertToPixels();
|
||||
double topMargin = TOP_MARGIN.convertToPixels();
|
||||
double boardX = (x + rowSpacing / 2.0) - boardW / 2.0;
|
||||
double boardY = y - topMargin;
|
||||
|
||||
double antennaW = ANTENNA_WIDTH.convertToPixels();
|
||||
double antennaH = ANTENNA_LENGTH.convertToPixels();
|
||||
double antennaX = (x + rowSpacing / 2.0) - antennaW / 2.0;
|
||||
double antennaY = boardY;
|
||||
|
||||
Shape boardShape = getBodyShape();
|
||||
|
||||
Composite oldComposite = applyAlpha(g2d, componentState);
|
||||
|
||||
drawingObserver.startTracking();
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : bodyColor);
|
||||
g2d.fill(boardShape);
|
||||
if (outlineMode) {
|
||||
g2d.setColor(Constants.TRANSPARENT_COLOR);
|
||||
g2d.fill(boardShape);
|
||||
} else {
|
||||
if (version == DevKitVersion.DevKit_V1_30Pin) {
|
||||
g2d.setColor(bodyColor);
|
||||
g2d.fill(boardShape);
|
||||
} else {
|
||||
double mainW = BOARD_WIDTH_38.convertToPixels();
|
||||
double mainH = MAIN_BODY_LENGTH_38.convertToPixels();
|
||||
double antennaW = ANTENNA_WIDTH_38.convertToPixels();
|
||||
double antennaH = ANTENNA_LENGTH_38.convertToPixels();
|
||||
double mainX = (x + rowSpacing / 2.0) - mainW / 2.0;
|
||||
double mainY = (y + 18 * PIN_SPACING.convertToPixels() / 2.0) - mainH / 2.0;
|
||||
double antennaX = (x + rowSpacing / 2.0) - antennaW / 2.0;
|
||||
double antennaY = mainY - antennaH;
|
||||
|
||||
// Main board body
|
||||
g2d.setColor(bodyColor);
|
||||
g2d.fill(new RoundRectangle2D.Double(mainX, mainY, mainW, mainH, 8, 8));
|
||||
|
||||
// Antenna tab in slightly lighter color
|
||||
Color antennaTabColor = new Color(
|
||||
Math.min(255, bodyColor.getRed() + 32),
|
||||
Math.min(255, bodyColor.getGreen() + 32),
|
||||
Math.min(255, bodyColor.getBlue() + 32)
|
||||
);
|
||||
g2d.setColor(antennaTabColor);
|
||||
g2d.fill(new Rectangle2D.Double(antennaX, antennaY, antennaW, antennaH));
|
||||
}
|
||||
}
|
||||
drawingObserver.stopTracking();
|
||||
|
||||
g2d.setColor(getFinalBorderColor(componentState, outlineMode));
|
||||
@@ -161,19 +274,70 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
g2d.draw(boardShape);
|
||||
|
||||
if (!outlineMode) {
|
||||
// 4 Corner Mounting Holes (diameter 2.8mm, 0.8mm away from edges in both directions)
|
||||
double holeDiameter = HOLE_DIAMETER.convertToPixels();
|
||||
double holeRadius = holeDiameter / 2.0;
|
||||
double edgeMargin = HOLE_EDGE_MARGIN.convertToPixels();
|
||||
double leftHoleX = boardX + edgeMargin + holeRadius;
|
||||
double rightHoleX = boardX + boardW - edgeMargin - holeRadius;
|
||||
double topHoleY = boardY + edgeMargin + holeRadius;
|
||||
double bottomHoleY = boardY + boardH - edgeMargin - holeRadius;
|
||||
double antennaX;
|
||||
double antennaY;
|
||||
double antennaW;
|
||||
double antennaH;
|
||||
double shieldY;
|
||||
double shieldH = new Size(18.0d, SizeUnit.mm).convertToPixels();
|
||||
double shieldW = new Size(18.0d, SizeUnit.mm).convertToPixels();
|
||||
double shieldX = (x + rowSpacing / 2.0) - shieldW / 2.0;
|
||||
double usbY;
|
||||
double btnLeftX;
|
||||
double btnRightX;
|
||||
double btnY;
|
||||
double btnW = 20;
|
||||
double btnH = 20;
|
||||
double shift1mm = new Size(1.0d, SizeUnit.mm).convertToPixels();
|
||||
|
||||
drawMountingHole(g2d, leftHoleX, topHoleY, holeDiameter);
|
||||
drawMountingHole(g2d, rightHoleX, topHoleY, holeDiameter);
|
||||
drawMountingHole(g2d, leftHoleX, bottomHoleY, holeDiameter);
|
||||
drawMountingHole(g2d, rightHoleX, bottomHoleY, holeDiameter);
|
||||
if (version == DevKitVersion.DevKit_V1_30Pin) {
|
||||
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;
|
||||
|
||||
antennaW = ANTENNA_WIDTH_30.convertToPixels();
|
||||
antennaH = ANTENNA_LENGTH_30.convertToPixels();
|
||||
antennaX = (x + rowSpacing / 2.0) - antennaW / 2.0;
|
||||
antennaY = boardY;
|
||||
shieldY = boardY + antennaH + shift1mm;
|
||||
usbY = boardY + boardH - 22;
|
||||
|
||||
// 4 Corner Mounting Holes (diameter 2.8mm, 0.8mm away from edges in both directions)
|
||||
double holeDiameter = HOLE_DIAMETER_30.convertToPixels();
|
||||
double holeRadius = holeDiameter / 2.0;
|
||||
double edgeMargin = HOLE_EDGE_MARGIN_30.convertToPixels();
|
||||
double leftHoleX = boardX + edgeMargin + holeRadius;
|
||||
double rightHoleX = boardX + boardW - edgeMargin - holeRadius;
|
||||
double topHoleY = boardY + edgeMargin + holeRadius;
|
||||
double bottomHoleY = boardY + boardH - edgeMargin - holeRadius;
|
||||
|
||||
drawMountingHole(g2d, leftHoleX, topHoleY, holeDiameter);
|
||||
drawMountingHole(g2d, rightHoleX, topHoleY, holeDiameter);
|
||||
drawMountingHole(g2d, leftHoleX, bottomHoleY, holeDiameter);
|
||||
drawMountingHole(g2d, rightHoleX, bottomHoleY, holeDiameter);
|
||||
|
||||
btnY = boardY + boardH - 25 - shift1mm;
|
||||
btnLeftX = leftHoleX + 14 + shift1mm;
|
||||
btnRightX = rightHoleX - 14 - shift1mm - btnW;
|
||||
} else {
|
||||
double mainW = BOARD_WIDTH_38.convertToPixels();
|
||||
double mainH = MAIN_BODY_LENGTH_38.convertToPixels();
|
||||
double mainX = (x + rowSpacing / 2.0) - mainW / 2.0;
|
||||
double mainY = (y + 18 * PIN_SPACING.convertToPixels() / 2.0) - mainH / 2.0;
|
||||
|
||||
antennaW = ANTENNA_WIDTH_38.convertToPixels();
|
||||
antennaH = ANTENNA_LENGTH_38.convertToPixels();
|
||||
antennaX = (x + rowSpacing / 2.0) - antennaW / 2.0;
|
||||
antennaY = mainY - antennaH;
|
||||
shieldY = mainY + 10;
|
||||
usbY = mainY + mainH - 22;
|
||||
|
||||
btnY = mainY + mainH - 25;
|
||||
btnLeftX = mainX + 38;
|
||||
btnRightX = mainX + mainW - 38 - btnW;
|
||||
}
|
||||
|
||||
// Antenna trace (gold/copper serpentine PCB trace)
|
||||
g2d.setColor(ANTENNA_COLOR);
|
||||
@@ -195,29 +359,16 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
antPath.lineTo(antPadX + antPadW, antTopY);
|
||||
g2d.draw(antPath);
|
||||
|
||||
double shift1mm = new Size(1.0d, SizeUnit.mm).convertToPixels();
|
||||
|
||||
// ESP32-WROOM-32 metal shield module below antenna
|
||||
double shieldW = new Size(18.0d, SizeUnit.mm).convertToPixels();
|
||||
double shieldH = new Size(18.0d, SizeUnit.mm).convertToPixels();
|
||||
double shieldX = (x + rowSpacing / 2.0) - shieldW / 2.0;
|
||||
double shieldY = boardY + antennaH + shift1mm;
|
||||
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;
|
||||
double usbY = boardY + boardH - 22;
|
||||
drawMetalConnector(g2d, usbX, usbY, usbW, usbH, "USB");
|
||||
|
||||
// EN & BOOT tactile buttons at bottom (flanking the Micro-USB port)
|
||||
double btnW = 20;
|
||||
double btnH = 20;
|
||||
double btnY = boardY + boardH - 25 - shift1mm;
|
||||
double btnLeftX = leftHoleX + 14 + shift1mm;
|
||||
double btnRightX = rightHoleX - 14 - shift1mm - btnW;
|
||||
|
||||
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));
|
||||
@@ -237,7 +388,8 @@ public class ESP32DevKit extends AbstractMakerBoard {
|
||||
|
||||
// Silkscreen
|
||||
g2d.setFont(SILK_FONT);
|
||||
StringUtils.drawCenteredText(g2d, "ESP32 DevKit V1", x + rowSpacing / 2.0, shieldY + shieldH + 45, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
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);
|
||||
|
||||
@@ -1,279 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* DIY Layout Creator (DIYLC).
|
||||
* Copyright (c) 2009-2025 held jointly by the individual authors.
|
||||
*
|
||||
* This file is part of DIYLC.
|
||||
*
|
||||
* DIYLC is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* DIYLC is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.diylc.components.micro;
|
||||
|
||||
import org.diylc.awt.StringUtils;
|
||||
import org.diylc.common.HorizontalAlignment;
|
||||
import org.diylc.common.ObjectCache;
|
||||
import org.diylc.common.Orientation;
|
||||
import org.diylc.common.VerticalAlignment;
|
||||
import org.diylc.components.AbstractMakerBoard;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.annotations.BomPolicy;
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.KeywordPolicy;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.diylc.utils.Constants;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.*;
|
||||
|
||||
@ComponentDescriptor(name = "ESP32 DevKitC", category = "Controllers",
|
||||
author = "Branislav Stojkovic", description = "ESP32 DevKitC V4 Wi-Fi and Bluetooth Development Board",
|
||||
instanceNamePrefix = "MCU", zOrder = IDIYComponent.COMPONENT,
|
||||
bomPolicy = BomPolicy.SHOW_ONLY_TYPE_NAME, keywordPolicy = KeywordPolicy.SHOW_TYPE_NAME,
|
||||
enableCache = true)
|
||||
public class ESP32DevKitC extends AbstractMakerBoard {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static Color ESP_BLACK = Color.decode("#1E1E1E");
|
||||
public static Color ANTENNA_COLOR = Color.decode("#DAA520");
|
||||
public static Color ANTENNA_TAB_COLOR = Color.decode("#383838");
|
||||
public static Color BUTTON_BODY_COLOR = Color.decode("#383838");
|
||||
public static Color BUTTON_BORDER_COLOR = Color.decode("#666666");
|
||||
public static Color BUTTON_ACTUATOR_COLOR = Color.decode("#A0A0A0");
|
||||
public static Color SILK_COLOR = Color.WHITE;
|
||||
public static Size BOARD_WIDTH = new Size(27.9d, SizeUnit.mm);
|
||||
public static Size BOARD_LENGTH = new Size(54.4d, SizeUnit.mm);
|
||||
public static Size MAIN_BODY_LENGTH = new Size(48.2d, SizeUnit.mm);
|
||||
public static Size ANTENNA_LENGTH = new Size(6.2d, SizeUnit.mm);
|
||||
public static Size ANTENNA_WIDTH = new Size(19.0d, SizeUnit.mm);
|
||||
public static Size ROW_SPACING = new Size(1.0d, SizeUnit.in);
|
||||
|
||||
public static final String[] PIN_NAMES = new String[] {
|
||||
// Left row (pins 0..18, top to bottom)
|
||||
"3V3", "EN", "VP (GPIO36)", "VN (GPIO39)", "GPIO34", "GPIO35", "GPIO32", "GPIO33",
|
||||
"GPIO25", "GPIO26", "GPIO27", "GPIO14", "GPIO12", "GND1", "GPIO13",
|
||||
"D2 (GPIO9)", "D3 (GPIO10)", "CMD (GPIO11)", "5V",
|
||||
// Right row (pins 19..37, top to bottom)
|
||||
"GND2", "GPIO23", "GPIO22", "TX0 (GPIO1)", "RX0 (GPIO3)", "GPIO21", "GND3",
|
||||
"GPIO19", "GPIO18", "GPIO5", "GPIO17", "GPIO16", "GPIO4", "GPIO0", "GPIO2",
|
||||
"GPIO15", "D1 (GPIO8)", "D0 (GPIO7)", "CLK (GPIO6)"
|
||||
};
|
||||
|
||||
public ESP32DevKitC() {
|
||||
super();
|
||||
this.bodyColor = ESP_BLACK;
|
||||
updateControlPoints();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getControlPointNodeName(int index) {
|
||||
if (index >= 0 && index < PIN_NAMES.length) {
|
||||
return PIN_NAMES[index];
|
||||
}
|
||||
return "Pin " + (index + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateControlPoints() {
|
||||
Point2D firstPoint = controlPoints[0];
|
||||
double spacing = PIN_SPACING.convertToPixels();
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
|
||||
double[][] relativeOffsets = new double[PIN_NAMES.length][2];
|
||||
for (int i = 0; i < 19; i++) {
|
||||
relativeOffsets[i][0] = 0;
|
||||
relativeOffsets[i][1] = i * spacing;
|
||||
}
|
||||
for (int i = 0; i < 19; i++) {
|
||||
relativeOffsets[19 + i][0] = rowSpacing;
|
||||
relativeOffsets[19 + i][1] = i * spacing;
|
||||
}
|
||||
|
||||
rotatePoints(firstPoint, relativeOffsets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape getBodyShape() {
|
||||
Point2D p0 = controlPoints[0];
|
||||
double x = p0.getX();
|
||||
double y = p0.getY();
|
||||
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
double mainW = BOARD_WIDTH.convertToPixels();
|
||||
double mainH = MAIN_BODY_LENGTH.convertToPixels();
|
||||
double antennaW = ANTENNA_WIDTH.convertToPixels();
|
||||
double antennaH = ANTENNA_LENGTH.convertToPixels();
|
||||
|
||||
double mainX = (x + rowSpacing / 2.0) - mainW / 2.0;
|
||||
double mainY = (y + 18 * PIN_SPACING.convertToPixels() / 2.0) - mainH / 2.0;
|
||||
double antennaX = (x + rowSpacing / 2.0) - antennaW / 2.0;
|
||||
double antennaY = mainY - antennaH;
|
||||
|
||||
Area bodyArea = new Area(new RoundRectangle2D.Double(mainX, mainY, mainW, mainH, 8, 8));
|
||||
bodyArea.add(new Area(new Rectangle2D.Double(antennaX, antennaY, antennaW, antennaH + 1)));
|
||||
return bodyArea;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics2D g2d, ComponentState componentState, boolean outlineMode, Project project,
|
||||
IDrawingObserver drawingObserver) {
|
||||
if (checkPointsClipped(g2d.getClip())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Point2D p0 = controlPoints[0];
|
||||
double x = p0.getX();
|
||||
double y = p0.getY();
|
||||
|
||||
AffineTransform oldTx = g2d.getTransform();
|
||||
if (orientation != Orientation.DEFAULT) {
|
||||
g2d.rotate(orientation.toRadians(), x, y);
|
||||
}
|
||||
|
||||
double rowSpacing = ROW_SPACING.convertToPixels();
|
||||
double mainW = BOARD_WIDTH.convertToPixels();
|
||||
double mainH = MAIN_BODY_LENGTH.convertToPixels();
|
||||
double antennaW = ANTENNA_WIDTH.convertToPixels();
|
||||
double antennaH = ANTENNA_LENGTH.convertToPixels();
|
||||
|
||||
double mainX = (x + rowSpacing / 2.0) - mainW / 2.0;
|
||||
double mainY = (y + 18 * PIN_SPACING.convertToPixels() / 2.0) - mainH / 2.0;
|
||||
double antennaX = (x + rowSpacing / 2.0) - antennaW / 2.0;
|
||||
double antennaY = mainY - antennaH;
|
||||
|
||||
Shape boardShape = getBodyShape();
|
||||
|
||||
Composite oldComposite = applyAlpha(g2d, componentState);
|
||||
|
||||
drawingObserver.startTracking();
|
||||
if (outlineMode) {
|
||||
g2d.setColor(Constants.TRANSPARENT_COLOR);
|
||||
g2d.fill(boardShape);
|
||||
} else {
|
||||
// Main board body
|
||||
g2d.setColor(bodyColor);
|
||||
g2d.fill(new RoundRectangle2D.Double(mainX, mainY, mainW, mainH, 8, 8));
|
||||
|
||||
// Antenna tab in slightly lighter color
|
||||
Color antennaColor = new Color(
|
||||
Math.min(255, bodyColor.getRed() + 32),
|
||||
Math.min(255, bodyColor.getGreen() + 32),
|
||||
Math.min(255, bodyColor.getBlue() + 32)
|
||||
);
|
||||
g2d.setColor(antennaColor);
|
||||
g2d.fill(new Rectangle2D.Double(antennaX, antennaY, antennaW, antennaH));
|
||||
}
|
||||
drawingObserver.stopTracking();
|
||||
|
||||
// Outline border around the full board
|
||||
g2d.setColor(getFinalBorderColor(componentState, outlineMode));
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1.5f));
|
||||
g2d.draw(boardShape);
|
||||
|
||||
if (!outlineMode) {
|
||||
// Antenna trace (gold/copper serpentine PCB trace)
|
||||
g2d.setColor(ANTENNA_COLOR);
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1.5f));
|
||||
Path2D.Double antPath = new Path2D.Double();
|
||||
double antPadX = antennaX + 16;
|
||||
double antPadW = antennaW - 32;
|
||||
double antTopY = antennaY + 10;
|
||||
double antMidY = antennaY + antennaH - 12;
|
||||
antPath.moveTo(antPadX, antMidY);
|
||||
antPath.lineTo(antPadX, antTopY);
|
||||
antPath.lineTo(antPadX + antPadW * 0.25, antTopY);
|
||||
antPath.lineTo(antPadX + antPadW * 0.25, antMidY);
|
||||
antPath.lineTo(antPadX + antPadW * 0.50, antMidY);
|
||||
antPath.lineTo(antPadX + antPadW * 0.50, antTopY);
|
||||
antPath.lineTo(antPadX + antPadW * 0.75, antTopY);
|
||||
antPath.lineTo(antPadX + antPadW * 0.75, antMidY);
|
||||
antPath.lineTo(antPadX + antPadW, antMidY);
|
||||
antPath.lineTo(antPadX + antPadW, antTopY);
|
||||
g2d.draw(antPath);
|
||||
|
||||
// Micro-USB Jack at bottom
|
||||
double usbW = 58;
|
||||
double usbH = 34;
|
||||
double usbX = (x + rowSpacing / 2.0) - usbW / 2.0;
|
||||
double usbY = mainY + mainH - 22;
|
||||
drawMetalConnector(g2d, usbX, usbY, usbW, usbH, "USB");
|
||||
|
||||
// ESP32-WROOM-32 metal shield module below antenna
|
||||
double shieldW = new Size(18.0d, SizeUnit.mm).convertToPixels();
|
||||
double shieldH = new Size(18.0d, SizeUnit.mm).convertToPixels();
|
||||
double shieldX = (x + rowSpacing / 2.0) - shieldW / 2.0;
|
||||
double shieldY = mainY + 10;
|
||||
drawMetalConnector(g2d, shieldX, shieldY, shieldW, shieldH, "ESP32-WROOM-32");
|
||||
|
||||
// EN & BOOT tactile buttons at bottom (flanking the Micro-USB port)
|
||||
double btnW = 20;
|
||||
double btnH = 20;
|
||||
double btnY = mainY + mainH - 25;
|
||||
double btnLeftX = mainX + 38;
|
||||
double btnRightX = mainX + mainW - 38 - btnW;
|
||||
|
||||
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);
|
||||
StringUtils.drawCenteredText(g2d, "ESP32 DevKitC V4", x + rowSpacing / 2.0, mainY + shieldH + 45, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
|
||||
g2d.setTransform(oldTx);
|
||||
|
||||
drawPins(g2d, 0, controlPoints.length, false, outlineMode, drawingObserver);
|
||||
|
||||
g2d.setComposite(oldComposite);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
g2d.setColor(ESP_BLACK);
|
||||
g2d.fill(new RoundRectangle2D.Double(5, 6, width - 10, height - 8, 3, 3));
|
||||
|
||||
// Antenna tab
|
||||
g2d.setColor(ANTENNA_TAB_COLOR);
|
||||
g2d.fillRect(8, 2, width - 16, 5);
|
||||
g2d.setColor(Color.GRAY);
|
||||
g2d.draw(new RoundRectangle2D.Double(5, 6, width - 10, height - 8, 3, 3));
|
||||
|
||||
// Metal shield
|
||||
g2d.setColor(METAL_SHIELD_COLOR);
|
||||
g2d.fillRect(8, 9, width - 16, 10);
|
||||
|
||||
g2d.setColor(SILK_COLOR);
|
||||
g2d.setFont(new Font("SansSerif", Font.BOLD, 5));
|
||||
StringUtils.drawCenteredText(g2d, "ESP32", width / 2, height / 2 + 8, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
}
|
||||
@@ -239,7 +239,6 @@ public class MakerComponentsTest {
|
||||
public void testControlPointsAreDistinct() throws Exception {
|
||||
for (Class<? extends IDIYComponent<?>> clazz : allMakerComponentClasses) {
|
||||
IDIYComponent<?> component = clazz.getDeclaredConstructor().newInstance();
|
||||
component.setControlPoint(new Point2D.Double(200, 200), 0);
|
||||
int count = component.getControlPointCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
Point2D p1 = component.getControlPoint(i);
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
package org.diylc.components.micro;
|
||||
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ESP32DevKitCTest {
|
||||
|
||||
@Test
|
||||
public void testControlPointCountAndNames() {
|
||||
ESP32DevKitC devKit = new ESP32DevKitC();
|
||||
Assert.assertEquals(38, 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..18, top to bottom)
|
||||
Assert.assertEquals("3V3", devKit.getControlPointNodeName(0));
|
||||
Assert.assertEquals("EN", devKit.getControlPointNodeName(1));
|
||||
Assert.assertEquals("VP (GPIO36)", devKit.getControlPointNodeName(2));
|
||||
Assert.assertEquals("VN (GPIO39)", devKit.getControlPointNodeName(3));
|
||||
Assert.assertEquals("GPIO34", devKit.getControlPointNodeName(4));
|
||||
Assert.assertEquals("GPIO35", devKit.getControlPointNodeName(5));
|
||||
Assert.assertEquals("GPIO32", devKit.getControlPointNodeName(6));
|
||||
Assert.assertEquals("GPIO33", devKit.getControlPointNodeName(7));
|
||||
Assert.assertEquals("GPIO25", devKit.getControlPointNodeName(8));
|
||||
Assert.assertEquals("GPIO26", devKit.getControlPointNodeName(9));
|
||||
Assert.assertEquals("GPIO27", devKit.getControlPointNodeName(10));
|
||||
Assert.assertEquals("GPIO14", devKit.getControlPointNodeName(11));
|
||||
Assert.assertEquals("GPIO12", devKit.getControlPointNodeName(12));
|
||||
Assert.assertEquals("GND1", devKit.getControlPointNodeName(13));
|
||||
Assert.assertEquals("GPIO13", devKit.getControlPointNodeName(14));
|
||||
Assert.assertEquals("D2 (GPIO9)", devKit.getControlPointNodeName(15));
|
||||
Assert.assertEquals("D3 (GPIO10)", devKit.getControlPointNodeName(16));
|
||||
Assert.assertEquals("CMD (GPIO11)", devKit.getControlPointNodeName(17));
|
||||
Assert.assertEquals("5V", devKit.getControlPointNodeName(18));
|
||||
|
||||
// Right row (19..37, top to bottom)
|
||||
Assert.assertEquals("GND2", devKit.getControlPointNodeName(19));
|
||||
Assert.assertEquals("GPIO23", devKit.getControlPointNodeName(20));
|
||||
Assert.assertEquals("GPIO22", devKit.getControlPointNodeName(21));
|
||||
Assert.assertEquals("TX0 (GPIO1)", devKit.getControlPointNodeName(22));
|
||||
Assert.assertEquals("RX0 (GPIO3)", devKit.getControlPointNodeName(23));
|
||||
Assert.assertEquals("GPIO21", devKit.getControlPointNodeName(24));
|
||||
Assert.assertEquals("GND3", devKit.getControlPointNodeName(25));
|
||||
Assert.assertEquals("GPIO19", devKit.getControlPointNodeName(26));
|
||||
Assert.assertEquals("GPIO18", devKit.getControlPointNodeName(27));
|
||||
Assert.assertEquals("GPIO5", devKit.getControlPointNodeName(28));
|
||||
Assert.assertEquals("GPIO17", devKit.getControlPointNodeName(29));
|
||||
Assert.assertEquals("GPIO16", devKit.getControlPointNodeName(30));
|
||||
Assert.assertEquals("GPIO4", devKit.getControlPointNodeName(31));
|
||||
Assert.assertEquals("GPIO0", devKit.getControlPointNodeName(32));
|
||||
Assert.assertEquals("GPIO2", devKit.getControlPointNodeName(33));
|
||||
Assert.assertEquals("GPIO15", devKit.getControlPointNodeName(34));
|
||||
Assert.assertEquals("D1 (GPIO8)", devKit.getControlPointNodeName(35));
|
||||
Assert.assertEquals("D0 (GPIO7)", devKit.getControlPointNodeName(36));
|
||||
Assert.assertEquals("CLK (GPIO6)", devKit.getControlPointNodeName(37));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPinGeometryAndSpacing() {
|
||||
ESP32DevKitC devKit = new ESP32DevKitC();
|
||||
|
||||
// Left row pitch (20px per pin = 0.10")
|
||||
for (int i = 0; i < 18; 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 = 19; i < 37; 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: 1.00" = 200px between Left row and Right row
|
||||
Point2D pLeftTop = devKit.getControlPoint(0);
|
||||
Point2D pRightTop = devKit.getControlPoint(19);
|
||||
Assert.assertEquals(200.0, pLeftTop.distance(pRightTop), 0.01);
|
||||
Assert.assertEquals(pLeftTop.getY(), pRightTop.getY(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBodyShapeDimensions() {
|
||||
ESP32DevKitC devKit = new ESP32DevKitC();
|
||||
|
||||
Shape body = devKit.getBodyShape();
|
||||
Assert.assertNotNull(body);
|
||||
Rectangle2D bounds = body.getBounds2D();
|
||||
|
||||
double expectedWidth = new Size(27.9d, SizeUnit.mm).convertToPixels();
|
||||
double expectedTotalLength = new Size(54.4d, SizeUnit.mm).convertToPixels();
|
||||
|
||||
Assert.assertEquals(expectedWidth, bounds.getWidth(), 0.1);
|
||||
Assert.assertEquals(expectedTotalLength, bounds.getHeight(), 0.1);
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,9 @@ import org.junit.Test;
|
||||
public class ESP32DevKitTest {
|
||||
|
||||
@Test
|
||||
public void testControlPointCountAndNames() {
|
||||
public void testControlPointCountAndNames30Pin() {
|
||||
ESP32DevKit devKit = new ESP32DevKit();
|
||||
Assert.assertEquals(ESP32DevKit.DevKitVersion.DevKit_V1_30Pin, devKit.getVersion());
|
||||
Assert.assertEquals(30, devKit.getControlPointCount());
|
||||
|
||||
for (int i = 0; i < devKit.getControlPointCount(); i++) {
|
||||
@@ -58,7 +59,63 @@ public class ESP32DevKitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPinGeometryAndSpacing() {
|
||||
public void testControlPointCountAndNames38Pin() {
|
||||
ESP32DevKit devKit = new ESP32DevKit();
|
||||
devKit.setVersion(ESP32DevKit.DevKitVersion.DevKitC_V4_38Pin);
|
||||
Assert.assertEquals(ESP32DevKit.DevKitVersion.DevKitC_V4_38Pin, devKit.getVersion());
|
||||
Assert.assertEquals(38, 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..18, top to bottom)
|
||||
Assert.assertEquals("3V3", devKit.getControlPointNodeName(0));
|
||||
Assert.assertEquals("EN", devKit.getControlPointNodeName(1));
|
||||
Assert.assertEquals("VP (GPIO36)", devKit.getControlPointNodeName(2));
|
||||
Assert.assertEquals("VN (GPIO39)", devKit.getControlPointNodeName(3));
|
||||
Assert.assertEquals("GPIO34", devKit.getControlPointNodeName(4));
|
||||
Assert.assertEquals("GPIO35", devKit.getControlPointNodeName(5));
|
||||
Assert.assertEquals("GPIO32", devKit.getControlPointNodeName(6));
|
||||
Assert.assertEquals("GPIO33", devKit.getControlPointNodeName(7));
|
||||
Assert.assertEquals("GPIO25", devKit.getControlPointNodeName(8));
|
||||
Assert.assertEquals("GPIO26", devKit.getControlPointNodeName(9));
|
||||
Assert.assertEquals("GPIO27", devKit.getControlPointNodeName(10));
|
||||
Assert.assertEquals("GPIO14", devKit.getControlPointNodeName(11));
|
||||
Assert.assertEquals("GPIO12", devKit.getControlPointNodeName(12));
|
||||
Assert.assertEquals("GND1", devKit.getControlPointNodeName(13));
|
||||
Assert.assertEquals("GPIO13", devKit.getControlPointNodeName(14));
|
||||
Assert.assertEquals("D2 (GPIO9)", devKit.getControlPointNodeName(15));
|
||||
Assert.assertEquals("D3 (GPIO10)", devKit.getControlPointNodeName(16));
|
||||
Assert.assertEquals("CMD (GPIO11)", devKit.getControlPointNodeName(17));
|
||||
Assert.assertEquals("5V", devKit.getControlPointNodeName(18));
|
||||
|
||||
// Right row (19..37, top to bottom)
|
||||
Assert.assertEquals("GND2", devKit.getControlPointNodeName(19));
|
||||
Assert.assertEquals("GPIO23", devKit.getControlPointNodeName(20));
|
||||
Assert.assertEquals("GPIO22", devKit.getControlPointNodeName(21));
|
||||
Assert.assertEquals("TX0 (GPIO1)", devKit.getControlPointNodeName(22));
|
||||
Assert.assertEquals("RX0 (GPIO3)", devKit.getControlPointNodeName(23));
|
||||
Assert.assertEquals("GPIO21", devKit.getControlPointNodeName(24));
|
||||
Assert.assertEquals("GND3", devKit.getControlPointNodeName(25));
|
||||
Assert.assertEquals("GPIO19", devKit.getControlPointNodeName(26));
|
||||
Assert.assertEquals("GPIO18", devKit.getControlPointNodeName(27));
|
||||
Assert.assertEquals("GPIO5", devKit.getControlPointNodeName(28));
|
||||
Assert.assertEquals("GPIO17", devKit.getControlPointNodeName(29));
|
||||
Assert.assertEquals("GPIO16", devKit.getControlPointNodeName(30));
|
||||
Assert.assertEquals("GPIO4", devKit.getControlPointNodeName(31));
|
||||
Assert.assertEquals("GPIO0", devKit.getControlPointNodeName(32));
|
||||
Assert.assertEquals("GPIO2", devKit.getControlPointNodeName(33));
|
||||
Assert.assertEquals("GPIO15", devKit.getControlPointNodeName(34));
|
||||
Assert.assertEquals("D1 (GPIO8)", devKit.getControlPointNodeName(35));
|
||||
Assert.assertEquals("D0 (GPIO7)", devKit.getControlPointNodeName(36));
|
||||
Assert.assertEquals("CLK (GPIO6)", devKit.getControlPointNodeName(37));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPinGeometryAndSpacing30Pin() {
|
||||
ESP32DevKit devKit = new ESP32DevKit();
|
||||
|
||||
// Left row pitch (20px per pin = 0.10")
|
||||
@@ -85,7 +142,35 @@ public class ESP32DevKitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBodyShapeDimensions() {
|
||||
public void testPinGeometryAndSpacing38Pin() {
|
||||
ESP32DevKit devKit = new ESP32DevKit();
|
||||
devKit.setVersion(ESP32DevKit.DevKitVersion.DevKitC_V4_38Pin);
|
||||
|
||||
// Left row pitch (20px per pin = 0.10")
|
||||
for (int i = 0; i < 18; 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 = 19; i < 37; 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: 1.00" = 200px between Left row and Right row
|
||||
Point2D pLeftTop = devKit.getControlPoint(0);
|
||||
Point2D pRightTop = devKit.getControlPoint(19);
|
||||
Assert.assertEquals(200.0, pLeftTop.distance(pRightTop), 0.01);
|
||||
Assert.assertEquals(pLeftTop.getY(), pRightTop.getY(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBodyShapeDimensions30Pin() {
|
||||
ESP32DevKit devKit = new ESP32DevKit();
|
||||
|
||||
Shape body = devKit.getBodyShape();
|
||||
@@ -102,4 +187,36 @@ public class ESP32DevKitTest {
|
||||
Point2D p0 = devKit.getControlPoint(0);
|
||||
Assert.assertEquals(expectedTopMargin, p0.getY() - bounds.getY(), 0.1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBodyShapeDimensions38Pin() {
|
||||
ESP32DevKit devKit = new ESP32DevKit();
|
||||
devKit.setVersion(ESP32DevKit.DevKitVersion.DevKitC_V4_38Pin);
|
||||
|
||||
Shape body = devKit.getBodyShape();
|
||||
Assert.assertNotNull(body);
|
||||
Rectangle2D bounds = body.getBounds2D();
|
||||
|
||||
double expectedWidth = new Size(27.9d, SizeUnit.mm).convertToPixels();
|
||||
double expectedTotalLength = new Size(54.4d, SizeUnit.mm).convertToPixels();
|
||||
|
||||
Assert.assertEquals(expectedWidth, bounds.getWidth(), 0.1);
|
||||
Assert.assertEquals(expectedTotalLength, bounds.getHeight(), 0.1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVersionSwitching() {
|
||||
ESP32DevKit devKit = new ESP32DevKit();
|
||||
Assert.assertEquals(30, devKit.getControlPointCount());
|
||||
|
||||
devKit.setVersion(ESP32DevKit.DevKitVersion.DevKitC_V4_38Pin);
|
||||
Assert.assertEquals(38, devKit.getControlPointCount());
|
||||
Assert.assertEquals("5V", devKit.getControlPointNodeName(18));
|
||||
Assert.assertEquals("CLK (GPIO6)", devKit.getControlPointNodeName(37));
|
||||
|
||||
devKit.setVersion(ESP32DevKit.DevKitVersion.DevKit_V1_30Pin);
|
||||
Assert.assertEquals(30, devKit.getControlPointCount());
|
||||
Assert.assertEquals("3V3", devKit.getControlPointNodeName(14));
|
||||
Assert.assertEquals("D23", devKit.getControlPointNodeName(29));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user