Days2Bin: Pico Powered Bin Reminder

Updated 17 April 2024

Our recycle bin is collected fortnightly, but I can never remember which week, and the printed calendar changes every year! So I made a Raspberry Pi Pico W and GlowBit Matrix powered model wheelie bin which shows when the bins are due at a press of the lid.

Like Steve Jobs, I only wanted one button. So I wanted to set the dates and frequencies from my phone via a simple web interface. The Pico W is perfect for the job. I also needed a clock so that the device knew the date, so I used a DS3231 real-time clock IC. The GlowBit Matrix has a bright colourful display.

My first working version was written in MicroPython, but it took several seconds to boot, so I wrote the final program in the language C using the Raspberry Pi Pico SDK. The GlowBit starts scrolling the info in a fraction of a second now.


3D Printing The Case

I designed the wheelie bin in FreeCAD and 3D printed the lid in red PLA and the bin in green PLA. I also printed a thin white PLA diffuser/cover for the GlowBit Matrix.

I sliced most of the models in PrusaSlicer and printed at 0.2mm layer height on a Prusa MK4. The diffuser layer height was 0.15mm.

The STL and OBJ files for this print can be found at the bottom of this page




Designing The Circuit

I used KiCAD for the circuit design and prototyped it on a breadboard.

The device is powered by 3 x AAA batteries, and the DS3231 by 2 x AAA batteries. I wanted to maximise battery life, so the power is controlled by a pair of logic-level MOSFETs. The gate on the N channel MOSFET is grounded by a momentary push button under the lid, causing the Pico to power on. Once the Pico is on, GPIO8 goes high to keep the N channel MOSFET switched on, which continues to ground the P Channel MOSFET. After displaying the bin times, GPIO8 goes low, shutting off the power. In other words, the power is switched on by pressing the button and switched off by the software.

When the 4.5V power is off, the 3V supply keeps the clock going, drawing an extremely low current.

GPIO9 is configured as a digital input to monitor the On push button. If the button is kept down the Pico W starts an ad hoc wi-fi access point (“Days2Bin”) and the web server. If you join the AP with an Apple device it is treated as a captive portal, and the settings web page opens. For other devices, simply open a browser to 192.168.4.1

For the finished device, I had a PCB fabricated. I used a breakout board for the prototype, and a stand-alone SMD DS3231 IC on the custom PCB to reduce space.

This schematic is available at the bottom of the page


Writing The Software

I originally wrote the software in MicroPython but switched to C to speed up the response.

I wrote quite a bit of it on a Raspberry Pi 4B running VSCode based on the Pico SDK. The benefits of using a Pi 4 were firstly that Raspberry Pi supports the Pico SDK out of the box for Raspberry Pi, and secondly, the RPi can directly run and debug the code on the Pico via SWD (Single Wire Debug).

Eventually, I switched from the Pi 4 to an iMac for speed of compilation, which was a bit fiddly to set up, and required a Pico Probe to operate the SWD. Thankfully it is very easy to turn a standard Pico into a Pico Probe!

Unlike MicroPython, there is no file system on the C version, so the settings are saved in a section of flash memory reserved by a custom linker script.

Settings are entered by holding the push button down until a WiFi symbol is displayed and joining the Days2Bin wifi access point. Apple devices should then display the settings page via captive portal. Other devices can display the page by browsing to 192.168.4.1 after joining the access point.

Up to three bins can be configured: general waste, recycling, and green waste. The device scrolls the number of days to each type in red, yellow, and green colours respectively, then powers off, unless the button is held on, in which case Settings mode is entered.

On first use, or if the clock battery has failed, users are prompted to join the access point.

The time-out for the access point is 2 minutes.

/**
 * Days2Bin
 * An indicator to show number of days until different kerbside
 * bins/trash/recycling etc are due to be collected.
 *
 * Hardware - Raspberry Pi Pico W, DS3231 RTC and
 * Core Electronics GlowBit (based on WS2812 addressable LEDs).
 *
 * The device is powered on by a pair of logic level MOSFETs
 * triggered by grounding via a momentary pushbutton, and kept alive
 * by one of the Pico W GPIO's.
 *
 * 2024 by John Lamb
 * Licenced under MIT Licence
 */

#include 
#include 
#include "pico/stdlib.h"
#include "hardware/adc.h"
#include "pico/cyw43_arch.h"
#include "pico/float.h"

#include 

#include "flash/flash_utils.h"
#include "peripherals/glowbit.h"
#include "ds3231.h"
#include "GPIO_pin_assignments.h"
#include "peripherals/power_mgr.h"
#include "access_point.h"

/* Globals */

ds3231_t ds3231;                    // DS3231 real time clock
char batteryVoltageStr [8]={};      // Battery voltage

