mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-07 12:24:58 +10:00
pi zero
This commit is contained in:
@@ -99,9 +99,12 @@ public class RaspberryPiZero extends AbstractMakerBoard {
|
||||
double y = p0.getY();
|
||||
double boardW = BOARD_WIDTH.convertToPixels();
|
||||
double boardH = BOARD_HEIGHT.convertToPixels();
|
||||
double boardX = x - 55;
|
||||
double boardY = y - 45;
|
||||
return new RoundRectangle2D.Double(boardX, boardY, boardW, boardH, 12, 12);
|
||||
double pin1OffsetX = new Size(8.37d, SizeUnit.mm).convertToPixels();
|
||||
double pin1OffsetY = new Size(3.5d, SizeUnit.mm).convertToPixels() + PIN_SPACING.convertToPixels() / 2.0;
|
||||
double boardX = x - pin1OffsetX;
|
||||
double boardY = y - pin1OffsetY;
|
||||
double cornerArc = new Size(6.0d, SizeUnit.mm).convertToPixels();
|
||||
return new RoundRectangle2D.Double(boardX, boardY, boardW, boardH, cornerArc, cornerArc);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,8 +125,10 @@ public class RaspberryPiZero extends AbstractMakerBoard {
|
||||
|
||||
double boardW = BOARD_WIDTH.convertToPixels();
|
||||
double boardH = BOARD_HEIGHT.convertToPixels();
|
||||
double boardX = x - 55;
|
||||
double boardY = y - 45;
|
||||
double pin1OffsetX = new Size(8.37d, SizeUnit.mm).convertToPixels();
|
||||
double pin1OffsetY = new Size(3.5d, SizeUnit.mm).convertToPixels() + PIN_SPACING.convertToPixels() / 2.0;
|
||||
double boardX = x - pin1OffsetX;
|
||||
double boardY = y - pin1OffsetY;
|
||||
|
||||
Shape boardShape = getBodyShape();
|
||||
|
||||
@@ -132,31 +137,79 @@ public class RaspberryPiZero extends AbstractMakerBoard {
|
||||
drawingObserver.startTracking();
|
||||
g2d.setColor(outlineMode ? Constants.TRANSPARENT_COLOR : bodyColor);
|
||||
g2d.fill(boardShape);
|
||||
drawingObserver.stopTracking();
|
||||
|
||||
g2d.setColor(getFinalBorderColor(componentState, outlineMode));
|
||||
g2d.setStroke(ObjectCache.getInstance().fetchBasicStroke(1.5f));
|
||||
g2d.draw(boardShape);
|
||||
|
||||
if (!outlineMode) {
|
||||
drawMountingHole(g2d, boardX + 25, boardY + 25, 20);
|
||||
drawMountingHole(g2d, boardX + 25, boardY + boardH - 25, 20);
|
||||
drawMountingHole(g2d, boardX + boardW - 25, boardY + 25, 20);
|
||||
drawMountingHole(g2d, boardX + boardW - 25, boardY + boardH - 25, 20);
|
||||
// 4 Mounting holes (diameter 2.75mm, located 3.5mm from board edges)
|
||||
double holeDiameter = new Size(2.75d, SizeUnit.mm).convertToPixels();
|
||||
drawMountingHole(g2d, boardX + new Size(3.5d, SizeUnit.mm).convertToPixels(),
|
||||
boardY + new Size(3.5d, SizeUnit.mm).convertToPixels(), holeDiameter);
|
||||
drawMountingHole(g2d, boardX + new Size(3.5d, SizeUnit.mm).convertToPixels(),
|
||||
boardY + boardH - new Size(3.5d, SizeUnit.mm).convertToPixels(), holeDiameter);
|
||||
drawMountingHole(g2d, boardX + boardW - new Size(3.5d, SizeUnit.mm).convertToPixels(),
|
||||
boardY + new Size(3.5d, SizeUnit.mm).convertToPixels(), holeDiameter);
|
||||
drawMountingHole(g2d, boardX + boardW - new Size(3.5d, SizeUnit.mm).convertToPixels(),
|
||||
boardY + boardH - new Size(3.5d, SizeUnit.mm).convertToPixels(), holeDiameter);
|
||||
|
||||
// Mini HDMI & Dual Micro-USB
|
||||
drawMetalConnector(g2d, boardX + 80, boardY + boardH - 8, 65, 40, "HDMI");
|
||||
drawMetalConnector(g2d, boardX + 240, boardY + boardH - 8, 55, 40, "USB");
|
||||
drawMetalConnector(g2d, boardX + 350, boardY + boardH - 8, 55, 40, "PWR");
|
||||
// MicroSD card slot on the left edge
|
||||
double sdW = new Size(11.0d, SizeUnit.mm).convertToPixels();
|
||||
double sdH = new Size(12.0d, SizeUnit.mm).convertToPixels();
|
||||
double sdX = boardX + new Size(1.5d, SizeUnit.mm).convertToPixels();
|
||||
double sdY = boardY + new Size(7.5d, SizeUnit.mm).convertToPixels();
|
||||
drawMetalConnector(g2d, sdX, sdY, sdW, sdH, "SD");
|
||||
|
||||
// SoC chip
|
||||
drawChip(g2d, boardX + 150, boardY + 80, 80, 80, "RPi SoC");
|
||||
// Mini HDMI Connector (center at X = 12.4mm, width = 11.2mm, height = 7.5mm, overhang = 1.5mm)
|
||||
double hdmiW = new Size(11.2d, SizeUnit.mm).convertToPixels();
|
||||
double hdmiH = new Size(7.5d, SizeUnit.mm).convertToPixels();
|
||||
double hdmiX = boardX + new Size(12.4d, SizeUnit.mm).convertToPixels() - hdmiW / 2.0;
|
||||
double hdmiY = boardY + boardH - new Size(6.0d, SizeUnit.mm).convertToPixels();
|
||||
drawMetalConnector(g2d, hdmiX, hdmiY, hdmiW, hdmiH, "HDMI");
|
||||
|
||||
// Micro USB Data (center at X = 41.4mm, width = 7.5mm, height = 5.6mm, overhang = 1.4mm)
|
||||
double usbW = new Size(7.5d, SizeUnit.mm).convertToPixels();
|
||||
double usbH = new Size(5.6d, SizeUnit.mm).convertToPixels();
|
||||
double usbX = boardX + new Size(41.4d, SizeUnit.mm).convertToPixels() - usbW / 2.0;
|
||||
double usbY = boardY + boardH - new Size(4.2d, SizeUnit.mm).convertToPixels();
|
||||
drawMetalConnector(g2d, usbX, usbY, usbW, usbH, "USB");
|
||||
|
||||
// Micro USB Power (center at X = 54.0mm, width = 7.5mm, height = 5.6mm, overhang = 1.4mm)
|
||||
double pwrX = boardX + new Size(54.0d, SizeUnit.mm).convertToPixels() - usbW / 2.0;
|
||||
double pwrY = boardY + boardH - new Size(4.2d, SizeUnit.mm).convertToPixels();
|
||||
drawMetalConnector(g2d, pwrX, pwrY, usbW, usbH, "PWR");
|
||||
|
||||
// Camera Connector (CSI) on right edge
|
||||
double csiW = new Size(3.2d, SizeUnit.mm).convertToPixels();
|
||||
double csiH = new Size(16.5d, SizeUnit.mm).convertToPixels();
|
||||
double csiX = boardX + boardW - new Size(4.2d, SizeUnit.mm).convertToPixels();
|
||||
double csiY = boardY + new Size(6.75d, SizeUnit.mm).convertToPixels();
|
||||
drawChip(g2d, csiX, csiY, csiW, csiH, "CSI");
|
||||
|
||||
// Main SoC chip (Broadcom BCM2835 / RP3A0)
|
||||
double socW = new Size(12.0d, SizeUnit.mm).convertToPixels();
|
||||
double socH = new Size(12.0d, SizeUnit.mm).convertToPixels();
|
||||
double socX = boardX + new Size(19.5d, SizeUnit.mm).convertToPixels();
|
||||
double socY = boardY + new Size(11.5d, SizeUnit.mm).convertToPixels();
|
||||
drawChip(g2d, socX, socY, socW, socH, "");
|
||||
|
||||
// Raspberry Pi logo on SoC chip
|
||||
double logoSize = new Size(7.0d, SizeUnit.mm).convertToPixels();
|
||||
double logoW = logoSize * (72.51 / 92.604);
|
||||
double logoX = socX + (socW - logoW) / 2.0;
|
||||
double logoY = socY + (socH - logoSize) / 2.0;
|
||||
drawRaspberryPiLogo(g2d, logoX, logoY, logoSize);
|
||||
|
||||
// Silkscreen "GPIO" label next to the top pins
|
||||
g2d.setColor(Color.WHITE);
|
||||
g2d.setFont(SILK_FONT);
|
||||
StringUtils.drawCenteredText(g2d, "Pi Zero", boardX + 280, boardY + 100, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
g2d.setFont(SILK_FONT_SMALL);
|
||||
StringUtils.drawCenteredText(g2d, "GPIO", boardX + new Size(47.5d, SizeUnit.mm).convertToPixels(),
|
||||
boardY + new Size(7.8d, SizeUnit.mm).convertToPixels(), HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
|
||||
drawingObserver.stopTracking();
|
||||
|
||||
g2d.setTransform(oldTx);
|
||||
|
||||
drawPins(g2d, 0, controlPoints.length, false, outlineMode, drawingObserver);
|
||||
@@ -167,18 +220,26 @@ public class RaspberryPiZero extends AbstractMakerBoard {
|
||||
@Override
|
||||
public void drawIcon(Graphics2D g2d, int width, int height) {
|
||||
g2d.setColor(RPI_GREEN);
|
||||
g2d.fill(new RoundRectangle2D.Double(2, 8, width - 4, height - 16, 4, 4));
|
||||
g2d.fill(new RoundRectangle2D.Double(2, 6, width - 4, height - 12, 3, 3));
|
||||
g2d.setColor(RPI_GREEN.darker());
|
||||
g2d.draw(new RoundRectangle2D.Double(2, 8, width - 4, height - 16, 4, 4));
|
||||
g2d.draw(new RoundRectangle2D.Double(2, 6, width - 4, height - 12, 3, 3));
|
||||
|
||||
// GPIO Header
|
||||
g2d.setColor(HEADER_BODY_COLOR);
|
||||
g2d.fillRect(6, 10, width - 12, 3);
|
||||
g2d.fillRect(5, 7, width - 10, 3);
|
||||
|
||||
// SoC
|
||||
g2d.setColor(IC_BODY_COLOR);
|
||||
g2d.fillRect(11, 15, 10, 6);
|
||||
g2d.fillRect(10, 12, 6, 6);
|
||||
|
||||
// Connectors on bottom
|
||||
g2d.setColor(USB_METAL_COLOR);
|
||||
g2d.fillRect(6, height - 7, 4, 3);
|
||||
g2d.fillRect(18, height - 7, 3, 3);
|
||||
g2d.fillRect(23, height - 7, 3, 3);
|
||||
|
||||
g2d.setColor(Color.WHITE);
|
||||
g2d.setFont(new Font("SansSerif", Font.BOLD, 5));
|
||||
StringUtils.drawCenteredText(g2d, "ZERO", width / 2, height / 2 + 5, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
StringUtils.drawCenteredText(g2d, "ZERO", width / 2 + 4, 15, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
|
||||
}
|
||||
}
|
||||
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
package org.diylc.components.micro;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.diylc.common.Orientation;
|
||||
import org.diylc.core.ComponentState;
|
||||
import org.diylc.core.IDrawingObserver;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.measures.Size;
|
||||
import org.diylc.core.measures.SizeUnit;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class RaspberryPiZeroTest {
|
||||
|
||||
@Test
|
||||
public void testControlPointCountAndNames() {
|
||||
RaspberryPiZero pi = new RaspberryPiZero();
|
||||
Assert.assertEquals(40, pi.getControlPointCount());
|
||||
|
||||
for (int i = 0; i < pi.getControlPointCount(); i++) {
|
||||
String name = pi.getControlPointNodeName(i);
|
||||
Assert.assertNotNull("Pin " + i + " name should not be null", name);
|
||||
Assert.assertFalse("Pin " + i + " name should not be empty", name.trim().isEmpty());
|
||||
}
|
||||
|
||||
Assert.assertEquals("3.3V (Pin 1)", pi.getControlPointNodeName(0));
|
||||
Assert.assertEquals("5V (Pin 2)", pi.getControlPointNodeName(1));
|
||||
Assert.assertEquals("GPIO2/SDA (Pin 3)", pi.getControlPointNodeName(2));
|
||||
Assert.assertEquals("5V (Pin 4)", pi.getControlPointNodeName(3));
|
||||
Assert.assertEquals("GND (Pin 39)", pi.getControlPointNodeName(38));
|
||||
Assert.assertEquals("GPIO21 (Pin 40)", pi.getControlPointNodeName(39));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDimensionsAndPinGeometry() {
|
||||
RaspberryPiZero pi = new RaspberryPiZero();
|
||||
|
||||
// Board dimensions: 65 mm x 30 mm
|
||||
double expectedWidth = new Size(65.0d, SizeUnit.mm).convertToPixels();
|
||||
double expectedHeight = new Size(30.0d, SizeUnit.mm).convertToPixels();
|
||||
|
||||
Shape body = pi.getBodyShape();
|
||||
Assert.assertNotNull(body);
|
||||
Rectangle2D bounds = body.getBounds2D();
|
||||
|
||||
Assert.assertEquals(expectedWidth, bounds.getWidth(), 0.1);
|
||||
Assert.assertEquals(expectedHeight, bounds.getHeight(), 0.1);
|
||||
|
||||
// Verify Pin 1 location relative to board top-left edge
|
||||
// Pin 1 offset X: 8.37 mm from left edge (centered between holes at X=3.5mm and X=61.5mm)
|
||||
// Pin 1 offset Y: 4.77 mm from top edge (3.5 mm + spacing/2 = 4.77 mm)
|
||||
// Pin 2 offset Y: 2.23 mm from top edge (3.5 mm - spacing/2 = 2.23 mm)
|
||||
// Vertical center of header: (4.77 + 2.23) / 2 = 3.5 mm (dead-centered with mounting holes)
|
||||
double expectedPin1OffsetX = new Size(8.37d, SizeUnit.mm).convertToPixels();
|
||||
double expectedPin1OffsetY = new Size(3.5d, SizeUnit.mm).convertToPixels() + new Size(0.1d, SizeUnit.in).convertToPixels() / 2.0;
|
||||
|
||||
Point2D p0 = pi.getControlPoint(0); // Pin 1
|
||||
Assert.assertEquals(expectedPin1OffsetX, p0.getX() - bounds.getX(), 0.1);
|
||||
Assert.assertEquals(expectedPin1OffsetY, p0.getY() - bounds.getY(), 0.1);
|
||||
|
||||
// Pin 2 (outer row) should be at Y = 2.23 mm from top edge (3.5 mm - spacing/2)
|
||||
Point2D p1 = pi.getControlPoint(1); // Pin 2
|
||||
double expectedPin2OffsetY = new Size(3.5d, SizeUnit.mm).convertToPixels() - new Size(0.1d, SizeUnit.in).convertToPixels() / 2.0;
|
||||
Assert.assertEquals(p0.getX(), p1.getX(), 0.01);
|
||||
Assert.assertEquals(expectedPin2OffsetY, p1.getY() - bounds.getY(), 0.1);
|
||||
|
||||
// Verify vertical center of header is dead in the middle with the 3.5mm mounting hole line
|
||||
double headerCenterY = (p0.getY() + p1.getY()) / 2.0 - bounds.getY();
|
||||
Assert.assertEquals(new Size(3.5d, SizeUnit.mm).convertToPixels(), headerCenterY, 0.1);
|
||||
|
||||
// Check pin spacing (20px per 0.1" pitch)
|
||||
double spacing = new Size(0.1d, SizeUnit.in).convertToPixels();
|
||||
for (int col = 0; col < 19; col++) {
|
||||
int pinOdd1 = col * 2;
|
||||
int pinOdd2 = (col + 1) * 2;
|
||||
Point2D po1 = pi.getControlPoint(pinOdd1);
|
||||
Point2D po2 = pi.getControlPoint(pinOdd2);
|
||||
Assert.assertEquals(spacing, po2.getX() - po1.getX(), 0.01);
|
||||
Assert.assertEquals(po1.getY(), po2.getY(), 0.01);
|
||||
|
||||
int pinEven1 = col * 2 + 1;
|
||||
int pinEven2 = (col + 1) * 2 + 1;
|
||||
Point2D pe1 = pi.getControlPoint(pinEven1);
|
||||
Point2D pe2 = pi.getControlPoint(pinEven2);
|
||||
Assert.assertEquals(spacing, pe2.getX() - pe1.getX(), 0.01);
|
||||
Assert.assertEquals(pe1.getY(), pe2.getY(), 0.01);
|
||||
}
|
||||
|
||||
// Header center should be at 32.5 mm from left edge
|
||||
Point2D pLastOdd = pi.getControlPoint(38); // Pin 39 (col 19)
|
||||
double headerCenterX = (p0.getX() + pLastOdd.getX()) / 2.0;
|
||||
double expectedHeaderCenterX = bounds.getX() + new Size(32.5d, SizeUnit.mm).convertToPixels();
|
||||
Assert.assertEquals(expectedHeaderCenterX, headerCenterX, 0.1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDrawingAndOutline() {
|
||||
RaspberryPiZero pi = new RaspberryPiZero();
|
||||
pi.setControlPoint(new Point2D.Double(200, 200), 0);
|
||||
|
||||
BufferedImage img = new BufferedImage(600, 600, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = img.createGraphics();
|
||||
g2d.setClip(new Rectangle(0, 0, 600, 600));
|
||||
|
||||
Project project = new Project();
|
||||
final AtomicInteger trackingStartCount = new AtomicInteger(0);
|
||||
final AtomicInteger trackingStopCount = new AtomicInteger(0);
|
||||
|
||||
IDrawingObserver observer = new IDrawingObserver() {
|
||||
@Override public void startTracking() {
|
||||
trackingStartCount.incrementAndGet();
|
||||
}
|
||||
@Override public void stopTracking() {
|
||||
trackingStopCount.incrementAndGet();
|
||||
}
|
||||
@Override public void startTrackingContinuityArea(boolean positive) {}
|
||||
@Override public void stopTrackingContinuityArea() {}
|
||||
@Override public boolean isTrackingContinuityArea() { return false; }
|
||||
@Override public void setContinuityMarker(String marker) {}
|
||||
};
|
||||
|
||||
pi.draw(g2d, ComponentState.NORMAL, false, project, observer);
|
||||
Assert.assertEquals(1, trackingStartCount.get());
|
||||
Assert.assertEquals(1, trackingStopCount.get());
|
||||
|
||||
pi.draw(g2d, ComponentState.SELECTED, false, project, observer);
|
||||
pi.draw(g2d, ComponentState.NORMAL, true, project, observer);
|
||||
pi.drawIcon(g2d, 32, 32);
|
||||
|
||||
g2d.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRotation() {
|
||||
RaspberryPiZero pi = new RaspberryPiZero();
|
||||
pi.setControlPoint(new Point2D.Double(200, 200), 0);
|
||||
|
||||
Point2D p0Initial = pi.getControlPoint(0);
|
||||
Point2D p1Initial = pi.getControlPoint(1);
|
||||
|
||||
pi.setOrientation(Orientation._90);
|
||||
Point2D p0Rot = pi.getControlPoint(0);
|
||||
Point2D p1Rot = pi.getControlPoint(1);
|
||||
|
||||
Assert.assertEquals(p0Initial.getX(), p0Rot.getX(), 0.01);
|
||||
Assert.assertEquals(p0Initial.getY(), p0Rot.getY(), 0.01);
|
||||
// After 90 deg clockwise rotation, p1 (which was at (x, y - spacing)) should be at (x + spacing, y)
|
||||
double spacing = new Size(0.1d, SizeUnit.in).convertToPixels();
|
||||
Assert.assertEquals(p0Rot.getX() + spacing, p1Rot.getX(), 0.01);
|
||||
Assert.assertEquals(p0Rot.getY(), p1Rot.getY(), 0.01);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user