Project by arb; RPi Garbage Bin Reminder

arb just shared a new project: "RPi Garbage Bin Reminder"



Our local council picks up recycling bins one week and green waste the following week. Sometimes people forget which bins go out each week and perhaps they mistakenly put the wrong bins out. Not that that has ever happened to me of course!
I decided to put together a simple circuit and write a Python script for my Raspberry Pi to remind me whether it is recycling week or green waste week. A few LEDs, a resistor, a switch and a small breadboard are all that are required for this handy dandy bin night reminder!

Read more

Great project Arb!

I feel like I can never remember what week it is for the bins. I need one of these in my life for sure.

Thanks for sharing!

Thanks Stephen,

I’d like to try integrate a captive touch sensor to remove the physical button. I haven’t had a chance to play with them yet, but I hope that I can get it working through the case and mount the sensor inside. Then I can just tap the case and have the LEDs show me which bins go out.

1 Like

Captive touch is really easy to work with! Its great to be able to removed the potential failure point of a mechanical button.

Thank you for your project, I wanted to see how you applied the datetime module in its entirety. I tried to download the file https://core-electronics.com.au/media/projects/assets/60773/attachments/1531140719_BinMinder.py.zip and no matter whether I clicked the link or ā€œsaved link asā€ (in Firefox), I kept on getting an error,
I would love to see the code to apply the datetime python module,
Thank you

That’s odd - it seems to be a problem on Core-Electronics’ website. I’ll try to paste the code into this comment…

# Bin Minder v1.0

# MIT License
#
# Copyright (c) 2018 Amos Bannister
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.


import RPi.GPIO as GPIO
import time
import datetime

# Set a known date for recycling day
# (we assume recycling one week, green waste the next)
RECYCLE_START = datetime.datetime(2018, 6, 27)  # Our recycle day is on a Wednesday
GARBAGE_DAY = RECYCLE_START.weekday()

# Set the pin numbers for each LED
RED = 16
YELLOW = 20
GREEN = 21

# Set the pin number for the button...
BUTTON = 12


def setup():
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    set_GPIO_OUT()
    all_off()
    set_BUTTON_IN()


def set_GPIO_OUT():
    GPIO.setup([RED, YELLOW, GREEN], GPIO.OUT)


def switch_on(colours):
    set_GPIO_OUT()
    GPIO.output(colours, GPIO.HIGH)


def switch_off(colours):
    set_GPIO_OUT()
    GPIO.output(colours, GPIO.LOW)


def all_off():
    set_GPIO_OUT()
    switch_off([RED, YELLOW, GREEN])


def set_BUTTON_IN():
    GPIO.setup(BUTTON, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.add_event_detect(BUTTON, GPIO.FALLING, callback=button_clicked,
                          bouncetime=200)


def flash_LEDs(colour, flash_rate):
    switch_on([RED, colour])
    if flash_rate > 0:
        for _ in xrange(flash_rate):
            time.sleep(1.0 / flash_rate)
            switch_off([RED, colour])
            time.sleep(1.0 / flash_rate)
            switch_on([RED, colour])
    else:
        time.sleep(2)
    time.sleep(2)
    all_off()


def recycling_week(flash_rate):
    print "Recycling Week"
    flash_LEDs(YELLOW, flash_rate)


def greenwaste_week(flash_rate):
    print "Green waste Week"
    flash_LEDs(GREEN, flash_rate)


def button_clicked(pin_num):
    # First let's stop checking for the button press...
    # We'll add the event detect back in after checking...
    GPIO.remove_event_detect(BUTTON)

    check_bin_day()
    # time.sleep(0.01) # Sleep a lil to avoid detecting phantom button presses...
    set_BUTTON_IN()


def check_bin_day():
    # Let's find out if tonight is bin night...
    today = datetime.datetime.today()

    print "Is it bin day today?"

    today_weekday = today.weekday()

    flash_rate = 0
    if (today_weekday == GARBAGE_DAY):
        flash_rate = 10
        print "Your bins should have gone out this morning!"

    if ((today_weekday + 1) % 7 == GARBAGE_DAY):
        flash_rate = 5
        print "Put your bins out tonight!"

    weeks_since_start = ((today - datetime.timedelta(days=1)) - RECYCLE_START).days / 7

    if ((weeks_since_start % 2) == 1):
        recycling_week(flash_rate)
    else:
        greenwaste_week(flash_rate)

    # Now make sure all LEDs are off
    all_off()


setup()

print "Press the button to check what bins go out this week!"

while True:
    time.sleep(0.1)

Dear arb,
Thank you for that. I copied the contents of the textbox and saved the it as binminder.py on my computer for study.
Anhony

2 Likes

Dear arb,
Going through the code. I have learned how to setup the pin configurations for input and output, setting up an event whenever a button is pressed.The event occurs when the button is released = falling edge = going from 1 to 0.

I also learned from the code that every time you want to switch on or off the LEDs, you always setup the LEDs = pin numbers for output.

My question is what do you use for a real time clock (ā€˜RTC’) given that the RPi does not have a RTC on board. I will be asking a separate technical question about the various RTCs,

Thank you,
Anthony

Hello Anthony,

I always set the pins as output when I want to light the LEDs because one configuration I used while testing shared a pin for both input and output. Naughty I know, but I was trying to see if I could fit the circuit on the tiny 5x5 breadboard you can see if the final picture with the PiStop. It turns out you can ā€œreuseā€ pins for both input and output, but that can cause problems with LEDs being dimly lit when you don’t really want them to be. I should have removed that code and just set the input and output pins once in the setup() function. (This is also part of the reason why I remove the button detect event in the button_clicked() function - when I was reusing the button pin for an LED, if I left the event enabled, when I lit the LED bad things could happen. Again, this code should probably have been removed.)

With the button detection, you can set whether the event should be triggered on a rising or falling edge. (Or you could trigger on both if you want.)

I should stress that you do not normally need to set the GPIO pins to OUTPUT or INPUT all the time - that was just a left over bit of code from my earlier experiments. I really should tidy that code and re-upload it.

I don’t use an RTC, instead I rely on the RPi’s internal clock. Because I use network-enabled Pis (the 3 B+ and the Pi Zero with WiFi) when they boot up they will automatically set the time using the network time protocol (NTP). If your Pi is not connected to a network you would need some kind of RTC to maintain the correct time when the device is rebooted. I don’t have an RTC for the Pi so I probably can’t help you on that front.

Hope some of that helps

–
arb

2 Likes