/Boxes/USBCharger.foocad

I have numerous wall wart going spare and I want to convert one or two into USB chargers, with the aid of a buck module to step the voltage down to 5V.
Inside is a simple circuit board with 1 to 4 USB sockets. Each has their data pins shorted (which indicates this is a charger only, and the device can draw high current)
Pinout for the sockets can be seen here : [https://en.wikipedia.org/wiki/USB_hardware#/media/File:USB.svg]
Add a short between D+ and D- to indicate this is a "charge only" port.
My buck module has a max output current of 3A. A Raspberry Pi 4 need 3A, so may not be suitable. A Pi 3 needs 2.5A, And Pi 1&2 less than 2A.
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*
include SmoothOutsideBox.foocad
class Box( val width : double, val depth : double, val bh : double, val th : double )
: SmoothOutsideBox()
{
init {
wallThickness = 1.6
lipThickness = 1.6
topChamfer = 1
height = bh
topHeight = th
lipHeight = 3
slack = 0.1
}
override fun profile() = Square( width, depth ).center().roundAllCorners(2)
override fun inset( amount : double ) = profile().offset(-amount)
}
/**
A housing for a boost module, and a simple circuit board with (up to) 4
USB charging sockets.
*/
class USBCharger : AbstractModel() {
@Custom
var socketCount = 3
@Custom
var moduleCount = 1
// Must be wider if you want 4 or more outputs.
@Custom
var width = 65
@Custom
var depth = 47 // 71 for dual buck module.
@Custom
var bottomHeight = 13
@Custom
var topHeight = 9
// Should the power lead be fed from the side (or the back)?
@Custom
var sideEntry = false
// Should the USB ports exit the front (or the top)?
@Custom
var frontExit = true
// Used for debugging only. Shows the size of the boost module, as well
// as the mounting holes.
fun buckModule() : Shape3d {
val board = Cube( 43.5, 21.5, 1.5 ).color("Green")
val components = Cube(43.5, 21.5, 14).translateZ(1.5).color("WhiteSmoke")
val holes = Cylinder.hole( 20, 1.5 ).translate(15,-7.5,-1)
.translate(-30,15,-1).also()
return (board + components).centerXY() - holes
}
fun box() = Box( width, depth, bottomHeight, topHeight )
@Piece
fun top() : Shape3d {
val box : Box = box()
val top = box.build("top").color("Purple")
return if ( frontExit ) {
top
} else {
val usbHoles = Cube( 6, 13.5, 10 ).bottomTo( 4 ).center()
.frontTo( -depth/2 + 4 )
.repeatX( socketCount, 2.54 * 4 )
.centerX()
val sockets = Cube( 5.5, 13.5, 15).centerX()
.repeatX( socketCount, 2.54 * 4 )
.previewOnly().centerXY()
.frontTo(-depth/2+4).bottomTo(0)
val shelf = Cube( usbHoles.size.x, 2, 16 ).centerXY().frontTo( sockets.back )
.backTo( sockets.front ).also()
top - usbHoles + shelf + sockets
}
}
@Piece
fun bottom() : Shape3d {
val box : Box = box()
val bottom = box.build("bottom")
var hole : Shape3d = Cylinder( 10, 8.5/2 )
.center()
.rotateX(90)
.translateZ(7)
if ( sideEntry ) {
hole = hole.rotateZ(90).translateX( -width/2 ).translateY( depth/2 - 8 )
//strain = strain.rotateZ(90).leftTo( -width/2 ).translateY( depth/2 - 8 )
} else {
hole = hole.translateY( depth/2 ).translateX(-width/2 + 8)
//strain = strain.backTo(depth/2).translateX(-width/2 + 8)
}
val boxWithHole = bottom - hole
return if ( frontExit ) {
val usbHoles = Cube( 13.5, 10, 6 ).bottomTo( 4 ).centerX()
.frontTo( -box.depth/2-4 )
.repeatX( socketCount, 2.54 * 7 )
.centerX()
val sockets = Cube(13.5, 15, 5.5).centerX()
.repeatX( socketCount, 2.54 * 7 )
.previewOnly().centerXY()
.frontTo(-depth/2).bottomTo(4)
val shelf = Cube( 59, 7, 4 ).centerXY().backTo( sockets.back )
boxWithHole + shelf + sockets - usbHoles
} else {
boxWithHole
}
}
@Piece( printable = false )
override fun build() : Shape3d {
return top().rotateY(180).translateZ( bottomHeight + topHeight + 1 ) +
bottom() +
buckModule().tileY( moduleCount, 2 )
.rightTo(width/2-4)
.bottomTo( 3 )
.backTo( depth/2 - 4)
.previewOnly()
}
}

