Introduction: Cat Litter Box Cleaning Indicator/Timer
Author's note: This Instructable was written and published by our Making and Tinkering Programs Manager, who's personal Instructable account we co-opted. He is now publishing personal Instructables over at member ID MechaNickW.
We only have a single cat in our household, but multiple people that clean the litter box. It's one of those tasks that nobody wants to do, but it needs to be done regularly. Since it's not a common subject of daily conversation that we want to waste time talking about, sometimes it can go longer than you'd like between cat litter box cleanings, which is not good for the cat or house/apartment! Instead of trying to remember when it was last cleaned and who did so, it's much easier to have a visual indicator for an approximate amount of time elapsed since cleaning. This project details a method using a microprocessor (AdaFruit Trinket or Arduino Uno) to measure the time elapsed since a switch was last triggered, and output that time in a user-friendly way. If it's been less than 24 hours, the light is green. 24-48, yellow. Over 48 hours it's red, and definitely time to clean it.
Cat litter boxes should be cleaned daily ideally, though life can get busy and you'll forget - this project should help you keep on top of things. Also, the enclosure I designed is a cat's butt with an LED shining out of it, because they are iconic and one half of the reason for cleaning the litter box in the first place!
Supplies
- Project Enclosure (see attached 3D design in the enclosure step to print one, or use what you have)
- Microprocessor - code is included here for an Adafruit Trinket 3V ($6.95) or Arduino Uno ($22.95)
- RGB LED - I had a common anode, if you use a common cathode you'll have to tweak the code
- Magnetic reed switch - if your box has a lid, this is an easy way to do things. You can use a pushbutton switch as well
- If you're using the Uno, you'll want a 10K ohm resistor as well for the reed switch
- Power supply - batteries did not last as long as I'd thought, I ended up switching to a 5V supply for the Trinket. Either microprocessor has a wide range for input voltage, reuse a cell phone charger or something similar - as long as it's in the proper input range you're good.
Step 1: Plan Your Installation
There's a wide variety of cat litter boxes out there that this could be adapted to. If yours has a removable lid/top like mine, there's nothing you'll need to change about this Instructable. Make sure your litter box is close to an outlet and you're good. If it doesn't have a lid, you might make something for the cat litter scoop to rest on which presses down the input button, so that when you lift up the scoop the light changes - or you can simply design things so that when you clean the litter box, you push the button to reset the timer - do whatever works best for you!
Important safety note: Sometimes cats are very, very interested in cables and wires and such. You don't want your cat to chew on the wires going to your electronics, so hide it under a rug or the litter pan itself, etc. Just be wary of this when setting up this installation, we don't want your kitty to get injured or cause a potential electrical fire!
Step 2: Upload Code to Trinket Microprocessor
Getting the code to work properly for this project took a lot of time and debugging. The microprocessors used are very picky about how they keep time for very long periods (days/weeks) because of some complicated internal architecture with the chips. Also, interrupts are somewhat complicated to get working on top of the timekeeping functions of the chips. Fortunately, I've done all of that hard work for you! I built this and uploaded code in 2016, it's worked flawlessly since then. The comments in the code indicate which parts do what. If you want to change the time interval for how long the LED is green, yellow, red, convert your desired time period into milliseconds and change the lines for greenTime, yellowTime and redTime.
First, you'll need to download the elapsedMillis library. This is necessary for both the Arduino and Trinket codes. This is necessary for the timekeeping part of the code. This guide has helpful tips for getting libraries installed if it's not something you've done before.
For the Adafruit Trinket, uploading code is different than for the Uno in the IDE. See this page for tips. If you're having troubles, you might try uploading through a USB port instead of your computer's direct port - that can solve a lot of issues. I recommend uploading code before doing the final soldering for Trinket! You ideally should upload the code, plug all as indicated in the next step into a breadboard to test before soldering and installing in an enclosure. On to the code!
/*
Cat Pan Code Trinket 3V */ #includeint redPin = 1; // red pin of RGB LED int greenPin = 4; // green leg of RGB LED volatile int sensor = 0; // magnetic reed switch on Pin 2 (external interrupt pin) unsigned long greenTime = 86400000; // duration of time up until which the LED is to be green in milliseconds (24 hours) unsigned long yellowTime = 86400001; // duration of time after which LED is to be yellow in milliseconds (between 24-48 hours) unsigned long redTime = 172800000; // duration of time after which LED is to be red in milliseconds (more than 48 hours) elapsedMillis last_Cleaned; // Variable to track elapsed time since the box was last cleaned/switch was last triggered elapsedMillis interrupt_time; //Variable to debounce switch #define COMMON_ANODE // comment this out if you are using a common cathode RGB LED - you will have to determine this from a datasheet or experimentation. void setup() { PCMSK = 0b00000100; // turn on interrupts on pins PB2 sei(); // enables interrupts pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(sensor, INPUT); attachInterrupt(sensor, pin_ISR, CHANGE); // Interrupt for change of pin 2 (switch) to CHANGE. Initiates interrupt funcion pin_ISR. }
void loop() { if ( last_Cleaned <= greenTime) //If time elapsed is equal to or less than greenTime {setColor(0, 100); //set RGB to green } else if((last_Cleaned >= yellowTime) && ( last_Cleaned <= redTime)) //If time elapsed is equal to or greater than yellowTime but not more than redTime {setColor(125, 125); //set RGB to yellow } else if( last_Cleaned > redTime) //If time elapsed is equal to or greater than redTime {setColor(100, 0); // set RGB to red } } void pin_ISR(){ static unsigned long last_interrupt_time; //Variable to debounce switch - time elapsed since last interrupt trigger if (interrupt_time - last_interrupt_time > 1000) // If interrupts come faster than 1000ms, assume it's a bounce and ignore { last_Cleaned = 0; // If the state of the reed switch changes, reset the timer to 0 } last_interrupt_time = interrupt_time; // Resets last_interrupt_time to match interrupt_time for comparison at beginning of function } void setColor(int red, int green) //To set the colors of the RGB led { #ifdef COMMON_ANODE red = 255 - red; green = 255 - green; #endif analogWrite(redPin, red); analogWrite(greenPin, green); }
Step 3: Upload Code to Arduino Uno
If you're using an Arduino Uno, use this code instead. They are different because of how the interrupts are called and some other boring stuff you don't need to worry too much about. Please note you'll need the elapsedMillis library installed, as indicated in the previous step.
/*
Cat Pan Code Arduino Uno */ #includeint redPin = 11; // red pin of RGB LED int greenPin = 10; // green leg of RGB LED volatile int sensor = 2; // magnetic reed switch on Pin 2 (external interrupt pin) unsigned long greenTime = 86400000; // duration of time up until which the LED is to be green in milliseconds (24 hours) unsigned long yellowTime = 86400001; // duration of time after which LED is to be yellow in milliseconds (between 24-48 hours) unsigned long redTime = 172800000; // duration of time after which LED is to be red in milliseconds (more than 48 hours) elapsedMillis last_Cleaned; // Variable to track elapsed time since the box was last cleaned/switch was last triggered elapsedMillis interrupt_time; //Variable to debounce switch #define COMMON_ANODE // comment this out if you are using a common cathode RGB LED - you will have to determine this from a datasheet or experimentation. void setup() { pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(sensor, INPUT); attachInterrupt(digitalPinToInterrupt(sensor), pin_ISR, CHANGE); // Interrupt for change of pin 2 (switch) to CHANGE. Initiates interrupt funcion pin_ISR. }
void loop() { if ( last_Cleaned <= greenTime) //If time elapsed is equal to or less than greenTime {setColor(0, 100); //set RGB to green } else if((last_Cleaned >= yellowTime) && ( last_Cleaned <= redTime)) //If time elapsed is equal to or greater than yellowTime but not more than redTime {setColor(125, 125); //set RGB to yellow } else if( last_Cleaned > redTime) //If time elapsed is equal to or greater than redTime {setColor(100, 0); // set RGB to red } } void pin_ISR(){ static unsigned long last_interrupt_time; //Variable to debounce switch - time elapsed since last interrupt trigger if (interrupt_time - last_interrupt_time > 1000) // If interrupts come faster than 1000ms, assume it's a bounce and ignore { last_Cleaned = 0; // If the state of the reed switch changes, reset the timer to 0 } last_interrupt_time = interrupt_time; // Resets last_interrupt_time to match interrupt_time for comparison at beginning of function } void setColor(int red, int green) //To set the colors of the RGB led { #ifdef COMMON_ANODE red = 255 - red; green = 255 - green; #endif analogWrite(redPin, red); analogWrite(greenPin, green); }
Step 4: Wire the Microprocessor and Components
Wire as shown above. It is very important that you wire the circuit to the pins as shown - the code uses interrupts, which is a service that runs only on specific pins both on the Uno and on the Trinket. If you switch things around and then change the code, it may not work! If you are using a different microprocessor than the two indicated, see the datasheet for which pins have available interrupts. You'll want to thread your power supply cable and the magnetic reed switch leads through the enclosure hole detailed in the next step before soldering to your microprocessor. I used female jumpers and plugged the legs of the LED into those, and a JST connector for the reed switch to be able to remove it - do what works for you with what you have, though!
For the Adafruit Trinket:
- Pin 1 goes to the red leg of the LED
- Pin 4 goes to the green leg of the LED
- 3.3V goes to the common anode leg of the LED
- Pin 2 goes to one wire on the reed switch (doesn't matter which)
- GND is wired to the other leg of the reed switch
- Wire the positive side of your power source to BAT+
- Wire the negative side of your power source to GND
For the Arduino Uno:
- Pin 11 goes to the red leg of the LED
- Pin 10 goes to the green leg of the LED
- 3.3V goes to the common anode leg of the LED
- Pin 2 goes to to one wire of the reed switch
- A 10K ohm resistor is wired in series between Pin 2 and GND
- 5V goes to the other leg of the reed switch
- You can plug in a power supply/wall wart adapter to the input jack of the Uno, or wire it to the Vin pin - just make sure it's in range of the input voltage of the Uno!
Step 5: Print Enclosure and Install Electronics
I designed the enclosure attached to this step to house a lot of stuff - you can fit the Uno in there and wire through the hole in the side - you might have to drill out the hole to be bigger for your cables/power source, depending on how big the cables are. I used a 10mm LED, that is what the cat butt fits, you can use some hot glue to get a smaller LED to fit just fine. I just glued the enclosure to the side of the cat litter box.
Low infill on printing is fine for this, if your printer has decent tolerances the lid will snap snugly into the base.
The magnetic reed switch is wired through the hole in the enclosure and goes outside of it, attached to the bottom of the litter box. The other part of the reed switch (it's the magnetic one) will go on the lid - make sure they are very close together, as close as possible - if they are separated too much, the switch will not work properly! Set them up so that when the lid is closed, they are aligned well.
Step 6: Get to Cleaning!
Test out your project - if the light turns yellow after 24 hours, you're there! Open the box to clean it out, and it should reset to green. If the light turns red, it's been over 48 hours since the box was cleaned - better get to it! If you have any issues with the light turning green when it shouldn't simply unplug and plug back in - though it's relatively stable over longer periods of time, sometimes after a couple of months it needs a reset.
This Instructable is entered into the Pets Challenge - please vote if you find it useful or plan on making it, and comment to share input or your own ideas for how to adapt this. Thanks for looking!