My cat refuses to use the scratch board I bought for her, so I made this device to motivate her to use it instead of my sofa… we'll see how that works…
Attached to the scratch board is an MPU6050 accelerometer that monitors interaction with the board. If the cat uses the board, the servo is triggered to dispense a treat.
Here is a WIP preview of the device. The electronics are not integrated yet.
Parts List
Arduino Nano (I used a Nano Every but any other variation with the same size should work - other third-party alternatives may even be smaller, those should work fine too)
MPU6050 inertial measurement unit (IMU).
HW-085 5V step-up converter to boost the battery voltage to 5V for powering the arduino and the servo (others will work as well, this is just what I had)
Li-Ion battery (at most 40mm x 75mm x 22mm). I used an 18650 in a battery holder. The battery compartment is large enough to take a battery holder for two 18650 batteries.
Feetech FS90 Micro Servo
wires and connectors
a short piece (6-7mm) of 1,75mm filemant
All the 3D-printed parts from this listing
Software used
FreeCAD for the part design
Arduino IDE for programming and uploading the code to the microcontroller
Fritzing for the wiring diagram
Blender & Krita for making the images in this listing
git/github for code versioning
Assembly Overview
Here you can see the main corpus parts.
Electronics Compartment The left is meant for the Arduino and the voltage regulator. It is a bit tight in there. In retrospect I should have made this a bit larger. The slots at the side are used to attach the Arduino and voltage regulator using the two clips (not shown in image). The right, larger compartment was designed to take a 2x18650 battery holder.
Base & Base Extension At the back of this two-part compound is a slot that takes the servo. There is a slot to route the servo cable into the electronics compartment. The Base's bottom ledge has two cutouts that the hopper (not shown in image) will slot-in.
Sled The Sled will be moved by the servo. It has three positions: center and one beneath each hopper tube. When it moves towards one of the sides, a treat will fall into the hole in the middle. When the sled moves back to the center, the treat will fall thrugh the Chute. The controller will move the sled alternating between the two tubes to take treats equally from both sides. The Sled will be connected to the servo by a short (6-7mm) piece of 1,75mm filament.
Bottom The bottom part of the assembly. Holds the Sled and Chute.
Chute Redirects the treat away from the wall.
Step 1 - Insert Chute into Bottom
Push the Chute at an angle into the slot in the bottom.
When it is fully inserted, rotate the front part of the chute down to level the chute's upper edge with the bottoms surface.
Make sure the Chute's top edge is below the sled guide's surface by pressing it in firmly. Otherwise the sled may get stuck and the servo won't be able to move it.
Step 2 - insert Sled
Step 3 - attach Base
Instead of two long rails as the last two parts, this connection only has four short studs. Make sure they are aligned. It may be a bit difficult to get them all in at once. I needed some force (placing the parts upright on the table and gently hammering on them with the heel of my hand).
The Sled should slide smothly in its slot at this point.
Step 4 - Attach Base Extension and Electronics Compartment
As with the previous step, slotting the pieces together may need some force. But here the alignment is not that much of an issue as only the two slots need to be aligned.
When fully assembled, make sure the back sides of all the individual pieces align.
Four pieces were not described yet:
Arduino Nano Clip & Voltage Regulator Clip These parts hold the Arduino and the voltage regulator. Attach the boards first (simply clip them on to the clips), before inserting them into the inner wall of the electronics compartment. As space is quite tight in there, I recommend using tweezers to get them in.
Electronics Cover Just a cover that goes on the electronics compartment. Place it when everything is installed inside.
Hopper The Hopper consists of two pipes that are holding the treats. It simply slides into the square cutouts in the Base part. Attach this last and finally fill the hopper with treats.
Installing the servo
Connect the servo to the Arduino running the code from the repository below and power it on. The servo will now turn to its 90°-position. Disconnect the servo and install the servo horn.
The horn should point straight up when the servo lays on its side. Make sure to put it the right way up. You can see it from the two images below. When inserted into the slot at the back of the 3D-printed case, the horn should point into the part.
Now insert the piece of filament into the servo horn's large hole. Align the horn with the slot in the Sled so that the filament connects the two. Now slide the servo back and clip it into its slot.
If this doesn't work you can also take the bottom off, then install the servo into its slot and reattach the bottom again, making sure the filament-pin is in place.
Wiring
Power
connect battery+ with the In+ pin of the voltage regulator
connect battery- with the In- pin of the voltage regulator
connect the voltage regulator's Out+ pin to the servo's red wire and the Arduino's Vin contact
connect the voltage regulator's Out- pin to the servo's black/brown wire and the Arduino's GND contact
connect the MPU's VCC contact to the Arduino's 5V contact
connect the MPU's GND contact to the Arduino's GND contact
Logic
connect the servo's data-pin (usually yellow or orange) to the Arduino's D9 contact. This is a PWM pin. If you need to use another pin, make sure it is a PWM pin (usually marked with a ~) and don't forget to change that pin in the code as well (PIN_SERVO)
connect the MPU's…
SCL to the Arduino's A5
SDA to the Arduino's A4
You can find an svg version of this graphic in the Other Files section.
Comissioning
Flashing the code onto the Arduino should have happened already during assembly as it is required for installing the servo.
When the Arduino is powered on, it will initially wait for a moment (5 seconds) to allow the device to settle and vibration to fade out.
Then, there is a brief calibration procedure that analyses the accelerometer's data to detect the sensor noise without the device moving. Don't move the sensor during that time as this will reduce the sensitivity later on.
When calibration is complete, the servo will slightly twitch to show that the calibration is complete. Moving the MPU now will trigger a treat-dispensing now.
There are a few parameters that can be changed in code to adjust the behavior. These are:
Dispense Cooldown: When dispensing was triggered, the next trigger will not happen until this cooldown is over. Default: 5 seconds
Dispense Amount: The number of treats that will be dispensed when triggerd. Default: 1
Dispense Period Length & Dispense Amount per Period: The period is a means of limiting the number of treats that are dispensed over time. During a period only the set amount per period will be dispensed. Example: period length is set to 60 minutes and amount per period is set to 3 (these are the defaults). Within the 60 minutes after the first dispensing was triggered, only 3 treats will be dispensed in total. This can happen during the first minute or over the whole period's time. Once the period has passed after a dispense, that ‘slot’ will be cleared and another treat is ready for dispensing.
Dispense Interaction Duration: This is a means of controlling the sensitivity for triggering. Interactions with the MPU need to be recorded for at least this amount of time before the treat is dispensed. Higher values require longer interactions. Default: 3 seconds
Dispense Interaction Timeout: An interaction can consist of multiple small interactions, not only a continuous long one. This is the time before a interaction will time out. If another interaction is recorded within this period, this is considered the same interaction. Default: 2 seconds
The parameters mentioned in the above section are these:
DISPENSE_COOLDOWN
DISPENSE_AMOUNT
DISPENSE_PERIOD_LENGTH
DISPENSE_AMOUNT_PER_PERIOD
DISPENSE_INTERACTION_DURATION
DISPENSE_INTERACTION_TIMEOUT
Those values are in milliseconds.
The calibration uses a ring buffer to store the last 50 samples from all relevant sensor readings. The values stored in the ring buffer are used to calculate the average of all the values. This average is used as the base-line for detecting movement.
An interaction is recorded when the current acceleration value exceeds the sensor's average + a threshold value. The threshold is calculated from the noise measured during the start-up period.
This way a sensor value drift is not a problem as long as it happens slowly.
Printing Instructions
The parts are already oriented in the way they should be printed.
Material: PLA
Layer Height: 0,2 mm
Infill: 15%
I used a brim for all of the parts although that might not be necessary for the larger parts. In particular I had problems with bed adhesion when printing the Sled. Without, it just didn't stick. For the two small clips a brim is highly recommended.
Only the Base Extension-part needs supports because of the large overhang for the servo and the servo cable. I used auto-tree supports. This is how I painted the supports in Orca Slicer (green: support, red: no support).
Room for Improvements
add power switch - I was a bit under time pressure for this project. So I simply forgot to consider this
cut power to servo when not needed
arduino power management. sleep when unused
improve motion detection to avoid triggering when mounted to a door and that is moved
improve Electronics Cover so it snaps shut. It works as it is but I'd prefer a snappier attachment
add hopper cap to protect the treats from dust and (at least a bit) moisture