I’ve made the final iteration of my earlier Tiny LED Strip Driver project. I made the PCB in Kicad and sent it to be fabbed at JLCPCB for under a Pound per board, delivered in under two weeks!

Schematic:

img

PCB:

img

3D render:

img

I then used Fusion 360 to make an enclosure for it. That wasn’t as easy as I thought, but I think I still have some things to learn - for example extruding the screw terminals from the PCB STEP file to make the holes in the case didn’t update when you moved the PCB up a bit to give more clearance. I think projecting the geometry and just extruding a square would be the way to go.

Also when shelling a round box (cube with fillets) it doesn’t apply internal fillets, you just get a cube, so again its better to extrude a square and fillet that rather than using shell. I was pleased with the countersunk screw holes I made inside the standoffs though. I also used my old semi-circle snap-fit method on the lid.

img

Finally here are the finished boards with the components soldered and in the enclosure:

img

I’ve got some 6x6x25mm tactile pushbuttons on order as the 20mm ones are not quite long enough to protrude from the lid!

The software hasn’t changed much other than to re-order the output pins, but I’ve replaced arduino-mk with arduino-cli and the “tiny” core with ATTinyCore:

FQBN = ATTinyCore:avr:attinyx5

all:
	arduino-cli compile --fqbn $(FQBN) $(notdir $(CURDIR)).ino

ispload:
	arduino-cli upload -b $(FQBN) -P usbasp $(CURDIR)

burn_bootloader:
	arduino-cli burn-bootloader -b $(FQBN) -P usbasp -v $(CURDIR)

clean:
	rm -rf $(CURDIR)/build

I had some issue with the EEPROM not always writing properly, so migrated to the new update() method instead of the old write() which seems to have solved the problem. Here’s the code for the traffic lights/gearbox:

#include <EEPROM.h>

// init vars
const int output1 = 0; // pin5 = red led
const int output2 = 1; // pin6 = amber led
const int output3 = 4; // pin3 = green led
const int button  = 3; // pin2
int previous = LOW;
int counter = EEPROM.read(0);
unsigned long last_time = 0;

void changeGear(int one, int two, int three)
{
    // light led and solenoid
    digitalWrite(output1, one);
    digitalWrite(output2, two);
    digitalWrite(output3, three);

    // store counter in eeprom
    EEPROM.update(0, counter);
}

void setup()
{
    // set button to input with built-in pull-up
    pinMode(button, INPUT_PULLUP);

    // set led/solenoid pins to outputs
    pinMode(output1, OUTPUT);
    pinMode(output2, OUTPUT);
    pinMode(output3, OUTPUT);
}

void loop()
{
    // take a reading
    int reading = digitalRead(button);

    // changed state - debounce=250ms
    if (reading == LOW && previous == HIGH && (millis() - last_time > 250))
    {
        // increment counter
        counter++;

        // store the time the button was pressed
        last_time = millis();
    }

    // being held down in 3rd gear - holdtime=3s
    if (reading == LOW && previous == LOW && counter > 3 && (millis() - last_time > 3000))
    {
        counter = 0;
    }

    // change gear
    switch (counter)
    {
        case 0:
            changeGear(0,0,0);
            break;
        case 1:
            changeGear(1,0,0);
            break;
        case 2:
            changeGear(0,1,0);
            break;
        case 3:
            changeGear(0,0,1);
            break;
    }

    // store previous reading
    previous = reading;
}