Colin’s brain dump

I write lots of code and build cool things


Bindicator: My homage to the BinDayCator

This is a rubbish subtitle

Date: []
Views: [219]
Categories: [projects]
Tags: [raspberrypi], [automation]

Every few months, someone sends me a link to the original BinDayCator project by Darren Tarbard, as if it hasn't been burning a hole in my imagination ever since I saw it first land on Hackaday. To a surprising number of people, the idea of hooking up a mini-wheelie-bin to the internet so you don't miss bin night immediately makes them think of me.

This write-up means I've now finally got the correct response: yes, the original BinDayCator is fantastic, so here's my homage.

lit_up

Parts bin

The idea behind this is simple: ensure there's a visual cue somewhere to remind us which bin needs to be put out the evening before collection. It's been buzzing around my head to build this for ages, and then I realised I'd accumulated enough gumph from old projects to put it together without much effort. The only missing pieces were the coloured wheelie bins, which thankfully Amazon is flush with!

Each bin has a little 12V light bulb driven from an old power brick. Switching is controlled by a relay board that previously automated my heating in our last house. It's all driven by the Raspberry Pi in my garage that I'm using to track planes. Everything's held together with B&Q leftovers and spare wiring from years of never throwing things out; a veritable feast of abandoned or superseded projects.

Lighting up the bins

I had some 12V G4 light bulbs like these floating around and hooked them up to my bench supply, discovering they don't take much effort to get running. You can wire them up either way, and they accept a fairly wide voltage range.

bulbs

The "4" in G4 stands for 4mm, which is the distance between the terminals. Armed with this knowledge I drilled a couple of 1mm holes into the bottom of each bin 4mm apart, flooded their bases with superglue, and then pushed the bulbs down through the new orifices.

tail_connectors

The plinth the bins sit upon is made from three slats of pine, all wood-glued together. The topmost board is drilled out with connectors stuffed through and all laced up: the 12V lines are tied together, and along with the return lines, everything's wired to a JST connector.

wired_together

To hide the cabling, I routed a channel out of the slats. I'm including my first attempt with the new router here for posterity, as it really highlighted the gap between ambition and reality. Everything was left overnight, clamped up tight and stuffed full of glue to set.

router

Clamps!

clamps

Driving the lights

For switching lights bulbs on and off I'm using the Automation pHAT. Although they dont make this exact model anymore any of its brethren will do the same job.

Here I'm using it's source-sink "output" pins. These let us control whether something is disconnected (floating) or hooked up to ground.

automation_phat

Electrically all the bins are wired to 12V and then have a seperate return line which is routed the via junction box to the output terminals of the Automation pHAT.

wired_up

Signal routing

Everything else is just basic signal routing; for that, I used some Veroboard, screw terminals, toggle switches, and some old wiring, then chucked it into a blanking panel. This should have been the simplest part of the build, as the wiring is all 1:1. But after an hour of losing my mind, I discovered a hairline crack running through the copper of the veroboard, splitting all the tracks. Thinking about it as I'm writing this: I did the trick of smacking the Veroboard over the edge of a table to chop it to length, which was probably the source of the crack further up the copper.

junction_box

The cabling gets a little messy here, as I knocked the holes in the box thinking I'd have it mounted on the left of the Raspberry Pi, but I hadn't accounted for the cabling that goes to the antenna on the garage roof. Still, it looks pretty neat. Here it is with the covers off.

cover_off

And with the cover on, in its final form.

cover_on

The bins themselves are in the bin shed next door with the cabling running through an existing channel I've made for routing the ADS-B antenna. I might put a little more effort into this arrangement at some point but for now it's out the way and doing its job nicely.

bindicator_mounted_1

The final circuit looks something like this. The eagle-eyed will spot that there are four bulbs but only three relays controlling them. Luckily for this project both recycling bins are picked up on the same day which means the 3 available output-sinking channels on the Automation pHAT are perfectly adequate.

circuit

A sprinkle of code

The code for this is exceptionally simple. I was tempted to go full-hog and have the code grok the council's refuse collection cycle, but one look at the calendar showed it's as simple as: even-numbered weeks are for recycling, otherwise it's general waste, with the garden refuse collection joining the party for part of the year.

I figured it would be fun to write more in a functional programming style, as I've been learning a bit of Lisp this year to understand why so many early computing courses had us looking at tree structures.

import automationhat
from datetime import datetime, time

# Channel each light is wired to
RECYCLING_CHANNEL = 0
WASTE_CHANNEL = 1
GARDEN_CHANNEL = 2

# Start and end week numbers for garden waste collection
GARDEN_WASTE_WEEKS = (11, 49)

def is_after_lunchtime_wednesday_or_before_lunchtime_thursday():
    """Checks if it's after Wednesday lunchtime or before Thursday lunchtime."""
    now = datetime.now()
    lunchtime = time(12, 0)

    if now.weekday() == 2 and now.time() >= lunchtime:  # After Wednesday afternoon
        return True
    if now.weekday() == 3 and now.time() < lunchtime:  # Before Thursday lunchtime
        return True
    return False

def is_odd_week():
    """Returns True if the current week number is odd."""
    return datetime.now().isocalendar()[1] % 2 != 0

def is_garden_waste_collection_period():
    """Checks if the current week is within the garden waste collection period."""
    week_number = datetime.now().isocalendar()[1]
    return GARDEN_WASTE_WEEKS[0] <= week_number <= GARDEN_WASTE_WEEKS[1]

def determine_bin_status():
    """Determines which bins should be out based on the current week and schedule."""
    recycling_enabled = (
        not is_odd_week() and is_after_lunchtime_wednesday_or_before_lunchtime_thursday()
    )
    waste_enabled = (
        is_odd_week() and is_after_lunchtime_wednesday_or_before_lunchtime_thursday()
    )
    garden_enabled = (
        is_odd_week()
        and is_garden_waste_collection_period()
        and is_after_lunchtime_wednesday_or_before_lunchtime_thursday()
    )
    return recycling_enabled, waste_enabled, garden_enabled

def set_bin_lights(recycling, waste, garden):
    """Sets the automation hat outputs based on bin status."""
    automationhat.output[RECYCLING_CHANNEL].write(recycling)
    automationhat.output[WASTE_CHANNEL].write(waste)
    automationhat.output[GARDEN_CHANNEL].write(garden)
    print(f"RECYCLING = {recycling}")
    print(f"WASTE = {waste}")
    print(f"GARDEN = {garden}")

# Main logic
if __name__ == "__main__":
    recycling, waste, garden = determine_bin_status()
    set_bin_lights(recycling, waste, garden)

This gets ran as a cron job every lunchtime and midnight.

The repo is over here.

In conclusion, I named it wrong

I started calling this thing the Bindicator when I wrote the code this evening, and then realised how much funnier the original author of this project is; both by coming up with the title BinDayCator and by actually making the thing in the first place. I'm sticking with my naming, though, as if nothing else, after all these years of being asked whether I've made my own version, I now feel bindicated.

Previous »