Exit Full View
Up

/Boxes/USBCharger.foocad

USBCharger

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.

FooCAD Source Code
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 : Model {
    
    @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
        }
    }

    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()
    }
}