Hi! We created this project as an entry for the Hackster.io - Connect Things With Code! contest sponsored by Infineon.
The WhyCats need a litter box to relieve themselves. Owning one or more cats can sometimes become a hurdle because of this, the smell emanating from the litter box can get pretty bad at times, especially in small apartment homes. They also require constant maintenance from the owner, including emptying the litter, cleaning and washing the box itself, requiring time and energy to be spent on this quite often.
The WhatWe built a self-cleaning litter box, which automates the maintenance steps required for the owner of the cats, allowing them to save time and energy.
Commercially available self-cleaning boxes are quite expensive, which makes it an interesting concept for a DIY project.
The ConceptBefore getting into the details of the project, here's a short video demo of the litter box cleaning process!
The litter box consists of a plastic barrel (the kind usually employed for liquid storage) lying on its side and rotating around its central axis. The rotation originates from two stepper motors that move 4 3D-printed wheels mounted on threaded rods.
The cat enters from one end of the barrel, which has been cut open, and leaves its droppings on the bottom facing side where the cat litter is located. The cleaning process starts once the radar sensor (located inside the barrel) does not detect any movement for 2 minutes.
The cleaning process consists of 4 phases.
1. Filtering: the cat litter passes through a filtering grid by rotating the barrel counter-clockwise. The filtering grid is mounted on a wooden structure attached to the inside of the barrel (which we dubbed the litterrecipient). This process separates the droppings from the actual cat litter, leaving the droppings on top of the grid. The barrel keeps rotating until a limit switch is tripped by a screw attached to the barrel, allowing the droppings to slide on the side of the litter recipient.
2. Dumping: the limit switch triggers the actual dumping of the contents, which consists of fast and alternating rotations of the motors resulting in slight shakes of the barrel. This allows any droppings that might have stuck to the barrel to fall. A hole on the side of the barrel allows the contents to drop out underneath the structure, where a droppings container can be easily placed.
3. Return: once the dumping process is finished the barrel rotates clockwise back to the home position, which is detected by tripping a second limit switch. By rotating clockwise the cat litter exits from the litter recipient and returns to the floor of the barrel.
4. Leveling: with the barrel in its initial position the cat litter is leveled by shaking the barrel again through fast motor movements, making it lay flat on the floor of the barrel.
The following is a simplified state diagram of the process previously described:
Before getting started on how to reproduce our build, a quick introduction to the code used to drive the project. We opted for the Modus Toolbox suite provided by Infineon, which integrates extremely well with the provided board we used for the project (Infineon PSoCβ’ 62S2 Wi-Fi BT, or CY8CKIT-062S2-43012). This means that anyone willing to try and reproduce our project needs to have ModusToolbox properly installed (more details can be found at the top of this page, under the in the "Software apps and online services" section, following the "Infineon ModusToolboxβ’ Software" link). The code has been developed using Visual Studio Code (VSCode for short). While it is not necessary to use VSCode to reproduce our project, it streamlines the process since there is no need to make changes to the code structure.
The linked GitHub repository hosts all the code that was used for this project, in the form of a Visual Studio Code Workspace directory. The next steps describe how to compile and run the code from the repository:
1. Clone the repository from GitHub (if you have never done this, follow this simple tutorial)
2. Import the project into VSCode by selecting "File > Open Workspace from File" and selecting cat-litter-box.code-workspace
from the directory containing the cloned repository
3. Edit the settings.modustoolbox.toolsPath
key to point towards the path of your tools
directory inside the ModusToolbox directory.
4. Run make getlibs
to fetch the necessary dependencies and create the mtb_shared
directory.
If everything was set up correctly you should be able to run make program
in the main project directory and the code will be compiled and copied onto the board!
More details on the code structure can be found in a later section of this page.
BonusHint: we suggest installing the ModusToolbox Assistant extension for VSCode. Saying that it greatly simplifies interactions with the the ModusToolbox suite is an understatement. It also features an error code decoder for cy_rslt_t
values! It was extremely helpful when we needed to figure out why some dependencies were not being imported.
The system's two main components are the base panel and the barrel.
The base panel consists of all the necessary hardware to drive the barrel's rotation and support the overall structure during operations.
The barrel contains the cat litter and the litter recipient attached to its side. Some work was also done on the exterior of the barrel.
What follows is the detailed process for replicating our build, divided into four sections: one for the base panel, one for the barrel exterior, one for the barrel interior, and one for the wiring of all hardware components.
Base panel
We used a plywood board as the foundation for the project's base panel, ensuring the rigidity of the overall structure.
Here's a rundown of the panel structure:
- Six custom 3D-printed brackets (highlighted in green) are attached to the panel by using short screws, which support the rotation of threaded rods. Inside the holes of the brackets, there are six metal pipe pieces to allow the rotation of the threaded rods without them carving away the PLA inside of the brackets, which could happen due to the bending of the rods or slight misplacements
- Four 3D-printed wheels (highlighted in blue) are held in place by metal nuts on the threaded rods; these will support the barrel and transfer the rotation through friction. The wheels are composed of a rigid part made from PLA filament, and a softer "tire" piece printed from TPU filament
- Two stepper motors (highlighted in yellow) rotate the threaded rods thanks to a 3D-printed gear transmission (highlighted in red). The large gears are held in position by metal bolts placed in bolt-shaped slots on the gears bodies
- Two limit switches (highlighted in magenta) are attached to short wooden beams to keep them in the correct position to detect phase changes during the rotation of the barrel
NOTE: you might have noticed we did not provide any measurement or size for the panel layout. While all 3D custom parts are attached to this project page and should be reusable for anyone attempting to replicate our build, the actual positioning of all the components is subject to change depending on the size of the plastic barrel employed. Here are some tips to keep in mind while planning the actual positioning:
- The distance between the threaded rods should allow the barrel to rotate without touching any of the base panel parts (e.g. gears, motors, supports, etc...) except for the wheels, to reduce unwanted friction and casual bumps of the barrel while rotating
- The limit switches beams should be positioned right where the end of the barrel will be during rotation; to simplify this you could leverage a small wooden guide beam as a reference while placing the barrel (visible in the picture above between the rightmost brackets)
- To prevent the wheels from roaming around the threaded rods while rotating, two bolts per wheel should be used, one on each side of each wheel
Barrel (structure)
The barrel we used for the project was a 25-liter plastic barrel similar to the one shown in the following picture:
To make it easier to construct the barrel's interior, we removed the top 2-3 cm to create a plastic disk. We then proceeded to cut a hole in the center of the disk to allow cats to enter the litter box.
One issue that we noted with the hole was that it allowed too much cat litter to slip outside of the barrel. To prevent this we cut a semi-circular piece of plywood and shaped it to act as a lateral barrier while allowing a wide enough hole for cats to enter the barrel. The barrier was then glued to the top disc to keep it firmly in place.
After completing the work on the inside of the barrel, the disc was inserted inside the barrel to reinforce the structure and prevent it from losing its circular shape. The disc was secured to the barrel using six screws on the side.
During the project construction, we discovered that the wheels we used tended to lose grip on the barrel occasionally. To counteract this issue, we decided to hot-glue strips of sanding paper to the barrel. This modification enhanced the friction between the barrel and the wheels, ensuring that the wheels could more effectively transfer their movement to the barrel.
Barrel (inside)
The inside of the barrel (the litter recipient) proved to be the most challenging part to build. It needs to be able to filter the droppings from the cat litter, while also preventing them from merging back together.
NOTE: similar to the base panel, we are not providing specific measurements or sizes for each part of the barrel's inside, since they greatly depend on the barrel used for the build.
The recipient design is similar to the one shown in the picture below.
The concept is to strain the cat droppings with a metal mesh and prevent the litter from mixing back with them by enclosing it in a wooden container. Additionally, one side of the container is curved, to allow the droppings to slide onto it and increase the internal space available to the cat.
Ideally, the container should be constructed from alternative materials or lined with plastic to prevent the droppings from adhering and make cleaning easier. However, we opted for wood since it allowed us to quickly prototype different designs for the recipient.
The recipient is attached to the barrel using long screws, inserted from the outside of the barrel.
After installing the cat litter recipient on the barrel, the last step on the inside of the barrel is to install the BGT60LTR11 Radar Shield2Go at the very end. This enables the detection of cats inside the barrel and initiates the cleaning process when motion stops.
To connect the sensor wires with the Infineon PSoCβ’ 62S2 board, a small hole (~1cm) was cut in the middle of the barrel floor, allowing wires to pass through. We hot-glued a small breadboard to the barrel floor, and then used it to connect the Radar Shield with the wires.
Wiring
The last and crucial part of the project is to wire up the hardware components, so that the Infineon PSoCβ’ 62S2 board can talk to them and everything can be controlled properly.
It is probably easier to explain this step by showing a simplified circuit diagram of the overall system. You can find it attached to this project at the bottom of the page.
NOTE: all pins on the Infineon PSoCβ’ 62S2 board can be changed by altering their corresponding constants in the consts.h
file.
This section gets a little into more detail about the structure of the code for the project, and what each piece is tasked with.
The following is the tree structure of the code repository:
βββ bsps <-- contains the BSP specs for the target platform
β βββ TARGET_APP_CY8CKIT-062S2-43012
βββ cat-litter-box.code-workspace <-- VSCode workspace file
βββ deps <-- dependencies, managed by ModusToolbox
βββ libs <--dependencies, managed by ModusToolbox
βββ source <-- source code for the firmware
The source directory is going to be our focus for now. Feel free to reach out in the comments for more details regarding the other directories!
The code's general system behavior relies on triggering state changes via hardware interrupts while putting the CPU to sleep for the remainder of the time. If you are not familiar with the concept of interrupts, check out this article on the subject.
The firmware's main
function is in source/main.c
, serving as the entry point. Its objective is to initialize data structures and put the CPU to sleep, awaiting hardware interrupts.
Hardware APIs
We have devised two simple modules to ease interactions with some of the hardware components involved:
motor.c
(andmotor.h
) provide a useful API for stepper motor control for DRV8825-based driverslimit_switch.c
(andlimit_switch.h
) simplify the management of callback functions when a limit switch triggers
Both modules have been designed by defining a data structure that contained all the relevant information for the specific hardware component (e.g. the motor speed, rotation direction, pins, etc...) and a set of functions interacting with such data structures.
motor.c
data structures and functions
typedef enum
{
MOTOR_ROT_CLOCK,
MOTOR_ROT_COUNTERCLOCK,
} motor_rot_dir_t;
// Type for the possible states of the stepper motor
typedef enum
{
MOTOR_STATE_ON,
MOTOR_STATE_OFF,
} motor_state_t;
typedef struct {
cyhal_pwm_t pwm_step_pin;
cyhal_gpio_t gpio_dir_pin;
motor_state_t current_motor_state;
motor_rot_dir_t current_rotation_direction;
} motor_data_t;
cy_rslt_t motor_init(motor_data_t *motor, cyhal_gpio_t step_pin, cyhal_gpio_t dir_pin);
cy_rslt_t motor_stop(motor_data_t *motor);
cy_rslt_t motor_start(motor_data_t *motor, uint16_t speed);
cy_rslt_t motor_set_rotation_direction(motor_data_t *motor, motor_rot_dir_t direction);
limit_switch.c
data structure and functions
typedef struct
{
uint32_t gpio_control_pin;
cyhal_gpio_callback_data_t callback;
} limit_switch_data_t;
cy_rslt_t limit_switch_init(limit_switch_data_t *limit_switch, cyhal_gpio_t control_pin, void *callback);
cy_rslt_t limit_switch_update_pin(limit_switch_data_t *limit_switch, cyhal_gpio_t control_pin);
cy_rslt_t limit_switch_update_callback(limit_switch_data_t *limit_switch, void *callback);
For more details regarding the specific functions please refer to the code comments in both files.
These functions are called from callback functions defined inside the main.c
file in order to properly interact with limit switches and motors.
One particular function that leverages the motor API is the shake
function from main.c
:
void shake(uint32_t speed, uint16_t delay, uint16_t shakes_count)
{
// Start all motors
for (size_t i = 0; i < MOTORS_COUNT; i++)
{
motor_start(&motors[i], speed);
}
// Shake shakes_count times
for (uint16_t i = 0; i < shakes_count; i++)
{
// Set each motor to rotate clockwise;
for (size_t i = 0; i < MOTORS_COUNT; i++)
{
motor_set_rotation_direction(&motors[i], MOTOR_ROT_CLOCK);
}
cyhal_system_delay_ms(delay);
// Invert rotation direction
for (size_t i = 0; i < MOTORS_COUNT; i++)
{
motor_set_rotation_direction(&motors[i], MOTOR_ROT_COUNTERCLOCK);
}
cyhal_system_delay_ms(delay);
}
// Stop all motors
for (size_t i = 0; i < MOTORS_COUNT; i++)
{
motor_stop(&motors[i]);
}
}
State functions
The system states described in TheConcept section of this project can be identified as functions inside the main.c
file.
filter_litter
ββ Filter statedump_contents
ββ Dump statereset_position
ββ Return statelevel_litter
ββ Level state
Each of them begins with a simple state check, to make sure they are not executed while the system is in the wrong state (e.g. dump_contents
can only be called while the system is in the Filter state, moving into the Dump state). What follows the state checking part is the actual logic for the state, which varies for each function as described in the first part of this project.
Some functionalities we originally thought of ended up not being part of the project since the deadline for the contest quickly approached. We figured that we could implement them in the future, ideally turning this project into a valid and cheaper alternative to commercially available self-cleaning cat litter boxes.
Some of these ideas are:
- Measure cat, droppings and cat litter weight by adding piezoelectric sensors to the base panel of the structure
- Improve torque transfer from the motors by experimenting with different types of transmissions (e.g. by attaching a gear directly to the barrel)
- Add some sort of easily removable droppings container on the base panel (or, even better, a pressurized container to prevent odors)
- Make the litter box really smart by providing a Wi-Fi accessible dashboard, which would open all sorts of possibilities for interaction with the system (e.g. notifications on litterbox usage, statistics, system status analysis, forced operations and cleaning, etc...)
- Implement a pressure washing feature for the barrel, which could leverage a water tank and pump
Comments