int main()
{
    /* First we have to take over from the pushbutton keep the PICO powered until   */ 
    /* we want to shut down.                                                        */

    power_mgr_init();

    /* Initialise coms for debug messages, and wait to stabilise   */

    stdio_init_all();
    sleep_ms(200);

    /* Initialise the ADC so we can check battery voltage */

    adc_init();

    /* Pico W uses a CYW43 pin to get VBUS so we need to initialise it.                 */
    /* The same pin is used for wi-fi so we need to check the voltage then de-init      */
    /* before the webserver runs.                                                       */

    if (!cyw43_arch_init())
    {
        // Get voltage
        float voltage;
        int voltage_return = power_voltage(&voltage);
        voltage = floorf(voltage * 100) / 100;
        snprintf(batteryVoltageStr,sizeof(batteryVoltageStr),"%.2f",voltage);
        cyw43_arch_deinit();
    }

    /* Initialise ds3231 struct. */

    ds3231_init(&ds3231, i2c_default, DS3231_DEVICE_ADRESS, AT24C32_EEPROM_ADRESS_0);
    sleep_ms(200);

    /* Initialise I2C for the DS3231. */

    gpio_init(DS3231_SDA_PIN);
    gpio_init(DS3231_SCL_PIN);
    gpio_set_function(DS3231_SDA_PIN, GPIO_FUNC_I2C);
    gpio_set_function(DS3231_SCL_PIN, GPIO_FUNC_I2C);
    gpio_pull_up(DS3231_SDA_PIN);
    gpio_pull_up(DS3231_SCL_PIN);
    i2c_init(ds3231.i2c, 400 * 1000);

    /* Initialise Glowbit matrix */

    glowbit_init();

    /* For debugging and development only */
    // make_test_data();
    // write_flash();

    /* Get a pointer to the reserved flash page where   */
    /* our settings are stored.                         */

    Bin_Info *bi = read_flash();

    /* Get the date and time from the DS3231. */

    ds3231_data_t ds3231_data = {};
    ds3231_read_current_time(&ds3231, &ds3231_data);

    if ( (bi[NUM_BIN_KINDS].interval == MAGIC_NUMBER) || (ds3231_data.year==0) )
    {
        /* Here if already set up, ie Magic number in flash, and DS3231 has a non-zero year. */ 

        int dtc[NUM_BIN_KINDS];
        getDaysToCollection(dtc, ds3231_data.century, ds3231_data.year, ds3231_data.month, ds3231_data.date);
        uint32_t binColours[] = {glowbit_RED, glowbit_YELLOW, glowbit_GREEN};
        for (int j = 0; j < 2; j++)
        {
            for (int i = 0; i < NUM_BIN_KINDS; i++)
            {
                char s[10] = {};
                sprintf(s, "%d", dtc[i]);
                uint32_t colour;
                if (dtc[i] > 0)
                    glowbit_scrollText(s, binColours[i]);
            };
        };
    }
    else
    {
        /* Here if no magic number or an invalid date, so prompt to enter set up mode           */
        /* This will occur for first time use, or if RTC battery has failed or been replaced.   */

        glowbit_scrollText("Keep pressing lid to set up ...", glowbit_BLUE);
    }

    /* Is the power on button still on?                 */
    /* If so start web server and await new settings    */ 

    if (!gpio_get(PowerOnButtonGPIO))
    {
        glowbit_scrollText("Join Days2Bin WiFi ...", glowbit_BLUE);
        glowbit_drawChar('~', glowbit_BLUE); // wifi symbol
        glowbit_show();
        access_point();
    }
    else        /* Power down */
    {
        power_mgr_shutDownNow();
    }
}

Download Project Files

All files for this project are available here, this includes the code, 3D model STL files, circuit schematics, and KiCad files.

The compiled .uf2 executable file can also be downloaded, and loaded onto a Pico W by holding the BootSel button on the Pico W while plugging in a USB cable from a computer, then dragged onto the Pico volume.

Have a question? Ask the Author of this guide today!

Please enter minimum 20 characters

Your comment will be posted (automatically) on our Support Forum which is publicly accessible. Don't enter private information, such as your phone number.

Expect a quick reply during business hours, many of us check-in over the weekend as well.

Comments


Loading...
Feedback

Please continue if you would like to leave feedback for any of these topics:

  • Website features/issues
  • Content errors/improvements
  • Missing products/categories
  • Product assignments to categories
  • Search results relevance

For all other inquiries (orders status, stock levels, etc), please contact our support team for quick assistance.

Note: click continue and a draft email will be opened to edit. If you don't have an email client on your device, then send a message via the chat icon on the bottom left of our website.

Makers love reviews as much as you do, please follow this link to review the products you have purchased.